From patchwork Thu Jun 3 07:22:24 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yoshiaki Tamura X-Patchwork-Id: 54457 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 64878B7D1C for ; Thu, 3 Jun 2010 17:32:50 +1000 (EST) Received: from localhost ([127.0.0.1]:38217 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1OK4px-00054c-UO for incoming@patchwork.ozlabs.org; Thu, 03 Jun 2010 03:27:34 -0400 Received: from [140.186.70.92] (port=58297 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1OK4lo-0002GX-Mu for qemu-devel@nongnu.org; Thu, 03 Jun 2010 03:23:19 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.69) (envelope-from ) id 1OK4lm-00052d-NF for qemu-devel@nongnu.org; Thu, 03 Jun 2010 03:23:16 -0400 Received: from sh.osrg.net ([192.16.179.4]:50932) by eggs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1OK4lm-00051x-59 for qemu-devel@nongnu.org; Thu, 03 Jun 2010 03:23:14 -0400 Received: from fs.osrg.net (postfix@fs.osrg.net [10.0.0.12]) by sh.osrg.net (8.14.3/8.14.3/OSRG-NET) with ESMTP id o537N82r010557; Thu, 3 Jun 2010 16:23:08 +0900 Received: from localhost (hype-wd0.osrg.net [10.72.1.16]) by fs.osrg.net (Postfix) with ESMTP id AB0FA3E02D1; Thu, 3 Jun 2010 16:23:08 +0900 (JST) From: Yoshiaki Tamura To: qemu-devel@nongnu.org Date: Thu, 3 Jun 2010 16:22:24 +0900 Message-Id: <1275549747-18061-2-git-send-email-tamura.yoshiaki@lab.ntt.co.jp> X-Mailer: git-send-email 1.7.0.31.g1df487 In-Reply-To: <1275549747-18061-1-git-send-email-tamura.yoshiaki@lab.ntt.co.jp> References: <1275549747-18061-1-git-send-email-tamura.yoshiaki@lab.ntt.co.jp> X-Dispatcher: imput version 20070423(IM149) Lines: 280 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-3.0 (sh.osrg.net [192.16.179.4]); Thu, 03 Jun 2010 16:23:09 +0900 (JST) X-Virus-Scanned: clamav-milter 0.96 at sh X-Virus-Status: Clean X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 2) Cc: aliguori@us.ibm.com, Yoshiaki Tamura Subject: [Qemu-devel] [PATCH 1/4] savevm: refactor qemu_loadvm_state(). 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 Split qemu_loadvm_state(), and introduce qemu_loadvm_state_{begin,iterate,complete,async}. qemu_loadvm_state_async() is a function to handle a single incoming section. Signed-off-by: Yoshiaki Tamura --- savevm.c | 206 +++++++++++++++++++++++++++++++++++++++++++------------------- sysemu.h | 2 + 2 files changed, 146 insertions(+), 62 deletions(-) diff --git a/savevm.c b/savevm.c index dc20390..aa4f98c 100644 --- a/savevm.c +++ b/savevm.c @@ -1005,6 +1005,8 @@ typedef struct SaveStateEntry { static QTAILQ_HEAD(savevm_handlers, SaveStateEntry) savevm_handlers = QTAILQ_HEAD_INITIALIZER(savevm_handlers); +static QLIST_HEAD(, LoadStateEntry) loadvm_handlers = + QLIST_HEAD_INITIALIZER(loadvm_handlers); static int global_section_id; static int calculate_new_instance_id(const char *idstr) @@ -1460,14 +1462,9 @@ typedef struct LoadStateEntry { int version_id; } LoadStateEntry; -int qemu_loadvm_state(QEMUFile *f) +int qemu_loadvm_state_begin(QEMUFile *f) { - QLIST_HEAD(, LoadStateEntry) loadvm_handlers = - QLIST_HEAD_INITIALIZER(loadvm_handlers); - LoadStateEntry *le, *new_le; - uint8_t section_type; unsigned int v; - int ret; v = qemu_get_be32(f); if (v != QEMU_VM_FILE_MAGIC) @@ -1481,73 +1478,157 @@ int qemu_loadvm_state(QEMUFile *f) if (v != QEMU_VM_FILE_VERSION) return -ENOTSUP; - while ((section_type = qemu_get_byte(f)) != QEMU_VM_EOF) { - uint32_t instance_id, version_id, section_id; - SaveStateEntry *se; - char idstr[257]; - int len; + return 0; +} - switch (section_type) { - case QEMU_VM_SECTION_START: - case QEMU_VM_SECTION_FULL: - /* Read section start */ - section_id = qemu_get_be32(f); - len = qemu_get_byte(f); - qemu_get_buffer(f, (uint8_t *)idstr, len); - idstr[len] = 0; - instance_id = qemu_get_be32(f); - version_id = qemu_get_be32(f); - - /* Find savevm section */ - se = find_se(idstr, instance_id); - if (se == NULL) { - fprintf(stderr, "Unknown savevm section or instance '%s' %d\n", idstr, instance_id); - ret = -EINVAL; - goto out; - } +static int qemu_loadvm_state_iterate(QEMUFile *f) +{ + LoadStateEntry *le; + uint32_t section_id; + int ret; - /* Validate version */ - if (version_id > se->version_id) { - fprintf(stderr, "savevm: unsupported version %d for '%s' v%d\n", - version_id, idstr, se->version_id); - ret = -EINVAL; - goto out; - } + section_id = qemu_get_be32(f); + + QLIST_FOREACH(le, &loadvm_handlers, entry) { + if (le->section_id == section_id) { + break; + } + } + if (le == NULL) { + fprintf(stderr, "Unknown savevm section %d\n", section_id); + return -EINVAL; + } + + ret = vmstate_load(f, le->se, le->version_id); + if (ret < 0) { + fprintf(stderr, "qemu: warning: error while loading state section id %d\n", + section_id); + return ret; + } + + return 0; +} + +static int qemu_loadvm_state_complete(QEMUFile *f) +{ + LoadStateEntry *le; + uint32_t instance_id, version_id, section_id; + SaveStateEntry *se; + char idstr[257]; + int ret = -1, len; + + /* Read section start */ + section_id = qemu_get_be32(f); + len = qemu_get_byte(f); + qemu_get_buffer(f, (uint8_t *)idstr, len); + idstr[len] = 0; + instance_id = qemu_get_be32(f); + version_id = qemu_get_be32(f); + + /* Find savevm section */ + se = find_se(idstr, instance_id); + if (se == NULL) { + fprintf(stderr, "Unknown savevm section or instance '%s' %d\n", idstr, instance_id); + return -EINVAL; + } + + /* Validate version */ + if (version_id > se->version_id) { + fprintf(stderr, "savevm: unsupported version %d for '%s' v%d\n", + version_id, idstr, se->version_id); + return -EINVAL; + } + + /* Add entry */ + le = qemu_mallocz(sizeof(*le)); + + le->se = se; + le->section_id = section_id; + le->version_id = version_id; + QLIST_INSERT_HEAD(&loadvm_handlers, le, entry); + + ret = vmstate_load(f, le->se, le->version_id); + if (ret < 0) { + fprintf(stderr, "qemu: warning: error while loading state for instance 0x%x of device '%s'\n", + instance_id, idstr); + return ret; + } + + return 0; +} - /* Add entry */ - le = qemu_mallocz(sizeof(*le)); +int qemu_loadvm_state_async(QEMUFile *f) +{ + LoadStateEntry *le, *new_le; + int ret; + uint8_t section_type; - le->se = se; - le->section_id = section_id; - le->version_id = version_id; - QLIST_INSERT_HEAD(&loadvm_handlers, le, entry); + section_type = qemu_get_byte(f); + switch (section_type) { + case QEMU_VM_SECTION_START: + case QEMU_VM_SECTION_FULL: + ret = qemu_loadvm_state_complete(f); + if (ret < 0) { + goto out_free; + } + break; + case QEMU_VM_SECTION_PART: + case QEMU_VM_SECTION_END: + ret = qemu_loadvm_state_iterate(f); + if (ret < 0) { + goto out_free; + } + break; + case QEMU_VM_EOF: + cpu_synchronize_all_post_init(); + break; + default: + fprintf(stderr, "Unknown savevm section type %d\n", section_type); + ret = -EINVAL; + goto out_free; + } + + ret = section_type; + if (ret != QEMU_VM_EOF) { + goto out; + } - ret = vmstate_load(f, le->se, le->version_id); +out_free: + QLIST_FOREACH_SAFE(le, &loadvm_handlers, entry, new_le) { + QLIST_REMOVE(le, entry); + qemu_free(le); + } +out: + if (qemu_file_has_error(f)) { + ret = -EIO; + } + + return ret; +} + +int qemu_loadvm_state(QEMUFile *f) +{ + LoadStateEntry *le, *new_le; + int ret; + uint8_t section_type; + + ret = qemu_loadvm_state_begin(f); + if (ret < 0) + goto out; + + while ((section_type = qemu_get_byte(f)) != QEMU_VM_EOF) { + switch (section_type) { + case QEMU_VM_SECTION_START: + case QEMU_VM_SECTION_FULL: + ret = qemu_loadvm_state_complete(f); if (ret < 0) { - fprintf(stderr, "qemu: warning: error while loading state for instance 0x%x of device '%s'\n", - instance_id, idstr); goto out; } break; case QEMU_VM_SECTION_PART: case QEMU_VM_SECTION_END: - section_id = qemu_get_be32(f); - - QLIST_FOREACH(le, &loadvm_handlers, entry) { - if (le->section_id == section_id) { - break; - } - } - if (le == NULL) { - fprintf(stderr, "Unknown savevm section %d\n", section_id); - ret = -EINVAL; - goto out; - } - - ret = vmstate_load(f, le->se, le->version_id); + ret = qemu_loadvm_state_iterate(f); if (ret < 0) { - fprintf(stderr, "qemu: warning: error while loading state section id %d\n", - section_id); goto out; } break; @@ -1568,8 +1649,9 @@ out: qemu_free(le); } - if (qemu_file_has_error(f)) + if (qemu_file_has_error(f)) { ret = -EIO; + } return ret; } diff --git a/sysemu.h b/sysemu.h index 879446a..c576840 100644 --- a/sysemu.h +++ b/sysemu.h @@ -69,6 +69,8 @@ int qemu_savevm_state_begin(Monitor *mon, QEMUFile *f, int blk_enable, int qemu_savevm_state_iterate(Monitor *mon, QEMUFile *f); int qemu_savevm_state_complete(Monitor *mon, QEMUFile *f); void qemu_savevm_state_cancel(Monitor *mon, QEMUFile *f); +int qemu_loadvm_state_begin(QEMUFile *f); +int qemu_loadvm_state_async(QEMUFile *f); int qemu_loadvm_state(QEMUFile *f); #ifdef _WIN32