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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list