[libvirt] [PATCH 13/14] qemu: Allow nvdimm in devices CGroups

Michal Privoznik mprivozn at redhat.com
Thu Feb 23 09:02:56 UTC 2017


Some users might want to pass a blockdev or a chardev as a
backend for NVDIMM. In fact, this is expected to be the mostly
used configuration. Therefore libvirt should allow the device in
devices CGroup then.

Signed-off-by: Michal Privoznik <mprivozn at redhat.com>
---
 src/qemu/qemu_cgroup.c  | 49 +++++++++++++++++++++++++++++++++++++++++++++++++
 src/qemu/qemu_cgroup.h  |  4 ++++
 src/qemu/qemu_hotplug.c | 10 ++++++++++
 3 files changed, 63 insertions(+)

diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c
index 42a47a798..8f68a22dc 100644
--- a/src/qemu/qemu_cgroup.c
+++ b/src/qemu/qemu_cgroup.c
@@ -348,6 +348,50 @@ qemuTeardownHostdevCgroup(virDomainObjPtr vm,
 }
 
 
+int
+qemuSetupMemoryDevicesCgroup(virDomainObjPtr vm,
+                             virDomainMemoryDefPtr mem)
+{
+    qemuDomainObjPrivatePtr priv = vm->privateData;
+    int rv;
+
+    if (!virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_DEVICES))
+        return 0;
+
+    if (mem->model != VIR_DOMAIN_MEMORY_MODEL_NVDIMM)
+        return 0;
+
+    VIR_DEBUG("Setting devices Cgroup for NVDIMM device: %s", mem->path);
+    rv = virCgroupAllowDevicePath(priv->cgroup, mem->path,
+                                  VIR_CGROUP_DEVICE_RW, false);
+    virDomainAuditCgroupPath(vm, priv->cgroup, "allow",
+                             mem->path, "rw", rv == 0);
+
+    return rv;
+}
+
+
+int
+qemuTeardownMemoryDevicesCgroup(virDomainObjPtr vm,
+                                virDomainMemoryDefPtr mem)
+{
+    qemuDomainObjPrivatePtr priv = vm->privateData;
+    int rv;
+
+    if (!virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_DEVICES))
+        return 0;
+
+    if (mem->model != VIR_DOMAIN_MEMORY_MODEL_NVDIMM)
+        return 0;
+
+    rv = virCgroupDenyDevicePath(priv->cgroup, mem->path,
+                                 VIR_CGROUP_DEVICE_RWM, false);
+    virDomainAuditCgroupPath(vm, priv->cgroup,
+                             "deny", mem->path, "rwm", rv == 0);
+    return rv;
+}
+
+
 static int
 qemuSetupGraphicsCgroup(virDomainObjPtr vm,
                         virDomainGraphicsDefPtr gfx)
@@ -647,6 +691,11 @@ qemuSetupDevicesCgroup(virQEMUDriverPtr driver,
             goto cleanup;
     }
 
+    for (i = 0; i < vm->def->nmems; i++) {
+        if (qemuSetupMemoryDevicesCgroup(vm, vm->def->mems[i]) < 0)
+            goto cleanup;
+    }
+
     for (i = 0; i < vm->def->ngraphics; i++) {
         if (qemuSetupGraphicsCgroup(vm, vm->def->graphics[i]) < 0)
             goto cleanup;
diff --git a/src/qemu/qemu_cgroup.h b/src/qemu/qemu_cgroup.h
index 8ae4a72ab..d016ce29d 100644
--- a/src/qemu/qemu_cgroup.h
+++ b/src/qemu/qemu_cgroup.h
@@ -43,6 +43,10 @@ int qemuSetupHostdevCgroup(virDomainObjPtr vm,
 int qemuTeardownHostdevCgroup(virDomainObjPtr vm,
                               virDomainHostdevDefPtr dev)
    ATTRIBUTE_RETURN_CHECK;
+int qemuSetupMemoryDevicesCgroup(virDomainObjPtr vm,
+                                 virDomainMemoryDefPtr mem);
+int qemuTeardownMemoryDevicesCgroup(virDomainObjPtr vm,
+                                    virDomainMemoryDefPtr mem);
 int qemuSetupRNGCgroup(virDomainObjPtr vm,
                        virDomainRNGDefPtr rng);
 int qemuTeardownRNGCgroup(virDomainObjPtr vm,
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index 7e837a422..e821596bf 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -2192,6 +2192,7 @@ qemuDomainAttachMemory(virQEMUDriverPtr driver,
     const char *backendType;
     bool objAdded = false;
     bool teardownlabel = false;
+    bool teardowncgroup = false;
     virJSONValuePtr props = NULL;
     virObjectEventPtr event;
     int id;
@@ -2233,6 +2234,10 @@ qemuDomainAttachMemory(virQEMUDriverPtr driver,
         goto removedef;
     }
 
+    if (qemuSetupMemoryDevicesCgroup(vm, mem) < 0)
+        goto removedef;
+    teardowncgroup = true;
+
     if (qemuSecuritySetMemoryLabel(driver, vm, mem) < 0)
         goto removedef;
     teardownlabel = true;
@@ -2272,6 +2277,8 @@ qemuDomainAttachMemory(virQEMUDriverPtr driver,
     virDomainAuditMemory(vm, oldmem, newmem, "update", ret == 0);
  cleanup:
     if (mem && ret < 0) {
+        if (teardowncgroup && qemuTeardownMemoryDevicesCgroup(vm, mem) < 0)
+            VIR_WARN("Unable to remove memory device cgroup ACL on hotplug fail");
         if (teardownlabel && qemuSecurityRestoreMemoryLabel(driver, vm, mem) < 0)
             VIR_WARN("Unable to restore security label on memdev");
     }
@@ -3739,6 +3746,9 @@ qemuDomainRemoveMemoryDevice(virQEMUDriverPtr driver,
     if (qemuSecurityRestoreMemoryLabel(driver, vm, mem) < 0)
         VIR_WARN("Unable to restore security label on memdev");
 
+    if (qemuTeardownMemoryDevicesCgroup(vm, mem) < 0)
+        VIR_WARN("Unable to remove memory device cgroup ACL");
+
     virDomainMemoryDefFree(mem);
 
     /* fix the balloon size */
-- 
2.11.0




More information about the libvir-list mailing list