Just like in the previous commit, we are not updating CGroups on chardev hot(un-)plug and thus leaving qemu unable to access any non-default device users are trying to hotplug. Signed-off-by: Michal Privoznik <mprivozn@xxxxxxxxxx> --- src/qemu/qemu_cgroup.c | 46 ++++++++++++++++++++++++++++++++++++++++++---- src/qemu/qemu_cgroup.h | 4 ++++ src/qemu/qemu_hotplug.c | 20 ++++++++++++++++---- 3 files changed, 62 insertions(+), 8 deletions(-) diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c index e7ce032..50e3d35 100644 --- a/src/qemu/qemu_cgroup.c +++ b/src/qemu/qemu_cgroup.c @@ -189,10 +189,32 @@ qemuSetupChrSourceCgroup(virDomainObjPtr vm, return ret; } + static int -qemuSetupChardevCgroup(virDomainDefPtr def ATTRIBUTE_UNUSED, - virDomainChrDefPtr dev, - void *opaque) +qemuTeardownChrSourceCgroup(virDomainObjPtr vm, + virDomainChrSourceDefPtr source) +{ + qemuDomainObjPrivatePtr priv = vm->privateData; + int ret; + + if (source->type != VIR_DOMAIN_CHR_TYPE_DEV) + return 0; + + VIR_DEBUG("Process path '%s' for device", source->data.file.path); + + ret = virCgroupDenyDevicePath(priv->cgroup, source->data.file.path, + VIR_CGROUP_DEVICE_RW, false); + virDomainAuditCgroupPath(vm, priv->cgroup, "deny", + source->data.file.path, "rw", ret == 0); + + return ret; +} + + +static int +qemuSetupChardevCgroupCB(virDomainDefPtr def ATTRIBUTE_UNUSED, + virDomainChrDefPtr dev, + void *opaque) { virDomainObjPtr vm = opaque; @@ -617,6 +639,22 @@ qemuTeardownRNGCgroup(virDomainObjPtr vm, } +int +qemuSetupChardevCgroup(virDomainObjPtr vm, + virDomainChrDefPtr dev) +{ + return qemuSetupChrSourceCgroup(vm, dev->source); +} + + +int +qemuTeardownChardevCgroup(virDomainObjPtr vm, + virDomainChrDefPtr dev) +{ + return qemuTeardownChrSourceCgroup(vm, dev->source); +} + + static int qemuSetupDevicesCgroup(virQEMUDriverPtr driver, virDomainObjPtr vm) @@ -693,7 +731,7 @@ qemuSetupDevicesCgroup(virQEMUDriverPtr driver, if (virDomainChrDefForeach(vm->def, true, - qemuSetupChardevCgroup, + qemuSetupChardevCgroupCB, vm) < 0) goto cleanup; diff --git a/src/qemu/qemu_cgroup.h b/src/qemu/qemu_cgroup.h index 1c3b7ff..6e2c742 100644 --- a/src/qemu/qemu_cgroup.h +++ b/src/qemu/qemu_cgroup.h @@ -47,6 +47,10 @@ int qemuSetupRNGCgroup(virDomainObjPtr vm, virDomainRNGDefPtr rng); int qemuTeardownRNGCgroup(virDomainObjPtr vm, virDomainRNGDefPtr rng); +int qemuSetupChardevCgroup(virDomainObjPtr vm, + virDomainChrDefPtr dev); +int qemuTeardownChardevCgroup(virDomainObjPtr vm, + virDomainChrDefPtr dev); int qemuConnectCgroup(virQEMUDriverPtr driver, virDomainObjPtr vm); int qemuSetupCgroup(virQEMUDriverPtr driver, diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index b43d9dd..5038ce1 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -1830,6 +1830,7 @@ int qemuDomainAttachChrDevice(virConnectPtr conn, char *charAlias = NULL; bool chardevAttached = false; bool tlsobjAdded = false; + bool teardowncgroup = false; bool secobjAdded = false; virJSONValuePtr tlsProps = NULL; char *tlsAlias = NULL; @@ -1851,6 +1852,10 @@ int qemuDomainAttachChrDevice(virConnectPtr conn, if (rc == 1) need_release = true; + if (qemuSetupChardevCgroup(vm, chr) < 0) + goto cleanup; + teardowncgroup = true; + if (qemuBuildChrDeviceStr(&devstr, vmdef, chr, priv->qemuCaps) < 0) goto cleanup; @@ -1903,10 +1908,14 @@ int qemuDomainAttachChrDevice(virConnectPtr conn, audit: virDomainAuditChardev(vm, NULL, chr, "attach", ret == 0); cleanup: - if (ret < 0 && virDomainObjIsActive(vm)) - qemuDomainChrInsertPreAllocCleanup(vmdef, chr); - if (ret < 0 && need_release) - qemuDomainReleaseDeviceAddress(vm, &chr->info, NULL); + if (ret < 0) { + if (virDomainObjIsActive(vm)) + qemuDomainChrInsertPreAllocCleanup(vmdef, chr); + if (need_release) + qemuDomainReleaseDeviceAddress(vm, &chr->info, NULL); + if (teardowncgroup && qemuTeardownChardevCgroup(vm, chr) < 0) + VIR_WARN("Unable to remove chr device cgroup ACL on hotplug fail"); + } VIR_FREE(tlsAlias); virJSONValueFree(tlsProps); VIR_FREE(secAlias); @@ -3847,6 +3856,9 @@ qemuDomainRemoveChrDevice(virQEMUDriverPtr driver, if (rc < 0) goto cleanup; + if (qemuTeardownChardevCgroup(vm, chr) < 0) + VIR_WARN("Failed to remove chr device cgroup ACL"); + event = virDomainEventDeviceRemovedNewFromObj(vm, chr->info.alias); qemuDomainEventQueue(driver, event); -- 2.8.4 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list