From e6d3eb25267155a35a068c7e0f740e7d44af9e28 Mon Sep 17 00:00:00 2001 From: Aaron Andersen Date: Thu, 1 Jan 2026 16:02:36 -0500 Subject: [PATCH] Handle already-mounted cgroups in cgroup_init() Add handling for EBUSY when mounting cgroup2 filesystem, which occurs when cgroups are already mounted. This can happen after switch_root when cgroups were moved from the initramfs, or in container environments. Verify the existing mount is actually cgroup2 before proceeding, and track whether we mounted to avoid unmounting on error if we didn't. --- src/cgroup.c | 38 ++++++++++++++++++++++++++++++++------ 1 file changed, 32 insertions(+), 6 deletions(-) diff --git a/src/cgroup.c b/src/cgroup.c index ccb44a77..20289cf4 100644 --- a/src/cgroup.c +++ b/src/cgroup.c @@ -34,6 +34,8 @@ #endif #include #include /* get_nprocs_conf() */ +#include +#include #include "cgroup.h" #include "finit.h" @@ -841,6 +843,7 @@ void cgroup_config(void) void cgroup_init(uev_ctx_t *ctx) { int opts = MS_NODEV | MS_NOEXEC | MS_NOSUID; + int mounted = 0; char buf[80]; FILE *fp; int fd; @@ -851,14 +854,36 @@ void cgroup_init(uev_ctx_t *ctx) #endif if (mount("none", FINIT_CGPATH, "cgroup2", opts, NULL)) { - if (errno == ENOENT) + if (errno == EBUSY) { + /* + * Already mounted - this happens after switch_root + * when cgroups were moved from the initramfs. + * Verify it's actually cgroup2 before proceeding. + */ + struct statfs sfs; + + if (statfs(FINIT_CGPATH, &sfs) || sfs.f_type != CGROUP2_SUPER_MAGIC) { + logit(LOG_ERR, "Mount point %s busy but not cgroup2", FINIT_CGPATH); + avail = 0; + return; + } + dbg("cgroup2 already mounted at %s, reusing", FINIT_CGPATH); + } else if (errno == ENOENT) { logit(LOG_INFO, "Kernel does not support cgroups v2, disabling."); - else if (errno == EPERM) /* Probably inside an unprivileged container */ + avail = 0; + return; + } else if (errno == EPERM) { + /* Probably inside an unprivileged container */ logit(LOG_INFO, "Not allowed to mount cgroups v2, disabling."); - else + avail = 0; + return; + } else { err(1, "Failed mounting cgroup v2"); - avail = 0; - return; + avail = 0; + return; + } + } else { + mounted = 1; } avail = 1; @@ -867,7 +892,8 @@ void cgroup_init(uev_ctx_t *ctx) if (!fp) { err(1, "Failed opening %s", FINIT_CGPATH "/cgroup.controllers"); abort: - umount(FINIT_CGPATH); + if (mounted) + umount(FINIT_CGPATH); avail = 0; return; }