]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
cgroup-setup: drop hierarchy detection, always use v2
authorMike Yuan <me@yhndnzj.com>
Wed, 5 Mar 2025 16:57:27 +0000 (17:57 +0100)
committerMike Yuan <me@yhndnzj.com>
Sun, 16 Mar 2025 14:30:39 +0000 (15:30 +0100)
src/shared/cgroup-setup.c
src/shared/cgroup-setup.h
src/shared/mount-setup.c
src/test/meson.build
src/test/test-cgroup-setup.c [deleted file]

index c1019f571d53ae2b1f6d8703375f683be7562238..b94d0b00a665094fbd2d493f1cec86b63b3cecf1 100644 (file)
@@ -1,6 +1,5 @@
 /* SPDX-License-Identifier: LGPL-2.1-or-later */
 
-#include <threads.h>
 #include <unistd.h>
 
 #include "cgroup-setup.h"
 #include "mkdir.h"
 #include "parse-util.h"
 #include "path-util.h"
-#include "proc-cmdline.h"
 #include "process-util.h"
 #include "recurse-dir.h"
 #include "stdio-util.h"
 #include "string-util.h"
 #include "user-util.h"
-#include "virt.h"
-
-static int cg_any_controller_used_for_v1(void) {
-        _cleanup_free_ char *buf = NULL;
-        _cleanup_strv_free_ char **lines = NULL;
-        int r;
-
-        r = read_full_virtual_file("/proc/cgroups", &buf, NULL);
-        if (r < 0)
-                return log_debug_errno(r, "Could not read /proc/cgroups, ignoring: %m");
-
-        r = strv_split_newlines_full(&lines, buf, 0);
-        if (r < 0)
-                return r;
-
-        /* The intention of this is to check if the fully unified cgroup tree setup is possible, meaning all
-         * enabled kernel cgroup controllers are currently not in use by cgroup1.  For reference:
-         * https://systemd.io/CGROUP_DELEGATION/#three-different-tree-setups-
-         *
-         * Note that this is typically only useful to check inside a container where we don't know what
-         * cgroup tree setup is in use by the host; if the host is using legacy or hybrid, we can't use
-         * unified since some or all controllers would be missing. This is not the best way to detect this,
-         * as whatever container manager created our container should have mounted /sys/fs/cgroup
-         * appropriately, but in case that wasn't done, we try to detect if it's possible for us to use
-         * unified cgroups. */
-        STRV_FOREACH(line, lines) {
-                _cleanup_free_ char *name = NULL, *hierarchy_id = NULL, *num = NULL, *enabled = NULL;
-
-                /* Skip header line */
-                if (startswith(*line, "#"))
-                        continue;
-
-                const char *p = *line;
-                r = extract_many_words(&p, NULL, 0, &name, &hierarchy_id, &num, &enabled);
-                if (r < 0)
-                        return log_debug_errno(r, "Error parsing /proc/cgroups line, ignoring: %m");
-                else if (r < 4) {
-                        log_debug("Invalid /proc/cgroups line, ignoring.");
-                        continue;
-                }
-
-                /* Ignore disabled controllers. */
-                if (streq(enabled, "0"))
-                        continue;
-
-                /* Ignore controllers we don't care about. */
-                if (cgroup_controller_from_string(name) < 0)
-                        continue;
-
-                /* Since the unified cgroup doesn't use multiple hierarchies, if any controller has a
-                 * non-zero hierarchy_id that means it's in use already in a legacy (or hybrid) cgroup v1
-                 * hierarchy, and can't be used in a unified cgroup. */
-                if (!streq(hierarchy_id, "0")) {
-                        log_debug("Cgroup controller %s in use by legacy v1 hierarchy.", name);
-                        return 1;
-                }
-        }
-
-        return 0;
-}
-
-bool cg_is_unified_wanted(void) {
-        static thread_local int wanted = -1;
-        int r;
-
-        /* If we have a cached value, return that. */
-        if (wanted >= 0)
-                return wanted;
-
-        /* If the hierarchy is already mounted, then follow whatever was chosen for it. */
-        r = cg_unified_cached(true);
-        if (r >= 0)
-                return (wanted = r >= CGROUP_UNIFIED_ALL);
-
-        /* If we have explicit configuration for v1 or v2, respect that. */
-        if (cg_is_legacy_force_enabled())
-                return (wanted = false);
-
-        bool b;
-        r = proc_cmdline_get_bool("systemd.unified_cgroup_hierarchy", /* flags = */ 0, &b);
-        if (r > 0 && b)
-                return (wanted = true);
-
-        /* If we passed cgroup_no_v1=all with no other instructions, it seems highly unlikely that we want to
-         * use hybrid or legacy hierarchy. */
-        _cleanup_free_ char *c = NULL;
-        r = proc_cmdline_get_key("cgroup_no_v1", 0, &c);
-        if (r > 0 && streq_ptr(c, "all"))
-                return (wanted = true);
-
-        /* If any controller is in use as v1, don't use unified. */
-        if (cg_any_controller_used_for_v1() > 0)
-                return (wanted = false);
-
-        return (wanted = true);
-}
-
-bool cg_is_legacy_wanted(void) {
-        /* Check if we have cgroup v2 already mounted. */
-        if (cg_unified_cached(true) == CGROUP_UNIFIED_ALL)
-                return false;
-
-        /* Otherwise, assume that at least partial legacy is wanted,
-         * since cgroup v2 should already be mounted at this point. */
-        return true;
-}
-
-bool cg_is_hybrid_wanted(void) {
-        static thread_local int wanted = -1;
-        int r;
-
-        /* If we have a cached value, return that. */
-        if (wanted >= 0)
-                return wanted;
-
-        /* If the hierarchy is already mounted, then follow whatever was chosen for it. */
-        if (cg_unified_cached(true) == CGROUP_UNIFIED_ALL)
-                return (wanted = false);
-
-        /* Otherwise, let's see what the kernel command line has to say.  Since checking is expensive, cache
-         * a non-error result.
-         * The meaning of the kernel option is reversed wrt. to the return value of this function, hence the
-         * negation. */
-        bool b;
-        r = proc_cmdline_get_bool("systemd.legacy_systemd_cgroup_controller", /* flags = */ 0, &b);
-        if (r > 0)
-                return (wanted = !b);
-
-        /* The default hierarchy is "unified". But if this is reached, it means that unified hierarchy was
-         * not mounted, so return true too. */
-        return (wanted = true);
-}
-
-bool cg_is_legacy_enabled(void) {
-        int r;
-        bool b;
-
-        r = proc_cmdline_get_bool("systemd.unified_cgroup_hierarchy", /* flags = */ 0, &b);
-        return r > 0 && !b;
-}
-
-bool cg_is_legacy_force_enabled(void) {
-        int r;
-        bool b;
-
-        /* Require both systemd.unified_cgroup_hierarchy=0 and SYSTEMD_CGROUP_ENABLE_LEGACY_FORCE=1. */
-
-        if (!cg_is_legacy_enabled())
-                return false;
-
-        r = proc_cmdline_get_bool("SYSTEMD_CGROUP_ENABLE_LEGACY_FORCE", /* flags = */ 0, &b);
-        if (r <= 0 || !b)
-                return false;
-
-        return true;
-}
 
 int cg_weight_parse(const char *s, uint64_t *ret) {
         uint64_t u;
index 31c4ea1aced2c219a576625f147a540ad31445cb..6eecb9be10118744f261b016413991c71e0863a2 100644 (file)
@@ -7,12 +7,6 @@
 
 #include "cgroup-util.h"
 
-bool cg_is_unified_wanted(void);
-bool cg_is_legacy_wanted(void);
-bool cg_is_hybrid_wanted(void);
-bool cg_is_legacy_enabled(void);
-bool cg_is_legacy_force_enabled(void);
-
 int cg_weight_parse(const char *s, uint64_t *ret);
 int cg_cpu_weight_parse(const char *s, uint64_t *ret);
 int cg_cpu_shares_parse(const char *s, uint64_t *ret);
index 611d233167fda02fd0dccffee8d69b4df8f356b2..db963df39e6d4e2cd242d7431b6df4f2f7577992 100644 (file)
@@ -55,9 +55,6 @@ typedef struct MountPoint {
 bool cgroupfs_recursiveprot_supported(void) {
         int r;
 
-        if (!cg_is_unified_wanted())
-                return false;
-
         /* Added in kernel 5.7 */
 
         r = mount_option_supported("cgroup2", "memory_recursiveprot", /* value = */ NULL);
@@ -95,11 +92,9 @@ static const MountPoint mount_table[] = {
         { "tmpfs",       "/run",                      "tmpfs",      "mode=0755" TMPFS_LIMITS_RUN,               MS_NOSUID|MS_NODEV|MS_STRICTATIME,
           NULL,          MNT_FATAL|MNT_IN_CONTAINER },
         { "cgroup2",     "/sys/fs/cgroup",            "cgroup2",    "nsdelegate,memory_recursiveprot",          MS_NOSUID|MS_NOEXEC|MS_NODEV,
-          cgroupfs_recursiveprot_supported, MNT_IN_CONTAINER|MNT_CHECK_WRITABLE },
+          cgroupfs_recursiveprot_supported, MNT_FATAL|MNT_IN_CONTAINER|MNT_CHECK_WRITABLE },
         { "cgroup2",     "/sys/fs/cgroup",            "cgroup2",    "nsdelegate",                               MS_NOSUID|MS_NOEXEC|MS_NODEV,
-          cg_is_unified_wanted, MNT_IN_CONTAINER|MNT_CHECK_WRITABLE },
-        { "cgroup2",     "/sys/fs/cgroup",            "cgroup2",    NULL,                                       MS_NOSUID|MS_NOEXEC|MS_NODEV,
-          cg_is_unified_wanted, MNT_IN_CONTAINER|MNT_CHECK_WRITABLE },
+          NULL, MNT_FATAL|MNT_IN_CONTAINER|MNT_CHECK_WRITABLE },
 #if ENABLE_PSTORE
         { "pstore",      "/sys/fs/pstore",            "pstore",     NULL,                                       MS_NOSUID|MS_NOEXEC|MS_NODEV,
           NULL,          MNT_NONE                   },
index ec03ad2b7d2bdb0bea3f8e8267cee501fe363efd..e86a28f8761a86fff44fbfa6af221e150fc599aa 100644 (file)
@@ -55,7 +55,6 @@ simple_tests += files(
         'test-build-path.c',
         'test-bus-util.c',
         'test-calendarspec.c',
-        'test-cgroup-setup.c',
         'test-cgroup-util.c',
         'test-cgroup.c',
         'test-chase.c',
diff --git a/src/test/test-cgroup-setup.c b/src/test/test-cgroup-setup.c
deleted file mode 100644 (file)
index af57120..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1-or-later */
-
-#include <unistd.h>
-
-#include "alloc-util.h"
-#include "cgroup-setup.h"
-#include "errno-util.h"
-#include "log.h"
-#include "proc-cmdline.h"
-#include "string-util.h"
-#include "tests.h"
-
-static void test_is_wanted_print_one(bool header) {
-        _cleanup_free_ char *cmdline = NULL;
-
-        log_info("-- %s --", __func__);
-        ASSERT_OK(proc_cmdline(&cmdline));
-        log_info("cmdline: %s", cmdline);
-        if (header)
-                (void) system("findmnt -n /sys/fs/cgroup");
-
-        log_info("is_unified_wanted() → %s", yes_no(cg_is_unified_wanted()));
-        log_info("is_hybrid_wanted() → %s", yes_no(cg_is_hybrid_wanted()));
-        log_info("is_legacy_wanted() → %s", yes_no(cg_is_legacy_wanted()));
-        log_info(" ");
-}
-
-TEST(is_wanted_print) {
-        test_is_wanted_print_one(true);
-        test_is_wanted_print_one(false); /* run twice to test caching */
-}
-
-TEST(is_wanted) {
-        ASSERT_OK_ERRNO(setenv("SYSTEMD_PROC_CMDLINE",
-                               "systemd.unified_cgroup_hierarchy", 1));
-        test_is_wanted_print_one(false);
-
-        ASSERT_OK_ERRNO(setenv("SYSTEMD_PROC_CMDLINE",
-                               "systemd.unified_cgroup_hierarchy=0", 1));
-        test_is_wanted_print_one(false);
-
-        ASSERT_OK_ERRNO(setenv("SYSTEMD_PROC_CMDLINE",
-                               "systemd.unified_cgroup_hierarchy=0 "
-                               "systemd.legacy_systemd_cgroup_controller", 1));
-        test_is_wanted_print_one(false);
-
-        ASSERT_OK_ERRNO(setenv("SYSTEMD_PROC_CMDLINE",
-                               "systemd.unified_cgroup_hierarchy=0 "
-                               "systemd.legacy_systemd_cgroup_controller=0", 1));
-        test_is_wanted_print_one(false);
-
-        /* cgroup_no_v1=all implies unified cgroup hierarchy, unless otherwise
-         * explicitly specified. */
-        ASSERT_OK_ERRNO(setenv("SYSTEMD_PROC_CMDLINE",
-                               "cgroup_no_v1=all", 1));
-        test_is_wanted_print_one(false);
-
-        ASSERT_OK_ERRNO(setenv("SYSTEMD_PROC_CMDLINE",
-                               "cgroup_no_v1=all "
-                               "systemd.unified_cgroup_hierarchy=0", 1));
-        test_is_wanted_print_one(false);
-}
-
-static int intro(void) {
-        if (access("/proc/cmdline", R_OK) < 0 && ERRNO_IS_PRIVILEGE(errno))
-                return log_tests_skipped("can't read /proc/cmdline");
-
-        return EXIT_SUCCESS;
-}
-
-DEFINE_TEST_MAIN_WITH_INTRO(LOG_DEBUG, intro);