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(a)redhat.com>
---
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