Re: [PATCH 15/19] savevm: introduce qemu_savevm_trans_{begin,commit}.

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

 



Paolo,

I refactored the savevm functions.  Could you give me your
comments?

Thanks,

Yoshi

diff --git a/savevm.c b/savevm.c
index 5418280..90aae55 100644
--- a/savevm.c
+++ b/savevm.c
@@ -1602,29 +1602,68 @@ bool qemu_savevm_state_blocked(Monitor *mon)
     return false;
 }

-int qemu_savevm_state_begin(Monitor *mon, QEMUFile *f, int blk_enable,
-                            int shared)
+/*
+ * section: header to write
+ * inc: if true, forces to pass SECTION_PART instead of SECTION_START
+ * pause: if true, breaks the loop when live handler returned 0
+ */
+static int qemu_savevm_state_live(Monitor *mon, QEMUFile *f, int section,
+                                  bool inc, bool pause)
 {
     SaveStateEntry *se;
+    int skip = 0, ret;

     QTAILQ_FOREACH(se, &savevm_handlers, entry) {
-        if(se->set_params == NULL) {
+        int len, stage;
+
+        if (se->save_live_state == NULL) {
             continue;
-	}
-	se->set_params(blk_enable, shared, se->opaque);
+        }
+
+        /* Section type */
+        qemu_put_byte(f, section);
+        qemu_put_be32(f, se->section_id);
+
+        if (section == QEMU_VM_SECTION_START) {
+            /* ID string */
+            len = strlen(se->idstr);
+            qemu_put_byte(f, len);
+            qemu_put_buffer(f, (uint8_t *)se->idstr, len);
+
+            qemu_put_be32(f, se->instance_id);
+            qemu_put_be32(f, se->version_id);
+
+            stage = inc ? QEMU_VM_SECTION_PART : QEMU_VM_SECTION_START;
+        } else {
+            assert(inc);
+            stage = section;
+        }
+
+        ret = se->save_live_state(mon, f, stage, se->opaque);
+        if (!ret) {
+            skip++;
+            if (pause) {
+                break;
+            }
+        }
     }
-
-    qemu_put_be32(f, QEMU_VM_FILE_MAGIC);
-    qemu_put_be32(f, QEMU_VM_FILE_VERSION);
+
+    return skip;
+}
+
+static void qemu_savevm_state_full(QEMUFile *f)
+{
+    SaveStateEntry *se;

     QTAILQ_FOREACH(se, &savevm_handlers, entry) {
         int len;

-        if (se->save_live_state == NULL)
+        if (se->save_state == NULL && se->vmsd == NULL) {
             continue;
+        }

         /* Section type */
-        qemu_put_byte(f, QEMU_VM_SECTION_START);
+        qemu_put_byte(f, QEMU_VM_SECTION_FULL);
         qemu_put_be32(f, se->section_id);

         /* ID string */
@@ -1635,8 +1674,28 @@ int qemu_savevm_state_begin(Monitor *mon,
QEMUFile *f, int blk_enable,
         qemu_put_be32(f, se->instance_id);
         qemu_put_be32(f, se->version_id);

-        se->save_live_state(mon, f, QEMU_VM_SECTION_START, se->opaque);
+        vmstate_save(f, se);
+    }
+
+    qemu_put_byte(f, QEMU_VM_EOF);
+}
+
+int qemu_savevm_state_begin(Monitor *mon, QEMUFile *f, int blk_enable,
+                            int shared)
+{
+    SaveStateEntry *se;
+
+    QTAILQ_FOREACH(se, &savevm_handlers, entry) {
+        if(se->set_params == NULL) {
+            continue;
+        }
+        se->set_params(blk_enable, shared, se->opaque);
     }
+
+    qemu_put_be32(f, QEMU_VM_FILE_MAGIC);
+    qemu_put_be32(f, QEMU_VM_FILE_VERSION);
+
+    qemu_savevm_state_live(mon, f, QEMU_VM_SECTION_START, 0, 0);

     if (qemu_file_has_error(f)) {
         qemu_savevm_state_cancel(mon, f);
@@ -1648,29 +1707,16 @@ int qemu_savevm_state_begin(Monitor *mon,
QEMUFile *f, int blk_enable,

 int qemu_savevm_state_iterate(Monitor *mon, QEMUFile *f)
 {
-    SaveStateEntry *se;
     int ret = 1;

-    QTAILQ_FOREACH(se, &savevm_handlers, entry) {
-        if (se->save_live_state == NULL)
-            continue;
-
-        /* Section type */
-        qemu_put_byte(f, QEMU_VM_SECTION_PART);
-        qemu_put_be32(f, se->section_id);
-
-        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)
+    /* 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. */
+    ret = qemu_savevm_state_live(mon, f, QEMU_VM_SECTION_PART, 1, 1);
+    if (!ret) {
         return 1;
+    }

     if (qemu_file_has_error(f)) {
         qemu_savevm_state_cancel(mon, f);
@@ -1682,46 +1728,40 @@ int qemu_savevm_state_iterate(Monitor *mon, QEMUFile *f)

 int qemu_savevm_state_complete(Monitor *mon, QEMUFile *f)
 {
-    SaveStateEntry *se;
-
     cpu_synchronize_all_states();

-    QTAILQ_FOREACH(se, &savevm_handlers, entry) {
-        if (se->save_live_state == NULL)
-            continue;
-
-        /* Section type */
-        qemu_put_byte(f, QEMU_VM_SECTION_END);
-        qemu_put_be32(f, se->section_id);
+    qemu_savevm_state_live(mon, f, QEMU_VM_SECTION_END, 1, 0);
+    qemu_savevm_state_full(f);

-        se->save_live_state(mon, f, QEMU_VM_SECTION_END, se->opaque);
-    }
+    if (qemu_file_has_error(f))
+        return -EIO;

-    QTAILQ_FOREACH(se, &savevm_handlers, entry) {
-        int len;
+    return 0;
+}

-	if (se->save_state == NULL && se->vmsd == NULL)
-	    continue;
+int qemu_savevm_trans_begin(Monitor *mon, QEMUFile *f, int init)
+{
+    int ret;

-        /* Section type */
-        qemu_put_byte(f, QEMU_VM_SECTION_FULL);
-        qemu_put_be32(f, se->section_id);
+    ret = qemu_savevm_state_live(mon, f, QEMU_VM_SECTION_START, !init, 0);

-        /* ID string */
-        len = strlen(se->idstr);
-        qemu_put_byte(f, len);
-        qemu_put_buffer(f, (uint8_t *)se->idstr, len);
+    if (qemu_file_has_error(f)) {
+        return -EIO;
+    }

-        qemu_put_be32(f, se->instance_id);
-        qemu_put_be32(f, se->version_id);
+    return ret;
+}

-        vmstate_save(f, se);
-    }
+int qemu_savevm_trans_complete(Monitor *mon, QEMUFile *f)
+{
+    cpu_synchronize_all_states();

-    qemu_put_byte(f, QEMU_VM_EOF);
+    qemu_savevm_state_live(mon, f, QEMU_VM_SECTION_PART, 1, 0);
+    qemu_savevm_state_full(f);

-    if (qemu_file_has_error(f))
+    if (qemu_file_has_error(f)) {
         return -EIO;
+    }

     return 0;
 }
diff --git a/sysemu.h b/sysemu.h
index 329415f..ee2c382 100644
--- a/sysemu.h
+++ b/sysemu.h
@@ -81,6 +81,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_savevm_trans_begin(Monitor *mon, QEMUFile *f, int init);
+int qemu_savevm_trans_complete(Monitor *mon, QEMUFile *f);
 int qemu_loadvm_state(QEMUFile *f, int skip_header);

 /* SLIRP */
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]
  Powered by Linux