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