qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [RFC 08/13] snapshot: Save VM's device state into snapshot


From: zhanghailiang
Subject: [Qemu-devel] [RFC 08/13] snapshot: Save VM's device state into snapshot file
Date: Thu, 7 Jan 2016 20:20:03 +0800

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 <address@hidden>
---
 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





reply via email to

[Prev in Thread] Current Thread [Next in Thread]