From: Michal Privoznik Date: Fri, 18 Nov 2016 14:19:12 +0000 (+0100) Subject: qemu: Manage /dev entry on RNG hotplug X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=f95c5c48d416dcdab2f3ee7718f12a02833c9339;p=libvirt.git qemu: Manage /dev entry on RNG hotplug 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 --- diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 7da3963bba..52fe7c01aa 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -7535,6 +7535,7 @@ qemuDomainAttachDeviceMknodHelper(pid_t pid ATTRIBUTE_UNUSED, } break; case VIR_DOMAIN_DEVICE_CHR: + case VIR_DOMAIN_DEVICE_RNG: /* No labelling. */ break; @@ -7553,7 +7554,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: @@ -7671,6 +7671,7 @@ qemuDomainDetachDeviceUnlink(virQEMUDriverPtr driver, } break; case VIR_DOMAIN_DEVICE_CHR: + case VIR_DOMAIN_DEVICE_RNG: /* No labelling. */ break; @@ -7689,7 +7690,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: @@ -7889,3 +7889,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 7a774a543d..b2db45e877 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 8b41edc560..92a2e73711 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);