From patchwork Mon Jun 14 05:51:34 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alex Williamson X-Patchwork-Id: 105869 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter.kernel.org (8.14.3/8.14.3) with ESMTP id o5E5pPZS030903 for ; Mon, 14 Jun 2010 05:51:45 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752450Ab0FNFvg (ORCPT ); Mon, 14 Jun 2010 01:51:36 -0400 Received: from qmta05.emeryville.ca.mail.comcast.net ([76.96.30.48]:42517 "EHLO qmta05.emeryville.ca.mail.comcast.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752234Ab0FNFvg (ORCPT ); Mon, 14 Jun 2010 01:51:36 -0400 Received: from omta04.emeryville.ca.mail.comcast.net ([76.96.30.35]) by qmta05.emeryville.ca.mail.comcast.net with comcast id Vhrb1e0040lTkoCA5hrbji; Mon, 14 Jun 2010 05:51:35 +0000 Received: from localhost.localdomain ([75.71.122.219]) by omta04.emeryville.ca.mail.comcast.net with comcast id Vhra1e0044k7Kz78Qhra08; Mon, 14 Jun 2010 05:51:35 +0000 From: Alex Williamson Subject: [RFC PATCH 3/5] savevm: Make use of the new DeviceState param To: qemu-devel@nongnu.org Cc: kvm@vger.kernel.org, avi@redhat.com, anthony@codemonkey.ws, paul@codesourcery.com, kraxel@redhat.com, chrisw@redhat.com, alex.williamson@redhat.com Date: Sun, 13 Jun 2010 23:51:34 -0600 Message-ID: <20100614055134.879.72781.stgit@localhost.localdomain> In-Reply-To: <20100614054923.879.33717.stgit@localhost.localdomain> References: <20100614054923.879.33717.stgit@localhost.localdomain> User-Agent: StGIT/0.14.3 MIME-Version: 1.0 Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter.kernel.org [140.211.167.41]); Mon, 14 Jun 2010 05:51:45 +0000 (UTC) diff --git a/savevm.c b/savevm.c index 81d544f..4cc542b 100644 --- a/savevm.c +++ b/savevm.c @@ -1002,6 +1002,8 @@ typedef struct SaveStateEntry { LoadStateHandler *load_state; const VMStateDescription *vmsd; void *opaque; + char compat_idstr[256]; + int compat_instance_id; } SaveStateEntry; @@ -1023,6 +1025,20 @@ static int calculate_new_instance_id(const char *idstr) return instance_id; } +static int calculate_new_compat_instance_id(const char *idstr) +{ + SaveStateEntry *se; + int instance_id = 0; + + QTAILQ_FOREACH(se, &savevm_handlers, entry) { + if (strcmp(idstr, se->compat_idstr) == 0 + && instance_id <= se->compat_instance_id) { + instance_id = se->compat_instance_id + 1; + } + } + return instance_id; +} + /* TODO: Individual devices generally have very little idea about the rest of the system, so instance_id should be removed/replaced. Meanwhile pass -1 as instance_id if you do not already have a clearly @@ -1040,7 +1056,16 @@ int register_savevm_live(DeviceState *dev, SaveStateEntry *se; se = qemu_mallocz(sizeof(SaveStateEntry)); - pstrcpy(se->idstr, sizeof(se->idstr), idstr); + + if (dev) { + char *path = qdev_get_dev_path(dev); + pstrcpy(se->idstr, sizeof(se->idstr), path); + pstrcat(se->idstr, sizeof(se->idstr), "/"); + pstrcat(se->idstr, sizeof(se->idstr), idstr); + qemu_free(path); + } else { + pstrcpy(se->idstr, sizeof(se->idstr), idstr); + } se->version_id = version_id; se->section_id = global_section_id++; se->set_params = set_params; @@ -1050,11 +1075,19 @@ int register_savevm_live(DeviceState *dev, se->opaque = opaque; se->vmsd = NULL; + pstrcpy(se->compat_idstr, sizeof(se->idstr), idstr); if (instance_id == -1) { - se->instance_id = calculate_new_instance_id(idstr); + se->instance_id = calculate_new_instance_id(se->idstr); + se->compat_instance_id = calculate_new_compat_instance_id(idstr); } else { - se->instance_id = instance_id; + se->instance_id = se->compat_instance_id = instance_id; + } + + if (dev && instance_id == -1 && se->instance_id != 0) { + fprintf(stderr, "%s: Failed to create unqiue path \"%s\"\n", + __FUNCTION__, se->idstr); } + /* add at the end of list */ QTAILQ_INSERT_TAIL(&savevm_handlers, se, entry); return 0; @@ -1075,13 +1108,25 @@ int register_savevm(DeviceState *dev, void unregister_savevm(DeviceState *dev, const char *idstr, void *opaque) { SaveStateEntry *se, *new_se; + char *path; + + if (dev) { + int len; + path = qdev_get_dev_path(dev); + len = strlen(path); + path = qemu_realloc(path, len + strlen(idstr) + 2); + sprintf(path + len, "/%s", idstr); + } else { + path = qemu_strdup(idstr); + } QTAILQ_FOREACH_SAFE(se, &savevm_handlers, entry, new_se) { - if (strcmp(se->idstr, idstr) == 0 && se->opaque == opaque) { + if (strcmp(se->idstr, path) == 0 && se->opaque == opaque) { QTAILQ_REMOVE(&savevm_handlers, se, entry); qemu_free(se); } } + qemu_free(path); } int vmstate_register_with_alias_id(DeviceState *dev, int instance_id, @@ -1095,7 +1140,16 @@ int vmstate_register_with_alias_id(DeviceState *dev, int instance_id, assert(alias_id == -1 || required_for_version >= vmsd->minimum_version_id); se = qemu_mallocz(sizeof(SaveStateEntry)); - pstrcpy(se->idstr, sizeof(se->idstr), vmsd->name); + + if (dev) { + char *path = qdev_get_dev_path(dev); + pstrcpy(se->idstr, sizeof(se->idstr), path); + pstrcat(se->idstr, sizeof(se->idstr), "/"); + pstrcat(se->idstr, sizeof(se->idstr), vmsd->name); + qemu_free(path); + } else { + pstrcpy(se->idstr, sizeof(se->idstr), vmsd->name); + } se->version_id = vmsd->version_id; se->section_id = global_section_id++; se->save_live_state = NULL; @@ -1105,11 +1159,19 @@ int vmstate_register_with_alias_id(DeviceState *dev, int instance_id, se->vmsd = vmsd; se->alias_id = alias_id; + pstrcpy(se->compat_idstr, sizeof(se->idstr), vmsd->name); if (instance_id == -1) { - se->instance_id = calculate_new_instance_id(vmsd->name); + se->instance_id = calculate_new_instance_id(se->idstr); + se->compat_instance_id = calculate_new_compat_instance_id(vmsd->name); } else { - se->instance_id = instance_id; + se->instance_id = se->compat_instance_id = instance_id; } + + if (dev && instance_id == -1 && se->instance_id != 0) { + fprintf(stderr, "%s: Failed to create unqiue path \"%s\"\n", + __FUNCTION__, se->idstr); + } + /* add at the end of list */ QTAILQ_INSERT_TAIL(&savevm_handlers, se, entry); return 0; @@ -1456,6 +1518,13 @@ static SaveStateEntry *find_se(const char *idstr, int instance_id) instance_id == se->alias_id)) return se; } + + QTAILQ_FOREACH(se, &savevm_handlers, entry) { + if (!strcmp(se->compat_idstr, idstr) && + (instance_id == se->compat_instance_id || + instance_id == se->alias_id)) + return se; + } return NULL; }