Hey folks, we've gotten an issue with how libvirt is currently detecting the cgroup2 mounts. Basically we expose cgroup2 mounts in a container from the host-level and libvirt was selecting that instead of the container-level mount, which uses the canonical path.
The current logic basically iterate on the mounts until it finds a cgroup2 mount and uses that. If there's multiple, it will override until the last one is read, which is not very safe. I've cut a quick patch that should: 1. Validate that the mount is actually an existing directory in the context 2. Prefer the canonical mount (/sys/fs/cgroup) if it's available 3. only override it once, so it will not go through lists of mounts overriding up to the end I'm happy to get some feedback here especially on step 3 as I'm not very sure how we should proceed on non-canonical situations or if we should at all. Maybe the best solution is to just use the canonical path? >From 4a0bf5c5b1e1cd4e0393981a25e1407d29beb43e Mon Sep 17 00:00:00 2001 From: Rogerio Vinhal Nunes <[email protected]> Date: Mon, 2 Feb 2026 19:24:52 +0000 Subject: [PATCH] Preferred /sys/fs/cgroup as a canonical mount but also verifies if the mount is an existing directory in the namespace. The reason for this is preventing that mounts that are not visible in the container namespace or additional cgroupv2 mounts to share host context might be incorrectly taken as targets here. --- src/util/vircgroupv2.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c index eaf5ae98f6..aa8c950691 100644 --- a/src/util/vircgroupv2.c +++ b/src/util/vircgroupv2.c @@ -23,6 +23,7 @@ #ifdef __linux__ # include <mntent.h> # include <sys/mount.h> +# include <sys/stat.h> #endif /* __linux__ */ #include "internal.h" @@ -46,6 +47,8 @@ VIR_LOG_INIT("util.cgroup"); #define VIR_FROM_THIS VIR_FROM_CGROUP +#define VIR_CGROUP_SYSFS_MOUNT "/sys/fs/cgroup" + VIR_ENUM_DECL(virCgroupV2Controller); VIR_ENUM_IMPL(virCgroupV2Controller, VIR_CGROUP_CONTROLLER_LAST, @@ -173,12 +176,26 @@ virCgroupV2DetectMounts(virCgroup *group, const char *mntOpts G_GNUC_UNUSED, const char *mntDir) { + struct stat sb; + if (STRNEQ(mntType, "cgroup2")) return 0; - VIR_FREE(group->unified.mountPoint); + if (stat(mntDir, &sb) < 0 || !S_ISDIR(sb.st_mode)) { + VIR_DEBUG("Skipping non-directory cgroup2 mount: %s", mntDir); + return 0; + } + + /* Always prefer /sys/fs/cgroup as the canonical mount point. + * If we already have /sys/fs/cgroup, don't override it. + * Otherwise, use the first valid directory we find as fallback. */ + if (STREQ(mntDir, VIR_CGROUP_SYSFS_MOUNT)) { + VIR_FREE(group->unified.mountPoint); + group->unified.mountPoint = g_strdup(mntDir); + } else if (!group->unified.mountPoint) { + group->unified.mountPoint = g_strdup(mntDir); + } - group->unified.mountPoint = g_strdup(mntDir); return 0; } -- 2.52.0
