]> git.proxmox.com Git - qemu.git/blobdiff - savevm.c
tcg-sparc: Use TCG_TARGET_REG_BITS in conditional compilation.
[qemu.git] / savevm.c
index 17a6c97053589faea7b38324fe7e555b0219ebe1..aefe052cd3b691072887b49468c78512d1c967ff 100644 (file)
--- a/savevm.c
+++ b/savevm.c
@@ -1264,7 +1264,8 @@ static void vmstate_save(QEMUFile *f, SaveStateEntry *se)
 #define QEMU_VM_SECTION_END          0x03
 #define QEMU_VM_SECTION_FULL         0x04
 
-int qemu_savevm_state_begin(QEMUFile *f, int blk_enable, int shared)
+int qemu_savevm_state_begin(Monitor *mon, QEMUFile *f, int blk_enable,
+                            int shared)
 {
     SaveStateEntry *se;
 
@@ -1296,16 +1297,18 @@ int qemu_savevm_state_begin(QEMUFile *f, int blk_enable, int shared)
         qemu_put_be32(f, se->instance_id);
         qemu_put_be32(f, se->version_id);
 
-        se->save_live_state(f, QEMU_VM_SECTION_START, se->opaque);
+        se->save_live_state(mon, f, QEMU_VM_SECTION_START, se->opaque);
     }
 
-    if (qemu_file_has_error(f))
+    if (qemu_file_has_error(f)) {
+        qemu_savevm_state_cancel(mon, f);
         return -EIO;
+    }
 
     return 0;
 }
 
-int qemu_savevm_state_iterate(QEMUFile *f)
+int qemu_savevm_state_iterate(Monitor *mon, QEMUFile *f)
 {
     SaveStateEntry *se;
     int ret = 1;
@@ -1318,19 +1321,28 @@ int qemu_savevm_state_iterate(QEMUFile *f)
         qemu_put_byte(f, QEMU_VM_SECTION_PART);
         qemu_put_be32(f, se->section_id);
 
-        ret &= !!se->save_live_state(f, QEMU_VM_SECTION_PART, se->opaque);
+        ret = se->save_live_state(mon, f, QEMU_VM_SECTION_PART, se->opaque);
+        if (!ret) {
+            /* Do not proceed to the next vmstate before this one reported
+               completion of the current stage. This serializes the migration
+               and reduces the probability that a faster changing state is
+               synchronized over and over again. */
+            break;
+        }
     }
 
     if (ret)
         return 1;
 
-    if (qemu_file_has_error(f))
+    if (qemu_file_has_error(f)) {
+        qemu_savevm_state_cancel(mon, f);
         return -EIO;
+    }
 
     return 0;
 }
 
-int qemu_savevm_state_complete(QEMUFile *f)
+int qemu_savevm_state_complete(Monitor *mon, QEMUFile *f)
 {
     SaveStateEntry *se;
 
@@ -1342,7 +1354,7 @@ int qemu_savevm_state_complete(QEMUFile *f)
         qemu_put_byte(f, QEMU_VM_SECTION_END);
         qemu_put_be32(f, se->section_id);
 
-        se->save_live_state(f, QEMU_VM_SECTION_END, se->opaque);
+        se->save_live_state(mon, f, QEMU_VM_SECTION_END, se->opaque);
     }
 
     QTAILQ_FOREACH(se, &savevm_handlers, entry) {
@@ -1374,7 +1386,18 @@ int qemu_savevm_state_complete(QEMUFile *f)
     return 0;
 }
 
-int qemu_savevm_state(QEMUFile *f)
+void qemu_savevm_state_cancel(Monitor *mon, QEMUFile *f)
+{
+    SaveStateEntry *se;
+
+    QTAILQ_FOREACH(se, &savevm_handlers, entry) {
+        if (se->save_live_state) {
+            se->save_live_state(mon, f, -1, se->opaque);
+        }
+    }
+}
+
+static int qemu_savevm_state(Monitor *mon, QEMUFile *f)
 {
     int saved_vm_running;
     int ret;
@@ -1384,17 +1407,17 @@ int qemu_savevm_state(QEMUFile *f)
 
     bdrv_flush_all();
 
-    ret = qemu_savevm_state_begin(f, 0, 0);
+    ret = qemu_savevm_state_begin(mon, f, 0, 0);
     if (ret < 0)
         goto out;
 
     do {
-        ret = qemu_savevm_state_iterate(f);
+        ret = qemu_savevm_state_iterate(mon, f);
         if (ret < 0)
             goto out;
     } while (ret == 0);
 
-    ret = qemu_savevm_state_complete(f);
+    ret = qemu_savevm_state_complete(mon, f);
 
 out:
     if (qemu_file_has_error(f))
@@ -1683,7 +1706,7 @@ void do_savevm(Monitor *mon, const QDict *qdict)
         monitor_printf(mon, "Could not open VM state file\n");
         goto the_end;
     }
-    ret = qemu_savevm_state(f);
+    ret = qemu_savevm_state(mon, f);
     vm_state_size = qemu_ftell(f);
     qemu_fclose(f);
     if (ret < 0) {