[libvirt] [PATCH v2 14/17] vircgroup: workaround devices in hybrid mode

Pavel Hrdina phrdina at redhat.com
Mon Jan 14 15:47:48 UTC 2019


So the issue here is that you can end up with configuration where
you have cgroup v1 and v2 enabled at the same time and the devices
controllers is enabled for cgroup v1.

In cgroup v2 there is no devices controller, the device access is
controlled using BPF and since it is not a cgroup controller both
of them can exists at the same time and both of them are applied while
resolving access to devices.

In order to avoid configuring both BPF and cgroup v1 devices we will
use BPF if possible and otherwise fallback to cgroup v1 devices.

Signed-off-by: Pavel Hrdina <phrdina at redhat.com>
---
 src/util/vircgroup.c        | 3 ++-
 src/util/vircgroupbackend.h | 3 ++-
 src/util/vircgroupv1.c      | 9 ++++++++-
 src/util/vircgroupv2.c      | 5 ++++-
 4 files changed, 16 insertions(+), 4 deletions(-)

diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c
index 3ebb3b0a0f..9d284e9bf4 100644
--- a/src/util/vircgroup.c
+++ b/src/util/vircgroup.c
@@ -381,7 +381,8 @@ virCgroupDetect(virCgroupPtr group,
 
     for (i = 0; i < VIR_CGROUP_BACKEND_TYPE_LAST; i++) {
         if (group->backends[i]) {
-            int rc = group->backends[i]->detectControllers(group, controllers);
+            int rc = group->backends[i]->detectControllers(group, controllers,
+                                                           controllersAvailable);
             if (rc < 0)
                 return -1;
             controllersAvailable |= rc;
diff --git a/src/util/vircgroupbackend.h b/src/util/vircgroupbackend.h
index 24b45be9bb..9bc8e7b11d 100644
--- a/src/util/vircgroupbackend.h
+++ b/src/util/vircgroupbackend.h
@@ -96,7 +96,8 @@ typedef char *
 
 typedef int
 (*virCgroupDetectControllersCB)(virCgroupPtr group,
-                                int controllers);
+                                int controllers,
+                                int detected);
 
 typedef bool
 (*virCgroupHasControllerCB)(virCgroupPtr cgroup,
diff --git a/src/util/vircgroupv1.c b/src/util/vircgroupv1.c
index f6707e4894..c94fad0591 100644
--- a/src/util/vircgroupv1.c
+++ b/src/util/vircgroupv1.c
@@ -417,7 +417,8 @@ virCgroupV1StealPlacement(virCgroupPtr group)
 
 static int
 virCgroupV1DetectControllers(virCgroupPtr group,
-                             int controllers)
+                             int controllers,
+                             int detected)
 {
     size_t i;
     size_t j;
@@ -427,6 +428,9 @@ virCgroupV1DetectControllers(virCgroupPtr group,
         /* First mark requested but non-existing controllers to be ignored */
         for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) {
             if (((1 << i) & controllers)) {
+                int type = 1 << i;
+                if (type & detected)
+                    VIR_FREE(group->legacy[i].mountPoint);
                 /* Remove non-existent controllers  */
                 if (!group->legacy[i].mountPoint) {
                     VIR_DEBUG("Requested controller '%s' not mounted, ignoring",
@@ -466,6 +470,9 @@ virCgroupV1DetectControllers(virCgroupPtr group,
         VIR_DEBUG("Auto-detecting controllers");
         controllers = 0;
         for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) {
+            int type = 1 << i;
+            if (type & detected)
+                VIR_FREE(group->legacy[i].mountPoint);
             VIR_DEBUG("Controller '%s' present=%s",
                       virCgroupV1ControllerTypeToString(i),
                       group->legacy[i].mountPoint ? "yes" : "no");
diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c
index f2ea1eb7df..44c4c7fc90 100644
--- a/src/util/vircgroupv2.c
+++ b/src/util/vircgroupv2.c
@@ -284,7 +284,8 @@ virCgroupV2ParseControllersFile(virCgroupPtr group)
 
 static int
 virCgroupV2DetectControllers(virCgroupPtr group,
-                             int controllers)
+                             int controllers,
+                             int detected)
 {
     size_t i;
 
@@ -297,6 +298,8 @@ virCgroupV2DetectControllers(virCgroupPtr group,
     if (virCgroupV2DevicesAvailable(group))
         group->unified.controllers |= 1 << VIR_CGROUP_CONTROLLER_DEVICES;
 
+    group->unified.controllers &= ~detected;
+
     for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++)
         VIR_DEBUG("Controller '%s' present=%s",
                   virCgroupV2ControllerTypeToString(i),
-- 
2.20.1




More information about the libvir-list mailing list