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

Michal Privoznik posted 14 patches 8 years, 11 months ago
There is a newer version of this series
[libvirt] [PATCH v2 13/14] qemu: Allow nvdimm in devices CGroups
Posted by Michal Privoznik 8 years, 11 months ago
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@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

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH v2 13/14] qemu: Allow nvdimm in devices CGroups
Posted by John Ferlan 8 years, 11 months ago

On 02/27/2017 08:19 AM, Michal Privoznik wrote:
> 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@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;

This would seem to be a quicker check than HasController... and should
go first shouldn't it?

> +
> +    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;

Same

Otherwise seems reasonable (although I cannot git am it)


John
> +
> +    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 */
> 

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list