diff mbox

[RFC,05/13] migration: implement initialization work for snapshot

Message ID 1452169208-840-6-git-send-email-zhang.zhanghailiang@huawei.com
State New
Headers show

Commit Message

Zhanghailiang Jan. 7, 2016, 12:20 p.m. UTC
We re-use some migration helper fucntions to realize setup work
for snapshot, besides, we need to do some initialization work (for example,
save VM's device state) with VM pausing.

Signed-off-by: zhanghailiang <zhang.zhanghailiang@huawei.com>
---
 migration/migration.c | 36 +++++++++++++++++++++++++++++++++++-
 migration/ram.c       |  8 +++++---
 trace-events          |  1 +
 3 files changed, 41 insertions(+), 4 deletions(-)
diff mbox

Patch

diff --git a/migration/migration.c b/migration/migration.c
index 7633043..7413e0d 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -1740,6 +1740,10 @@  static void *migration_thread(void *opaque)
 
 static void *snapshot_thread(void *opaque)
 {
+    MigrationState *ms = opaque;;
+    bool old_vm_running = false;
+    int ret;
+
     rcu_register_thread();
     /* Fix me: Remove this if we support snapshot for KVM */
     if (strcmp(current_machine->accel, "tcg")) {
@@ -1747,8 +1751,38 @@  static void *snapshot_thread(void *opaque)
         goto error;
     }
 
-    /* TODO: create memory snapshot */
+    qemu_savevm_state_header(ms->file);
+    qemu_savevm_state_begin(ms->file, &ms->params);
+
+    qemu_mutex_lock_iothread();
+    qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER);
+    old_vm_running = runstate_is_running();
+    ret = global_state_store();
+    if (!ret) {
+        ret = vm_stop_force_state(RUN_STATE_SAVE_VM);
+        if (ret < 0) {
+            error_report("Failed to stop VM");
+            goto error;
+        }
+    }
+
+    /* TODO: other setup work */
 
+    if (old_vm_running) {
+        vm_start();
+    }
+    qemu_mutex_unlock_iothread();
+
+    migrate_set_state(ms, MIGRATION_STATUS_SETUP, MIGRATION_STATUS_ACTIVE);
+
+    trace_snapshot_thread_setup_complete();
+
+    /* Save VM's state */
+
+    qemu_mutex_lock_iothread();
+    qemu_savevm_state_cleanup();
+    qemu_bh_schedule(ms->cleanup_bh);
+    qemu_mutex_unlock_iothread();
 error:
     rcu_unregister_thread();
     return NULL;
diff --git a/migration/ram.c b/migration/ram.c
index 0490f00..c87663f 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -1935,9 +1935,11 @@  static int ram_save_setup(QEMUFile *f, void *opaque)
      * gaps due to alignment or unplugs.
      */
     migration_dirty_pages = ram_bytes_total() >> TARGET_PAGE_BITS;
-
-    memory_global_dirty_log_start();
-    migration_bitmap_sync();
+    /* For snapshot, we don't need to enable global dirty log */
+    if (!migration_in_snapshot(migrate_get_current())) {
+        memory_global_dirty_log_start();
+        migration_bitmap_sync();
+    }
     qemu_mutex_unlock_ramlist();
     qemu_mutex_unlock_iothread();
 
diff --git a/trace-events b/trace-events
index ea5872d..cfebbed 100644
--- a/trace-events
+++ b/trace-events
@@ -1495,6 +1495,7 @@  migrate_state_too_big(void) ""
 migrate_transferred(uint64_t tranferred, uint64_t time_spent, double bandwidth, uint64_t size) "transferred %" PRIu64 " time_spent %" PRIu64 " bandwidth %g max_size %" PRId64
 process_incoming_migration_co_end(int ret, int ps) "ret=%d postcopy-state=%d"
 process_incoming_migration_co_postcopy_end_main(void) ""
+snapshot_thread_setup_complete(void) ""
 
 # migration/rdma.c
 qemu_rdma_accept_incoming_migration(void) ""