}
+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)
}
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;
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,
char *tlsAlias = NULL;
char *secAlias = NULL;
bool releaseaddr = false;
+ bool teardowncgroup = false;
bool chardevAdded = false;
bool objAdded = false;
bool tlsobjAdded = false;
goto cleanup;
}
+ if (qemuSetupRNGCgroup(vm, rng) < 0)
+ goto cleanup;
+ teardowncgroup = true;
+
if (rng->backend == VIR_DOMAIN_RNG_BACKEND_EGD)
qemuDomainPrepareChardevSourceTLS(rng->source.chardev, cfg);
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);
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);