[libvirt PATCH 3/4] qemu: wire up support for controlling use of cgroups backend

Daniel P. Berrangé berrange at redhat.com
Fri Mar 20 13:40:13 UTC 2020


Currently the QEMU driver chooses between systemd machined and
direct cgroups usage of privileged, and does not use either when
unprivileged.

This wires up support for the new backend choice introduced by
the earlier commits, allowing apps to override the default logic
in the driver when privileged.

This reverts commit c32a7de7d8f81384b17dbe529c6d3b3ac13c631d.
---
 src/qemu/qemu_cgroup.c  | 68 ++++++++++++++++++++++++++++++++---------
 src/qemu/qemu_command.c |  9 +++---
 2 files changed, 59 insertions(+), 18 deletions(-)

diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c
index cd7c381185..a1b53f6628 100644
--- a/src/qemu/qemu_cgroup.c
+++ b/src/qemu/qemu_cgroup.c
@@ -917,6 +917,46 @@ qemuSetupCpuCgroup(virDomainObjPtr vm)
 }
 
 
+static int qemuGetCgroupMode(virDomainObjPtr vm,
+                             virDomainResourceBackend backend,
+                             virCgroupRegister *cgreg)
+{
+    qemuDomainObjPrivatePtr priv = vm->privateData;
+    bool avail = virQEMUDriverIsPrivileged(priv->driver) &&
+        virCgroupAvailable();
+
+    switch (backend) {
+    case VIR_DOMAIN_RESOURCE_BACKEND_NONE:
+        return 0;
+    case VIR_DOMAIN_RESOURCE_BACKEND_DEFAULT:
+        if (!avail)
+            return 0;
+        *cgreg = VIR_CGROUP_REGISTER_DEFAULT;
+        break;
+    case VIR_DOMAIN_RESOURCE_BACKEND_MACHINED:
+        if (!avail)
+            goto unsupported;
+        *cgreg = VIR_CGROUP_REGISTER_MACHINED;
+        break;
+    case VIR_DOMAIN_RESOURCE_BACKEND_CGROUPFS:
+        if (!avail)
+            goto unsupported;
+        *cgreg = VIR_CGROUP_REGISTER_DIRECT;
+        break;
+    case VIR_DOMAIN_RESOURCE_BACKEND_LAST:
+    default:
+        virReportEnumRangeError(virDomainResourceBackend, backend);
+    }
+
+    return 1;
+
+ unsupported:
+    virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                   _("Resource backend '%s' not available"),
+                   virDomainResourceBackendTypeToString(backend));
+    return -1;
+}
+
 static int
 qemuInitCgroup(virDomainObjPtr vm,
                size_t nnicindexes,
@@ -925,11 +965,17 @@ qemuInitCgroup(virDomainObjPtr vm,
     int ret = -1;
     qemuDomainObjPrivatePtr priv = vm->privateData;
     virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(priv->driver);
+    virCgroupRegister reg;
+    int rv;
 
-    if (!virQEMUDriverIsPrivileged(priv->driver))
-        goto done;
-
-    if (!virCgroupAvailable())
+    rv = qemuGetCgroupMode(vm,
+                           vm->def->resource ?
+                           vm->def->resource->backend :
+                           VIR_DOMAIN_RESOURCE_BACKEND_DEFAULT,
+                           &reg);
+    if (rv < 0)
+        goto cleanup;
+    if (rv == 0)
         goto done;
 
     virCgroupFree(&priv->cgroup);
@@ -941,18 +987,12 @@ qemuInitCgroup(virDomainObjPtr vm,
             goto cleanup;
 
         res->backend = VIR_DOMAIN_RESOURCE_BACKEND_DEFAULT;
-        res->partition = g_strdup("/machine");
-
         vm->def->resource = res;
     }
 
-    if (vm->def->resource->backend != VIR_DOMAIN_RESOURCE_BACKEND_DEFAULT) {
-        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
-                       _("Resource backend '%s' not available"),
-                       virDomainResourceBackendTypeToString(
-                           vm->def->resource->backend));
-        goto cleanup;
-    }
+    if (vm->def->resource->backend != VIR_DOMAIN_RESOURCE_BACKEND_NONE &&
+        !vm->def->resource->partition)
+        vm->def->resource->partition = g_strdup("/machine");
 
     if (vm->def->resource->partition[0] != '/') {
         virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
@@ -968,7 +1008,7 @@ qemuInitCgroup(virDomainObjPtr vm,
                             vm->pid,
                             false,
                             nnicindexes, nicindexes,
-                            VIR_CGROUP_REGISTER_DEFAULT,
+                            &reg,
                             vm->def->resource->partition,
                             cfg->cgroupControllers,
                             cfg->maxThreadsPerProc,
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 9790c92cf8..eb1c3f6e12 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -9662,7 +9662,8 @@ qemuBuildCommandLineValidate(virQEMUDriverPtr driver,
     int spice = 0;
     int egl_headless = 0;
 
-    if (!virQEMUDriverIsPrivileged(driver)) {
+    if (!virQEMUDriverIsPrivileged(driver) ||
+        (def->resource && def->resource->backend == VIR_DOMAIN_RESOURCE_BACKEND_NONE)) {
         /* If we have no cgroups then we can have no tunings that
          * require them */
 
@@ -9670,13 +9671,13 @@ qemuBuildCommandLineValidate(virQEMUDriverPtr driver,
             virMemoryLimitIsSet(def->mem.soft_limit) ||
             virMemoryLimitIsSet(def->mem.swap_hard_limit)) {
             virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
-                           _("Memory tuning is not available in session mode"));
+                           _("Memory tuning is not available without cgroups"));
             return -1;
         }
 
         if (def->blkio.weight) {
             virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
-                           _("Block I/O tuning is not available in session mode"));
+                           _("Block I/O tuning is not available without cgroups"));
             return -1;
         }
 
@@ -9686,7 +9687,7 @@ qemuBuildCommandLineValidate(virQEMUDriverPtr driver,
             def->cputune.emulator_quota || def->cputune.iothread_period ||
             def->cputune.iothread_quota) {
             virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
-                           _("CPU tuning is not available in session mode"));
+                           _("CPU tuning is not available without cgroups"));
             return -1;
         }
     }
-- 
2.24.1




More information about the libvir-list mailing list