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