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: 55476 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [199.232.76.165]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 8D037B7D99 for ; Mon, 14 Jun 2010 16:15:36 +1000 (EST) Received: from localhost ([127.0.0.1]:42900 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1OO2lY-0008LT-74 for incoming@patchwork.ozlabs.org; Mon, 14 Jun 2010 02:03:24 -0400 Received: from [140.186.70.92] (port=49903 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1OO2aC-0004BI-TF for qemu-devel@nongnu.org; Mon, 14 Jun 2010 01:51:42 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.69) (envelope-from ) id 1OO2a8-00085b-VW for qemu-devel@nongnu.org; Mon, 14 Jun 2010 01:51:40 -0400 Received: from qmta05.emeryville.ca.mail.comcast.net ([76.96.30.48]:36443) by eggs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1OO2a8-00085S-MR for qemu-devel@nongnu.org; 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 VhgL1e0020lTkoCA5hrbjg; 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 To: qemu-devel@nongnu.org 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 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. Cc: chrisw@redhat.com, kvm@vger.kernel.org, paul@codesourcery.com, alex.williamson@redhat.com, kraxel@redhat.com, avi@redhat.com Subject: [Qemu-devel] [RFC PATCH 3/5] savevm: Make use of the new DeviceState param X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Use the now passed in DeviceState along with qdev_get_dev_path() to create meaningful id strings for the SaveStateEntry. We append the driver provided string so we can differentiate multiple savevm handlers per device: "/main-system-bus/pci.0,addr=03.0/i82551,mac=52:54:00:12:34:56/eeprom" "/main-system-bus/pci.0,addr=03.0/i82551,mac=52:54:00:12:34:56/i82551" We also introduce compatibility fields so that we can attempt to import savevm data from an older VM. These should be deprecated and removed at some point. Signed-off-by: Alex Williamson --- savevm.c | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 files changed, 76 insertions(+), 7 deletions(-) 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; }