From nobody Tue May 13 16:10:54 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1538469997524890.0372004915997; Tue, 2 Oct 2018 01:46:37 -0700 (PDT) Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id A001C7F3EC; Tue, 2 Oct 2018 08:46:34 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.20]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 625723DE5; Tue, 2 Oct 2018 08:46:34 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id E801D181D0B8; Tue, 2 Oct 2018 08:46:33 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id w928jY9j031771 for ; Tue, 2 Oct 2018 04:45:34 -0400 Received: by smtp.corp.redhat.com (Postfix) id 4B3FA103BAB3; Tue, 2 Oct 2018 08:45:34 +0000 (UTC) Received: from antique-work.brq.redhat.com (unknown [10.43.2.181]) by smtp.corp.redhat.com (Postfix) with ESMTP id C1AB6100194A for ; Tue, 2 Oct 2018 08:45:33 +0000 (UTC) From: Pavel Hrdina To: libvir-list@redhat.com Date: Tue, 2 Oct 2018 10:44:36 +0200 Message-Id: <35fae869ae214e2cb6cd87b8fe5a122a449506c0.1538469654.git.phrdina@redhat.com> In-Reply-To: References: In-Reply-To: References: X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH 52/53] virt-host-validate: rewrite cgroup detection to use util/vircgroup X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.25]); Tue, 02 Oct 2018 08:46:36 +0000 (UTC) X-ZohoMail: RDMRC_0 RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" This removes code duplication and simplifies cgroup detection. As a drawback we will not have separate messages to enable cgroup controller in kernel or to mount it. On the other side the rewrite adds support for cgroup v2. The kernel config support was wrong because it was parsing '/proc/self/cgroup' instead of '/proc/cgroups/' file. The mount suggestion is removed as well because it will not work with cgroup v2. Signed-off-by: Pavel Hrdina --- tools/virt-host-validate-common.c | 162 ++++++------------------------ tools/virt-host-validate-common.h | 7 +- tools/virt-host-validate-lxc.c | 40 ++------ tools/virt-host-validate-qemu.c | 40 ++------ 4 files changed, 54 insertions(+), 195 deletions(-) diff --git a/tools/virt-host-validate-common.c b/tools/virt-host-validate-c= ommon.c index ccbd764c84..4e70fe9e9c 100644 --- a/tools/virt-host-validate-common.c +++ b/tools/virt-host-validate-common.c @@ -24,12 +24,10 @@ #include #include #include -#ifdef HAVE_MNTENT_H -# include -#endif /* HAVE_MNTENT_H */ #include =20 #include "viralloc.h" +#include "vircgroup.h" #include "virfile.h" #include "virt-host-validate-common.h" #include "virstring.h" @@ -288,152 +286,50 @@ int virHostValidateLinuxKernel(const char *hvname, } } =20 - -static int virHostValidateCGroupSupport(const char *hvname, - const char *cg_name, - virHostValidateLevel level, - const char *config_name) -{ - virHostMsgCheck(hvname, "for cgroup '%s' controller support", cg_name); - FILE *fp =3D fopen("/proc/self/cgroup", "r"); - size_t len =3D 0; - char *line =3D NULL; - ssize_t ret; - bool matched =3D false; - - if (!fp) - goto error; - - while ((ret =3D getline(&line, &len, fp)) >=3D 0 && !matched) { - 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/emula= tor - * - * Since multiple cgroups can be part of the same line and some cg= roup - * names can appear as part of other cgroup names (eg. 'cpu' is a - * prefix for both 'cpuacct' and 'cpuset'), it's not enough to sim= ply - * check whether the cgroup name is present somewhere inside the f= ile. - * - * Moreover, there's nothing stopping the cgroup name from appeari= ng - * 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 =3D strchr(line, ':'))) - continue; - start++; - - /* Look for the second colon. - * The part we're interested in ends exactly there */ - if (!(end =3D strchr(start, ':'))) - continue; - *end =3D '\0'; - - if (!(cgroups =3D virStringSplitCount(start, ",", 0, &ncgroups))) - continue; - - /* Look for the matching cgroup */ - for (i =3D 0; i < ncgroups; i++) { - if (STREQ(cgroups[i], cg_name)) - matched =3D true; - } - - virStringListFreeCount(cgroups, ncgroups); - } - - VIR_FREE(line); - VIR_FORCE_FCLOSE(fp); - if (!matched) - goto error; - - virHostMsgPass(); - return 0; - - error: - VIR_FREE(line); - virHostMsgFail(level, "Enable CONFIG_%s in kernel Kconfig file", confi= g_name); - return -1; -} - -#ifdef HAVE_MNTENT_H -static int virHostValidateCGroupMount(const char *hvname, - const char *cg_name, - virHostValidateLevel level) +#ifdef __linux__ +int virHostValidateCGroupControllers(const char *hvname, + int controllers, + virHostValidateLevel level) { - virHostMsgCheck(hvname, "for cgroup '%s' controller mount-point", cg_n= ame); - FILE *fp =3D setmntent("/proc/mounts", "r"); - struct mntent ent; - char mntbuf[1024]; - bool matched =3D false; + virCgroupPtr group =3D NULL; + int ret =3D 0; + size_t i; =20 - if (!fp) - goto error; + if (virCgroupNewSelf(&group) < 0) + return -1; =20 - while (getmntent_r(fp, &ent, mntbuf, sizeof(mntbuf)) && !matched) { - char **opts; - size_t nopts; - size_t i; + for (i =3D 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) { + int flag =3D 1 << i; + const char *cg_name =3D virCgroupControllerTypeToString(i); =20 - /* Ignore non-cgroup mounts */ - if (STRNEQ(ent.mnt_type, "cgroup")) + if (!(controllers & flag)) continue; =20 - if (!(opts =3D virStringSplitCount(ent.mnt_opts, ",", 0, &nopts))) - continue; + virHostMsgCheck(hvname, "for cgroup '%s' controller support", cg_n= ame); =20 - /* Look for a mount option matching the cgroup name */ - for (i =3D 0; i < nopts; i++) { - if (STREQ(opts[i], cg_name)) - matched =3D true; + if (!virCgroupHasController(group, i)) { + ret =3D -1; + virHostMsgFail(level, "Enable '%s' in kernel Kconfig file or " + "mount/enable cgroup controller in your system", + cg_name); + } else { + virHostMsgPass(); } - - virStringListFreeCount(opts, nopts); } - endmntent(fp); - if (!matched) - goto error; =20 - virHostMsgPass(); - return 0; + virCgroupFree(&group); =20 - error: - virHostMsgFail(level, "Mount '%s' cgroup controller (suggested at /sys= /fs/cgroup/%s)", - cg_name, cg_name); - return -1; + return ret; } -#else /* ! HAVE_MNTENT_H */ -static int virHostValidateCGroupMount(const char *hvname, - const char *cg_name, - virHostValidateLevel level) +#else /* !__linux__ */ +int virHostValidateCGroupControllers(const char *hvname, + int controllers, + virHostValidateLevel level) { - virHostMsgCheck(hvname, "for cgroup '%s' controller mount-point", cg_n= ame); virHostMsgFail(level, "%s", "This platform does not support cgroups"); return -1; } -#endif /* ! HAVE_MNTENT_H */ - -int virHostValidateCGroupController(const char *hvname, - const char *cg_name, - virHostValidateLevel level, - const char *config_name) -{ - if (virHostValidateCGroupSupport(hvname, - cg_name, - level, - config_name) < 0) - return -1; - if (virHostValidateCGroupMount(hvname, - cg_name, - level) < 0) - return -1; - return 0; -} +#endif /* !__linux__ */ =20 int virHostValidateIOMMU(const char *hvname, virHostValidateLevel level) diff --git a/tools/virt-host-validate-common.h b/tools/virt-host-validate-c= ommon.h index b6fe17daa7..b23dd7cdbe 100644 --- a/tools/virt-host-validate-common.h +++ b/tools/virt-host-validate-common.h @@ -77,10 +77,9 @@ int virHostValidateNamespace(const char *hvname, virHostValidateLevel level, const char *hint); =20 -int virHostValidateCGroupController(const char *hvname, - const char *cg_name, - virHostValidateLevel level, - const char *config_name); +int virHostValidateCGroupControllers(const char *hvname, + int controllers, + virHostValidateLevel level); =20 int virHostValidateIOMMU(const char *hvname, virHostValidateLevel level); diff --git a/tools/virt-host-validate-lxc.c b/tools/virt-host-validate-lxc.c index 64d9279c30..3c55b1b26d 100644 --- a/tools/virt-host-validate-lxc.c +++ b/tools/virt-host-validate-lxc.c @@ -23,6 +23,7 @@ =20 #include "virt-host-validate-lxc.h" #include "virt-host-validate-common.h" +#include "vircgroup.h" =20 int virHostValidateLXC(void) { @@ -63,35 +64,16 @@ int virHostValidateLXC(void) _("User namespace support is recommended"= )) < 0) ret =3D -1; =20 - if (virHostValidateCGroupController("LXC", "memory", - VIR_HOST_VALIDATE_FAIL, - "MEMCG") < 0) - ret =3D -1; - - if (virHostValidateCGroupController("LXC", "cpu", - VIR_HOST_VALIDATE_FAIL, - "CGROUP_CPU") < 0) - ret =3D -1; - - if (virHostValidateCGroupController("LXC", "cpuacct", - VIR_HOST_VALIDATE_FAIL, - "CGROUP_CPUACCT") < 0) - ret =3D -1; - - if (virHostValidateCGroupController("LXC", "cpuset", - VIR_HOST_VALIDATE_FAIL, - "CPUSETS") < 0) - ret =3D -1; - - if (virHostValidateCGroupController("LXC", "devices", - VIR_HOST_VALIDATE_FAIL, - "CGROUP_DEVICE") < 0) - ret =3D -1; - - if (virHostValidateCGroupController("LXC", "blkio", - VIR_HOST_VALIDATE_FAIL, - "BLK_CGROUP") < 0) - ret =3D -1; + if (virHostValidateCGroupControllers("LXC", + (1 << VIR_CGROUP_CONTROLLER_MEMOR= Y) | + (1 << VIR_CGROUP_CONTROLLER_CPU) | + (1 << VIR_CGROUP_CONTROLLER_CPUAC= CT) | + (1 << VIR_CGROUP_CONTROLLER_CPUSE= T) | + (1 << VIR_CGROUP_CONTROLLER_DEVIC= ES) | + (1 << VIR_CGROUP_CONTROLLER_BLKIO= ), + VIR_HOST_VALIDATE_FAIL) < 0) { + ret =3D -1; + } =20 #if WITH_FUSE if (virHostValidateDeviceExists("LXC", "/sys/fs/fuse/connections", diff --git a/tools/virt-host-validate-qemu.c b/tools/virt-host-validate-qem= u.c index d7573ea8b3..ff3c1f0231 100644 --- a/tools/virt-host-validate-qemu.c +++ b/tools/virt-host-validate-qemu.c @@ -26,6 +26,7 @@ #include "virt-host-validate-common.h" #include "virarch.h" #include "virbitmap.h" +#include "vircgroup.h" =20 int virHostValidateQEMU(void) { @@ -96,35 +97,16 @@ int virHostValidateQEMU(void) _("Load the 'tun' module to enable net= working for QEMU guests")) < 0) ret =3D -1; =20 - if (virHostValidateCGroupController("QEMU", "memory", - VIR_HOST_VALIDATE_WARN, - "MEMCG") < 0) - ret =3D -1; - - if (virHostValidateCGroupController("QEMU", "cpu", - VIR_HOST_VALIDATE_WARN, - "CGROUP_CPU") < 0) - ret =3D -1; - - if (virHostValidateCGroupController("QEMU", "cpuacct", - VIR_HOST_VALIDATE_WARN, - "CGROUP_CPUACCT") < 0) - ret =3D -1; - - if (virHostValidateCGroupController("QEMU", "cpuset", - VIR_HOST_VALIDATE_WARN, - "CPUSETS") < 0) - ret =3D -1; - - if (virHostValidateCGroupController("QEMU", "devices", - VIR_HOST_VALIDATE_WARN, - "CGROUP_DEVICES") < 0) - ret =3D -1; - - if (virHostValidateCGroupController("QEMU", "blkio", - VIR_HOST_VALIDATE_WARN, - "BLK_CGROUP") < 0) - ret =3D -1; + if (virHostValidateCGroupControllers("QEMU", + (1 << VIR_CGROUP_CONTROLLER_MEMOR= Y) | + (1 << VIR_CGROUP_CONTROLLER_CPU) | + (1 << VIR_CGROUP_CONTROLLER_CPUAC= CT) | + (1 << VIR_CGROUP_CONTROLLER_CPUSE= T) | + (1 << VIR_CGROUP_CONTROLLER_DEVIC= ES) | + (1 << VIR_CGROUP_CONTROLLER_BLKIO= ), + VIR_HOST_VALIDATE_WARN) < 0) { + ret =3D -1; + } =20 if (virHostValidateIOMMU("QEMU", VIR_HOST_VALIDATE_WARN) < 0) --=20 2.17.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list