When attaching a device to a domain that's using separate mount
namespace we must maintain /dev entries in order for qemu process
to see them.
Signed-off-by: Michal Privoznik <mprivozn(a)redhat.com>
---
src/qemu/qemu_domain.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++--
src/qemu/qemu_domain.h | 8 ++++++
src/qemu/qemu_hotplug.c | 10 +++++++
3 files changed, 86 insertions(+), 2 deletions(-)
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index a8cc8ecfa..a5dc7bbd2 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -7471,6 +7471,7 @@ qemuDomainAttachDeviceMknodHelper(pid_t pid ATTRIBUTE_UNUSED,
} break;
case VIR_DOMAIN_DEVICE_CHR:
+ case VIR_DOMAIN_DEVICE_RNG:
/* No labelling. */
break;
@@ -7489,7 +7490,6 @@ qemuDomainAttachDeviceMknodHelper(pid_t pid ATTRIBUTE_UNUSED,
case VIR_DOMAIN_DEVICE_SMARTCARD:
case VIR_DOMAIN_DEVICE_MEMBALLOON:
case VIR_DOMAIN_DEVICE_NVRAM:
- case VIR_DOMAIN_DEVICE_RNG:
case VIR_DOMAIN_DEVICE_SHMEM:
case VIR_DOMAIN_DEVICE_TPM:
case VIR_DOMAIN_DEVICE_PANIC:
@@ -7607,6 +7607,7 @@ qemuDomainDetachDeviceUnlink(virQEMUDriverPtr driver,
} break;
case VIR_DOMAIN_DEVICE_CHR:
+ case VIR_DOMAIN_DEVICE_RNG:
/* No labelling. */
break;
@@ -7625,7 +7626,6 @@ qemuDomainDetachDeviceUnlink(virQEMUDriverPtr driver,
case VIR_DOMAIN_DEVICE_SMARTCARD:
case VIR_DOMAIN_DEVICE_MEMBALLOON:
case VIR_DOMAIN_DEVICE_NVRAM:
- case VIR_DOMAIN_DEVICE_RNG:
case VIR_DOMAIN_DEVICE_SHMEM:
case VIR_DOMAIN_DEVICE_TPM:
case VIR_DOMAIN_DEVICE_PANIC:
@@ -7825,3 +7825,69 @@ qemuDomainNamespaceTeardownChardev(virQEMUDriverPtr driver,
cleanup:
return ret;
}
+
+
+int
+qemuDomainNamespaceSetupRNG(virQEMUDriverPtr driver,
+ virDomainObjPtr vm,
+ virDomainRNGDefPtr rng)
+{
+ virDomainDeviceDef dev = {.type = VIR_DOMAIN_DEVICE_RNG, .data.rng = rng};
+ const char *path = NULL;
+ int ret = -1;
+
+ if (!qemuDomainNamespaceEnabled(vm, QEMU_DOMAIN_NS_MOUNT))
+ return 0;
+
+ switch ((virDomainRNGBackend) rng->backend) {
+ case VIR_DOMAIN_RNG_BACKEND_RANDOM:
+ path = rng->source.file;
+ break;
+
+ case VIR_DOMAIN_RNG_BACKEND_EGD:
+ case VIR_DOMAIN_RNG_BACKEND_LAST:
+ ret = 0;
+ goto cleanup;
+ }
+
+ if (qemuDomainAttachDeviceMknod(driver,
+ vm,
+ &dev,
+ path) < 0)
+ goto cleanup;
+ ret = 0;
+ cleanup:
+ return ret;
+}
+
+
+int
+qemuDomainNamespaceTeardownRNG(virQEMUDriverPtr driver,
+ virDomainObjPtr vm,
+ virDomainRNGDefPtr rng)
+{
+ virDomainDeviceDef dev = {.type = VIR_DOMAIN_DEVICE_RNG, .data.rng = rng};
+ int ret = -1;
+ const char *path = NULL;
+
+ if (!qemuDomainNamespaceEnabled(vm, QEMU_DOMAIN_NS_MOUNT))
+ return 0;
+
+ switch ((virDomainRNGBackend) rng->backend) {
+ case VIR_DOMAIN_RNG_BACKEND_RANDOM:
+ path = rng->source.file;
+ break;
+
+ case VIR_DOMAIN_RNG_BACKEND_EGD:
+ case VIR_DOMAIN_RNG_BACKEND_LAST:
+ ret = 0;
+ goto cleanup;
+ }
+
+ if (qemuDomainDetachDeviceUnlink(driver, vm, &dev, path) < 0)
+ goto cleanup;
+
+ ret = 0;
+ cleanup:
+ return ret;
+}
diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
index 7a774a543..b2db45e87 100644
--- a/src/qemu/qemu_domain.h
+++ b/src/qemu/qemu_domain.h
@@ -829,4 +829,12 @@ int qemuDomainNamespaceSetupChardev(virQEMUDriverPtr driver,
int qemuDomainNamespaceTeardownChardev(virQEMUDriverPtr driver,
virDomainObjPtr vm,
virDomainChrDefPtr chr);
+
+int qemuDomainNamespaceSetupRNG(virQEMUDriverPtr driver,
+ virDomainObjPtr vm,
+ virDomainRNGDefPtr rng);
+
+int qemuDomainNamespaceTeardownRNG(virQEMUDriverPtr driver,
+ virDomainObjPtr vm,
+ virDomainRNGDefPtr rng);
#endif /* __QEMU_DOMAIN_H__ */
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index 8b41edc56..92a2e7371 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -1988,6 +1988,7 @@ qemuDomainAttachRNGDevice(virConnectPtr conn,
char *secAlias = NULL;
bool releaseaddr = false;
bool teardowncgroup = false;
+ bool teardowndevice = false;
bool chardevAdded = false;
bool objAdded = false;
bool tlsobjAdded = false;
@@ -2033,6 +2034,10 @@ qemuDomainAttachRNGDevice(virConnectPtr conn,
goto cleanup;
}
+ if (qemuDomainNamespaceSetupRNG(driver, vm, rng) < 0)
+ goto cleanup;
+ teardowndevice = true;
+
if (qemuSetupRNGCgroup(vm, rng) < 0)
goto cleanup;
teardowncgroup = true;
@@ -2119,6 +2124,8 @@ qemuDomainAttachRNGDevice(virConnectPtr conn,
qemuDomainReleaseDeviceAddress(vm, &rng->info, NULL);
if (teardowncgroup && qemuTeardownRNGCgroup(vm, rng) < 0)
VIR_WARN("Unable to remove RNG device cgroup ACL on hotplug
fail");
+ if (teardowndevice && qemuDomainNamespaceTeardownRNG(driver, vm, rng)
< 0)
+ VIR_WARN("Unable to remove chr device from /dev");
}
VIR_FREE(tlsAlias);
@@ -4109,6 +4116,9 @@ qemuDomainRemoveRNGDevice(virQEMUDriverPtr driver,
if (qemuTeardownRNGCgroup(vm, rng) < 0)
VIR_WARN("Failed to remove RNG device cgroup ACL");
+ if (qemuDomainNamespaceTeardownRNG(driver, vm, rng) < 0)
+ VIR_WARN("Unable to remove RNG device from /dev");
+
event = virDomainEventDeviceRemovedNewFromObj(vm, rng->info.alias);
qemuDomainEventQueue(driver, event);
--
2.11.0