[libvirt] [PATCH 2/2] qemu: Update cgroup on chardev hotplug

Michal Privoznik mprivozn at redhat.com
Fri Nov 18 11:30:13 UTC 2016


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 at 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




More information about the libvir-list mailing list