]> xenbits.xensource.com Git - libvirt.git/commitdiff
qemu: support fd: migration with compression
authorEric Blake <eblake@redhat.com>
Fri, 25 Mar 2011 17:02:27 +0000 (11:02 -0600)
committerEric Blake <eblake@redhat.com>
Mon, 28 Mar 2011 16:26:33 +0000 (10:26 -0600)
Spawn the compressor ourselves, instead of requiring the shell.

* src/qemu/qemu_migration.c (qemuMigrationToFile): Spawn
compression helper process when needed.

src/qemu/qemu_migration.c

index 2803de6995fb4d8f58026a7e3c9a6dd279ea927b..98b9d01315b3287dc5141cd24862951ec9858dfb 100644 (file)
@@ -1298,9 +1298,11 @@ qemuMigrationToFile(struct qemud_driver *driver, virDomainObjPtr vm,
     int ret = -1;
     int rc;
     bool restoreLabel = false;
+    virCommandPtr cmd = NULL;
+    int pipeFD[2] = { -1, -1 };
 
     if (qemuCaps && qemuCapsGet(qemuCaps, QEMU_CAPS_MIGRATE_QEMU_FD) &&
-        !compressor) {
+        (!compressor || 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.  */
@@ -1359,9 +1361,31 @@ qemuMigrationToFile(struct qemud_driver *driver, virDomainObjPtr vm,
             "-c",
             NULL
         };
-        rc = qemuMonitorMigrateToFile(priv->mon,
-                                      QEMU_MONITOR_MIGRATE_BACKGROUND,
-                                      args, path, offset);
+        if (pipeFD[0] != -1) {
+            cmd = virCommandNewArgs(args);
+            virCommandSetInputFD(cmd, pipeFD[0]);
+            virCommandSetOutputFD(cmd, &fd);
+            if (virSetCloseExec(pipeFD[1]) < 0) {
+                virReportSystemError(errno, "%s",
+                                     _("Unable to set cloexec flag"));
+                qemuDomainObjExitMonitorWithDriver(driver, vm);
+                goto cleanup;
+            }
+            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);
 
@@ -1373,9 +1397,15 @@ qemuMigrationToFile(struct qemud_driver *driver, virDomainObjPtr 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]);
+    virCommandFree(cmd);
     if (restoreLabel && (!bypassSecurityDriver) &&
         virSecurityManagerRestoreSavedStateLabel(driver->securityManager,
                                                  vm, path) < 0)