Pablo Greco 40546a
From 50c5a71ce4a4400d08deff481c8781f3fca755c8 Mon Sep 17 00:00:00 2001
Pablo Greco 40546a
Message-Id: <50c5a71ce4a4400d08deff481c8781f3fca755c8@dist-git>
Pablo Greco 40546a
From: Pavel Hrdina <phrdina@redhat.com>
Pablo Greco 40546a
Date: Mon, 1 Jul 2019 17:07:53 +0200
Pablo Greco 40546a
Subject: [PATCH] vircgroup: add support for hybrid configuration
Pablo Greco 40546a
MIME-Version: 1.0
Pablo Greco 40546a
Content-Type: text/plain; charset=UTF-8
Pablo Greco 40546a
Content-Transfer-Encoding: 8bit
Pablo Greco 40546a
Pablo Greco 40546a
This enables to use both cgroup v1 and v2 at the same time together
Pablo Greco 40546a
with libvirt.  It is supported by kernel and there is valid use-case,
Pablo Greco 40546a
not all controllers are implemented in cgroup v2 so there might be
Pablo Greco 40546a
configurations where administrator would enable these missing
Pablo Greco 40546a
controllers in cgroup v1.
Pablo Greco 40546a
Pablo Greco 40546a
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
Pablo Greco 40546a
(cherry picked from commit b79d858518ed15b1a4271457fc9f39463dd99230)
Pablo Greco 40546a
Pablo Greco 40546a
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297
Pablo Greco 40546a
Pablo Greco 40546a
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
Pablo Greco 40546a
Message-Id: <c84d8624633d438daa6b4de651eb6bb9e0afa25c.1561993100.git.phrdina@redhat.com>
Pablo Greco 40546a
Reviewed-by: Ján Tomko <jtomko@redhat.com>
Pablo Greco 40546a
---
Pablo Greco 40546a
 src/util/vircgroup.c        | 351 ++++++++++++++++++++++++++----------
Pablo Greco 40546a
 src/util/vircgroupbackend.c |  20 ++
Pablo Greco 40546a
 src/util/vircgroupbackend.h |  16 +-
Pablo Greco 40546a
 src/util/vircgrouppriv.h    |   2 +-
Pablo Greco 40546a
 4 files changed, 291 insertions(+), 98 deletions(-)
Pablo Greco 40546a
Pablo Greco 40546a
diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c
Pablo Greco 40546a
index a859628241..069f1ae396 100644
Pablo Greco 40546a
--- a/src/util/vircgroup.c
Pablo Greco 40546a
+++ b/src/util/vircgroup.c
Pablo Greco 40546a
@@ -232,6 +232,7 @@ virCgroupDetectMounts(virCgroupPtr group)
Pablo Greco 40546a
     struct mntent entry;
Pablo Greco 40546a
     char buf[CGROUP_MAX_VAL];
Pablo Greco 40546a
     int ret = -1;
Pablo Greco 40546a
+    size_t i;
Pablo Greco 40546a
 
Pablo Greco 40546a
     mounts = fopen("/proc/mounts", "r");
Pablo Greco 40546a
     if (mounts == NULL) {
Pablo Greco 40546a
@@ -240,11 +241,14 @@ virCgroupDetectMounts(virCgroupPtr group)
Pablo Greco 40546a
     }
Pablo Greco 40546a
 
Pablo Greco 40546a
     while (getmntent_r(mounts, &entry, buf, sizeof(buf)) != NULL) {
Pablo Greco 40546a
-        if (group->backend->detectMounts(group,
Pablo Greco 40546a
-                                         entry.mnt_type,
Pablo Greco 40546a
-                                         entry.mnt_opts,
Pablo Greco 40546a
-                                         entry.mnt_dir) < 0) {
Pablo Greco 40546a
-            goto cleanup;
Pablo Greco 40546a
+        for (i = 0; i < VIR_CGROUP_BACKEND_TYPE_LAST; i++) {
Pablo Greco 40546a
+            if (group->backends[i] &&
Pablo Greco 40546a
+                group->backends[i]->detectMounts(group,
Pablo Greco 40546a
+                                                 entry.mnt_type,
Pablo Greco 40546a
+                                                 entry.mnt_opts,
Pablo Greco 40546a
+                                                 entry.mnt_dir) < 0) {
Pablo Greco 40546a
+                goto cleanup;
Pablo Greco 40546a
+            }
Pablo Greco 40546a
         }
Pablo Greco 40546a
     }
Pablo Greco 40546a
 
Pablo Greco 40546a
@@ -307,6 +311,7 @@ virCgroupDetectPlacement(virCgroupPtr group,
Pablo Greco 40546a
     }
Pablo Greco 40546a
 
Pablo Greco 40546a
     while (fgets(line, sizeof(line), mapping) != NULL) {
Pablo Greco 40546a
+        size_t i;
Pablo Greco 40546a
         char *controllers = strchr(line, ':');
Pablo Greco 40546a
         char *selfpath = controllers ? strchr(controllers + 1, ':') : NULL;
Pablo Greco 40546a
         char *nl = selfpath ? strchr(selfpath, '\n') : NULL;
Pablo Greco 40546a
@@ -321,9 +326,12 @@ virCgroupDetectPlacement(virCgroupPtr group,
Pablo Greco 40546a
         controllers++;
Pablo Greco 40546a
         selfpath++;
Pablo Greco 40546a
 
Pablo Greco 40546a
-        if (group->backend->detectPlacement(group, path, controllers,
Pablo Greco 40546a
-                                            selfpath) < 0) {
Pablo Greco 40546a
-            goto cleanup;
Pablo Greco 40546a
+        for (i = 0; i < VIR_CGROUP_BACKEND_TYPE_LAST; i++) {
Pablo Greco 40546a
+            if (group->backends[i] &&
Pablo Greco 40546a
+                group->backends[i]->detectPlacement(group, path, controllers,
Pablo Greco 40546a
+                                                    selfpath) < 0) {
Pablo Greco 40546a
+                goto cleanup;
Pablo Greco 40546a
+            }
Pablo Greco 40546a
         }
Pablo Greco 40546a
     }
Pablo Greco 40546a
 
Pablo Greco 40546a
@@ -342,8 +350,9 @@ virCgroupDetect(virCgroupPtr group,
Pablo Greco 40546a
                 const char *path,
Pablo Greco 40546a
                 virCgroupPtr parent)
Pablo Greco 40546a
 {
Pablo Greco 40546a
-    int rc;
Pablo Greco 40546a
     size_t i;
Pablo Greco 40546a
+    bool backendAvailable = false;
Pablo Greco 40546a
+    int controllersAvailable = 0;
Pablo Greco 40546a
     virCgroupBackendPtr *backends = virCgroupBackendGetAll();
Pablo Greco 40546a
 
Pablo Greco 40546a
     VIR_DEBUG("group=%p controllers=%d path=%s parent=%p",
Pablo Greco 40546a
@@ -354,31 +363,40 @@ virCgroupDetect(virCgroupPtr group,
Pablo Greco 40546a
 
Pablo Greco 40546a
     for (i = 0; i < VIR_CGROUP_BACKEND_TYPE_LAST; i++) {
Pablo Greco 40546a
         if (backends[i] && backends[i]->available()) {
Pablo Greco 40546a
-            group->backend = backends[i];
Pablo Greco 40546a
-            break;
Pablo Greco 40546a
+            group->backends[i] = backends[i];
Pablo Greco 40546a
+            backendAvailable = true;
Pablo Greco 40546a
         }
Pablo Greco 40546a
     }
Pablo Greco 40546a
 
Pablo Greco 40546a
-    if (!group->backend) {
Pablo Greco 40546a
+    if (!backendAvailable) {
Pablo Greco 40546a
         virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
Pablo Greco 40546a
                        _("no cgroup backend available"));
Pablo Greco 40546a
         return -1;
Pablo Greco 40546a
     }
Pablo Greco 40546a
 
Pablo Greco 40546a
     if (parent) {
Pablo Greco 40546a
-        if (group->backend->copyMounts(group, parent) < 0)
Pablo Greco 40546a
-            return -1;
Pablo Greco 40546a
+        for (i = 0; i < VIR_CGROUP_BACKEND_TYPE_LAST; i++) {
Pablo Greco 40546a
+            if (group->backends[i] &&
Pablo Greco 40546a
+                group->backends[i]->copyMounts(group, parent) < 0) {
Pablo Greco 40546a
+                return -1;
Pablo Greco 40546a
+            }
Pablo Greco 40546a
+        }
Pablo Greco 40546a
     } else {
Pablo Greco 40546a
         if (virCgroupDetectMounts(group) < 0)
Pablo Greco 40546a
             return -1;
Pablo Greco 40546a
     }
Pablo Greco 40546a
 
Pablo Greco 40546a
-    rc = group->backend->detectControllers(group, controllers);
Pablo Greco 40546a
-    if (rc < 0)
Pablo Greco 40546a
-        return -1;
Pablo Greco 40546a
+    for (i = 0; i < VIR_CGROUP_BACKEND_TYPE_LAST; i++) {
Pablo Greco 40546a
+        if (group->backends[i]) {
Pablo Greco 40546a
+            int rc = group->backends[i]->detectControllers(group, controllers);
Pablo Greco 40546a
+            if (rc < 0)
Pablo Greco 40546a
+                return -1;
Pablo Greco 40546a
+            controllersAvailable |= rc;
Pablo Greco 40546a
+        }
Pablo Greco 40546a
+    }
Pablo Greco 40546a
 
Pablo Greco 40546a
     /* Check that at least 1 controller is available */
Pablo Greco 40546a
-    if (rc == 0) {
Pablo Greco 40546a
+    if (controllersAvailable == 0) {
Pablo Greco 40546a
         virReportSystemError(ENXIO, "%s",
Pablo Greco 40546a
                              _("At least one cgroup controller is required"));
Pablo Greco 40546a
         return -1;
Pablo Greco 40546a
@@ -387,17 +405,26 @@ virCgroupDetect(virCgroupPtr group,
Pablo Greco 40546a
     /* In some cases we can copy part of the placement info
Pablo Greco 40546a
      * based on the parent cgroup...
Pablo Greco 40546a
      */
Pablo Greco 40546a
-    if ((parent || path[0] == '/') &&
Pablo Greco 40546a
-        group->backend->copyPlacement(group, path, parent) < 0)
Pablo Greco 40546a
-        return -1;
Pablo Greco 40546a
+    if (parent || path[0] == '/') {
Pablo Greco 40546a
+        for (i = 0; i < VIR_CGROUP_BACKEND_TYPE_LAST; i++) {
Pablo Greco 40546a
+            if (group->backends[i] &&
Pablo Greco 40546a
+                group->backends[i]->copyPlacement(group, path, parent) < 0) {
Pablo Greco 40546a
+                return -1;
Pablo Greco 40546a
+            }
Pablo Greco 40546a
+        }
Pablo Greco 40546a
+    }
Pablo Greco 40546a
 
Pablo Greco 40546a
     /* ... but use /proc/cgroups to fill in the rest */
Pablo Greco 40546a
     if (virCgroupDetectPlacement(group, pid, path) < 0)
Pablo Greco 40546a
         return -1;
Pablo Greco 40546a
 
Pablo Greco 40546a
     /* Check that for every mounted controller, we found our placement */
Pablo Greco 40546a
-    if (group->backend->validatePlacement(group, pid) < 0)
Pablo Greco 40546a
-        return -1;
Pablo Greco 40546a
+    for (i = 0; i < VIR_CGROUP_BACKEND_TYPE_LAST; i++) {
Pablo Greco 40546a
+        if (group->backends[i] &&
Pablo Greco 40546a
+            group->backends[i]->validatePlacement(group, pid) < 0) {
Pablo Greco 40546a
+            return -1;
Pablo Greco 40546a
+        }
Pablo Greco 40546a
+    }
Pablo Greco 40546a
 
Pablo Greco 40546a
     return 0;
Pablo Greco 40546a
 }
Pablo Greco 40546a
@@ -603,9 +630,14 @@ virCgroupMakeGroup(virCgroupPtr parent,
Pablo Greco 40546a
                    bool create,
Pablo Greco 40546a
                    unsigned int flags)
Pablo Greco 40546a
 {
Pablo Greco 40546a
-    if (group->backend->makeGroup(parent, group, create, flags) < 0) {
Pablo Greco 40546a
-        virCgroupRemove(group);
Pablo Greco 40546a
-        return -1;
Pablo Greco 40546a
+    size_t i;
Pablo Greco 40546a
+
Pablo Greco 40546a
+    for (i = 0; i < VIR_CGROUP_BACKEND_TYPE_LAST; i++) {
Pablo Greco 40546a
+        if (group->backends[i] &&
Pablo Greco 40546a
+            group->backends[i]->makeGroup(parent, group, create, flags) < 0) {
Pablo Greco 40546a
+            virCgroupRemove(group);
Pablo Greco 40546a
+            return -1;
Pablo Greco 40546a
+        }
Pablo Greco 40546a
     }
Pablo Greco 40546a
 
Pablo Greco 40546a
     return 0;
Pablo Greco 40546a
@@ -666,6 +698,24 @@ virCgroupNew(pid_t pid,
Pablo Greco 40546a
 }
Pablo Greco 40546a
 
Pablo Greco 40546a
 
Pablo Greco 40546a
+static int
Pablo Greco 40546a
+virCgroupAddTaskInternal(virCgroupPtr group,
Pablo Greco 40546a
+                         pid_t pid,
Pablo Greco 40546a
+                         unsigned int flags)
Pablo Greco 40546a
+{
Pablo Greco 40546a
+    size_t i;
Pablo Greco 40546a
+
Pablo Greco 40546a
+    for (i = 0; i < VIR_CGROUP_BACKEND_TYPE_LAST; i++) {
Pablo Greco 40546a
+        if (group->backends[i] &&
Pablo Greco 40546a
+            group->backends[i]->addTask(group, pid, flags) < 0) {
Pablo Greco 40546a
+            return -1;
Pablo Greco 40546a
+        }
Pablo Greco 40546a
+    }
Pablo Greco 40546a
+
Pablo Greco 40546a
+    return 0;
Pablo Greco 40546a
+}
Pablo Greco 40546a
+
Pablo Greco 40546a
+
Pablo Greco 40546a
 /**
Pablo Greco 40546a
  * virCgroupAddProcess:
Pablo Greco 40546a
  *
Pablo Greco 40546a
@@ -680,7 +730,7 @@ virCgroupNew(pid_t pid,
Pablo Greco 40546a
 int
Pablo Greco 40546a
 virCgroupAddProcess(virCgroupPtr group, pid_t pid)
Pablo Greco 40546a
 {
Pablo Greco 40546a
-    return group->backend->addTask(group, pid, VIR_CGROUP_TASK_PROCESS);
Pablo Greco 40546a
+    return virCgroupAddTaskInternal(group, pid, VIR_CGROUP_TASK_PROCESS);
Pablo Greco 40546a
 }
Pablo Greco 40546a
 
Pablo Greco 40546a
 /**
Pablo Greco 40546a
@@ -697,9 +747,9 @@ virCgroupAddProcess(virCgroupPtr group, pid_t pid)
Pablo Greco 40546a
 int
Pablo Greco 40546a
 virCgroupAddMachineProcess(virCgroupPtr group, pid_t pid)
Pablo Greco 40546a
 {
Pablo Greco 40546a
-    return group->backend->addTask(group, pid,
Pablo Greco 40546a
-                                   VIR_CGROUP_TASK_PROCESS |
Pablo Greco 40546a
-                                   VIR_CGROUP_TASK_SYSTEMD);
Pablo Greco 40546a
+    return virCgroupAddTaskInternal(group, pid,
Pablo Greco 40546a
+                                    VIR_CGROUP_TASK_PROCESS |
Pablo Greco 40546a
+                                    VIR_CGROUP_TASK_SYSTEMD);
Pablo Greco 40546a
 }
Pablo Greco 40546a
 
Pablo Greco 40546a
 /**
Pablo Greco 40546a
@@ -717,7 +767,7 @@ int
Pablo Greco 40546a
 virCgroupAddThread(virCgroupPtr group,
Pablo Greco 40546a
                    pid_t pid)
Pablo Greco 40546a
 {
Pablo Greco 40546a
-    return group->backend->addTask(group, pid, VIR_CGROUP_TASK_THREAD);
Pablo Greco 40546a
+    return virCgroupAddTaskInternal(group, pid, VIR_CGROUP_TASK_THREAD);
Pablo Greco 40546a
 }
Pablo Greco 40546a
 
Pablo Greco 40546a
 
Pablo Greco 40546a
@@ -971,17 +1021,24 @@ virCgroupNewDetectMachine(const char *name,
Pablo Greco 40546a
                           char *machinename,
Pablo Greco 40546a
                           virCgroupPtr *group)
Pablo Greco 40546a
 {
Pablo Greco 40546a
+    size_t i;
Pablo Greco 40546a
+
Pablo Greco 40546a
     if (virCgroupNewDetect(pid, controllers, group) < 0) {
Pablo Greco 40546a
         if (virCgroupNewIgnoreError())
Pablo Greco 40546a
             return 0;
Pablo Greco 40546a
         return -1;
Pablo Greco 40546a
     }
Pablo Greco 40546a
 
Pablo Greco 40546a
-    if (!(*group)->backend->validateMachineGroup(*group, name, drivername, machinename)) {
Pablo Greco 40546a
-        VIR_DEBUG("Failed to validate machine name for '%s' driver '%s'",
Pablo Greco 40546a
-                  name, drivername);
Pablo Greco 40546a
-        virCgroupFree(group);
Pablo Greco 40546a
-        return 0;
Pablo Greco 40546a
+    for (i = 0; i < VIR_CGROUP_BACKEND_TYPE_LAST; i++) {
Pablo Greco 40546a
+        if ((*group)->backends[i] &&
Pablo Greco 40546a
+            !(*group)->backends[i]->validateMachineGroup(*group, name,
Pablo Greco 40546a
+                                                         drivername,
Pablo Greco 40546a
+                                                         machinename)) {
Pablo Greco 40546a
+            VIR_DEBUG("Failed to validate machine name for '%s' driver '%s'",
Pablo Greco 40546a
+                      name, drivername);
Pablo Greco 40546a
+            virCgroupFree(group);
Pablo Greco 40546a
+            return 0;
Pablo Greco 40546a
+        }
Pablo Greco 40546a
     }
Pablo Greco 40546a
 
Pablo Greco 40546a
     return 0;
Pablo Greco 40546a
@@ -1059,6 +1116,7 @@ virCgroupNewMachineSystemd(const char *name,
Pablo Greco 40546a
     int rv;
Pablo Greco 40546a
     virCgroupPtr init;
Pablo Greco 40546a
     VIR_AUTOFREE(char *) path = NULL;
Pablo Greco 40546a
+    size_t i;
Pablo Greco 40546a
 
Pablo Greco 40546a
     VIR_DEBUG("Trying to setup machine '%s' via systemd", name);
Pablo Greco 40546a
     if ((rv = virSystemdCreateMachine(name,
Pablo Greco 40546a
@@ -1081,7 +1139,12 @@ virCgroupNewMachineSystemd(const char *name,
Pablo Greco 40546a
                            &init) < 0)
Pablo Greco 40546a
         return -1;
Pablo Greco 40546a
 
Pablo Greco 40546a
-    path = init->backend->stealPlacement(init);
Pablo Greco 40546a
+    for (i = 0; i < VIR_CGROUP_BACKEND_TYPE_LAST; i++) {
Pablo Greco 40546a
+        if (init->backends[i] &&
Pablo Greco 40546a
+            (path = init->backends[i]->stealPlacement(init))) {
Pablo Greco 40546a
+            break;
Pablo Greco 40546a
+        }
Pablo Greco 40546a
+    }
Pablo Greco 40546a
     virCgroupFree(&init);
Pablo Greco 40546a
 
Pablo Greco 40546a
     if (!path || STREQ(path, "/") || path[0] != '/') {
Pablo Greco 40546a
@@ -1260,12 +1323,21 @@ virCgroupFree(virCgroupPtr *group)
Pablo Greco 40546a
 bool
Pablo Greco 40546a
 virCgroupHasController(virCgroupPtr cgroup, int controller)
Pablo Greco 40546a
 {
Pablo Greco 40546a
+    size_t i;
Pablo Greco 40546a
+
Pablo Greco 40546a
     if (!cgroup)
Pablo Greco 40546a
         return false;
Pablo Greco 40546a
     if (controller < 0 || controller >= VIR_CGROUP_CONTROLLER_LAST)
Pablo Greco 40546a
         return false;
Pablo Greco 40546a
 
Pablo Greco 40546a
-    return cgroup->backend->hasController(cgroup, controller);
Pablo Greco 40546a
+    for (i = 0; i < VIR_CGROUP_BACKEND_TYPE_LAST; i++) {
Pablo Greco 40546a
+        if (cgroup->backends[i] &&
Pablo Greco 40546a
+            cgroup->backends[i]->hasController(cgroup, controller)) {
Pablo Greco 40546a
+            return true;
Pablo Greco 40546a
+        }
Pablo Greco 40546a
+    }
Pablo Greco 40546a
+
Pablo Greco 40546a
+    return false;
Pablo Greco 40546a
 }
Pablo Greco 40546a
 
Pablo Greco 40546a
 
Pablo Greco 40546a
@@ -1281,7 +1353,8 @@ virCgroupPathOfController(virCgroupPtr group,
Pablo Greco 40546a
         return -1;
Pablo Greco 40546a
     }
Pablo Greco 40546a
 
Pablo Greco 40546a
-    return group->backend->pathOfController(group, controller, key, path);
Pablo Greco 40546a
+    VIR_CGROUP_BACKEND_CALL(group, controller, pathOfController, -1,
Pablo Greco 40546a
+                            controller, key, path);
Pablo Greco 40546a
 }
Pablo Greco 40546a
 
Pablo Greco 40546a
 
Pablo Greco 40546a
@@ -1303,7 +1376,8 @@ virCgroupGetBlkioIoServiced(virCgroupPtr group,
Pablo Greco 40546a
                             long long *requests_read,
Pablo Greco 40546a
                             long long *requests_write)
Pablo Greco 40546a
 {
Pablo Greco 40546a
-    VIR_CGROUP_BACKEND_CALL(group, getBlkioIoServiced, -1,
Pablo Greco 40546a
+    VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_BLKIO,
Pablo Greco 40546a
+                            getBlkioIoServiced, -1,
Pablo Greco 40546a
                             bytes_read, bytes_write,
Pablo Greco 40546a
                             requests_read, requests_write);
Pablo Greco 40546a
 }
Pablo Greco 40546a
@@ -1329,7 +1403,8 @@ virCgroupGetBlkioIoDeviceServiced(virCgroupPtr group,
Pablo Greco 40546a
                                   long long *requests_read,
Pablo Greco 40546a
                                   long long *requests_write)
Pablo Greco 40546a
 {
Pablo Greco 40546a
-    VIR_CGROUP_BACKEND_CALL(group, getBlkioIoDeviceServiced, -1,
Pablo Greco 40546a
+    VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_BLKIO,
Pablo Greco 40546a
+                            getBlkioIoDeviceServiced, -1,
Pablo Greco 40546a
                             path, bytes_read, bytes_write,
Pablo Greco 40546a
                             requests_read, requests_write);
Pablo Greco 40546a
 }
Pablo Greco 40546a
@@ -1346,7 +1421,8 @@ virCgroupGetBlkioIoDeviceServiced(virCgroupPtr group,
Pablo Greco 40546a
 int
Pablo Greco 40546a
 virCgroupSetBlkioWeight(virCgroupPtr group, unsigned int weight)
Pablo Greco 40546a
 {
Pablo Greco 40546a
-    VIR_CGROUP_BACKEND_CALL(group, setBlkioWeight, -1, weight);
Pablo Greco 40546a
+    VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_BLKIO,
Pablo Greco 40546a
+                            setBlkioWeight, -1, weight);
Pablo Greco 40546a
 }
Pablo Greco 40546a
 
Pablo Greco 40546a
 
Pablo Greco 40546a
@@ -1361,7 +1437,8 @@ virCgroupSetBlkioWeight(virCgroupPtr group, unsigned int weight)
Pablo Greco 40546a
 int
Pablo Greco 40546a
 virCgroupGetBlkioWeight(virCgroupPtr group, unsigned int *weight)
Pablo Greco 40546a
 {
Pablo Greco 40546a
-    VIR_CGROUP_BACKEND_CALL(group, getBlkioWeight, -1, weight);
Pablo Greco 40546a
+    VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_BLKIO,
Pablo Greco 40546a
+                            getBlkioWeight, -1, weight);
Pablo Greco 40546a
 }
Pablo Greco 40546a
 
Pablo Greco 40546a
 /**
Pablo Greco 40546a
@@ -1377,7 +1454,8 @@ virCgroupSetBlkioDeviceReadIops(virCgroupPtr group,
Pablo Greco 40546a
                                 const char *path,
Pablo Greco 40546a
                                 unsigned int riops)
Pablo Greco 40546a
 {
Pablo Greco 40546a
-    VIR_CGROUP_BACKEND_CALL(group, setBlkioDeviceReadIops, -1, path, riops);
Pablo Greco 40546a
+    VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_BLKIO,
Pablo Greco 40546a
+                            setBlkioDeviceReadIops, -1, path, riops);
Pablo Greco 40546a
 }
Pablo Greco 40546a
 
Pablo Greco 40546a
 
Pablo Greco 40546a
@@ -1394,7 +1472,8 @@ virCgroupSetBlkioDeviceWriteIops(virCgroupPtr group,
Pablo Greco 40546a
                                  const char *path,
Pablo Greco 40546a
                                  unsigned int wiops)
Pablo Greco 40546a
 {
Pablo Greco 40546a
-    VIR_CGROUP_BACKEND_CALL(group, setBlkioDeviceWriteIops, -1, path, wiops);
Pablo Greco 40546a
+    VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_BLKIO,
Pablo Greco 40546a
+                            setBlkioDeviceWriteIops, -1, path, wiops);
Pablo Greco 40546a
 }
Pablo Greco 40546a
 
Pablo Greco 40546a
 
Pablo Greco 40546a
@@ -1411,7 +1490,8 @@ virCgroupSetBlkioDeviceReadBps(virCgroupPtr group,
Pablo Greco 40546a
                                const char *path,
Pablo Greco 40546a
                                unsigned long long rbps)
Pablo Greco 40546a
 {
Pablo Greco 40546a
-    VIR_CGROUP_BACKEND_CALL(group, setBlkioDeviceReadBps, -1, path, rbps);
Pablo Greco 40546a
+    VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_BLKIO,
Pablo Greco 40546a
+                            setBlkioDeviceReadBps, -1, path, rbps);
Pablo Greco 40546a
 }
Pablo Greco 40546a
 
Pablo Greco 40546a
 /**
Pablo Greco 40546a
@@ -1427,7 +1507,8 @@ virCgroupSetBlkioDeviceWriteBps(virCgroupPtr group,
Pablo Greco 40546a
                                 const char *path,
Pablo Greco 40546a
                                 unsigned long long wbps)
Pablo Greco 40546a
 {
Pablo Greco 40546a
-    VIR_CGROUP_BACKEND_CALL(group, setBlkioDeviceWriteBps, -1, path, wbps);
Pablo Greco 40546a
+    VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_BLKIO,
Pablo Greco 40546a
+                            setBlkioDeviceWriteBps, -1, path, wbps);
Pablo Greco 40546a
 }
Pablo Greco 40546a
 
Pablo Greco 40546a
 
Pablo Greco 40546a
@@ -1445,7 +1526,8 @@ virCgroupSetBlkioDeviceWeight(virCgroupPtr group,
Pablo Greco 40546a
                               const char *path,
Pablo Greco 40546a
                               unsigned int weight)
Pablo Greco 40546a
 {
Pablo Greco 40546a
-    VIR_CGROUP_BACKEND_CALL(group, setBlkioDeviceWeight, -1, path, weight);
Pablo Greco 40546a
+    VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_BLKIO,
Pablo Greco 40546a
+                            setBlkioDeviceWeight, -1, path, weight);
Pablo Greco 40546a
 }
Pablo Greco 40546a
 
Pablo Greco 40546a
 /**
Pablo Greco 40546a
@@ -1461,7 +1543,8 @@ virCgroupGetBlkioDeviceReadIops(virCgroupPtr group,
Pablo Greco 40546a
                                 const char *path,
Pablo Greco 40546a
                                 unsigned int *riops)
Pablo Greco 40546a
 {
Pablo Greco 40546a
-    VIR_CGROUP_BACKEND_CALL(group, getBlkioDeviceReadIops, -1, path, riops);
Pablo Greco 40546a
+    VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_BLKIO,
Pablo Greco 40546a
+                            getBlkioDeviceReadIops, -1, path, riops);
Pablo Greco 40546a
 }
Pablo Greco 40546a
 
Pablo Greco 40546a
 /**
Pablo Greco 40546a
@@ -1477,7 +1560,8 @@ virCgroupGetBlkioDeviceWriteIops(virCgroupPtr group,
Pablo Greco 40546a
                                  const char *path,
Pablo Greco 40546a
                                  unsigned int *wiops)
Pablo Greco 40546a
 {
Pablo Greco 40546a
-    VIR_CGROUP_BACKEND_CALL(group, getBlkioDeviceWriteIops, -1, path, wiops);
Pablo Greco 40546a
+    VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_BLKIO,
Pablo Greco 40546a
+                            getBlkioDeviceWriteIops, -1, path, wiops);
Pablo Greco 40546a
 }
Pablo Greco 40546a
 
Pablo Greco 40546a
 /**
Pablo Greco 40546a
@@ -1493,7 +1577,8 @@ virCgroupGetBlkioDeviceReadBps(virCgroupPtr group,
Pablo Greco 40546a
                                const char *path,
Pablo Greco 40546a
                                unsigned long long *rbps)
Pablo Greco 40546a
 {
Pablo Greco 40546a
-    VIR_CGROUP_BACKEND_CALL(group, getBlkioDeviceReadBps, -1, path, rbps);
Pablo Greco 40546a
+    VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_BLKIO,
Pablo Greco 40546a
+                            getBlkioDeviceReadBps, -1, path, rbps);
Pablo Greco 40546a
 }
Pablo Greco 40546a
 
Pablo Greco 40546a
 /**
Pablo Greco 40546a
@@ -1509,7 +1594,8 @@ virCgroupGetBlkioDeviceWriteBps(virCgroupPtr group,
Pablo Greco 40546a
                                 const char *path,
Pablo Greco 40546a
                                 unsigned long long *wbps)
Pablo Greco 40546a
 {
Pablo Greco 40546a
-    VIR_CGROUP_BACKEND_CALL(group, getBlkioDeviceWriteBps, -1, path, wbps);
Pablo Greco 40546a
+    VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_BLKIO,
Pablo Greco 40546a
+                            getBlkioDeviceWriteBps, -1, path, wbps);
Pablo Greco 40546a
 }
Pablo Greco 40546a
 
Pablo Greco 40546a
 /**
Pablo Greco 40546a
@@ -1525,7 +1611,8 @@ virCgroupGetBlkioDeviceWeight(virCgroupPtr group,
Pablo Greco 40546a
                               const char *path,
Pablo Greco 40546a
                               unsigned int *weight)
Pablo Greco 40546a
 {
Pablo Greco 40546a
-    VIR_CGROUP_BACKEND_CALL(group, getBlkioDeviceWeight, -1, path, weight);
Pablo Greco 40546a
+    VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_BLKIO,
Pablo Greco 40546a
+                            getBlkioDeviceWeight, -1, path, weight);
Pablo Greco 40546a
 }
Pablo Greco 40546a
 
Pablo Greco 40546a
 
Pablo Greco 40546a
@@ -1540,7 +1627,8 @@ virCgroupGetBlkioDeviceWeight(virCgroupPtr group,
Pablo Greco 40546a
 int
Pablo Greco 40546a
 virCgroupSetMemory(virCgroupPtr group, unsigned long long kb)
Pablo Greco 40546a
 {
Pablo Greco 40546a
-    VIR_CGROUP_BACKEND_CALL(group, setMemory, -1, kb);
Pablo Greco 40546a
+    VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_MEMORY,
Pablo Greco 40546a
+                            setMemory, -1, kb);
Pablo Greco 40546a
 }
Pablo Greco 40546a
 
Pablo Greco 40546a
 
Pablo Greco 40546a
@@ -1566,7 +1654,8 @@ virCgroupGetMemoryStat(virCgroupPtr group,
Pablo Greco 40546a
                        unsigned long long *inactiveFile,
Pablo Greco 40546a
                        unsigned long long *unevictable)
Pablo Greco 40546a
 {
Pablo Greco 40546a
-    VIR_CGROUP_BACKEND_CALL(group, getMemoryStat, -1, cache,
Pablo Greco 40546a
+    VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_MEMORY,
Pablo Greco 40546a
+                            getMemoryStat, -1, cache,
Pablo Greco 40546a
                             activeAnon, inactiveAnon,
Pablo Greco 40546a
                             activeFile, inactiveFile,
Pablo Greco 40546a
                             unevictable);
Pablo Greco 40546a
@@ -1584,7 +1673,8 @@ virCgroupGetMemoryStat(virCgroupPtr group,
Pablo Greco 40546a
 int
Pablo Greco 40546a
 virCgroupGetMemoryUsage(virCgroupPtr group, unsigned long *kb)
Pablo Greco 40546a
 {
Pablo Greco 40546a
-    VIR_CGROUP_BACKEND_CALL(group, getMemoryUsage, -1, kb);
Pablo Greco 40546a
+    VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_MEMORY,
Pablo Greco 40546a
+                            getMemoryUsage, -1, kb);
Pablo Greco 40546a
 }
Pablo Greco 40546a
 
Pablo Greco 40546a
 
Pablo Greco 40546a
@@ -1599,7 +1689,8 @@ virCgroupGetMemoryUsage(virCgroupPtr group, unsigned long *kb)
Pablo Greco 40546a
 int
Pablo Greco 40546a
 virCgroupSetMemoryHardLimit(virCgroupPtr group, unsigned long long kb)
Pablo Greco 40546a
 {
Pablo Greco 40546a
-    VIR_CGROUP_BACKEND_CALL(group, setMemoryHardLimit, -1, kb);
Pablo Greco 40546a
+    VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_MEMORY,
Pablo Greco 40546a
+                            setMemoryHardLimit, -1, kb);
Pablo Greco 40546a
 }
Pablo Greco 40546a
 
Pablo Greco 40546a
 
Pablo Greco 40546a
@@ -1614,7 +1705,8 @@ virCgroupSetMemoryHardLimit(virCgroupPtr group, unsigned long long kb)
Pablo Greco 40546a
 int
Pablo Greco 40546a
 virCgroupGetMemoryHardLimit(virCgroupPtr group, unsigned long long *kb)
Pablo Greco 40546a
 {
Pablo Greco 40546a
-    VIR_CGROUP_BACKEND_CALL(group, getMemoryHardLimit, -1, kb);
Pablo Greco 40546a
+    VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_MEMORY,
Pablo Greco 40546a
+                            getMemoryHardLimit, -1, kb);
Pablo Greco 40546a
 }
Pablo Greco 40546a
 
Pablo Greco 40546a
 
Pablo Greco 40546a
@@ -1629,7 +1721,8 @@ virCgroupGetMemoryHardLimit(virCgroupPtr group, unsigned long long *kb)
Pablo Greco 40546a
 int
Pablo Greco 40546a
 virCgroupSetMemorySoftLimit(virCgroupPtr group, unsigned long long kb)
Pablo Greco 40546a
 {
Pablo Greco 40546a
-    VIR_CGROUP_BACKEND_CALL(group, setMemorySoftLimit, -1, kb);
Pablo Greco 40546a
+    VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_MEMORY,
Pablo Greco 40546a
+                            setMemorySoftLimit, -1, kb);
Pablo Greco 40546a
 }
Pablo Greco 40546a
 
Pablo Greco 40546a
 
Pablo Greco 40546a
@@ -1644,7 +1737,8 @@ virCgroupSetMemorySoftLimit(virCgroupPtr group, unsigned long long kb)
Pablo Greco 40546a
 int
Pablo Greco 40546a
 virCgroupGetMemorySoftLimit(virCgroupPtr group, unsigned long long *kb)
Pablo Greco 40546a
 {
Pablo Greco 40546a
-    VIR_CGROUP_BACKEND_CALL(group, getMemorySoftLimit, -1, kb);
Pablo Greco 40546a
+    VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_MEMORY,
Pablo Greco 40546a
+                            getMemorySoftLimit, -1, kb);
Pablo Greco 40546a
 }
Pablo Greco 40546a
 
Pablo Greco 40546a
 
Pablo Greco 40546a
@@ -1659,7 +1753,8 @@ virCgroupGetMemorySoftLimit(virCgroupPtr group, unsigned long long *kb)
Pablo Greco 40546a
 int
Pablo Greco 40546a
 virCgroupSetMemSwapHardLimit(virCgroupPtr group, unsigned long long kb)
Pablo Greco 40546a
 {
Pablo Greco 40546a
-    VIR_CGROUP_BACKEND_CALL(group, setMemSwapHardLimit, -1, kb);
Pablo Greco 40546a
+    VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_MEMORY,
Pablo Greco 40546a
+                            setMemSwapHardLimit, -1, kb);
Pablo Greco 40546a
 }
Pablo Greco 40546a
 
Pablo Greco 40546a
 
Pablo Greco 40546a
@@ -1674,7 +1769,8 @@ virCgroupSetMemSwapHardLimit(virCgroupPtr group, unsigned long long kb)
Pablo Greco 40546a
 int
Pablo Greco 40546a
 virCgroupGetMemSwapHardLimit(virCgroupPtr group, unsigned long long *kb)
Pablo Greco 40546a
 {
Pablo Greco 40546a
-    VIR_CGROUP_BACKEND_CALL(group, getMemSwapHardLimit, -1, kb);
Pablo Greco 40546a
+    VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_MEMORY,
Pablo Greco 40546a
+                            getMemSwapHardLimit, -1, kb);
Pablo Greco 40546a
 }
Pablo Greco 40546a
 
Pablo Greco 40546a
 
Pablo Greco 40546a
@@ -1689,7 +1785,8 @@ virCgroupGetMemSwapHardLimit(virCgroupPtr group, unsigned long long *kb)
Pablo Greco 40546a
 int
Pablo Greco 40546a
 virCgroupGetMemSwapUsage(virCgroupPtr group, unsigned long long *kb)
Pablo Greco 40546a
 {
Pablo Greco 40546a
-    VIR_CGROUP_BACKEND_CALL(group, getMemSwapUsage, -1, kb);
Pablo Greco 40546a
+    VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_MEMORY,
Pablo Greco 40546a
+                            getMemSwapUsage, -1, kb);
Pablo Greco 40546a
 }
Pablo Greco 40546a
 
Pablo Greco 40546a
 
Pablo Greco 40546a
@@ -1704,7 +1801,8 @@ virCgroupGetMemSwapUsage(virCgroupPtr group, unsigned long long *kb)
Pablo Greco 40546a
 int
Pablo Greco 40546a
 virCgroupSetCpusetMems(virCgroupPtr group, const char *mems)
Pablo Greco 40546a
 {
Pablo Greco 40546a
-    VIR_CGROUP_BACKEND_CALL(group, setCpusetMems, -1, mems);
Pablo Greco 40546a
+    VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_CPUSET,
Pablo Greco 40546a
+                            setCpusetMems, -1, mems);
Pablo Greco 40546a
 }
Pablo Greco 40546a
 
Pablo Greco 40546a
 
Pablo Greco 40546a
@@ -1719,7 +1817,8 @@ virCgroupSetCpusetMems(virCgroupPtr group, const char *mems)
Pablo Greco 40546a
 int
Pablo Greco 40546a
 virCgroupGetCpusetMems(virCgroupPtr group, char **mems)
Pablo Greco 40546a
 {
Pablo Greco 40546a
-    VIR_CGROUP_BACKEND_CALL(group, getCpusetMems, -1, mems);
Pablo Greco 40546a
+    VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_CPUSET,
Pablo Greco 40546a
+                            getCpusetMems, -1, mems);
Pablo Greco 40546a
 }
Pablo Greco 40546a
 
Pablo Greco 40546a
 
Pablo Greco 40546a
@@ -1734,7 +1833,8 @@ virCgroupGetCpusetMems(virCgroupPtr group, char **mems)
Pablo Greco 40546a
 int
Pablo Greco 40546a
 virCgroupSetCpusetMemoryMigrate(virCgroupPtr group, bool migrate)
Pablo Greco 40546a
 {
Pablo Greco 40546a
-    VIR_CGROUP_BACKEND_CALL(group, setCpusetMemoryMigrate, -1, migrate);
Pablo Greco 40546a
+    VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_CPUSET,
Pablo Greco 40546a
+                            setCpusetMemoryMigrate, -1, migrate);
Pablo Greco 40546a
 }
Pablo Greco 40546a
 
Pablo Greco 40546a
 
Pablo Greco 40546a
@@ -1749,7 +1849,8 @@ virCgroupSetCpusetMemoryMigrate(virCgroupPtr group, bool migrate)
Pablo Greco 40546a
 int
Pablo Greco 40546a
 virCgroupGetCpusetMemoryMigrate(virCgroupPtr group, bool *migrate)
Pablo Greco 40546a
 {
Pablo Greco 40546a
-    VIR_CGROUP_BACKEND_CALL(group, getCpusetMemoryMigrate, -1, migrate);
Pablo Greco 40546a
+    VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_CPUSET,
Pablo Greco 40546a
+                            getCpusetMemoryMigrate, -1, migrate);
Pablo Greco 40546a
 }
Pablo Greco 40546a
 
Pablo Greco 40546a
 
Pablo Greco 40546a
@@ -1764,7 +1865,8 @@ virCgroupGetCpusetMemoryMigrate(virCgroupPtr group, bool *migrate)
Pablo Greco 40546a
 int
Pablo Greco 40546a
 virCgroupSetCpusetCpus(virCgroupPtr group, const char *cpus)
Pablo Greco 40546a
 {
Pablo Greco 40546a
-    VIR_CGROUP_BACKEND_CALL(group, setCpusetCpus, -1, cpus);
Pablo Greco 40546a
+    VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_CPUSET,
Pablo Greco 40546a
+                            setCpusetCpus, -1, cpus);
Pablo Greco 40546a
 }
Pablo Greco 40546a
 
Pablo Greco 40546a
 
Pablo Greco 40546a
@@ -1779,7 +1881,8 @@ virCgroupSetCpusetCpus(virCgroupPtr group, const char *cpus)
Pablo Greco 40546a
 int
Pablo Greco 40546a
 virCgroupGetCpusetCpus(virCgroupPtr group, char **cpus)
Pablo Greco 40546a
 {
Pablo Greco 40546a
-    VIR_CGROUP_BACKEND_CALL(group, getCpusetCpus, -1, cpus);
Pablo Greco 40546a
+    VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_CPUSET,
Pablo Greco 40546a
+                            getCpusetCpus, -1, cpus);
Pablo Greco 40546a
 }
Pablo Greco 40546a
 
Pablo Greco 40546a
 
Pablo Greco 40546a
@@ -1793,7 +1896,8 @@ virCgroupGetCpusetCpus(virCgroupPtr group, char **cpus)
Pablo Greco 40546a
 int
Pablo Greco 40546a
 virCgroupDenyAllDevices(virCgroupPtr group)
Pablo Greco 40546a
 {
Pablo Greco 40546a
-    VIR_CGROUP_BACKEND_CALL(group, denyAllDevices, -1);
Pablo Greco 40546a
+    VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_DEVICES,
Pablo Greco 40546a
+                            denyAllDevices, -1);
Pablo Greco 40546a
 }
Pablo Greco 40546a
 
Pablo Greco 40546a
 /**
Pablo Greco 40546a
@@ -1813,7 +1917,8 @@ virCgroupDenyAllDevices(virCgroupPtr group)
Pablo Greco 40546a
 int
Pablo Greco 40546a
 virCgroupAllowAllDevices(virCgroupPtr group, int perms)
Pablo Greco 40546a
 {
Pablo Greco 40546a
-    VIR_CGROUP_BACKEND_CALL(group, allowAllDevices, -1, perms);
Pablo Greco 40546a
+    VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_DEVICES,
Pablo Greco 40546a
+                            allowAllDevices, -1, perms);
Pablo Greco 40546a
 }
Pablo Greco 40546a
 
Pablo Greco 40546a
 
Pablo Greco 40546a
@@ -1832,7 +1937,8 @@ int
Pablo Greco 40546a
 virCgroupAllowDevice(virCgroupPtr group, char type, int major, int minor,
Pablo Greco 40546a
                      int perms)
Pablo Greco 40546a
 {
Pablo Greco 40546a
-    VIR_CGROUP_BACKEND_CALL(group, allowDevice, -1, type, major, minor, perms);
Pablo Greco 40546a
+    VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_DEVICES,
Pablo Greco 40546a
+                            allowDevice, -1, type, major, minor, perms);
Pablo Greco 40546a
 }
Pablo Greco 40546a
 
Pablo Greco 40546a
 
Pablo Greco 40546a
@@ -1871,7 +1977,8 @@ virCgroupAllowDevicePath(virCgroupPtr group,
Pablo Greco 40546a
     if (!S_ISCHR(sb.st_mode) && !S_ISBLK(sb.st_mode))
Pablo Greco 40546a
         return 1;
Pablo Greco 40546a
 
Pablo Greco 40546a
-    VIR_CGROUP_BACKEND_CALL(group, allowDevice, -1,
Pablo Greco 40546a
+    VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_DEVICES,
Pablo Greco 40546a
+                            allowDevice, -1,
Pablo Greco 40546a
                             S_ISCHR(sb.st_mode) ? 'c' : 'b',
Pablo Greco 40546a
                             major(sb.st_rdev),
Pablo Greco 40546a
                             minor(sb.st_rdev),
Pablo Greco 40546a
@@ -1894,7 +2001,8 @@ int
Pablo Greco 40546a
 virCgroupDenyDevice(virCgroupPtr group, char type, int major, int minor,
Pablo Greco 40546a
                     int perms)
Pablo Greco 40546a
 {
Pablo Greco 40546a
-    VIR_CGROUP_BACKEND_CALL(group, denyDevice, -1, type, major, minor, perms);
Pablo Greco 40546a
+    VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_DEVICES,
Pablo Greco 40546a
+                            denyDevice, -1, type, major, minor, perms);
Pablo Greco 40546a
 }
Pablo Greco 40546a
 
Pablo Greco 40546a
 
Pablo Greco 40546a
@@ -1933,7 +2041,8 @@ virCgroupDenyDevicePath(virCgroupPtr group,
Pablo Greco 40546a
     if (!S_ISCHR(sb.st_mode) && !S_ISBLK(sb.st_mode))
Pablo Greco 40546a
         return 1;
Pablo Greco 40546a
 
Pablo Greco 40546a
-    VIR_CGROUP_BACKEND_CALL(group, denyDevice, -1,
Pablo Greco 40546a
+    VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_DEVICES,
Pablo Greco 40546a
+                            denyDevice, -1,
Pablo Greco 40546a
                             S_ISCHR(sb.st_mode) ? 'c' : 'b',
Pablo Greco 40546a
                             major(sb.st_rdev),
Pablo Greco 40546a
                             minor(sb.st_rdev),
Pablo Greco 40546a
@@ -2176,14 +2285,16 @@ virCgroupGetDomainTotalCpuStats(virCgroupPtr group,
Pablo Greco 40546a
 int
Pablo Greco 40546a
 virCgroupSetCpuShares(virCgroupPtr group, unsigned long long shares)
Pablo Greco 40546a
 {
Pablo Greco 40546a
-    VIR_CGROUP_BACKEND_CALL(group, setCpuShares, -1, shares);
Pablo Greco 40546a
+    VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_CPU,
Pablo Greco 40546a
+                            setCpuShares, -1, shares);
Pablo Greco 40546a
 }
Pablo Greco 40546a
 
Pablo Greco 40546a
 
Pablo Greco 40546a
 int
Pablo Greco 40546a
 virCgroupGetCpuShares(virCgroupPtr group, unsigned long long *shares)
Pablo Greco 40546a
 {
Pablo Greco 40546a
-    VIR_CGROUP_BACKEND_CALL(group, getCpuShares, -1, shares);
Pablo Greco 40546a
+    VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_CPU,
Pablo Greco 40546a
+                            getCpuShares, -1, shares);
Pablo Greco 40546a
 }
Pablo Greco 40546a
 
Pablo Greco 40546a
 
Pablo Greco 40546a
@@ -2198,7 +2309,8 @@ virCgroupGetCpuShares(virCgroupPtr group, unsigned long long *shares)
Pablo Greco 40546a
 int
Pablo Greco 40546a
 virCgroupSetCpuCfsPeriod(virCgroupPtr group, unsigned long long cfs_period)
Pablo Greco 40546a
 {
Pablo Greco 40546a
-    VIR_CGROUP_BACKEND_CALL(group, setCpuCfsPeriod, -1, cfs_period);
Pablo Greco 40546a
+    VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_CPU,
Pablo Greco 40546a
+                            setCpuCfsPeriod, -1, cfs_period);
Pablo Greco 40546a
 }
Pablo Greco 40546a
 
Pablo Greco 40546a
 
Pablo Greco 40546a
@@ -2213,7 +2325,8 @@ virCgroupSetCpuCfsPeriod(virCgroupPtr group, unsigned long long cfs_period)
Pablo Greco 40546a
 int
Pablo Greco 40546a
 virCgroupGetCpuCfsPeriod(virCgroupPtr group, unsigned long long *cfs_period)
Pablo Greco 40546a
 {
Pablo Greco 40546a
-    VIR_CGROUP_BACKEND_CALL(group, getCpuCfsPeriod, -1, cfs_period);
Pablo Greco 40546a
+    VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_CPU,
Pablo Greco 40546a
+                            getCpuCfsPeriod, -1, cfs_period);
Pablo Greco 40546a
 }
Pablo Greco 40546a
 
Pablo Greco 40546a
 
Pablo Greco 40546a
@@ -2229,14 +2342,16 @@ virCgroupGetCpuCfsPeriod(virCgroupPtr group, unsigned long long *cfs_period)
Pablo Greco 40546a
 int
Pablo Greco 40546a
 virCgroupSetCpuCfsQuota(virCgroupPtr group, long long cfs_quota)
Pablo Greco 40546a
 {
Pablo Greco 40546a
-    VIR_CGROUP_BACKEND_CALL(group, setCpuCfsQuota, -1, cfs_quota);
Pablo Greco 40546a
+    VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_CPU,
Pablo Greco 40546a
+                            setCpuCfsQuota, -1, cfs_quota);
Pablo Greco 40546a
 }
Pablo Greco 40546a
 
Pablo Greco 40546a
 
Pablo Greco 40546a
 int
Pablo Greco 40546a
 virCgroupGetCpuacctPercpuUsage(virCgroupPtr group, char **usage)
Pablo Greco 40546a
 {
Pablo Greco 40546a
-    VIR_CGROUP_BACKEND_CALL(group, getCpuacctPercpuUsage, -1, usage);
Pablo Greco 40546a
+    VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_CPUACCT,
Pablo Greco 40546a
+                            getCpuacctPercpuUsage, -1, usage);
Pablo Greco 40546a
 }
Pablo Greco 40546a
 
Pablo Greco 40546a
 
Pablo Greco 40546a
@@ -2303,7 +2418,16 @@ virCgroupRemoveRecursively(char *grppath)
Pablo Greco 40546a
 int
Pablo Greco 40546a
 virCgroupRemove(virCgroupPtr group)
Pablo Greco 40546a
 {
Pablo Greco 40546a
-    return group->backend->remove(group);
Pablo Greco 40546a
+    size_t i;
Pablo Greco 40546a
+
Pablo Greco 40546a
+    for (i = 0; i < VIR_CGROUP_BACKEND_TYPE_LAST; i++) {
Pablo Greco 40546a
+        if (group->backends[i] &&
Pablo Greco 40546a
+            group->backends[i]->remove(group) < 0) {
Pablo Greco 40546a
+            return -1;
Pablo Greco 40546a
+        }
Pablo Greco 40546a
+    }
Pablo Greco 40546a
+
Pablo Greco 40546a
+    return 0;
Pablo Greco 40546a
 }
Pablo Greco 40546a
 
Pablo Greco 40546a
 
Pablo Greco 40546a
@@ -2312,11 +2436,16 @@ virCgroupPathOfAnyController(virCgroupPtr group,
Pablo Greco 40546a
                              const char *name,
Pablo Greco 40546a
                              char **keypath)
Pablo Greco 40546a
 {
Pablo Greco 40546a
+    size_t i;
Pablo Greco 40546a
     int controller;
Pablo Greco 40546a
 
Pablo Greco 40546a
-    controller = group->backend->getAnyController(group);
Pablo Greco 40546a
-    if (controller >= 0)
Pablo Greco 40546a
-        return virCgroupPathOfController(group, controller, name, keypath);
Pablo Greco 40546a
+    for (i = 0; i < VIR_CGROUP_BACKEND_TYPE_LAST; i++) {
Pablo Greco 40546a
+        if (group->backends[i]) {
Pablo Greco 40546a
+            controller = group->backends[i]->getAnyController(group);
Pablo Greco 40546a
+            if (controller >= 0)
Pablo Greco 40546a
+                return virCgroupPathOfController(group, controller, name, keypath);
Pablo Greco 40546a
+        }
Pablo Greco 40546a
+    }
Pablo Greco 40546a
 
Pablo Greco 40546a
     virReportSystemError(ENOSYS, "%s",
Pablo Greco 40546a
                          _("No controllers are mounted"));
Pablo Greco 40546a
@@ -2552,14 +2681,16 @@ virCgroupKillPainfully(virCgroupPtr group)
Pablo Greco 40546a
 int
Pablo Greco 40546a
 virCgroupGetCpuCfsQuota(virCgroupPtr group, long long *cfs_quota)
Pablo Greco 40546a
 {
Pablo Greco 40546a
-    VIR_CGROUP_BACKEND_CALL(group, getCpuCfsQuota, -1, cfs_quota);
Pablo Greco 40546a
+    VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_CPU,
Pablo Greco 40546a
+                            getCpuCfsQuota, -1, cfs_quota);
Pablo Greco 40546a
 }
Pablo Greco 40546a
 
Pablo Greco 40546a
 
Pablo Greco 40546a
 int
Pablo Greco 40546a
 virCgroupGetCpuacctUsage(virCgroupPtr group, unsigned long long *usage)
Pablo Greco 40546a
 {
Pablo Greco 40546a
-    VIR_CGROUP_BACKEND_CALL(group, getCpuacctUsage, -1, usage);
Pablo Greco 40546a
+    VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_CPUACCT,
Pablo Greco 40546a
+                            getCpuacctUsage, -1, usage);
Pablo Greco 40546a
 }
Pablo Greco 40546a
 
Pablo Greco 40546a
 
Pablo Greco 40546a
@@ -2567,21 +2698,24 @@ int
Pablo Greco 40546a
 virCgroupGetCpuacctStat(virCgroupPtr group, unsigned long long *user,
Pablo Greco 40546a
                         unsigned long long *sys)
Pablo Greco 40546a
 {
Pablo Greco 40546a
-    VIR_CGROUP_BACKEND_CALL(group, getCpuacctStat, -1, user, sys);
Pablo Greco 40546a
+    VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_CPUACCT,
Pablo Greco 40546a
+                            getCpuacctStat, -1, user, sys);
Pablo Greco 40546a
 }
Pablo Greco 40546a
 
Pablo Greco 40546a
 
Pablo Greco 40546a
 int
Pablo Greco 40546a
 virCgroupSetFreezerState(virCgroupPtr group, const char *state)
Pablo Greco 40546a
 {
Pablo Greco 40546a
-    VIR_CGROUP_BACKEND_CALL(group, setFreezerState, -1, state);
Pablo Greco 40546a
+    VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_FREEZER,
Pablo Greco 40546a
+                            setFreezerState, -1, state);
Pablo Greco 40546a
 }
Pablo Greco 40546a
 
Pablo Greco 40546a
 
Pablo Greco 40546a
 int
Pablo Greco 40546a
 virCgroupGetFreezerState(virCgroupPtr group, char **state)
Pablo Greco 40546a
 {
Pablo Greco 40546a
-    VIR_CGROUP_BACKEND_CALL(group, getFreezerState, -1, state);
Pablo Greco 40546a
+    VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_FREEZER,
Pablo Greco 40546a
+                            getFreezerState, -1, state);
Pablo Greco 40546a
 }
Pablo Greco 40546a
 
Pablo Greco 40546a
 
Pablo Greco 40546a
@@ -2589,7 +2723,16 @@ int
Pablo Greco 40546a
 virCgroupBindMount(virCgroupPtr group, const char *oldroot,
Pablo Greco 40546a
                    const char *mountopts)
Pablo Greco 40546a
 {
Pablo Greco 40546a
-    return group->backend->bindMount(group, oldroot, mountopts);
Pablo Greco 40546a
+    size_t i;
Pablo Greco 40546a
+
Pablo Greco 40546a
+    for (i = 0; i < VIR_CGROUP_BACKEND_TYPE_LAST; i++) {
Pablo Greco 40546a
+        if (group->backends[i] &&
Pablo Greco 40546a
+            group->backends[i]->bindMount(group, oldroot, mountopts) < 0) {
Pablo Greco 40546a
+            return -1;
Pablo Greco 40546a
+        }
Pablo Greco 40546a
+    }
Pablo Greco 40546a
+
Pablo Greco 40546a
+    return 0;
Pablo Greco 40546a
 }
Pablo Greco 40546a
 
Pablo Greco 40546a
 
Pablo Greco 40546a
@@ -2598,7 +2741,16 @@ int virCgroupSetOwner(virCgroupPtr cgroup,
Pablo Greco 40546a
                       gid_t gid,
Pablo Greco 40546a
                       int controllers)
Pablo Greco 40546a
 {
Pablo Greco 40546a
-    return cgroup->backend->setOwner(cgroup, uid, gid, controllers);
Pablo Greco 40546a
+    size_t i;
Pablo Greco 40546a
+
Pablo Greco 40546a
+    for (i = 0; i < VIR_CGROUP_BACKEND_TYPE_LAST; i++) {
Pablo Greco 40546a
+        if (cgroup->backends[i] &&
Pablo Greco 40546a
+            cgroup->backends[i]->setOwner(cgroup, uid, gid, controllers) < 0) {
Pablo Greco 40546a
+            return -1;
Pablo Greco 40546a
+        }
Pablo Greco 40546a
+    }
Pablo Greco 40546a
+
Pablo Greco 40546a
+    return 0;
Pablo Greco 40546a
 }
Pablo Greco 40546a
 
Pablo Greco 40546a
 
Pablo Greco 40546a
@@ -2612,13 +2764,24 @@ int virCgroupSetOwner(virCgroupPtr cgroup,
Pablo Greco 40546a
 bool
Pablo Greco 40546a
 virCgroupSupportsCpuBW(virCgroupPtr cgroup)
Pablo Greco 40546a
 {
Pablo Greco 40546a
-    VIR_CGROUP_BACKEND_CALL(cgroup, supportsCpuBW, false);
Pablo Greco 40546a
+    VIR_CGROUP_BACKEND_CALL(cgroup, VIR_CGROUP_CONTROLLER_CPU,
Pablo Greco 40546a
+                            supportsCpuBW, false);
Pablo Greco 40546a
 }
Pablo Greco 40546a
 
Pablo Greco 40546a
 int
Pablo Greco 40546a
 virCgroupHasEmptyTasks(virCgroupPtr cgroup, int controller)
Pablo Greco 40546a
 {
Pablo Greco 40546a
-    return cgroup->backend->hasEmptyTasks(cgroup, controller);
Pablo Greco 40546a
+    size_t i;
Pablo Greco 40546a
+
Pablo Greco 40546a
+    for (i = 0; i < VIR_CGROUP_BACKEND_TYPE_LAST; i++) {
Pablo Greco 40546a
+        if (cgroup->backends[i]) {
Pablo Greco 40546a
+            int rc = cgroup->backends[i]->hasEmptyTasks(cgroup, controller);
Pablo Greco 40546a
+            if (rc <= 0)
Pablo Greco 40546a
+                return rc;
Pablo Greco 40546a
+        }
Pablo Greco 40546a
+    }
Pablo Greco 40546a
+
Pablo Greco 40546a
+    return 1;
Pablo Greco 40546a
 }
Pablo Greco 40546a
 
Pablo Greco 40546a
 bool
Pablo Greco 40546a
diff --git a/src/util/vircgroupbackend.c b/src/util/vircgroupbackend.c
Pablo Greco 40546a
index 7ee39ac8ca..2e90781dc3 100644
Pablo Greco 40546a
--- a/src/util/vircgroupbackend.c
Pablo Greco 40546a
+++ b/src/util/vircgroupbackend.c
Pablo Greco 40546a
@@ -20,6 +20,9 @@
Pablo Greco 40546a
 #include <config.h>
Pablo Greco 40546a
 
Pablo Greco 40546a
 #include "vircgroupbackend.h"
Pablo Greco 40546a
+#define __VIR_CGROUP_ALLOW_INCLUDE_PRIV_H__
Pablo Greco 40546a
+#include "vircgrouppriv.h"
Pablo Greco 40546a
+#undef __VIR_CGROUP_ALLOW_INCLUDE_PRIV_H__
Pablo Greco 40546a
 #include "vircgroupv1.h"
Pablo Greco 40546a
 #include "vircgroupv2.h"
Pablo Greco 40546a
 #include "virerror.h"
Pablo Greco 40546a
@@ -67,3 +70,20 @@ virCgroupBackendGetAll(void)
Pablo Greco 40546a
     }
Pablo Greco 40546a
     return virCgroupBackends;
Pablo Greco 40546a
 }
Pablo Greco 40546a
+
Pablo Greco 40546a
+
Pablo Greco 40546a
+virCgroupBackendPtr
Pablo Greco 40546a
+virCgroupBackendForController(virCgroupPtr group,
Pablo Greco 40546a
+                              unsigned int controller)
Pablo Greco 40546a
+{
Pablo Greco 40546a
+    size_t i;
Pablo Greco 40546a
+
Pablo Greco 40546a
+    for (i = 0; i < VIR_CGROUP_BACKEND_TYPE_LAST; i++) {
Pablo Greco 40546a
+        if (group->backends[i] &&
Pablo Greco 40546a
+            group->backends[i]->hasController(group, controller)) {
Pablo Greco 40546a
+            return group->backends[i];
Pablo Greco 40546a
+        }
Pablo Greco 40546a
+    }
Pablo Greco 40546a
+
Pablo Greco 40546a
+    return NULL;
Pablo Greco 40546a
+}
Pablo Greco 40546a
diff --git a/src/util/vircgroupbackend.h b/src/util/vircgroupbackend.h
Pablo Greco 40546a
index 86d1539e07..bc60b44643 100644
Pablo Greco 40546a
--- a/src/util/vircgroupbackend.h
Pablo Greco 40546a
+++ b/src/util/vircgroupbackend.h
Pablo Greco 40546a
@@ -436,12 +436,22 @@ virCgroupBackendRegister(virCgroupBackendPtr backend);
Pablo Greco 40546a
 virCgroupBackendPtr *
Pablo Greco 40546a
 virCgroupBackendGetAll(void);
Pablo Greco 40546a
 
Pablo Greco 40546a
-# define VIR_CGROUP_BACKEND_CALL(group, func, ret, ...) \
Pablo Greco 40546a
-    if (!group->backend->func) { \
Pablo Greco 40546a
+virCgroupBackendPtr
Pablo Greco 40546a
+virCgroupBackendForController(virCgroupPtr group,
Pablo Greco 40546a
+                              unsigned int controller);
Pablo Greco 40546a
+
Pablo Greco 40546a
+# define VIR_CGROUP_BACKEND_CALL(group, controller, func, ret, ...) \
Pablo Greco 40546a
+    virCgroupBackendPtr backend = virCgroupBackendForController(group, controller); \
Pablo Greco 40546a
+    if (!backend) { \
Pablo Greco 40546a
+        virReportError(VIR_ERR_INTERNAL_ERROR, \
Pablo Greco 40546a
+                       _("failed to get cgroup backend for '%s'"), #func); \
Pablo Greco 40546a
+        return ret; \
Pablo Greco 40546a
+    } \
Pablo Greco 40546a
+    if (!backend->func) { \
Pablo Greco 40546a
         virReportError(VIR_ERR_OPERATION_UNSUPPORTED, \
Pablo Greco 40546a
                        _("operation '%s' not supported"), #func); \
Pablo Greco 40546a
         return ret; \
Pablo Greco 40546a
     } \
Pablo Greco 40546a
-    return group->backend->func(group, ##__VA_ARGS__);
Pablo Greco 40546a
+    return backend->func(group, ##__VA_ARGS__);
Pablo Greco 40546a
 
Pablo Greco 40546a
 #endif /* __VIR_CGROUP_BACKEND_H__ */
Pablo Greco 40546a
diff --git a/src/util/vircgrouppriv.h b/src/util/vircgrouppriv.h
Pablo Greco 40546a
index 4a0d75ddbc..8f24b0891e 100644
Pablo Greco 40546a
--- a/src/util/vircgrouppriv.h
Pablo Greco 40546a
+++ b/src/util/vircgrouppriv.h
Pablo Greco 40546a
@@ -56,7 +56,7 @@ typedef virCgroupV2Controller *virCgroupV2ControllerPtr;
Pablo Greco 40546a
 struct _virCgroup {
Pablo Greco 40546a
     char *path;
Pablo Greco 40546a
 
Pablo Greco 40546a
-    virCgroupBackendPtr backend;
Pablo Greco 40546a
+    virCgroupBackendPtr backends[VIR_CGROUP_BACKEND_TYPE_LAST];
Pablo Greco 40546a
 
Pablo Greco 40546a
     virCgroupV1Controller legacy[VIR_CGROUP_CONTROLLER_LAST];
Pablo Greco 40546a
     virCgroupV2Controller unified;
Pablo Greco 40546a
-- 
Pablo Greco 40546a
2.22.0
Pablo Greco 40546a