[libvirt] [PATCH v3] host-validate: Be more careful when checking for cgroup support

Andrea Bolognani abologna at redhat.com
Fri Apr 8 12:13:10 UTC 2016


Simply checking whether the cgroup name appears somewhere inside
/proc/self/cgroup is enough most of the time, but there are some
corner cases that require a more mindful parsing.
---
 tools/virt-host-validate-common.c | 43 +++++++++++++++++++++++++++++++++------
 1 file changed, 37 insertions(+), 6 deletions(-)

diff --git a/tools/virt-host-validate-common.c b/tools/virt-host-validate-common.c
index 95ae64a..e182d0c 100644
--- a/tools/virt-host-validate-common.c
+++ b/tools/virt-host-validate-common.c
@@ -303,17 +303,48 @@ static int virHostValidateCGroupSupport(const char *hvname,
         goto error;
 
     while ((ret = getline(&line, &len, fp)) >= 0 && !matched) {
-        char *tmp = strstr(line, cg_name);
-        if (!tmp)
+        char **cgroups;
+        char *start;
+        char *end;
+        size_t ncgroups;
+        size_t i;
+
+        /* Each line in this file looks like
+         *
+         *   4:cpu,cpuacct:/machine.slice/machine-qemu\x2dtest.scope/emulator
+         *
+         * Since multiple cgroups can be part of the same line and some cgroup
+         * names can appear as part of other cgroup names (eg. 'cpu' is a
+         * prefix for both 'cpuacct' and 'cpuset'), it's not enough to simply
+         * check whether the cgroup name is present somewhere inside the file.
+         *
+         * Moreover, there's nothing stopping the cgroup name from appearing
+         * in an unrelated mount point name as well */
+
+        /* Look for the first colon.
+         * The part we're interested in starts right after it */
+        if (!(start = strchr(line, ':')))
+            continue;
+        start++;
+
+        /* Look for the second colon.
+         * The part we're interested in ends exactly there */
+        if (!(end = strchr(start, ':')))
             continue;
+        *end = '\0';
 
-        tmp += strlen(cg_name);
-        if (*tmp != ',' &&
-            *tmp != ':')
+        if (!(cgroups = virStringSplitCount(start, ",", 0, &ncgroups)))
             continue;
 
-        matched = true;
+        /* Look for the matching cgroup */
+        for (i = 0; i < ncgroups; i++) {
+            if (STREQ(cgroups[i], cg_name))
+                matched = true;
+        }
+
+        virStringFreeListCount(cgroups, ncgroups);
     }
+
     VIR_FREE(line);
     VIR_FORCE_FCLOSE(fp);
     if (!matched)
-- 
2.5.5




More information about the libvir-list mailing list