]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
cgroup-util: drop handcrafted cg_is_empty(), always check cgroup.events populated...
authorMike Yuan <me@yhndnzj.com>
Mon, 26 May 2025 20:27:26 +0000 (22:27 +0200)
committerMike Yuan <me@yhndnzj.com>
Mon, 26 May 2025 20:59:48 +0000 (22:59 +0200)
This effectively renames cg_is_empty_recursive() to cg_is_empty().
Note that all existing code calls the former and not the latter,
hence with cgv1 support being dropped it's trivial to consult
cgroup.events directly for populated state everywhere.

Additionally, use more generic cg_get_keyed_attribute() helper
rather than cg_read_event().

src/basic/cgroup-util.c
src/basic/cgroup-util.h
src/core/cgroup.c
src/core/service.c
src/login/loginctl.c
src/machine/machinectl.c
src/shared/cgroup-show.c
src/test/test-cgroup.c

index 1c7524289245f9b89f609b06795212e7a919a79c..02398d074ad7d53cbc92373c4b595b2e7847e81b 100644 (file)
@@ -792,81 +792,25 @@ int cg_pidref_get_path(const char *controller, const PidRef *pidref, char **ret_
 }
 
 int cg_is_empty(const char *controller, const char *path) {
-        _cleanup_fclose_ FILE *f = NULL;
-        pid_t pid;
+        _cleanup_free_ char *t = NULL;
         int r;
 
-        assert(path);
-
-        r = cg_enumerate_processes(controller, path, &f);
-        if (r == -ENOENT)
-                return true;
-        if (r < 0)
-                return r;
-
-        r = cg_read_pid(f, &pid, CGROUP_DONT_SKIP_UNMAPPED);
-        if (r < 0)
-                return r;
-
-        return r == 0;
-}
-
-int cg_is_empty_recursive(const char *controller, const char *path) {
-        int r;
+        /* Check if the cgroup hierarchy under 'path' is empty. On cgroup v2 it's exposed via the "populated"
+         * attribute of "cgroup.events". */
 
         assert(path);
 
         /* The root cgroup is always populated */
-        if (controller && empty_or_root(path))
+        if (empty_or_root(path))
                 return false;
 
-        r = cg_unified_controller(controller);
+        r = cg_get_keyed_attribute(SYSTEMD_CGROUP_CONTROLLER, path, "cgroup.events", STRV_MAKE("populated"), &t);
+        if (r == -ENOENT)
+                return true;
         if (r < 0)
                 return r;
-        if (r > 0) {
-                _cleanup_free_ char *t = NULL;
-
-                /* On the unified hierarchy we can check empty state
-                 * via the "populated" attribute of "cgroup.events". */
-
-                r = cg_read_event(controller, path, "populated", &t);
-                if (r == -ENOENT)
-                        return true;
-                if (r < 0)
-                        return r;
-
-                return streq(t, "0");
-        } else {
-                _cleanup_closedir_ DIR *d = NULL;
-                char *fn;
-
-                r = cg_is_empty(controller, path);
-                if (r <= 0)
-                        return r;
-
-                r = cg_enumerate_subgroups(controller, path, &d);
-                if (r == -ENOENT)
-                        return true;
-                if (r < 0)
-                        return r;
 
-                while ((r = cg_read_subgroup(d, &fn)) > 0) {
-                        _cleanup_free_ char *p = NULL;
-
-                        p = path_join(path, fn);
-                        free(fn);
-                        if (!p)
-                                return -ENOMEM;
-
-                        r = cg_is_empty_recursive(controller, p);
-                        if (r <= 0)
-                                return r;
-                }
-                if (r < 0)
-                        return r;
-
-                return true;
-        }
+        return streq(t, "0");
 }
 
 int cg_split_spec(const char *spec, char **ret_controller, char **ret_path) {
index acb3427875eca28fdcb1dc5dd71a812d8c53a9f2..9f02e65410ae9fa0a562e65c15ddb7547b8bb5ac 100644 (file)
@@ -233,7 +233,6 @@ int cg_get_xattr_bool(const char *path, const char *name);
 int cg_remove_xattr(const char *path, const char *name);
 
 int cg_is_empty(const char *controller, const char *path);
-int cg_is_empty_recursive(const char *controller, const char *path);
 
 int cg_get_root_path(char **path);
 
index 61ac5b6f449389a57bdc7b075fba6b3f0f5419b5..abaffb22cde4bc949d90cef3835ae00bc8aa149e 100644 (file)
@@ -2760,7 +2760,7 @@ int unit_cgroup_is_empty(Unit *u) {
         if (!crt->cgroup_path)
                 return -EOWNERDEAD;
 
-        r = cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, crt->cgroup_path);
+        r = cg_is_empty(SYSTEMD_CGROUP_CONTROLLER, crt->cgroup_path);
         if (r < 0)
                 log_unit_debug_errno(u, r, "Failed to determine whether cgroup %s is empty: %m", empty_to_root(crt->cgroup_path));
         return r;
index d5874ce39383c2f8705e850c3d9e71c94e46075a..c976ee63e4f2c98f6cd42c9d3f0f84b7b9ddfbe0 100644 (file)
@@ -1976,7 +1976,7 @@ static int cgroup_good(Service *s) {
         if (!s->cgroup_runtime || !s->cgroup_runtime->cgroup_path)
                 return 0;
 
-        r = cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, s->cgroup_runtime->cgroup_path);
+        r = cg_is_empty(SYSTEMD_CGROUP_CONTROLLER, s->cgroup_runtime->cgroup_path);
         if (r < 0)
                 return r;
 
index 0f66c9dee663dd709d33329afccc9ef40f63c5bd..1cbbd4ecf72918cf62e3673adac78325bbd1a8b8 100644 (file)
@@ -457,7 +457,7 @@ static int show_unit_cgroup(
 
                 /* Fallback for older systemd versions where the GetUnitProcesses() call is not yet available */
 
-                if (cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, cgroup) != 0 && leader <= 0)
+                if (cg_is_empty(SYSTEMD_CGROUP_CONTROLLER, cgroup) != 0 && leader <= 0)
                         return 0;
 
                 show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER, cgroup, prefix, c, &leader, leader > 0, get_output_flags());
index d8dbaa09c53950ef6882a43acce6db420045f9d5..32849529c95393dd3ffa1d2f222e018269be0baf 100644 (file)
@@ -436,7 +436,7 @@ static int show_unit_cgroup(sd_bus *bus, const char *unit, pid_t leader) {
 
                 /* Fallback for older systemd versions where the GetUnitProcesses() call is not yet available */
 
-                if (cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, cgroup) != 0 && leader <= 0)
+                if (cg_is_empty(SYSTEMD_CGROUP_CONTROLLER, cgroup) != 0 && leader <= 0)
                         return 0;
 
                 show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER, cgroup, "\t\t  ", c, &leader, leader > 0, get_output_flags());
index 258229daf3d8c07338d152eedc0f406ff645c990..b95cecb3e66d3ff961d241ca229ee007a8344fb6 100644 (file)
@@ -251,7 +251,7 @@ int show_cgroup_by_path(
                 if (!k)
                         return -ENOMEM;
 
-                if (!(flags & OUTPUT_SHOW_ALL) && cg_is_empty_recursive(NULL, k) > 0)
+                if (!(flags & OUTPUT_SHOW_ALL) && cg_is_empty(NULL, k) > 0)
                         continue;
 
                 if (!shown_pids) {
index 4d1bbd4b342d667db7159b3ecb33c189d7c6cddf..31f2d87800a6c996d53d7215b3bbc5591182fb79 100644 (file)
@@ -106,9 +106,7 @@ TEST(cg_create) {
         free(path);
 
         ASSERT_OK_POSITIVE(cg_is_empty(SYSTEMD_CGROUP_CONTROLLER, test_a));
-        ASSERT_OK_POSITIVE(cg_is_empty(SYSTEMD_CGROUP_CONTROLLER, test_b));
-        ASSERT_OK_POSITIVE(cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, test_a));
-        ASSERT_OK_ZERO(cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, test_b));
+        ASSERT_OK_ZERO(cg_is_empty(SYSTEMD_CGROUP_CONTROLLER, test_b));
 
         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));