diff --git a/src/basic/cgroup-util.c b/src/basic/cgroup-util.c index 7b5839ccd6..2865cd518e 100644 --- a/src/basic/cgroup-util.c +++ b/src/basic/cgroup-util.c @@ -2526,20 +2526,20 @@ int cg_kernel_controllers(Set **ret) { return 0; } -static thread_local CGroupUnified unified_cache = CGROUP_UNIFIED_UNKNOWN; - -/* The hybrid mode was initially implemented in v232 and simply mounted cgroup2 on /sys/fs/cgroup/systemd. This - * unfortunately broke other tools (such as docker) which expected the v1 "name=systemd" hierarchy on - * /sys/fs/cgroup/systemd. From v233 and on, the hybrid mode mountnbs v2 on /sys/fs/cgroup/unified and maintains - * "name=systemd" hierarchy on /sys/fs/cgroup/systemd for compatibility with other tools. +/* The hybrid mode was initially implemented in v232 and simply mounted cgroup2 on + * /sys/fs/cgroup/systemd. This unfortunately broke other tools (such as docker) which expected the v1 + * "name=systemd" hierarchy on /sys/fs/cgroup/systemd. From v233 and on, the hybrid mode mounts v2 on + * /sys/fs/cgroup/unified and maintains "name=systemd" hierarchy on /sys/fs/cgroup/systemd for compatibility + * with other tools. * - * To keep live upgrade working, we detect and support v232 layout. When v232 layout is detected, to keep cgroup v2 - * process management but disable the compat dual layout, we return %true on - * cg_unified_controller(SYSTEMD_CGROUP_CONTROLLER) and %false on cg_hybrid_unified(). + * To keep live upgrade working, we detect and support v232 layout. When v232 layout is detected, to keep + * cgroup v2 process management but disable the compat dual layout, we return true on + * cg_unified_controller(SYSTEMD_CGROUP_CONTROLLER) and false on cg_hybrid_unified(). */ static thread_local bool unified_systemd_v232; -static int cg_unified_update(void) { +int cg_unified_cached(bool flush) { + static thread_local CGroupUnified unified_cache = CGROUP_UNIFIED_UNKNOWN; struct statfs fs; @@ -2548,8 +2548,10 @@ static int cg_unified_update(void) { * have any other trouble determining if the unified hierarchy * is supported. */ - if (unified_cache >= CGROUP_UNIFIED_NONE) - return 0; + if (flush) + unified_cache = CGROUP_UNIFIED_UNKNOWN; + else if (unified_cache >= CGROUP_UNIFIED_NONE) + return unified_cache; if (statfs("/sys/fs/cgroup/", &fs) < 0) return log_debug_errno(errno, "statfs(\"/sys/fs/cgroup/\") failed: %m"); @@ -2585,20 +2587,20 @@ static int cg_unified_update(void) { "Unknown filesystem type %llx mounted on /sys/fs/cgroup.", (unsigned long long)fs.f_type); - return 0; + return unified_cache; } int cg_unified_controller(const char *controller) { int r; - r = cg_unified_update(); + r = cg_unified_cached(false); if (r < 0) return r; - if (unified_cache == CGROUP_UNIFIED_NONE) + if (r == CGROUP_UNIFIED_NONE) return false; - if (unified_cache >= CGROUP_UNIFIED_ALL) + if (r >= CGROUP_UNIFIED_ALL) return true; return streq_ptr(controller, SYSTEMD_CGROUP_CONTROLLER); @@ -2607,27 +2609,21 @@ int cg_unified_controller(const char *controller) { int cg_all_unified(void) { int r; - r = cg_unified_update(); + r = cg_unified_cached(false); if (r < 0) return r; - return unified_cache >= CGROUP_UNIFIED_ALL; + return r >= CGROUP_UNIFIED_ALL; } int cg_hybrid_unified(void) { int r; - r = cg_unified_update(); + r = cg_unified_cached(false); if (r < 0) return r; - return unified_cache == CGROUP_UNIFIED_SYSTEMD && !unified_systemd_v232; -} - -int cg_unified_flush(void) { - unified_cache = CGROUP_UNIFIED_UNKNOWN; - - return cg_unified_update(); + return r == CGROUP_UNIFIED_SYSTEMD && !unified_systemd_v232; } int cg_enable_everywhere( @@ -2740,10 +2736,10 @@ int cg_enable_everywhere( bool cg_is_unified_wanted(void) { static thread_local int wanted = -1; - int r; bool b; const bool is_default = DEFAULT_HIERARCHY == CGROUP_UNIFIED_ALL; _cleanup_free_ char *c = NULL; + int r; /* If we have a cached value, return that. */ if (wanted >= 0) @@ -2751,8 +2747,9 @@ bool cg_is_unified_wanted(void) { /* If the hierarchy is already mounted, then follow whatever * was chosen for it. */ - if (cg_unified_flush() >= 0) - return (wanted = unified_cache >= CGROUP_UNIFIED_ALL); + r = cg_unified_cached(true); + if (r >= 0) + return (wanted = r >= CGROUP_UNIFIED_ALL); /* If we were explicitly passed systemd.unified_cgroup_hierarchy, * respect that. */ @@ -2777,8 +2774,7 @@ bool cg_is_legacy_wanted(void) { return wanted; /* Check if we have cgroup v2 already mounted. */ - if (cg_unified_flush() >= 0 && - unified_cache == CGROUP_UNIFIED_ALL) + if (cg_unified_cached(true) == CGROUP_UNIFIED_ALL) return (wanted = false); /* Otherwise, assume that at least partial legacy is wanted, @@ -2801,8 +2797,7 @@ bool cg_is_hybrid_wanted(void) { /* If the hierarchy is already mounted, then follow whatever * was chosen for it. */ - if (cg_unified_flush() >= 0 && - unified_cache == CGROUP_UNIFIED_ALL) + if (cg_unified_cached(true) == CGROUP_UNIFIED_ALL) return (wanted = false); /* Otherwise, let's see what the kernel command line has to say. diff --git a/src/basic/cgroup-util.h b/src/basic/cgroup-util.h index a39ab451b9..ba8df8139d 100644 --- a/src/basic/cgroup-util.h +++ b/src/basic/cgroup-util.h @@ -258,7 +258,10 @@ bool cg_ns_supported(void); int cg_all_unified(void); int cg_hybrid_unified(void); int cg_unified_controller(const char *controller); -int cg_unified_flush(void); +int cg_unified_cached(bool flush); +static inline int cg_unified(void) { + return cg_unified_cached(true); +} bool cg_is_unified_wanted(void); bool cg_is_legacy_wanted(void); diff --git a/src/core/cgroup.c b/src/core/cgroup.c index 60a7799361..7b0a41fbc8 100644 --- a/src/core/cgroup.c +++ b/src/core/cgroup.c @@ -2839,7 +2839,7 @@ int manager_setup_cgroup(Manager *m) { if (r < 0) return log_error_errno(r, "Cannot find cgroup mount point: %m"); - r = cg_unified_flush(); + r = cg_unified(); if (r < 0) return log_error_errno(r, "Couldn't determine if we are running in the unified hierarchy: %m"); diff --git a/src/libsystemd/sd-bus/test-bus-creds.c b/src/libsystemd/sd-bus/test-bus-creds.c index c02c459663..7f7bc491d2 100644 --- a/src/libsystemd/sd-bus/test-bus-creds.c +++ b/src/libsystemd/sd-bus/test-bus-creds.c @@ -13,7 +13,7 @@ int main(int argc, char *argv[]) { test_setup_logging(LOG_DEBUG); - if (cg_unified_flush() == -ENOMEDIUM) + if (cg_unified() == -ENOMEDIUM) return log_tests_skipped("/sys/fs/cgroup/ not available"); r = sd_bus_creds_new_from_pid(&creds, 0, _SD_BUS_CREDS_ALL); diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index 2aec8041f0..91ec61402b 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -4720,7 +4720,7 @@ static int run(int argc, char *argv[]) { if (r < 0) goto finish; - r = cg_unified_flush(); + r = cg_unified(); if (r < 0) { log_error_errno(r, "Failed to determine whether the unified cgroups hierarchy is used: %m"); goto finish; diff --git a/src/test/test-cgroup-util.c b/src/test/test-cgroup-util.c index b54b5e76c6..f45c5ff760 100644 --- a/src/test/test-cgroup-util.c +++ b/src/test/test-cgroup-util.c @@ -385,12 +385,12 @@ static void test_is_wanted(void) { static void test_cg_tests(void) { int all, hybrid, systemd, r; - r = cg_unified_flush(); + r = cg_unified(); if (r == -ENOMEDIUM) { log_notice_errno(r, "Skipping cg hierarchy tests: %m"); return; } - assert_se(r == 0); + assert_se(r >= 0); all = cg_all_unified(); assert_se(IN_SET(all, 0, 1)); diff --git a/src/test/test-condition.c b/src/test/test-condition.c index a79263a50b..9a0a4cfee2 100644 --- a/src/test/test-condition.c +++ b/src/test/test-condition.c @@ -124,7 +124,7 @@ static void test_condition_test_control_group_controller(void) { _cleanup_free_ char *controller_name = NULL; int r; - r = cg_unified_flush(); + r = cg_unified(); if (r < 0) { log_notice_errno(r, "Skipping ConditionControlGroupController tests: %m"); return;