]> xenbits.xensource.com Git - libvirt.git/commitdiff
qemu: Update cgroup on chardev hotplug
authorMichal Privoznik <mprivozn@redhat.com>
Fri, 18 Nov 2016 10:45:44 +0000 (11:45 +0100)
committerMichal Privoznik <mprivozn@redhat.com>
Wed, 23 Nov 2016 15:38:02 +0000 (16:38 +0100)
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@redhat.com>
src/qemu/qemu_cgroup.c
src/qemu/qemu_cgroup.h
src/qemu/qemu_hotplug.c

index 8d3ae4009aa0962b36316770cb5df08879bf6955..211d0b5af69d631608abd6d4ce26328581d58deb 100644 (file)
@@ -189,10 +189,32 @@ qemuSetupChrSourceCgroup(virDomainObjPtr vm,
     return ret;
 }
 
+
+static int
+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
-qemuSetupChardevCgroup(virDomainDefPtr def ATTRIBUTE_UNUSED,
-                       virDomainChrDefPtr dev,
-                       void *opaque)
+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;
 
index 1c3b7fffdbf6799f3cd4bb4f470aa01aaee6c720..6e2c74262943a7b367ad906290321afb2d5b9a81 100644 (file)
@@ -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,
index b43d9ddd1c15bc66fb3feaa9f0fe38963cad4c94..5038ce1254bcd3bdddff8001c595124075e21d82 100644 (file)
@@ -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);