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().
}
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) {
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);
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;
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;
/* 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());
/* 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());
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) {
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));