From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:44094) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aH9Ya-0007ua-FK for qemu-devel@nongnu.org; Thu, 07 Jan 2016 07:20:45 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1aH9YX-0004K3-NW for qemu-devel@nongnu.org; Thu, 07 Jan 2016 07:20:44 -0500 Received: from szxga02-in.huawei.com ([119.145.14.65]:22743) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aH9YX-0004In-4N for qemu-devel@nongnu.org; Thu, 07 Jan 2016 07:20:41 -0500 From: zhanghailiang Date: Thu, 7 Jan 2016 20:20:03 +0800 Message-ID: <1452169208-840-9-git-send-email-zhang.zhanghailiang@huawei.com> In-Reply-To: <1452169208-840-1-git-send-email-zhang.zhanghailiang@huawei.com> References: <1452169208-840-1-git-send-email-zhang.zhanghailiang@huawei.com> MIME-Version: 1.0 Content-Type: text/plain Subject: [Qemu-devel] [RFC 08/13] snapshot: Save VM's device state into snapshot file List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: aarcange@redhat.com, zhanghailiang , hanweidong@huawei.com, quintela@redhat.com, peter.huangpeng@huawei.com, dgilbert@redhat.com, amit.shah@redhat.com For live memory snapshot, we want to catch VM's state at the time of getting snapshot command. So we need to save the VM's static state (here, it is VM's device state) at the beginning of snapshot_thread(), but we can't do that while VM is running. Besides, we can't save device's state into snapshot file directly, because, we want to re-use the migration's incoming process with snapshot, we need to keep the save sequence. So here, we save the VM's device state into qsb temporarily in the SETUP stage with VM is stopped, and save it into snapshot file after finishing save VM's live state. Signed-off-by: zhanghailiang --- include/sysemu/sysemu.h | 3 +++ migration/migration.c | 14 ++++++++++++-- migration/savevm.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 59 insertions(+), 2 deletions(-) diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h index 3bb8897..3bc13b6 100644 --- a/include/sysemu/sysemu.h +++ b/include/sysemu/sysemu.h @@ -111,6 +111,9 @@ void qemu_savevm_state_begin(QEMUFile *f, void qemu_savevm_state_header(QEMUFile *f); int qemu_savevm_state_iterate(QEMUFile *f, bool postcopy); void qemu_savevm_state_cleanup(void); +QEMUSizedBuffer *qemu_save_device_buffer(void); +int qemu_save_buffer_file(MigrationState *s, QEMUSizedBuffer *buffer); + void qemu_savevm_state_complete_postcopy(QEMUFile *f); void qemu_savevm_state_complete_precopy(QEMUFile *f, bool iterable_only); void qemu_savevm_state_pending(QEMUFile *f, uint64_t max_size, diff --git a/migration/migration.c b/migration/migration.c index 7413e0d..fd234eb 100644 --- a/migration/migration.c +++ b/migration/migration.c @@ -1742,6 +1742,7 @@ static void *snapshot_thread(void *opaque) { MigrationState *ms = opaque;; bool old_vm_running = false; + QEMUSizedBuffer *buffer = NULL; int ret; rcu_register_thread(); @@ -1766,7 +1767,7 @@ static void *snapshot_thread(void *opaque) } } - /* TODO: other setup work */ + buffer = qemu_save_device_buffer(); if (old_vm_running) { vm_start(); @@ -1777,7 +1778,16 @@ static void *snapshot_thread(void *opaque) trace_snapshot_thread_setup_complete(); - /* Save VM's state */ + /* Save VM's Live state, such as RAM */ + + qemu_save_buffer_file(ms, buffer); + ret = qemu_file_get_error(ms->file); + if (ret < 0) { + migrate_set_state(ms, MIGRATION_STATUS_ACTIVE, MIGRATION_STATUS_FAILED); + } else { + migrate_set_state(ms, MIGRATION_STATUS_ACTIVE, + MIGRATION_STATUS_COMPLETED); + } qemu_mutex_lock_iothread(); qemu_savevm_state_cleanup(); diff --git a/migration/savevm.c b/migration/savevm.c index 1b4e5bd..a59f216 100644 --- a/migration/savevm.c +++ b/migration/savevm.c @@ -59,6 +59,8 @@ #define ARP_PTYPE_IP 0x0800 #define ARP_OP_REQUEST_REV 0x3 +#define BUFFER_BASE_SIZE (4 * 1024 * 1024) + const unsigned int postcopy_ram_discard_version = 0; static bool skip_section_footers; @@ -2206,3 +2208,45 @@ void vmstate_register_ram_global(MemoryRegion *mr) { vmstate_register_ram(mr, NULL); } + +QEMUSizedBuffer *qemu_save_device_buffer(void) +{ + QEMUSizedBuffer *buffer; + QEMUFile *trans = NULL; + + buffer = qsb_create(NULL, BUFFER_BASE_SIZE); + if (buffer == NULL) { + error_report("Failed to allocate colo buffer!"); + return NULL; + } + + qsb_set_length(buffer, 0); + trans = qemu_bufopen("w", buffer); + if (!trans) { + error_report("Open qsb buffer for write failed"); + goto error; + } + cpu_synchronize_all_states(); + qemu_savevm_section_full(trans); + qemu_fflush(trans); + error_report("buffer address 0 :%p", buffer); + return buffer; + +error: + qsb_free(buffer); + buffer = NULL; + return NULL; +} + +int qemu_save_buffer_file(MigrationState *s, QEMUSizedBuffer *buffer) +{ + size_t size; + + size = qsb_get_length(buffer); + + qsb_put_buffer(s->file, buffer, size); + qemu_fflush(s->file); + qsb_free(buffer); + buffer = NULL; + return qemu_file_get_error(s->file); +} -- 1.8.3.1