SELinux labeling and cgroup ACLs aren't required if we hand a pre-opened fd to qemu. All the more reason to love fd: migration. * src/qemu/qemu_driver.c (qemuDomainMigrateToFile): Skip steps that are irrelevant in fd migration. --- src/qemu/qemu_driver.c | 65 +++++++++++++++++++++++++++++------------------ 1 files changed, 40 insertions(+), 25 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 2422482..a679b2c 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -1779,35 +1779,52 @@ qemuDomainMigrateToFile(struct qemud_driver *driver, virDomainObjPtr vm, int ret = -1; int rc; - if (!is_reg && - qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_DEVICES)) { - if (virCgroupForDomain(driver->cgroup, vm->def->name, - &cgroup, 0) != 0) { - qemuReportError(VIR_ERR_INTERNAL_ERROR, - _("Unable to find cgroup for %s"), - vm->def->name); - goto cleanup; + if (qemuCaps && qemuCapsGet(qemuCaps, QEMU_CAPS_MIGRATE_QEMU_FD) && + priv->monConfig->type == VIR_DOMAIN_CHR_TYPE_UNIX && + compressed == QEMUD_SAVE_FORMAT_RAW) { + /* 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. */ + is_reg = true; + bypassSecurityDriver = true; + } else { + /* Phooey - we have to fall back on exec migration, where qemu + * has to popen() the file by name. We might also stumble on + * the qemu race where it does a wait() that botches pclose(). + * FIXME: can we reliably detect and ignore that particular + * failure where the migration completes but the reported + * status is wrong? */ + if (!is_reg && + qemuCgroupControllerActive(driver, + VIR_CGROUP_CONTROLLER_DEVICES)) { + if (virCgroupForDomain(driver->cgroup, vm->def->name, + &cgroup, 0) != 0) { + qemuReportError(VIR_ERR_INTERNAL_ERROR, + _("Unable to find cgroup for %s"), + vm->def->name); + goto cleanup; + } + rc = virCgroupAllowDevicePath(cgroup, path, + VIR_CGROUP_DEVICE_RW); + qemuAuditCgroupPath(vm, cgroup, "allow", path, "rw", rc); + if (rc < 0) { + virReportSystemError(-rc, + _("Unable to allow device %s for %s"), + path, vm->def->name); + goto cleanup; + } } - rc = virCgroupAllowDevicePath(cgroup, path, - VIR_CGROUP_DEVICE_RW); - qemuAuditCgroupPath(vm, cgroup, "allow", path, "rw", rc); - if (rc < 0) { - virReportSystemError(-rc, - _("Unable to allow device %s for %s"), - path, vm->def->name); + + if ((!bypassSecurityDriver) && + virSecurityManagerSetSavedStateLabel(driver->securityManager, + vm, path) < 0) goto cleanup; - } } - if ((!bypassSecurityDriver) && - virSecurityManagerSetSavedStateLabel(driver->securityManager, - vm, path) < 0) - goto cleanup; - + qemuDomainObjEnterMonitorWithDriver(driver, vm); if (compressed == QEMUD_SAVE_FORMAT_RAW) { const char *args[] = { "cat", NULL }; - qemuDomainObjEnterMonitorWithDriver(driver, vm); if (qemuCaps && qemuCapsGet(qemuCaps, QEMU_CAPS_MIGRATE_QEMU_FD) && priv->monConfig->type == VIR_DOMAIN_CHR_TYPE_UNIX) { rc = qemuMonitorMigrateToFd(priv->mon, @@ -1818,7 +1835,6 @@ qemuDomainMigrateToFile(struct qemud_driver *driver, virDomainObjPtr vm, QEMU_MONITOR_MIGRATE_BACKGROUND, args, path, offset); } - qemuDomainObjExitMonitorWithDriver(driver, vm); } else { const char *prog = qemudSaveCompressionTypeToString(compressed); const char *args[] = { @@ -1826,12 +1842,11 @@ qemuDomainMigrateToFile(struct qemud_driver *driver, virDomainObjPtr vm, "-c", NULL }; - qemuDomainObjEnterMonitorWithDriver(driver, vm); rc = qemuMonitorMigrateToFile(priv->mon, QEMU_MONITOR_MIGRATE_BACKGROUND, args, path, offset); - qemuDomainObjExitMonitorWithDriver(driver, vm); } + qemuDomainObjExitMonitorWithDriver(driver, vm); if (rc < 0) goto cleanup; -- 1.7.4 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list