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(a)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 8cba755..f5be7c7 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);
}
@@ -4989,6 +4993,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));
@@ -5028,6 +5035,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 e791d40..d785c60 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -3868,8 +3868,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);
@@ -6693,6 +6696,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;
}
@@ -16113,7 +16117,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 e06862c..daadfbf 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);
@@ -2253,6 +2261,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;
@@ -2280,8 +2290,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);
@@ -2355,6 +2366,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;
@@ -2398,8 +2412,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);
@@ -3431,6 +3446,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);
@@ -3609,6 +3627,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