From c35a5857637fef063dda6e9acdfa0a215dd07303 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Mon, 7 Apr 2025 03:47:16 +0900 Subject: [PATCH] cgroup-setup: drop cgroup v1 support --- src/shared/cgroup-setup.c | 400 +------------------------------------- src/shared/cgroup-setup.h | 11 -- src/test/test-cgroup.c | 11 +- 3 files changed, 10 insertions(+), 412 deletions(-) diff --git a/src/shared/cgroup-setup.c b/src/shared/cgroup-setup.c index 269824dfc22..f2cb3e87938 100644 --- a/src/shared/cgroup-setup.c +++ b/src/shared/cgroup-setup.c @@ -51,52 +51,6 @@ int cg_cpu_weight_parse(const char *s, uint64_t *ret) { return cg_weight_parse(s, ret); } -int cg_cpu_shares_parse(const char *s, uint64_t *ret) { - uint64_t u; - int r; - - assert(s); - assert(ret); - - if (isempty(s)) { - *ret = CGROUP_CPU_SHARES_INVALID; - return 0; - } - - r = safe_atou64(s, &u); - if (r < 0) - return r; - - if (u < CGROUP_CPU_SHARES_MIN || u > CGROUP_CPU_SHARES_MAX) - return -ERANGE; - - *ret = u; - return 0; -} - -int cg_blkio_weight_parse(const char *s, uint64_t *ret) { - uint64_t u; - int r; - - assert(s); - assert(ret); - - if (isempty(s)) { - *ret = CGROUP_BLKIO_WEIGHT_INVALID; - return 0; - } - - r = safe_atou64(s, &u); - if (r < 0) - return r; - - if (u < CGROUP_BLKIO_WEIGHT_MIN || u > CGROUP_BLKIO_WEIGHT_MAX) - return -ERANGE; - - *ret = u; - return 0; -} - static int trim_cb( RecurseDirEvent event, const char *path, @@ -118,7 +72,7 @@ static int trim_cb( int cg_trim(const char *controller, const char *path, bool delete_root) { _cleanup_free_ char *fs = NULL; - int r, q; + int r; assert(controller); @@ -149,12 +103,6 @@ int cg_trim(const char *controller, const char *path, bool delete_root) { RET_GATHER(r, -errno); } - q = cg_hybrid_unified(); - if (q < 0) - return q; - if (q > 0 && streq(controller, SYSTEMD_CGROUP_CONTROLLER)) - (void) cg_trim(SYSTEMD_CGROUP_CONTROLLER_LEGACY, path, delete_root); - return r; } @@ -181,15 +129,6 @@ int cg_create(const char *controller, const char *path) { if (r < 0) return r; - r = cg_hybrid_unified(); - if (r < 0) - return r; - if (r > 0 && streq(controller, SYSTEMD_CGROUP_CONTROLLER)) { - r = cg_create(SYSTEMD_CGROUP_CONTROLLER_LEGACY, path); - if (r < 0) - log_warning_errno(r, "Failed to create compat systemd cgroup '%s', ignoring: %m", path); - } - return 1; } @@ -218,15 +157,6 @@ int cg_attach(const char *controller, const char *path, pid_t pid) { if (r < 0) return r; - r = cg_hybrid_unified(); - if (r < 0) - return r; - if (r > 0 && streq(controller, SYSTEMD_CGROUP_CONTROLLER)) { - r = cg_attach(SYSTEMD_CGROUP_CONTROLLER_LEGACY, path, pid); - if (r < 0) - log_warning_errno(r, "Failed to attach "PID_FMT" to compat systemd cgroup '%s', ignoring: %m", pid, path); - } - return 0; } @@ -244,31 +174,6 @@ int cg_fd_attach(int fd, pid_t pid) { return write_string_file_at(fd, "cgroup.procs", c, WRITE_STRING_FILE_DISABLE_BUFFER); } -int cg_attach_fallback(const char *controller, const char *path, pid_t pid) { - int r; - - assert(controller); - assert(path); - assert(pid >= 0); - - r = cg_attach(controller, path, pid); - if (r < 0) { - char prefix[strlen(path) + 1]; - - /* This didn't work? Then let's try all prefixes of the destination */ - - PATH_FOREACH_PREFIX(prefix, path) { - int q; - - q = cg_attach(controller, prefix, pid); - if (q >= 0) - return q; - } - } - - return r; -} - int cg_create_and_attach(const char *controller, const char *path, pid_t pid) { int r, q; @@ -293,47 +198,25 @@ int cg_set_access( uid_t uid, gid_t gid) { - struct Attribute { + static const struct { const char *name; bool fatal; - }; - - /* cgroup v1, aka legacy/non-unified */ - static const struct Attribute legacy_attributes[] = { - { "cgroup.procs", true }, - { "tasks", false }, - { "cgroup.clone_children", false }, - {}, - }; - - /* cgroup v2, aka unified */ - static const struct Attribute unified_attributes[] = { + } attributes[] = { { "cgroup.procs", true }, { "cgroup.subtree_control", true }, { "cgroup.threads", false }, { "memory.oom.group", false }, { "memory.reclaim", false }, - {}, - }; - - static const struct Attribute* const attributes[] = { - [false] = legacy_attributes, - [true] = unified_attributes, }; _cleanup_free_ char *fs = NULL; - const struct Attribute *i; - int r, unified; + int r; assert(path); if (uid == UID_INVALID && gid == GID_INVALID) return 0; - unified = cg_unified_controller(controller); - if (unified < 0) - return unified; - /* Configure access to the cgroup itself */ r = cg_get_path(controller, path, NULL, &fs); if (r < 0) @@ -344,7 +227,7 @@ int cg_set_access( return r; /* Configure access to the cgroup's attributes */ - for (i = attributes[unified]; i->name; i++) { + FOREACH_ELEMENT(i, attributes) { fs = mfree(fs); r = cg_get_path(controller, path, i->name, &fs); @@ -360,18 +243,6 @@ int cg_set_access( } } - if (streq(controller, SYSTEMD_CGROUP_CONTROLLER)) { - r = cg_hybrid_unified(); - if (r < 0) - return r; - if (r > 0) { - /* Always propagate access mode from unified to legacy controller */ - r = cg_set_access(SYSTEMD_CGROUP_CONTROLLER_LEGACY, path, uid, gid); - if (r < 0) - log_debug_errno(r, "Failed to set access on compatibility systemd cgroup %s, ignoring: %m", path); - } - } - return 0; } @@ -514,108 +385,15 @@ int cg_migrate( } int cg_create_everywhere(CGroupMask supported, CGroupMask mask, const char *path) { - CGroupController c; - CGroupMask done; - bool created; - int r; - - /* This one will create a cgroup in our private tree, but also - * duplicate it in the trees specified in mask, and remove it - * in all others. - * - * Returns 0 if the group already existed in the systemd hierarchy, - * 1 on success, negative otherwise. - */ - - /* First create the cgroup in our own hierarchy. */ - r = cg_create(SYSTEMD_CGROUP_CONTROLLER, path); - if (r < 0) - return r; - created = r; - - /* If we are in the unified hierarchy, we are done now */ - r = cg_all_unified(); - if (r < 0) - return r; - if (r > 0) - return created; - - supported &= CGROUP_MASK_V1; - mask = CGROUP_MASK_EXTEND_JOINED(mask); - done = 0; - - /* Otherwise, do the same in the other hierarchies */ - for (c = 0; c < _CGROUP_CONTROLLER_MAX; c++) { - CGroupMask bit = CGROUP_CONTROLLER_TO_MASK(c); - const char *n; - - if (!FLAGS_SET(supported, bit)) - continue; - - if (FLAGS_SET(done, bit)) - continue; - - n = cgroup_controller_to_string(c); - if (FLAGS_SET(mask, bit)) - (void) cg_create(n, path); - - done |= CGROUP_MASK_EXTEND_JOINED(bit); - } - - return created; + return cg_create(SYSTEMD_CGROUP_CONTROLLER, path); } int cg_attach_everywhere(CGroupMask supported, const char *path, pid_t pid) { - int r; - - assert(path); - assert(pid >= 0); - - r = cg_attach(SYSTEMD_CGROUP_CONTROLLER, path, pid); - if (r < 0) - return r; - - r = cg_all_unified(); - if (r < 0) - return r; - if (r > 0) - return 0; - - supported &= CGROUP_MASK_V1; - CGroupMask done = 0; - - for (CGroupController c = 0; c < _CGROUP_CONTROLLER_MAX; c++) { - CGroupMask bit = CGROUP_CONTROLLER_TO_MASK(c); - - if (!FLAGS_SET(supported, bit)) - continue; - - if (FLAGS_SET(done, bit)) - continue; - - (void) cg_attach_fallback(cgroup_controller_to_string(c), path, pid); - done |= CGROUP_MASK_EXTEND_JOINED(bit); - } - - return 0; + return cg_attach(SYSTEMD_CGROUP_CONTROLLER, path, pid); } int cg_trim_everywhere(CGroupMask supported, const char *path, bool delete_root) { - int r, q; - - assert(path); - - r = cg_trim(SYSTEMD_CGROUP_CONTROLLER, path, delete_root); - if (r < 0) - return r; - - q = cg_all_unified(); - if (q < 0) - return q; - if (q > 0) - return r; - - return cg_trim_v1_controllers(supported, _CGROUP_MASK_ALL, path, delete_root); + return cg_trim(SYSTEMD_CGROUP_CONTROLLER, path, delete_root); } int cg_enable_everywhere( @@ -638,26 +416,6 @@ int cg_enable_everywhere( return 0; } - r = cg_all_unified(); - if (r < 0) - return r; - if (r == 0) { - /* On the legacy hierarchy there's no concept of "enabling" controllers in cgroups defined. Let's claim - * complete success right away. (If you wonder why we return the full mask here, rather than zero: the - * caller tends to use the returned mask later on to compare if all controllers where properly joined, - * and if not requeues realization. This use is the primary purpose of the return value, hence let's - * minimize surprises here and reduce triggers for re-realization by always saying we fully - * succeeded.) */ - if (ret_result_mask) - *ret_result_mask = mask & supported & CGROUP_MASK_V2; /* If you wonder why we mask this with - * CGROUP_MASK_V2: The 'supported' mask - * might contain pure-V1 or BPF - * controllers, and we never want to - * claim that we could enable those with - * cgroup.subtree_control */ - return 0; - } - r = cg_get_path(SYSTEMD_CGROUP_CONTROLLER, p, "cgroup.subtree_control", &fs); if (r < 0) return r; @@ -726,148 +484,6 @@ int cg_enable_everywhere( return 0; } -int cg_migrate_recursive( - const char *cfrom, - const char *pfrom, - const char *cto, - const char *pto, - CGroupFlags flags) { - - _cleanup_closedir_ DIR *d = NULL; - int r, ret = 0; - char *fn; - - assert(cfrom); - assert(pfrom); - assert(cto); - assert(pto); - - ret = cg_migrate(cfrom, pfrom, cto, pto, flags); - - r = cg_enumerate_subgroups(cfrom, pfrom, &d); - if (r < 0) { - if (ret >= 0 && r != -ENOENT) - return r; - - return ret; - } - - while ((r = cg_read_subgroup(d, &fn)) > 0) { - _cleanup_free_ char *p = NULL; - - p = path_join(empty_to_root(pfrom), fn); - free(fn); - if (!p) - return -ENOMEM; - - r = cg_migrate_recursive(cfrom, p, cto, pto, flags); - if (r != 0 && ret >= 0) - ret = r; - } - - if (r < 0 && ret >= 0) - ret = r; - - return ret; -} - -int cg_migrate_recursive_fallback( - const char *cfrom, - const char *pfrom, - const char *cto, - const char *pto, - CGroupFlags flags) { - - int r; - - assert(cfrom); - assert(pfrom); - assert(cto); - assert(pto); - - r = cg_migrate_recursive(cfrom, pfrom, cto, pto, flags); - if (r < 0) { - char prefix[strlen(pto) + 1]; - - /* This didn't work? Then let's try all prefixes of the destination */ - - PATH_FOREACH_PREFIX(prefix, pto) { - int q; - - q = cg_migrate_recursive(cfrom, pfrom, cto, prefix, flags); - if (q >= 0) - return q; - } - } - - return r; -} - -int cg_migrate_v1_controllers(CGroupMask supported, CGroupMask mask, const char *from, cg_migrate_callback_t to_callback, void *userdata) { - CGroupController c; - CGroupMask done; - int r = 0, q; - - assert(to_callback); - - supported &= CGROUP_MASK_V1; - mask = CGROUP_MASK_EXTEND_JOINED(mask); - done = 0; - - for (c = 0; c < _CGROUP_CONTROLLER_MAX; c++) { - CGroupMask bit = CGROUP_CONTROLLER_TO_MASK(c); - const char *to = NULL; - - if (!FLAGS_SET(supported, bit)) - continue; - - if (FLAGS_SET(done, bit)) - continue; - - if (!FLAGS_SET(mask, bit)) - continue; - - to = to_callback(bit, userdata); - - /* Remember first error and try continuing */ - q = cg_migrate_recursive_fallback(SYSTEMD_CGROUP_CONTROLLER, from, cgroup_controller_to_string(c), to, 0); - r = (r < 0) ? r : q; - - done |= CGROUP_MASK_EXTEND_JOINED(bit); - } - - return r; -} - -int cg_trim_v1_controllers(CGroupMask supported, CGroupMask mask, const char *path, bool delete_root) { - CGroupController c; - CGroupMask done; - int r = 0, q; - - supported &= CGROUP_MASK_V1; - mask = CGROUP_MASK_EXTEND_JOINED(mask); - done = 0; - - for (c = 0; c < _CGROUP_CONTROLLER_MAX; c++) { - CGroupMask bit = CGROUP_CONTROLLER_TO_MASK(c); - - if (!FLAGS_SET(supported, bit)) - continue; - - if (FLAGS_SET(done, bit)) - continue; - - if (FLAGS_SET(mask, bit)) { - /* Remember first error and try continuing */ - q = cg_trim(cgroup_controller_to_string(c), path, delete_root); - r = (r < 0) ? r : q; - } - done |= CGROUP_MASK_EXTEND_JOINED(bit); - } - - return r; -} - int cg_has_legacy(void) { struct statfs fs; diff --git a/src/shared/cgroup-setup.h b/src/shared/cgroup-setup.h index b20de46894c..1427ccd2e28 100644 --- a/src/shared/cgroup-setup.h +++ b/src/shared/cgroup-setup.h @@ -9,15 +9,12 @@ 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); -int cg_blkio_weight_parse(const char *s, uint64_t *ret); int cg_trim(const char *controller, const char *path, bool delete_root); int cg_create(const char *controller, const char *path); int cg_attach(const char *controller, const char *path, pid_t pid); int cg_fd_attach(int fd, pid_t pid); -int cg_attach_fallback(const char *controller, const char *path, pid_t pid); int cg_create_and_attach(const char *controller, const char *path, pid_t pid); int cg_set_access(const char *controller, const char *path, uid_t uid, gid_t gid); @@ -30,12 +27,4 @@ int cg_enable_everywhere(CGroupMask supported, CGroupMask mask, const char *p, C int cg_migrate(const char *cfrom, const char *pfrom, const char *cto, const char *pto, CGroupFlags flags); -typedef const char* (*cg_migrate_callback_t)(CGroupMask mask, void *userdata); - -/* CGroup V1 specific */ -int cg_migrate_recursive(const char *cfrom, const char *pfrom, const char *cto, const char *pto, CGroupFlags flags); -int cg_migrate_recursive_fallback(const char *cfrom, const char *pfrom, const char *cto, const char *pto, CGroupFlags flags); -int cg_migrate_v1_controllers(CGroupMask supported, CGroupMask mask, const char *from, cg_migrate_callback_t to_callback, void *userdata); -int cg_trim_v1_controllers(CGroupMask supported, CGroupMask mask, const char *path, bool delete_root); - int cg_has_legacy(void); diff --git a/src/test/test-cgroup.c b/src/test/test-cgroup.c index dd7d2c578b4..e4fc5d5c62f 100644 --- a/src/test/test-cgroup.c +++ b/src/test/test-cgroup.c @@ -114,15 +114,8 @@ TEST(cg_create) { ASSERT_OK_ZERO(cg_kill_recursive(test_a, 0, 0, NULL, NULL, NULL)); ASSERT_OK_POSITIVE(cg_kill_recursive(test_b, 0, 0, NULL, NULL, NULL)); - ASSERT_OK_POSITIVE(cg_migrate_recursive(SYSTEMD_CGROUP_CONTROLLER, test_b, SYSTEMD_CGROUP_CONTROLLER, test_a, 0)); - - ASSERT_OK_ZERO(cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, test_a)); - ASSERT_OK_POSITIVE(cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, test_b)); - - ASSERT_OK_POSITIVE(cg_kill_recursive(test_a, 0, 0, NULL, NULL, NULL)); - ASSERT_OK_ZERO(cg_kill_recursive(test_b, 0, 0, NULL, NULL, NULL)); - - ASSERT_OK(cg_trim(SYSTEMD_CGROUP_CONTROLLER, test_b, true)); + ASSERT_OK(cg_trim(SYSTEMD_CGROUP_CONTROLLER, test_a, true)); + ASSERT_ERROR(cg_trim(SYSTEMD_CGROUP_CONTROLLER, test_b, true), EBUSY); } TEST(id) { -- 2.47.3