|
|
c480ed |
From 0ede215415509022d94092b75ef075495c91a5d5 Mon Sep 17 00:00:00 2001
|
|
|
c480ed |
Message-Id: <0ede215415509022d94092b75ef075495c91a5d5@dist-git>
|
|
|
c480ed |
From: Pavel Hrdina <phrdina@redhat.com>
|
|
|
c480ed |
Date: Mon, 1 Jul 2019 17:08:03 +0200
|
|
|
c480ed |
Subject: [PATCH] virt-host-validate: rewrite cgroup detection to use
|
|
|
c480ed |
util/vircgroup
|
|
|
c480ed |
MIME-Version: 1.0
|
|
|
c480ed |
Content-Type: text/plain; charset=UTF-8
|
|
|
c480ed |
Content-Transfer-Encoding: 8bit
|
|
|
c480ed |
|
|
|
c480ed |
This removes code duplication and simplifies cgroup detection.
|
|
|
c480ed |
As a drawback we will not have separate messages to enable cgroup
|
|
|
c480ed |
controller in kernel or to mount it. On the other side the rewrite
|
|
|
c480ed |
adds support for cgroup v2.
|
|
|
c480ed |
|
|
|
c480ed |
The kernel config support was wrong because it was parsing
|
|
|
c480ed |
'/proc/self/cgroup' instead of '/proc/cgroups/' file.
|
|
|
c480ed |
|
|
|
c480ed |
The mount suggestion is removed as well because it will not work
|
|
|
c480ed |
with cgroup v2.
|
|
|
c480ed |
|
|
|
c480ed |
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
|
|
|
c480ed |
(cherry picked from commit 0f4d7daa8cd43b62911413c2cc1614f87380e459)
|
|
|
c480ed |
|
|
|
c480ed |
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297
|
|
|
c480ed |
|
|
|
c480ed |
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
|
|
|
c480ed |
Message-Id: <0a79b9dcaee25d04b993c4e6576d75ce7c45ac0f.1561993100.git.phrdina@redhat.com>
|
|
|
c480ed |
Reviewed-by: Ján Tomko <jtomko@redhat.com>
|
|
|
c480ed |
---
|
|
|
c480ed |
tools/virt-host-validate-common.c | 164 ++++++------------------------
|
|
|
c480ed |
tools/virt-host-validate-common.h | 7 +-
|
|
|
c480ed |
tools/virt-host-validate-lxc.c | 38 ++-----
|
|
|
c480ed |
tools/virt-host-validate-qemu.c | 38 ++-----
|
|
|
c480ed |
4 files changed, 53 insertions(+), 194 deletions(-)
|
|
|
c480ed |
|
|
|
c480ed |
diff --git a/tools/virt-host-validate-common.c b/tools/virt-host-validate-common.c
|
|
|
c480ed |
index c45dfc5d8c..73165d673a 100644
|
|
|
c480ed |
--- a/tools/virt-host-validate-common.c
|
|
|
c480ed |
+++ b/tools/virt-host-validate-common.c
|
|
|
c480ed |
@@ -26,12 +26,10 @@
|
|
|
c480ed |
#include <stdio.h>
|
|
|
c480ed |
#include <unistd.h>
|
|
|
c480ed |
#include <sys/utsname.h>
|
|
|
c480ed |
-#ifdef HAVE_MNTENT_H
|
|
|
c480ed |
-# include <mntent.h>
|
|
|
c480ed |
-#endif /* HAVE_MNTENT_H */
|
|
|
c480ed |
#include <sys/stat.h>
|
|
|
c480ed |
|
|
|
c480ed |
#include "viralloc.h"
|
|
|
c480ed |
+#include "vircgroup.h"
|
|
|
c480ed |
#include "virfile.h"
|
|
|
c480ed |
#include "virt-host-validate-common.h"
|
|
|
c480ed |
#include "virstring.h"
|
|
|
c480ed |
@@ -290,152 +288,50 @@ int virHostValidateLinuxKernel(const char *hvname,
|
|
|
c480ed |
}
|
|
|
c480ed |
}
|
|
|
c480ed |
|
|
|
c480ed |
-
|
|
|
c480ed |
-static int virHostValidateCGroupSupport(const char *hvname,
|
|
|
c480ed |
- const char *cg_name,
|
|
|
c480ed |
- virHostValidateLevel level,
|
|
|
c480ed |
- const char *config_name)
|
|
|
c480ed |
+#ifdef __linux__
|
|
|
c480ed |
+int virHostValidateCGroupControllers(const char *hvname,
|
|
|
c480ed |
+ int controllers,
|
|
|
c480ed |
+ virHostValidateLevel level)
|
|
|
c480ed |
{
|
|
|
c480ed |
- virHostMsgCheck(hvname, "for cgroup '%s' controller support", cg_name);
|
|
|
c480ed |
- FILE *fp = fopen("/proc/self/cgroup", "r");
|
|
|
c480ed |
- size_t len = 0;
|
|
|
c480ed |
- char *line = NULL;
|
|
|
c480ed |
- ssize_t ret;
|
|
|
c480ed |
- bool matched = false;
|
|
|
c480ed |
+ virCgroupPtr group = NULL;
|
|
|
c480ed |
+ int ret = 0;
|
|
|
c480ed |
+ size_t i;
|
|
|
c480ed |
|
|
|
c480ed |
- if (!fp)
|
|
|
c480ed |
- goto error;
|
|
|
c480ed |
+ if (virCgroupNewSelf(&group) < 0)
|
|
|
c480ed |
+ return -1;
|
|
|
c480ed |
|
|
|
c480ed |
- while ((ret = getline(&line, &len, fp)) >= 0 && !matched) {
|
|
|
c480ed |
- char **cgroups;
|
|
|
c480ed |
- char *start;
|
|
|
c480ed |
- char *end;
|
|
|
c480ed |
- size_t ncgroups;
|
|
|
c480ed |
- size_t i;
|
|
|
c480ed |
+ for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) {
|
|
|
c480ed |
+ int flag = 1 << i;
|
|
|
c480ed |
+ const char *cg_name = virCgroupControllerTypeToString(i);
|
|
|
c480ed |
|
|
|
c480ed |
- /* Each line in this file looks like
|
|
|
c480ed |
- *
|
|
|
c480ed |
- * 4:cpu,cpuacct:/machine.slice/machine-qemu\x2dtest.scope/emulator
|
|
|
c480ed |
- *
|
|
|
c480ed |
- * Since multiple cgroups can be part of the same line and some cgroup
|
|
|
c480ed |
- * names can appear as part of other cgroup names (eg. 'cpu' is a
|
|
|
c480ed |
- * prefix for both 'cpuacct' and 'cpuset'), it's not enough to simply
|
|
|
c480ed |
- * check whether the cgroup name is present somewhere inside the file.
|
|
|
c480ed |
- *
|
|
|
c480ed |
- * Moreover, there's nothing stopping the cgroup name from appearing
|
|
|
c480ed |
- * in an unrelated mount point name as well */
|
|
|
c480ed |
-
|
|
|
c480ed |
- /* Look for the first colon.
|
|
|
c480ed |
- * The part we're interested in starts right after it */
|
|
|
c480ed |
- if (!(start = strchr(line, ':')))
|
|
|
c480ed |
- continue;
|
|
|
c480ed |
- start++;
|
|
|
c480ed |
-
|
|
|
c480ed |
- /* Look for the second colon.
|
|
|
c480ed |
- * The part we're interested in ends exactly there */
|
|
|
c480ed |
- if (!(end = strchr(start, ':')))
|
|
|
c480ed |
- continue;
|
|
|
c480ed |
- *end = '\0';
|
|
|
c480ed |
-
|
|
|
c480ed |
- if (!(cgroups = virStringSplitCount(start, ",", 0, &ncgroups)))
|
|
|
c480ed |
+ if (!(controllers & flag))
|
|
|
c480ed |
continue;
|
|
|
c480ed |
|
|
|
c480ed |
- /* Look for the matching cgroup */
|
|
|
c480ed |
- for (i = 0; i < ncgroups; i++) {
|
|
|
c480ed |
- if (STREQ(cgroups[i], cg_name))
|
|
|
c480ed |
- matched = true;
|
|
|
c480ed |
+ virHostMsgCheck(hvname, "for cgroup '%s' controller support", cg_name);
|
|
|
c480ed |
+
|
|
|
c480ed |
+ if (!virCgroupHasController(group, i)) {
|
|
|
c480ed |
+ ret = -1;
|
|
|
c480ed |
+ virHostMsgFail(level, "Enable '%s' in kernel Kconfig file or "
|
|
|
c480ed |
+ "mount/enable cgroup controller in your system",
|
|
|
c480ed |
+ cg_name);
|
|
|
c480ed |
+ } else {
|
|
|
c480ed |
+ virHostMsgPass();
|
|
|
c480ed |
}
|
|
|
c480ed |
-
|
|
|
c480ed |
- virStringListFreeCount(cgroups, ncgroups);
|
|
|
c480ed |
}
|
|
|
c480ed |
|
|
|
c480ed |
- VIR_FREE(line);
|
|
|
c480ed |
- VIR_FORCE_FCLOSE(fp);
|
|
|
c480ed |
- if (!matched)
|
|
|
c480ed |
- goto error;
|
|
|
c480ed |
+ virCgroupFree(&group);
|
|
|
c480ed |
|
|
|
c480ed |
- virHostMsgPass();
|
|
|
c480ed |
- return 0;
|
|
|
c480ed |
-
|
|
|
c480ed |
- error:
|
|
|
c480ed |
- VIR_FREE(line);
|
|
|
c480ed |
- virHostMsgFail(level, "Enable CONFIG_%s in kernel Kconfig file", config_name);
|
|
|
c480ed |
- return -1;
|
|
|
c480ed |
+ return ret;
|
|
|
c480ed |
}
|
|
|
c480ed |
-
|
|
|
c480ed |
-#ifdef HAVE_MNTENT_H
|
|
|
c480ed |
-static int virHostValidateCGroupMount(const char *hvname,
|
|
|
c480ed |
- const char *cg_name,
|
|
|
c480ed |
- virHostValidateLevel level)
|
|
|
c480ed |
+#else /* !__linux__ */
|
|
|
c480ed |
+int virHostValidateCGroupControllers(const char *hvname,
|
|
|
c480ed |
+ int controllers,
|
|
|
c480ed |
+ virHostValidateLevel level)
|
|
|
c480ed |
{
|
|
|
c480ed |
- virHostMsgCheck(hvname, "for cgroup '%s' controller mount-point", cg_name);
|
|
|
c480ed |
- FILE *fp = setmntent("/proc/mounts", "r");
|
|
|
c480ed |
- struct mntent ent;
|
|
|
c480ed |
- char mntbuf[1024];
|
|
|
c480ed |
- bool matched = false;
|
|
|
c480ed |
-
|
|
|
c480ed |
- if (!fp)
|
|
|
c480ed |
- goto error;
|
|
|
c480ed |
-
|
|
|
c480ed |
- while (getmntent_r(fp, &ent, mntbuf, sizeof(mntbuf)) && !matched) {
|
|
|
c480ed |
- char **opts;
|
|
|
c480ed |
- size_t nopts;
|
|
|
c480ed |
- size_t i;
|
|
|
c480ed |
-
|
|
|
c480ed |
- /* Ignore non-cgroup mounts */
|
|
|
c480ed |
- if (STRNEQ(ent.mnt_type, "cgroup"))
|
|
|
c480ed |
- continue;
|
|
|
c480ed |
-
|
|
|
c480ed |
- if (!(opts = virStringSplitCount(ent.mnt_opts, ",", 0, &nopts)))
|
|
|
c480ed |
- continue;
|
|
|
c480ed |
-
|
|
|
c480ed |
- /* Look for a mount option matching the cgroup name */
|
|
|
c480ed |
- for (i = 0; i < nopts; i++) {
|
|
|
c480ed |
- if (STREQ(opts[i], cg_name))
|
|
|
c480ed |
- matched = true;
|
|
|
c480ed |
- }
|
|
|
c480ed |
-
|
|
|
c480ed |
- virStringListFreeCount(opts, nopts);
|
|
|
c480ed |
- }
|
|
|
c480ed |
- endmntent(fp);
|
|
|
c480ed |
- if (!matched)
|
|
|
c480ed |
- goto error;
|
|
|
c480ed |
-
|
|
|
c480ed |
- virHostMsgPass();
|
|
|
c480ed |
- return 0;
|
|
|
c480ed |
-
|
|
|
c480ed |
- error:
|
|
|
c480ed |
- virHostMsgFail(level, "Mount '%s' cgroup controller (suggested at /sys/fs/cgroup/%s)",
|
|
|
c480ed |
- cg_name, cg_name);
|
|
|
c480ed |
- return -1;
|
|
|
c480ed |
-}
|
|
|
c480ed |
-#else /* ! HAVE_MNTENT_H */
|
|
|
c480ed |
-static int virHostValidateCGroupMount(const char *hvname,
|
|
|
c480ed |
- const char *cg_name,
|
|
|
c480ed |
- virHostValidateLevel level)
|
|
|
c480ed |
-{
|
|
|
c480ed |
- virHostMsgCheck(hvname, "for cgroup '%s' controller mount-point", cg_name);
|
|
|
c480ed |
virHostMsgFail(level, "%s", "This platform does not support cgroups");
|
|
|
c480ed |
return -1;
|
|
|
c480ed |
}
|
|
|
c480ed |
-#endif /* ! HAVE_MNTENT_H */
|
|
|
c480ed |
-
|
|
|
c480ed |
-int virHostValidateCGroupController(const char *hvname,
|
|
|
c480ed |
- const char *cg_name,
|
|
|
c480ed |
- virHostValidateLevel level,
|
|
|
c480ed |
- const char *config_name)
|
|
|
c480ed |
-{
|
|
|
c480ed |
- if (virHostValidateCGroupSupport(hvname,
|
|
|
c480ed |
- cg_name,
|
|
|
c480ed |
- level,
|
|
|
c480ed |
- config_name) < 0)
|
|
|
c480ed |
- return -1;
|
|
|
c480ed |
- if (virHostValidateCGroupMount(hvname,
|
|
|
c480ed |
- cg_name,
|
|
|
c480ed |
- level) < 0)
|
|
|
c480ed |
- return -1;
|
|
|
c480ed |
- return 0;
|
|
|
c480ed |
-}
|
|
|
c480ed |
+#endif /* !__linux__ */
|
|
|
c480ed |
|
|
|
c480ed |
int virHostValidateIOMMU(const char *hvname,
|
|
|
c480ed |
virHostValidateLevel level)
|
|
|
c480ed |
diff --git a/tools/virt-host-validate-common.h b/tools/virt-host-validate-common.h
|
|
|
c480ed |
index b6fe17daa7..b23dd7cdbe 100644
|
|
|
c480ed |
--- a/tools/virt-host-validate-common.h
|
|
|
c480ed |
+++ b/tools/virt-host-validate-common.h
|
|
|
c480ed |
@@ -77,10 +77,9 @@ int virHostValidateNamespace(const char *hvname,
|
|
|
c480ed |
virHostValidateLevel level,
|
|
|
c480ed |
const char *hint);
|
|
|
c480ed |
|
|
|
c480ed |
-int virHostValidateCGroupController(const char *hvname,
|
|
|
c480ed |
- const char *cg_name,
|
|
|
c480ed |
- virHostValidateLevel level,
|
|
|
c480ed |
- const char *config_name);
|
|
|
c480ed |
+int virHostValidateCGroupControllers(const char *hvname,
|
|
|
c480ed |
+ int controllers,
|
|
|
c480ed |
+ virHostValidateLevel level);
|
|
|
c480ed |
|
|
|
c480ed |
int virHostValidateIOMMU(const char *hvname,
|
|
|
c480ed |
virHostValidateLevel level);
|
|
|
c480ed |
diff --git a/tools/virt-host-validate-lxc.c b/tools/virt-host-validate-lxc.c
|
|
|
c480ed |
index 64d9279c30..3c55b1b26d 100644
|
|
|
c480ed |
--- a/tools/virt-host-validate-lxc.c
|
|
|
c480ed |
+++ b/tools/virt-host-validate-lxc.c
|
|
|
c480ed |
@@ -23,6 +23,7 @@
|
|
|
c480ed |
|
|
|
c480ed |
#include "virt-host-validate-lxc.h"
|
|
|
c480ed |
#include "virt-host-validate-common.h"
|
|
|
c480ed |
+#include "vircgroup.h"
|
|
|
c480ed |
|
|
|
c480ed |
int virHostValidateLXC(void)
|
|
|
c480ed |
{
|
|
|
c480ed |
@@ -63,35 +64,16 @@ int virHostValidateLXC(void)
|
|
|
c480ed |
_("User namespace support is recommended")) < 0)
|
|
|
c480ed |
ret = -1;
|
|
|
c480ed |
|
|
|
c480ed |
- if (virHostValidateCGroupController("LXC", "memory",
|
|
|
c480ed |
- VIR_HOST_VALIDATE_FAIL,
|
|
|
c480ed |
- "MEMCG") < 0)
|
|
|
c480ed |
- ret = -1;
|
|
|
c480ed |
-
|
|
|
c480ed |
- if (virHostValidateCGroupController("LXC", "cpu",
|
|
|
c480ed |
- VIR_HOST_VALIDATE_FAIL,
|
|
|
c480ed |
- "CGROUP_CPU") < 0)
|
|
|
c480ed |
- ret = -1;
|
|
|
c480ed |
-
|
|
|
c480ed |
- if (virHostValidateCGroupController("LXC", "cpuacct",
|
|
|
c480ed |
- VIR_HOST_VALIDATE_FAIL,
|
|
|
c480ed |
- "CGROUP_CPUACCT") < 0)
|
|
|
c480ed |
- ret = -1;
|
|
|
c480ed |
-
|
|
|
c480ed |
- if (virHostValidateCGroupController("LXC", "cpuset",
|
|
|
c480ed |
- VIR_HOST_VALIDATE_FAIL,
|
|
|
c480ed |
- "CPUSETS") < 0)
|
|
|
c480ed |
- ret = -1;
|
|
|
c480ed |
-
|
|
|
c480ed |
- if (virHostValidateCGroupController("LXC", "devices",
|
|
|
c480ed |
- VIR_HOST_VALIDATE_FAIL,
|
|
|
c480ed |
- "CGROUP_DEVICE") < 0)
|
|
|
c480ed |
- ret = -1;
|
|
|
c480ed |
-
|
|
|
c480ed |
- if (virHostValidateCGroupController("LXC", "blkio",
|
|
|
c480ed |
- VIR_HOST_VALIDATE_FAIL,
|
|
|
c480ed |
- "BLK_CGROUP") < 0)
|
|
|
c480ed |
+ if (virHostValidateCGroupControllers("LXC",
|
|
|
c480ed |
+ (1 << VIR_CGROUP_CONTROLLER_MEMORY) |
|
|
|
c480ed |
+ (1 << VIR_CGROUP_CONTROLLER_CPU) |
|
|
|
c480ed |
+ (1 << VIR_CGROUP_CONTROLLER_CPUACCT) |
|
|
|
c480ed |
+ (1 << VIR_CGROUP_CONTROLLER_CPUSET) |
|
|
|
c480ed |
+ (1 << VIR_CGROUP_CONTROLLER_DEVICES) |
|
|
|
c480ed |
+ (1 << VIR_CGROUP_CONTROLLER_BLKIO),
|
|
|
c480ed |
+ VIR_HOST_VALIDATE_FAIL) < 0) {
|
|
|
c480ed |
ret = -1;
|
|
|
c480ed |
+ }
|
|
|
c480ed |
|
|
|
c480ed |
#if WITH_FUSE
|
|
|
c480ed |
if (virHostValidateDeviceExists("LXC", "/sys/fs/fuse/connections",
|
|
|
c480ed |
diff --git a/tools/virt-host-validate-qemu.c b/tools/virt-host-validate-qemu.c
|
|
|
c480ed |
index d7573ea8b3..ff3c1f0231 100644
|
|
|
c480ed |
--- a/tools/virt-host-validate-qemu.c
|
|
|
c480ed |
+++ b/tools/virt-host-validate-qemu.c
|
|
|
c480ed |
@@ -26,6 +26,7 @@
|
|
|
c480ed |
#include "virt-host-validate-common.h"
|
|
|
c480ed |
#include "virarch.h"
|
|
|
c480ed |
#include "virbitmap.h"
|
|
|
c480ed |
+#include "vircgroup.h"
|
|
|
c480ed |
|
|
|
c480ed |
int virHostValidateQEMU(void)
|
|
|
c480ed |
{
|
|
|
c480ed |
@@ -96,35 +97,16 @@ int virHostValidateQEMU(void)
|
|
|
c480ed |
_("Load the 'tun' module to enable networking for QEMU guests")) < 0)
|
|
|
c480ed |
ret = -1;
|
|
|
c480ed |
|
|
|
c480ed |
- if (virHostValidateCGroupController("QEMU", "memory",
|
|
|
c480ed |
- VIR_HOST_VALIDATE_WARN,
|
|
|
c480ed |
- "MEMCG") < 0)
|
|
|
c480ed |
- ret = -1;
|
|
|
c480ed |
-
|
|
|
c480ed |
- if (virHostValidateCGroupController("QEMU", "cpu",
|
|
|
c480ed |
- VIR_HOST_VALIDATE_WARN,
|
|
|
c480ed |
- "CGROUP_CPU") < 0)
|
|
|
c480ed |
- ret = -1;
|
|
|
c480ed |
-
|
|
|
c480ed |
- if (virHostValidateCGroupController("QEMU", "cpuacct",
|
|
|
c480ed |
- VIR_HOST_VALIDATE_WARN,
|
|
|
c480ed |
- "CGROUP_CPUACCT") < 0)
|
|
|
c480ed |
- ret = -1;
|
|
|
c480ed |
-
|
|
|
c480ed |
- if (virHostValidateCGroupController("QEMU", "cpuset",
|
|
|
c480ed |
- VIR_HOST_VALIDATE_WARN,
|
|
|
c480ed |
- "CPUSETS") < 0)
|
|
|
c480ed |
- ret = -1;
|
|
|
c480ed |
-
|
|
|
c480ed |
- if (virHostValidateCGroupController("QEMU", "devices",
|
|
|
c480ed |
- VIR_HOST_VALIDATE_WARN,
|
|
|
c480ed |
- "CGROUP_DEVICES") < 0)
|
|
|
c480ed |
- ret = -1;
|
|
|
c480ed |
-
|
|
|
c480ed |
- if (virHostValidateCGroupController("QEMU", "blkio",
|
|
|
c480ed |
- VIR_HOST_VALIDATE_WARN,
|
|
|
c480ed |
- "BLK_CGROUP") < 0)
|
|
|
c480ed |
+ if (virHostValidateCGroupControllers("QEMU",
|
|
|
c480ed |
+ (1 << VIR_CGROUP_CONTROLLER_MEMORY) |
|
|
|
c480ed |
+ (1 << VIR_CGROUP_CONTROLLER_CPU) |
|
|
|
c480ed |
+ (1 << VIR_CGROUP_CONTROLLER_CPUACCT) |
|
|
|
c480ed |
+ (1 << VIR_CGROUP_CONTROLLER_CPUSET) |
|
|
|
c480ed |
+ (1 << VIR_CGROUP_CONTROLLER_DEVICES) |
|
|
|
c480ed |
+ (1 << VIR_CGROUP_CONTROLLER_BLKIO),
|
|
|
c480ed |
+ VIR_HOST_VALIDATE_WARN) < 0) {
|
|
|
c480ed |
ret = -1;
|
|
|
c480ed |
+ }
|
|
|
c480ed |
|
|
|
c480ed |
if (virHostValidateIOMMU("QEMU",
|
|
|
c480ed |
VIR_HOST_VALIDATE_WARN) < 0)
|
|
|
c480ed |
--
|
|
|
c480ed |
2.22.0
|
|
|
c480ed |
|