[libvirt] [PATCH 14/17] qemu: Wire up virUdevMgr

Michal Privoznik mprivozn at redhat.com
Wed Oct 26 12:37:01 UTC 2016


Now that security drivers are capable of writing into virUdevMgr
module, we also need it to flush its internal database right
after that.

Signed-off-by: Michal Privoznik <mprivozn at redhat.com>
---
 src/qemu/qemu_domain.c  | 12 +++++++++++-
 src/qemu/qemu_domain.h  |  3 ++-
 src/qemu/qemu_driver.c  |  9 +++++++--
 src/qemu/qemu_hotplug.c | 35 ++++++++++++++++++++++++++++-------
 src/qemu/qemu_process.c | 47 +++++++++++++++++++++++++++++++++++++++++++++--
 src/qemu/qemu_process.h |  3 +++
 6 files changed, 96 insertions(+), 13 deletions(-)

diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 838e838..4422fbc 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -641,13 +641,15 @@ qemuDomainMasterKeyReadFile(qemuDomainObjPrivatePtr priv)
 
 
 /* qemuDomainMasterKeyRemove:
+ * @driver: qemu driver data
  * @priv: Pointer to the domain private object
  *
  * Remove the traces of the master key, clear the heap, clear the file,
  * delete the file.
  */
 void
-qemuDomainMasterKeyRemove(qemuDomainObjPrivatePtr priv)
+qemuDomainMasterKeyRemove(virQEMUDriverPtr driver,
+                          qemuDomainObjPrivatePtr priv)
 {
     char *path = NULL;
 
@@ -660,6 +662,8 @@ qemuDomainMasterKeyRemove(qemuDomainObjPrivatePtr priv)
     /* Delete the master key file */
     path = qemuDomainGetMasterKeyFilePath(priv->libDir);
     unlink(path);
+    if (driver->udevMgr)
+        virUdevMgrRemoveAllLabels(driver->udevMgr, path);
 
     VIR_FREE(path);
 }
@@ -4935,6 +4939,9 @@ qemuDomainDiskChainElementRevoke(virQEMUDriverPtr driver,
                                             vm->def, elem) < 0)
         VIR_WARN("Unable to restore security label on %s", NULLSTR(elem->path));
 
+    if (qemuProcessFlushUdev(driver) < 0)
+        VIR_WARN("Unable to clean up udev rules");
+
     if (qemuTeardownImageCgroup(vm, elem) < 0)
         VIR_WARN("Failed to teardown cgroup for disk path %s",
                  NULLSTR(elem->path));
@@ -4974,6 +4981,9 @@ qemuDomainDiskChainElementPrepare(virQEMUDriverPtr driver,
                                         elem) < 0)
         goto cleanup;
 
+    if (qemuProcessFlushUdev(driver) < 0)
+        goto cleanup;
+
     ret = 0;
 
  cleanup:
diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
index 2ee1829..a381b59 100644
--- a/src/qemu/qemu_domain.h
+++ b/src/qemu/qemu_domain.h
@@ -710,7 +710,8 @@ int qemuDomainWriteMasterKeyFile(virQEMUDriverPtr driver,
 
 int qemuDomainMasterKeyCreate(virDomainObjPtr vm);
 
-void qemuDomainMasterKeyRemove(qemuDomainObjPrivatePtr priv);
+void qemuDomainMasterKeyRemove(virQEMUDriverPtr driver,
+                               qemuDomainObjPrivatePtr priv);
 
 void qemuDomainSecretDiskDestroy(virDomainDiskDefPtr disk)
     ATTRIBUTE_NONNULL(1);
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 7dbbc25..cc34782 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -3864,8 +3864,11 @@ qemuDomainScreenshot(virDomainPtr dom,
 
  endjob:
     VIR_FORCE_CLOSE(tmp_fd);
-    if (unlink_tmp)
+    if (unlink_tmp) {
+        virSecurityManagerRestoreSavedStateLabel(driver->securityManager, vm->def, tmp);
+        qemuProcessFlushUdev(driver);
         unlink(tmp);
+    }
     VIR_FREE(tmp);
 
     qemuDomainObjEndJob(driver, vm);
@@ -6682,6 +6685,7 @@ qemuDomainSaveImageStartVM(virConnectPtr conn,
     if (virSecurityManagerRestoreSavedStateLabel(driver->securityManager,
                                                  vm->def, path) < 0)
         VIR_WARN("failed to restore save state label on %s", path);
+    qemuProcessFlushUdev(driver);
     virObjectUnref(cfg);
     return ret;
 }
@@ -16071,7 +16075,8 @@ qemuDomainBlockPivot(virQEMUDriverPtr driver,
                                      disk) < 0 ||
              qemuSetupDiskCgroup(vm, disk) < 0 ||
              virSecurityManagerSetDiskLabel(driver->securityManager, vm->def,
-                                            disk) < 0))
+                                            disk) < 0 ||
+             qemuProcessFlushUdev(driver) < 0))
             goto cleanup;
 
         disk->src = oldsrc;
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index 9746a06..fdac464 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -113,6 +113,9 @@ qemuDomainPrepareDisk(virQEMUDriverPtr driver,
                                        vm->def, disk) < 0)
         goto rollback_lock;
 
+    if (qemuProcessFlushUdev(driver) < 0)
+        goto rollback_label;
+
     if (qemuSetupDiskCgroup(vm, disk) < 0)
         goto rollback_label;
 
@@ -130,6 +133,9 @@ qemuDomainPrepareDisk(virQEMUDriverPtr driver,
         VIR_WARN("Unable to restore security label on %s",
                  virDomainDiskGetSource(disk));
 
+    if (qemuProcessFlushUdev(driver) < 0)
+        VIR_WARN("Unable to clean up udev rules");
+
  rollback_lock:
     if (virDomainLockDiskDetach(driver->lockManager, vm, disk) < 0)
         VIR_WARN("Unable to release lock on %s",
@@ -1427,6 +1433,8 @@ qemuDomainAttachHostPCIDevice(virQEMUDriverPtr driver,
         goto error;
     if (backend != VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO)
         teardownlabel = true;
+    if (qemuProcessFlushUdev(driver) < 0)
+        goto error;
 
     if (qemuAssignDeviceHostdevAlias(vm->def, &hostdev->info->alias, -1) < 0)
         goto error;
@@ -1476,10 +1484,10 @@ qemuDomainAttachHostPCIDevice(virQEMUDriverPtr driver,
     if (teardowncgroup && qemuTeardownHostdevCgroup(vm, hostdev) < 0)
         VIR_WARN("Unable to remove host device cgroup ACL on hotplug fail");
     if (teardownlabel &&
-        virSecurityManagerRestoreHostdevLabel(driver->securityManager,
-                                              vm->def, hostdev, NULL) < 0)
+        (virSecurityManagerRestoreHostdevLabel(driver->securityManager,
+                                               vm->def, hostdev, NULL) < 0 ||
+         qemuProcessFlushUdev(driver) < 0))
         VIR_WARN("Unable to restore host device labelling on hotplug fail");
-
     if (releaseaddr)
         qemuDomainReleaseDeviceAddress(vm, hostdev->info, NULL);
 
@@ -2262,6 +2270,8 @@ qemuDomainAttachHostUSBDevice(virQEMUDriverPtr driver,
                                           vm->def, hostdev, NULL) < 0)
         goto cleanup;
     teardownlabel = true;
+    if (qemuProcessFlushUdev(driver) < 0)
+        goto cleanup;
 
     if (qemuAssignDeviceHostdevAlias(vm->def, &hostdev->info->alias, -1) < 0)
         goto cleanup;
@@ -2289,8 +2299,9 @@ qemuDomainAttachHostUSBDevice(virQEMUDriverPtr driver,
         if (teardowncgroup && qemuTeardownHostdevCgroup(vm, hostdev) < 0)
             VIR_WARN("Unable to remove host device cgroup ACL on hotplug fail");
         if (teardownlabel &&
-            virSecurityManagerRestoreHostdevLabel(driver->securityManager,
-                                                  vm->def, hostdev, NULL) < 0)
+            (virSecurityManagerRestoreHostdevLabel(driver->securityManager,
+                                                   vm->def, hostdev, NULL) < 0 ||
+             qemuProcessFlushUdev(driver) < 0))
             VIR_WARN("Unable to restore host device labelling on hotplug fail");
         if (added)
             qemuHostdevReAttachUSBDevices(driver, vm->def->name, &hostdev, 1);
@@ -2364,6 +2375,9 @@ qemuDomainAttachHostSCSIDevice(virConnectPtr conn,
         goto cleanup;
     teardownlabel = true;
 
+    if (qemuProcessFlushUdev(driver) < 0)
+        goto cleanup;
+
     if (qemuAssignDeviceHostdevAlias(vm->def, &hostdev->info->alias, -1) < 0)
         goto cleanup;
 
@@ -2407,8 +2421,9 @@ qemuDomainAttachHostSCSIDevice(virConnectPtr conn,
         if (teardowncgroup && qemuTeardownHostdevCgroup(vm, hostdev) < 0)
             VIR_WARN("Unable to remove host device cgroup ACL on hotplug fail");
         if (teardownlabel &&
-            virSecurityManagerRestoreHostdevLabel(driver->securityManager,
-                                                  vm->def, hostdev, NULL) < 0)
+            (virSecurityManagerRestoreHostdevLabel(driver->securityManager,
+                                                   vm->def, hostdev, NULL) < 0 ||
+             qemuProcessFlushUdev(driver) < 0))
             VIR_WARN("Unable to restore host device labelling on hotplug fail");
     }
     VIR_FREE(drivealias);
@@ -3315,6 +3330,9 @@ qemuDomainRemoveDiskDevice(virQEMUDriverPtr driver,
                                            vm->def, disk) < 0)
         VIR_WARN("Unable to restore security label on %s", src);
 
+    if (qemuProcessFlushUdev(driver) < 0)
+        VIR_WARN("Unable to clean up udev rules");
+
     if (qemuTeardownDiskCgroup(vm, disk) < 0)
         VIR_WARN("Failed to tear down cgroup for disk path %s", src);
 
@@ -3493,6 +3511,9 @@ qemuDomainRemoveHostDevice(virQEMUDriverPtr driver,
                                               vm->def, hostdev, NULL) < 0)
         VIR_WARN("Failed to restore host device labelling");
 
+    if (qemuProcessFlushUdev(driver) < 0)
+        VIR_WARN("Unable to clean up udev rules");
+
     if (qemuTeardownHostdevCgroup(vm, hostdev) < 0)
         VIR_WARN("Failed to remove host device cgroup ACL");
 
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 1b67aee..10f29ff 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -5499,6 +5499,9 @@ qemuProcessLaunch(virConnectPtr conn,
      */
     ret = -2;
 
+    if (qemuProcessFlushUdev(driver) < 0)
+        goto cleanup;
+
     if (incoming && incoming->fd != -1) {
         /* if there's an fd to migrate from, and it's a pipe, put the
          * proper security label on it
@@ -5998,10 +6001,14 @@ void qemuProcessStop(virQEMUDriverPtr driver,
     }
 
     /* Remove the master key */
-    qemuDomainMasterKeyRemove(priv);
+    qemuDomainMasterKeyRemove(driver, priv);
 
     virFileDeleteTree(priv->libDir);
     virFileDeleteTree(priv->channelTargetDir);
+    if (driver->udevMgr) {
+        virUdevMgrRemoveAllLabels(driver->udevMgr, priv->libDir);
+        virUdevMgrRemoveAllLabels(driver->udevMgr, priv->channelTargetDir);
+    }
 
     qemuDomainClearPrivatePaths(vm);
 
@@ -6033,10 +6040,12 @@ void qemuProcessStop(virQEMUDriverPtr driver,
     }
 
     /* Reset Security Labels unless caller don't want us to */
-    if (!(flags & VIR_QEMU_PROCESS_STOP_NO_RELABEL))
+    if (!(flags & VIR_QEMU_PROCESS_STOP_NO_RELABEL)) {
         virSecurityManagerRestoreAllLabel(driver->securityManager,
                                           vm->def,
                                           !!(flags & VIR_QEMU_PROCESS_STOP_MIGRATED));
+        qemuProcessFlushUdev(driver);
+    }
     virSecurityManagerReleaseLabel(driver->securityManager, vm->def);
 
     for (i = 0; i < vm->def->ndisks; i++) {
@@ -6587,3 +6596,37 @@ qemuProcessRefreshDisks(virQEMUDriverPtr driver,
     virHashFree(table);
     return ret;
 }
+
+
+char *
+qemuProcessGetUdevPath(virQEMUDriverPtr driver)
+{
+    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
+    char *file;
+
+    ignore_value(virAsprintf(&file, "%s/devices.udev", cfg->stateDir));
+    virObjectUnref(cfg);
+    return file;
+}
+
+
+int
+qemuProcessFlushUdev(virQEMUDriverPtr driver)
+{
+    char *file = NULL;
+    int ret = -1;
+
+    if (!driver->udevMgr)
+        return 0;
+
+    if (!(file = qemuProcessGetUdevPath(driver)))
+        goto cleanup;
+
+    if (virUdevMgrDumpFile(driver->udevMgr, file) < 0)
+        goto cleanup;
+
+    ret = 0;
+ cleanup:
+    VIR_FREE(file);
+    return ret;
+}
diff --git a/src/qemu/qemu_process.h b/src/qemu/qemu_process.h
index 21f3b0c..8d1e937 100644
--- a/src/qemu/qemu_process.h
+++ b/src/qemu/qemu_process.h
@@ -191,4 +191,7 @@ int qemuProcessRefreshDisks(virQEMUDriverPtr driver,
                             virDomainObjPtr vm,
                             qemuDomainAsyncJob asyncJob);
 
+char * qemuProcessGetUdevPath(virQEMUDriverPtr driver);
+int qemuProcessFlushUdev(virQEMUDriverPtr driver);
+
 #endif /* __QEMU_PROCESS_H__ */
-- 
2.8.4




More information about the libvir-list mailing list