c313de
From 4551f704f56b289735ed17f3b9ee0f9663183d09 Mon Sep 17 00:00:00 2001
c313de
Message-Id: <4551f704f56b289735ed17f3b9ee0f9663183d09@dist-git>
c313de
From: Pavel Hrdina <phrdina@redhat.com>
c313de
Date: Mon, 1 Jul 2019 17:07:13 +0200
c313de
Subject: [PATCH] vircgroup: introduce virCgroupV2Available
c313de
MIME-Version: 1.0
c313de
Content-Type: text/plain; charset=UTF-8
c313de
Content-Transfer-Encoding: 8bit
c313de
c313de
We cannot detect only mount points to figure out whether cgroup v2
c313de
is available because systemd uses cgroup v2 for process tracking and
c313de
all controllers are mounted as cgroup v1 controllers.
c313de
c313de
To make sure that this is no the situation we need to check
c313de
'cgroup.controllers' file if it's not empty to make sure that cgroup
c313de
v2 is not mounted only for process tracking.
c313de
c313de
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
c313de
(cherry picked from commit 034ef217d73aa240340dd22590402bb9636648b5)
c313de
c313de
Conflicts:
c313de
    src/util/vircgroupv2.c: missing commit c0abcca417
c313de
c313de
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297
c313de
c313de
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
c313de
Message-Id: <46bcb2f86e4ca5f029f67be5385770d725ef5c42.1561993100.git.phrdina@redhat.com>
c313de
Reviewed-by: Ján Tomko <jtomko@redhat.com>
c313de
---
c313de
 src/util/vircgroupv2.c | 51 ++++++++++++++++++++++++++++++++++++++++++
c313de
 1 file changed, 51 insertions(+)
c313de
c313de
diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c
c313de
index 23bf81dae2..4ab9f2b792 100644
c313de
--- a/src/util/vircgroupv2.c
c313de
+++ b/src/util/vircgroupv2.c
c313de
@@ -19,16 +19,23 @@
c313de
  */
c313de
 #include <config.h>
c313de
 
c313de
+#ifdef __linux__
c313de
+# include <mntent.h>
c313de
+#endif /* __linux__ */
c313de
+
c313de
 #include "internal.h"
c313de
 
c313de
 #define __VIR_CGROUP_ALLOW_INCLUDE_PRIV_H__
c313de
 #include "vircgrouppriv.h"
c313de
 #undef __VIR_CGROUP_ALLOW_INCLUDE_PRIV_H__
c313de
 
c313de
+#include "viralloc.h"
c313de
 #include "vircgroup.h"
c313de
 #include "vircgroupbackend.h"
c313de
 #include "vircgroupv2.h"
c313de
+#include "virfile.h"
c313de
 #include "virlog.h"
c313de
+#include "virstring.h"
c313de
 
c313de
 VIR_LOG_INIT("util.cgroup");
c313de
 
c313de
@@ -41,8 +48,52 @@ VIR_ENUM_IMPL(virCgroupV2Controller, VIR_CGROUP_CONTROLLER_LAST,
c313de
 
c313de
 #ifdef __linux__
c313de
 
c313de
+/* We're looking for one 'cgroup2' fs mount which has some
c313de
+ * controllers enabled. */
c313de
+static bool
c313de
+virCgroupV2Available(void)
c313de
+{
c313de
+    bool ret = false;
c313de
+    FILE *mounts = NULL;
c313de
+    struct mntent entry;
c313de
+    char buf[CGROUP_MAX_VAL];
c313de
+
c313de
+    if (!(mounts = fopen("/proc/mounts", "r")))
c313de
+        return false;
c313de
+
c313de
+    while (getmntent_r(mounts, &entry, buf, sizeof(buf)) != NULL) {
c313de
+        VIR_AUTOFREE(char *) contFile = NULL;
c313de
+        VIR_AUTOFREE(char *) contStr = NULL;
c313de
+
c313de
+        if (STRNEQ(entry.mnt_type, "cgroup2"))
c313de
+            continue;
c313de
+
c313de
+        /* Systemd uses cgroup v2 for process tracking but no controller is
c313de
+         * available. We should consider this configuration as cgroup v2 is
c313de
+         * not available. */
c313de
+        if (virAsprintf(&contFile, "%s/cgroup.controllers", entry.mnt_dir) < 0)
c313de
+            goto cleanup;
c313de
+
c313de
+        if (virFileReadAll(contFile, 1024 * 1024, &contStr) < 0)
c313de
+            goto cleanup;
c313de
+
c313de
+        if (STREQ(contStr, ""))
c313de
+            continue;
c313de
+
c313de
+        ret = true;
c313de
+        break;
c313de
+    }
c313de
+
c313de
+ cleanup:
c313de
+    VIR_FORCE_FCLOSE(mounts);
c313de
+    return ret;
c313de
+}
c313de
+
c313de
+
c313de
 virCgroupBackend virCgroupV2Backend = {
c313de
     .type = VIR_CGROUP_BACKEND_TYPE_V2,
c313de
+
c313de
+    .available = virCgroupV2Available,
c313de
 };
c313de
 
c313de
 
c313de
-- 
c313de
2.22.0
c313de