[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[libvirt] [RFC PATCHv4 14/15] qemu: skip granting access during fd migration



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


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]