mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-26 14:03:49 +03:00
qemu: Update cgroup on RNG hotplug
If users try to hotplug RNG device with a backend different to /dev/random or /dev/urandom the whole operation fails as qemu is unable to access the device. The problem is we don't update device CGroups during the operation. Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
This commit is contained in:
parent
2878d145fc
commit
085692c8bb
@ -569,6 +569,54 @@ qemuSetupFirmwareCgroup(virDomainObjPtr vm)
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
qemuSetupRNGCgroup(virDomainObjPtr vm,
|
||||
virDomainRNGDefPtr rng)
|
||||
{
|
||||
qemuDomainObjPrivatePtr priv = vm->privateData;
|
||||
int rv;
|
||||
|
||||
if (rng->backend == VIR_DOMAIN_RNG_BACKEND_RANDOM) {
|
||||
VIR_DEBUG("Setting Cgroup ACL for RNG device");
|
||||
rv = virCgroupAllowDevicePath(priv->cgroup,
|
||||
rng->source.file,
|
||||
VIR_CGROUP_DEVICE_RW, false);
|
||||
virDomainAuditCgroupPath(vm, priv->cgroup, "allow",
|
||||
rng->source.file,
|
||||
"rw", rv == 0);
|
||||
if (rv < 0 &&
|
||||
!virLastErrorIsSystemErrno(ENOENT))
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
qemuTeardownRNGCgroup(virDomainObjPtr vm,
|
||||
virDomainRNGDefPtr rng)
|
||||
{
|
||||
qemuDomainObjPrivatePtr priv = vm->privateData;
|
||||
int rv;
|
||||
|
||||
if (rng->backend == VIR_DOMAIN_RNG_BACKEND_RANDOM) {
|
||||
VIR_DEBUG("Tearing down Cgroup ACL for RNG device");
|
||||
rv = virCgroupDenyDevicePath(priv->cgroup,
|
||||
rng->source.file,
|
||||
VIR_CGROUP_DEVICE_RW, false);
|
||||
virDomainAuditCgroupPath(vm, priv->cgroup, "deny",
|
||||
rng->source.file,
|
||||
"rw", rv == 0);
|
||||
if (rv < 0 &&
|
||||
!virLastErrorIsSystemErrno(ENOENT))
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
qemuSetupDevicesCgroup(virQEMUDriverPtr driver,
|
||||
virDomainObjPtr vm)
|
||||
@ -663,18 +711,8 @@ qemuSetupDevicesCgroup(virQEMUDriverPtr driver,
|
||||
}
|
||||
|
||||
for (i = 0; i < vm->def->nrngs; i++) {
|
||||
if (vm->def->rngs[i]->backend == VIR_DOMAIN_RNG_BACKEND_RANDOM) {
|
||||
VIR_DEBUG("Setting Cgroup ACL for RNG device");
|
||||
rv = virCgroupAllowDevicePath(priv->cgroup,
|
||||
vm->def->rngs[i]->source.file,
|
||||
VIR_CGROUP_DEVICE_RW, false);
|
||||
virDomainAuditCgroupPath(vm, priv->cgroup, "allow",
|
||||
vm->def->rngs[i]->source.file,
|
||||
"rw", rv == 0);
|
||||
if (rv < 0 &&
|
||||
!virLastErrorIsSystemErrno(ENOENT))
|
||||
goto cleanup;
|
||||
}
|
||||
if (qemuSetupRNGCgroup(vm, vm->def->rngs[i]) < 0)
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
|
@ -43,6 +43,10 @@ int qemuSetupHostdevCgroup(virDomainObjPtr vm,
|
||||
int qemuTeardownHostdevCgroup(virDomainObjPtr vm,
|
||||
virDomainHostdevDefPtr dev)
|
||||
ATTRIBUTE_RETURN_CHECK;
|
||||
int qemuSetupRNGCgroup(virDomainObjPtr vm,
|
||||
virDomainRNGDefPtr rng);
|
||||
int qemuTeardownRNGCgroup(virDomainObjPtr vm,
|
||||
virDomainRNGDefPtr rng);
|
||||
int qemuConnectCgroup(virQEMUDriverPtr driver,
|
||||
virDomainObjPtr vm);
|
||||
int qemuSetupCgroup(virQEMUDriverPtr driver,
|
||||
|
@ -1951,6 +1951,7 @@ qemuDomainAttachRNGDevice(virConnectPtr conn,
|
||||
char *tlsAlias = NULL;
|
||||
char *secAlias = NULL;
|
||||
bool releaseaddr = false;
|
||||
bool teardowncgroup = false;
|
||||
bool chardevAdded = false;
|
||||
bool objAdded = false;
|
||||
bool tlsobjAdded = false;
|
||||
@ -1996,6 +1997,10 @@ qemuDomainAttachRNGDevice(virConnectPtr conn,
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (qemuSetupRNGCgroup(vm, rng) < 0)
|
||||
goto cleanup;
|
||||
teardowncgroup = true;
|
||||
|
||||
if (rng->backend == VIR_DOMAIN_RNG_BACKEND_EGD)
|
||||
qemuDomainPrepareChardevSourceTLS(rng->source.chardev, cfg);
|
||||
|
||||
@ -2073,8 +2078,13 @@ qemuDomainAttachRNGDevice(virConnectPtr conn,
|
||||
virJSONValueFree(tlsProps);
|
||||
virJSONValueFree(secProps);
|
||||
virJSONValueFree(props);
|
||||
if (ret < 0 && releaseaddr)
|
||||
qemuDomainReleaseDeviceAddress(vm, &rng->info, NULL);
|
||||
if (ret < 0) {
|
||||
if (releaseaddr)
|
||||
qemuDomainReleaseDeviceAddress(vm, &rng->info, NULL);
|
||||
if (teardowncgroup && qemuTeardownRNGCgroup(vm, rng) < 0)
|
||||
VIR_WARN("Unable to remove RNG device cgroup ACL on hotplug fail");
|
||||
}
|
||||
|
||||
VIR_FREE(tlsAlias);
|
||||
VIR_FREE(secAlias);
|
||||
VIR_FREE(charAlias);
|
||||
@ -3912,6 +3922,9 @@ qemuDomainRemoveRNGDevice(virQEMUDriverPtr driver,
|
||||
if (rc < 0)
|
||||
goto cleanup;
|
||||
|
||||
if (qemuTeardownRNGCgroup(vm, rng) < 0)
|
||||
VIR_WARN("Failed to remove RNG device cgroup ACL");
|
||||
|
||||
event = virDomainEventDeviceRemovedNewFromObj(vm, rng->info.alias);
|
||||
qemuDomainEventQueue(driver, event);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user