[libvirt] [RFC PATCHv4 15/15] qemu: support fd: migration with compression

Eric Blake eblake at redhat.com
Thu Mar 10 02:18:33 UTC 2011


Spawn the compressor ourselves, instead of requiring the shell.

* src/qemu/qemu_driver.c (qemuDomainMigrateToFile): Spawn
compression helper process when needed.
---
 src/qemu/qemu_driver.c |   37 ++++++++++++++++++++++++++++++++-----
 1 files changed, 32 insertions(+), 5 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index a679b2c..02c3c48 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -1778,10 +1778,12 @@ qemuDomainMigrateToFile(struct qemud_driver *driver, virDomainObjPtr vm,
     virCgroupPtr cgroup = NULL;
     int ret = -1;
     int rc;
+    virCommandPtr cmd = NULL;
+    int pipeFD[2] = { -1, -1 };

     if (qemuCaps && qemuCapsGet(qemuCaps, QEMU_CAPS_MIGRATE_QEMU_FD) &&
         priv->monConfig->type == VIR_DOMAIN_CHR_TYPE_UNIX &&
-        compressed == QEMUD_SAVE_FORMAT_RAW) {
+        (compressed == QEMUD_SAVE_FORMAT_RAW || pipe(pipeFD) == 0)) {
         /* All right! We can use fd migration, which means that qemu
          * doesn't have to open() the file, so we don't have to futz
          * around with granting access or revoking it later.  */
@@ -1842,9 +1844,26 @@ qemuDomainMigrateToFile(struct qemud_driver *driver, virDomainObjPtr vm,
             "-c",
             NULL
         };
-        rc = qemuMonitorMigrateToFile(priv->mon,
-                                      QEMU_MONITOR_MIGRATE_BACKGROUND,
-                                      args, path, offset);
+        if (qemuCaps && qemuCapsGet(qemuCaps, QEMU_CAPS_MIGRATE_QEMU_FD) &&
+            priv->monConfig->type == VIR_DOMAIN_CHR_TYPE_UNIX) {
+            cmd = virCommandNewArgs(args);
+            virCommandSetInputFD(cmd, pipeFD[0]);
+            virCommandSetOutputFD(cmd, &fd);
+            if (virCommandRunAsync(cmd, NULL) < 0) {
+                qemuDomainObjExitMonitorWithDriver(driver, vm);
+                goto cleanup;
+            }
+            rc = qemuMonitorMigrateToFd(priv->mon,
+                                        QEMU_MONITOR_MIGRATE_BACKGROUND,
+                                        pipeFD[1]);
+            if (VIR_CLOSE(pipeFD[0]) < 0 ||
+                VIR_CLOSE(pipeFD[1]) < 0)
+                VIR_WARN0("failed to close intermediate pipe");
+        } else {
+            rc = qemuMonitorMigrateToFile(priv->mon,
+                                          QEMU_MONITOR_MIGRATE_BACKGROUND,
+                                          args, path, offset);
+        }
     }
     qemuDomainObjExitMonitorWithDriver(driver, vm);

@@ -1852,13 +1871,21 @@ qemuDomainMigrateToFile(struct qemud_driver *driver, virDomainObjPtr vm,
         goto cleanup;

     rc = qemuMigrationWaitForCompletion(driver, vm);
-
     if (rc < 0)
         goto cleanup;

+    if (cmd && virCommandWait(cmd, NULL) < 0)
+        goto cleanup;
+
     ret = 0;

 cleanup:
+    VIR_FORCE_CLOSE(pipeFD[0]);
+    VIR_FORCE_CLOSE(pipeFD[1]);
+    /* FIXME - virCommandWait can overwrite errors; need to add
+     * virCommandKill that does the job silently */
+    ignore_value(virCommandWait(cmd, NULL));
+    virCommandFree(cmd);
     if ((!bypassSecurityDriver) &&
         virSecurityManagerRestoreSavedStateLabel(driver->securityManager,
                                                  vm, path) < 0)
-- 
1.7.4




More information about the libvir-list mailing list