[libvirt] PATCH: Fix save/restore for new KVM

Daniel P. Berrange berrange at redhat.com
Thu Jan 29 12:23:00 UTC 2009


This is a repost of the patch from:

http://www.redhat.com/archives/libvir-list/2009-January/msg00583.html

updated to take account of the changes commited since I first posted it.

Daniel

diff -r 7aa9f1c885e7 src/qemu_conf.c
--- a/src/qemu_conf.c	Tue Jan 27 15:42:39 2009 +0000
+++ b/src/qemu_conf.c	Tue Jan 27 16:00:35 2009 +0000
@@ -412,6 +412,27 @@ int qemudExtractVersionInfo(const char *
     if (kvm_version >= 74)
         flags |= QEMUD_CMD_FLAG_VNET_HDR;
 
+    /*
+     * Handling of -incoming arg with varying features
+     *  -incoming tcp    (kvm >= 79)
+     *  -incoming exec   (kvm >= 80)
+     *  -incoming stdio  (all earlier kvm)
+     *
+     * NB, there was a pre-kvm-79 'tcp' support, but it
+     * was broken, because it blocked the monitor console
+     * while waiting for data, so pretend it doesn't exist
+     *
+     * XXX when next QEMU release after 0.9.1 arrives,
+     * we'll need to add MIGRATE_QEMU_TCP/EXEC here too
+     */
+    if (kvm_version >= 79) {
+        flags |= QEMUD_CMD_FLAG_MIGRATE_QEMU_TCP;
+        if (kvm_version >= 80)
+            flags |= QEMUD_CMD_FLAG_MIGRATE_QEMU_EXEC;
+    } else if (kvm_version > 0) {
+        flags |= QEMUD_CMD_FLAG_MIGRATE_KVM_STDIO;
+    }
+
     if (retversion)
         *retversion = version;
     if (retflags)
@@ -694,6 +715,33 @@ int qemudBuildCommandLine(virConnectPtr 
 
     virUUIDFormat(vm->def->uuid, uuid);
 
+    /* Migration is very annoying due to wildly varying syntax & capabilities
+     * over time of KVM / QEMU codebases
+     */
+    if (migrateFrom) {
+        if (STRPREFIX(migrateFrom, "tcp")) {
+            if (!(qemuCmdFlags & QEMUD_CMD_FLAG_MIGRATE_QEMU_TCP)) {
+                qemudReportError(conn, NULL, NULL, VIR_ERR_NO_SUPPORT,
+                                 "%s", _("TCP migration is not supported with this QEMU binary"));
+                return -1;
+            }
+        } else if (STREQ(migrateFrom, "stdio")) {
+            if (qemuCmdFlags & QEMUD_CMD_FLAG_MIGRATE_QEMU_EXEC) {
+                migrateFrom = "exec:cat";
+            } else if (!(qemuCmdFlags & QEMUD_CMD_FLAG_MIGRATE_KVM_STDIO)) {
+                qemudReportError(conn, NULL, NULL, VIR_ERR_NO_SUPPORT,
+                                 "%s", _("STDIO migration is not supported with this QEMU binary"));
+                return -1;
+            }
+        } else if (STRPREFIX(migrateFrom, "exec")) {
+            if (!(qemuCmdFlags & QEMUD_CMD_FLAG_MIGRATE_QEMU_EXEC)) {
+                qemudReportError(conn, NULL, NULL, VIR_ERR_NO_SUPPORT,
+                                 "%s", _("STDIO migration is not supported with this QEMU binary"));
+                return -1;
+            }
+        }
+    }
+
     /* Need to explicitly disable KQEMU if
      * 1. Arch matches host arch
      * 2. Guest is 'qemu'
diff -r 7aa9f1c885e7 src/qemu_conf.h
--- a/src/qemu_conf.h	Tue Jan 27 15:42:39 2009 +0000
+++ b/src/qemu_conf.h	Tue Jan 27 16:00:35 2009 +0000
@@ -40,15 +40,19 @@
 
 /* Internal flags to keep track of qemu command line capabilities */
 enum qemud_cmd_flags {
-    QEMUD_CMD_FLAG_KQEMU          = (1 << 0),
-    QEMUD_CMD_FLAG_VNC_COLON      = (1 << 1),
-    QEMUD_CMD_FLAG_NO_REBOOT      = (1 << 2),
-    QEMUD_CMD_FLAG_DRIVE          = (1 << 3),
-    QEMUD_CMD_FLAG_DRIVE_BOOT     = (1 << 4),
-    QEMUD_CMD_FLAG_NAME           = (1 << 5),
-    QEMUD_CMD_FLAG_UUID           = (1 << 6),
-    QEMUD_CMD_FLAG_DOMID          = (1 << 7), /* Xenner only */
-    QEMUD_CMD_FLAG_VNET_HDR       = (1 << 8),
+    QEMUD_CMD_FLAG_KQEMU          = (1 << 0), /* Whether KQEMU is compiled in */
+    QEMUD_CMD_FLAG_VNC_COLON      = (1 << 1), /* Does the VNC take just port, or address + display */
+    QEMUD_CMD_FLAG_NO_REBOOT      = (1 << 2), /* Is the -no-reboot flag available */
+    QEMUD_CMD_FLAG_DRIVE          = (1 << 3), /* Is the new -drive arg available */
+    QEMUD_CMD_FLAG_DRIVE_BOOT     = (1 << 4), /* Does -drive support boot=on */
+    QEMUD_CMD_FLAG_NAME           = (1 << 5), /* Is the -name flag available */
+    QEMUD_CMD_FLAG_UUID           = (1 << 6), /* Is the -uuid flag available */
+    QEMUD_CMD_FLAG_DOMID          = (1 << 7), /* Xenner only, special -domid flag available */
+    QEMUD_CMD_FLAG_VNET_HDR        = (1 << 8),
+    QEMUD_CMD_FLAG_MIGRATE_KVM_STDIO = (1 << 9),  /* Original migration code from KVM. Also had tcp, but we can't use that
+                                                   * since it had a design bug blocking the entire monitor console */
+    QEMUD_CMD_FLAG_MIGRATE_QEMU_TCP  = (1 << 10), /* New migration syntax after merge to QEMU with TCP transport */
+    QEMUD_CMD_FLAG_MIGRATE_QEMU_EXEC = (1 << 11), /* New migration syntax after merge to QEMU with EXEC transport */
 };
 
 /* Main driver state */
diff -r 7aa9f1c885e7 tests/qemuxml2argvdata/qemuxml2argv-migrate.args
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/qemuxml2argvdata/qemuxml2argv-migrate.args	Tue Jan 27 16:00:35 2009 +0000
@@ -0,0 +1,1 @@
+LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu-kvm -S -M pc -m 214 -smp 1 -nographic -monitor pty -pidfile /nowhere/QEMUGuest1.pid -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -net none -serial none -parallel none -usb -incoming tcp:10.0.0.1:5000
diff -r 7aa9f1c885e7 tests/qemuxml2argvdata/qemuxml2argv-migrate.xml
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/qemuxml2argvdata/qemuxml2argv-migrate.xml	Tue Jan 27 16:00:35 2009 +0000
@@ -0,0 +1,22 @@
+<domain type='qemu'>
+  <name>QEMUGuest1</name>
+  <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+  <memory>219200</memory>
+  <currentMemory>219200</currentMemory>
+  <vcpu>1</vcpu>
+  <os>
+    <type arch='i686' machine='pc'>hvm</type>
+    <boot dev='hd'/>
+  </os>
+  <clock offset='utc'/>
+  <on_poweroff>destroy</on_poweroff>
+  <on_reboot>restart</on_reboot>
+  <on_crash>destroy</on_crash>
+  <devices>
+    <emulator>/usr/bin/qemu-kvm</emulator>
+    <disk type='block' device='disk'>
+      <source dev='/dev/HostVG/QEMUGuest1'/>
+      <target dev='hda' bus='ide'/>
+    </disk>
+  </devices>
+</domain>
diff -r 7aa9f1c885e7 tests/qemuxml2argvdata/qemuxml2argv-restore-v1.args
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/qemuxml2argvdata/qemuxml2argv-restore-v1.args	Tue Jan 27 16:00:35 2009 +0000
@@ -0,0 +1,1 @@
+LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu-kvm -S -M pc -m 214 -smp 1 -nographic -monitor pty -pidfile /nowhere/QEMUGuest1.pid -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -net none -serial none -parallel none -usb -incoming stdio
diff -r 7aa9f1c885e7 tests/qemuxml2argvdata/qemuxml2argv-restore-v1.xml
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/qemuxml2argvdata/qemuxml2argv-restore-v1.xml	Tue Jan 27 16:00:35 2009 +0000
@@ -0,0 +1,22 @@
+<domain type='kvm'>
+  <name>QEMUGuest1</name>
+  <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+  <memory>219200</memory>
+  <currentMemory>219200</currentMemory>
+  <vcpu>1</vcpu>
+  <os>
+    <type arch='i686' machine='pc'>hvm</type>
+    <boot dev='hd'/>
+  </os>
+  <clock offset='utc'/>
+  <on_poweroff>destroy</on_poweroff>
+  <on_reboot>restart</on_reboot>
+  <on_crash>destroy</on_crash>
+  <devices>
+    <emulator>/usr/bin/qemu-kvm</emulator>
+    <disk type='block' device='disk'>
+      <source dev='/dev/HostVG/QEMUGuest1'/>
+      <target dev='hda' bus='ide'/>
+    </disk>
+  </devices>
+</domain>
diff -r 7aa9f1c885e7 tests/qemuxml2argvdata/qemuxml2argv-restore-v2.args
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/qemuxml2argvdata/qemuxml2argv-restore-v2.args	Tue Jan 27 16:00:35 2009 +0000
@@ -0,0 +1,1 @@
+LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu-kvm -S -M pc -m 214 -smp 1 -nographic -monitor pty -pidfile /nowhere/QEMUGuest1.pid -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -net none -serial none -parallel none -usb -incoming exec:cat
diff -r 7aa9f1c885e7 tests/qemuxml2argvdata/qemuxml2argv-restore-v2.xml
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/qemuxml2argvdata/qemuxml2argv-restore-v2.xml	Tue Jan 27 16:00:35 2009 +0000
@@ -0,0 +1,22 @@
+<domain type='kvm'>
+  <name>QEMUGuest1</name>
+  <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+  <memory>219200</memory>
+  <currentMemory>219200</currentMemory>
+  <vcpu>1</vcpu>
+  <os>
+    <type arch='i686' machine='pc'>hvm</type>
+    <boot dev='hd'/>
+  </os>
+  <clock offset='utc'/>
+  <on_poweroff>destroy</on_poweroff>
+  <on_reboot>restart</on_reboot>
+  <on_crash>destroy</on_crash>
+  <devices>
+    <emulator>/usr/bin/qemu-kvm</emulator>
+    <disk type='block' device='disk'>
+      <source dev='/dev/HostVG/QEMUGuest1'/>
+      <target dev='hda' bus='ide'/>
+    </disk>
+  </devices>
+</domain>
diff -r 7aa9f1c885e7 tests/qemuxml2argvtest.c
--- a/tests/qemuxml2argvtest.c	Tue Jan 27 15:42:39 2009 +0000
+++ b/tests/qemuxml2argvtest.c	Tue Jan 27 16:00:35 2009 +0000
@@ -24,7 +24,8 @@ static struct qemud_driver driver;
 
 static int testCompareXMLToArgvFiles(const char *xml,
                                      const char *cmd,
-                                     int extraFlags) {
+                                     int extraFlags,
+                                     const char *migrateFrom) {
     char argvData[MAX_FILE];
     char *expectargv = &(argvData[0]);
     char *actualargv = NULL;
@@ -56,7 +57,7 @@ static int testCompareXMLToArgvFiles(con
 
     if (qemudBuildCommandLine(NULL, &driver,
                               &vm, flags, &argv, &qenv,
-                              NULL, NULL, NULL) < 0)
+                              NULL, NULL, migrateFrom) < 0)
         goto fail;
 
     len = 1; /* for trailing newline */
@@ -122,6 +123,7 @@ static int testCompareXMLToArgvFiles(con
 struct testInfo {
     const char *name;
     int extraFlags;
+    const char *migrateFrom;
 };
 
 static int testCompareXMLToArgvHelper(const void *data) {
@@ -132,7 +134,7 @@ static int testCompareXMLToArgvHelper(co
              abs_srcdir, info->name);
     snprintf(args, PATH_MAX, "%s/qemuxml2argvdata/qemuxml2argv-%s.args",
              abs_srcdir, info->name);
-    return testCompareXMLToArgvFiles(xml, args, info->extraFlags);
+    return testCompareXMLToArgvFiles(xml, args, info->extraFlags, info->migrateFrom);
 }
 
 
@@ -161,7 +163,15 @@ mymain(int argc, char **argv)
 
 #define DO_TEST(name, extraFlags)                                       \
     do {                                                                \
-        struct testInfo info = { name, extraFlags };                    \
+        struct testInfo info = { name, extraFlags, NULL };              \
+        if (virtTestRun("QEMU XML-2-ARGV " name,                        \
+                        1, testCompareXMLToArgvHelper, &info) < 0)      \
+            ret = -1;                                                   \
+    } while (0)
+
+#define DO_TEST_MIGRATE(name, extraFlags, migrateFrom)                  \
+    do {                                                                \
+        struct testInfo info = { name, extraFlags, migrateFrom };       \
         if (virtTestRun("QEMU XML-2-ARGV " name,                        \
                         1, testCompareXMLToArgvHelper, &info) < 0)      \
             ret = -1;                                                   \
@@ -228,6 +238,11 @@ mymain(int argc, char **argv)
 
     DO_TEST("hostdev-pci-address", 0);
 
+    DO_TEST_MIGRATE("restore-v1", QEMUD_CMD_FLAG_MIGRATE_KVM_STDIO, "stdio");
+    DO_TEST_MIGRATE("restore-v2", QEMUD_CMD_FLAG_MIGRATE_QEMU_EXEC, "stdio");
+    DO_TEST_MIGRATE("restore-v2", QEMUD_CMD_FLAG_MIGRATE_QEMU_EXEC, "exec:cat");
+    DO_TEST_MIGRATE("migrate", QEMUD_CMD_FLAG_MIGRATE_QEMU_TCP, "tcp:10.0.0.1:5000");
+
     virCapabilitiesFree(driver.caps);
 
     return(ret==0 ? EXIT_SUCCESS : EXIT_FAILURE);


-- 
|: Red Hat, Engineering, London   -o-   http://people.redhat.com/berrange/ :|
|: http://libvirt.org  -o-  http://virt-manager.org  -o-  http://ovirt.org :|
|: http://autobuild.org       -o-         http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505  -o-  F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|




More information about the libvir-list mailing list