static int refresh_one( const char *controller, const char *path, Hashmap *a, Hashmap *b, unsigned iteration, unsigned depth) { DIR *d = NULL; int r; assert(controller); assert(path); assert(a); if (depth > arg_depth) return 0; r = process(controller, path, a, b, iteration); if (r < 0) return r; r = cg_enumerate_subgroups(controller, path, &d); if (r < 0) { if (r == -ENOENT) return 0; return r; } for (;;) { char *fn, *p; r = cg_read_subgroup(d, &fn); if (r <= 0) goto finish; p = strjoin(path, "/", fn, NULL); free(fn); if (!p) { r = -ENOMEM; goto finish; } path_kill_slashes(p); r = refresh_one(controller, p, a, b, iteration, depth + 1); free(p); if (r < 0) goto finish; } finish: if (d) closedir(d); return r; }
static int refresh(const char *root, Hashmap *a, Hashmap *b, unsigned iteration) { int r; assert(a); r = refresh_one(SYSTEMD_CGROUP_CONTROLLER, root, a, b, iteration, 0, NULL); if (r < 0) return r; r = refresh_one("cpu", root, a, b, iteration, 0, NULL); if (r < 0) return r; r = refresh_one("cpuacct", root, a, b, iteration, 0, NULL); if (r < 0) return r; r = refresh_one("memory", root, a, b, iteration, 0, NULL); if (r < 0) return r; r = refresh_one("io", root, a, b, iteration, 0, NULL); if (r < 0) return r; r = refresh_one("blkio", root, a, b, iteration, 0, NULL); if (r < 0) return r; r = refresh_one("pids", root, a, b, iteration, 0, NULL); if (r < 0) return r; return 0; }
static int refresh(Hashmap *a, Hashmap *b, unsigned iteration) { int r; assert(a); r = refresh_one("name=systemd", "/", a, b, iteration, 0); if (r < 0) if (r != -ENOENT) return r; r = refresh_one("cpuacct", "/", a, b, iteration, 0); if (r < 0) if (r != -ENOENT) return r; r = refresh_one("memory", "/", a, b, iteration, 0); if (r < 0) if (r != -ENOENT) return r; r = refresh_one("blkio", "/", a, b, iteration, 0); if (r < 0) if (r != -ENOENT) return r; return 0; }
static int refresh_one( const char *controller, const char *path, Hashmap *a, Hashmap *b, unsigned iteration, unsigned depth, Group **ret) { _cleanup_closedir_ DIR *d = NULL; Group *ours = NULL; int r; assert(controller); assert(path); assert(a); if (depth > arg_depth) return 0; r = process(controller, path, a, b, iteration, &ours); if (r < 0) return r; r = cg_enumerate_subgroups(controller, path, &d); if (r == -ENOENT) return 0; if (r < 0) return r; for (;;) { _cleanup_free_ char *fn = NULL, *p = NULL; Group *child = NULL; r = cg_read_subgroup(d, &fn); if (r < 0) return r; if (r == 0) break; p = strjoin(path, "/", fn, NULL); if (!p) return -ENOMEM; path_kill_slashes(p); r = refresh_one(controller, p, a, b, iteration, depth + 1, &child); if (r < 0) return r; if (arg_recursive && IN_SET(arg_count, COUNT_ALL_PROCESSES, COUNT_USERSPACE_PROCESSES) && child && child->n_tasks_valid && streq(controller, SYSTEMD_CGROUP_CONTROLLER)) { /* Recursively sum up processes */ if (ours->n_tasks_valid) ours->n_tasks += child->n_tasks; else { ours->n_tasks = child->n_tasks; ours->n_tasks_valid = true; } } } if (ret) *ret = ours; return 1; }