diff --git a/shell-completion/bash/systemd-cgtop b/shell-completion/bash/systemd-cgtop index a444b65064..325aa60de7 100644 --- a/shell-completion/bash/systemd-cgtop +++ b/shell-completion/bash/systemd-cgtop @@ -59,9 +59,7 @@ _systemd_cgtop() { fi COMPREPLY=( $(compgen -W '${OPTS[*]}' -- "$cur") ) - if [ -d /sys/fs/cgroup/systemd/ ]; then - COMPREPLY+=( $(cd /sys/fs/cgroup/systemd/ && compgen -o nospace -o dirnames "$cur") ) - elif [ -d /sys/fs/cgroup/ ]; then + if [ -d /sys/fs/cgroup/ ]; then COMPREPLY+=( $(cd /sys/fs/cgroup/ && compgen -o nospace -o dirnames "$cur") ) fi } diff --git a/shell-completion/zsh/_systemd b/shell-completion/zsh/_systemd index 4d9ec7f032..f555abd06b 100644 --- a/shell-completion/zsh/_systemd +++ b/shell-completion/zsh/_systemd @@ -28,8 +28,7 @@ case "$service" in '(- *)--version[Show package version]' \ '--no-pager[Do not pipe output into a pager]' \ '(-a --all)'{-a,--all}'[Show all groups, including empty]' \ - '-k[Include kernel threads in output]' \ - ':cgroups:(cpuset cpu cpuacct memory devices freezer blkio)' + '-k[Include kernel threads in output]' ;; systemd-cgtop) _arguments \ diff --git a/src/basic/cgroup-util.c b/src/basic/cgroup-util.c index 97f0bc741f..207f5428b7 100644 --- a/src/basic/cgroup-util.c +++ b/src/basic/cgroup-util.c @@ -50,11 +50,24 @@ typedef union { /* The .f_handle field is not aligned to 64bit on some archs, hence read it via an unaligned accessor */ #define CG_FILE_HANDLE_CGROUPID(fh) unaligned_read_ne64(fh.file_handle.f_handle) -int cg_path_open(const char *controller, const char *path) { +int cg_is_available(void) { + struct statfs fs; + + if (statfs("/sys/fs/cgroup/", &fs) < 0) { + if (errno == ENOENT) /* sysfs not mounted? */ + return false; + + return log_debug_errno(errno, "Failed to statfs /sys/fs/cgroup/: %m"); + } + + return is_fs_type(&fs, CGROUP2_SUPER_MAGIC); +} + +int cg_path_open(const char *path) { _cleanup_free_ char *fs = NULL; int r; - r = cg_get_path(controller, path, /* suffix=*/ NULL, &fs); + r = cg_get_path(path, /* suffix= */ NULL, &fs); if (r < 0) return r; @@ -117,14 +130,14 @@ int cg_get_cgroupid_at(int dfd, const char *path, uint64_t *ret) { return 0; } -int cg_enumerate_processes(const char *controller, const char *path, FILE **ret) { +int cg_enumerate_processes(const char *path, FILE **ret) { _cleanup_free_ char *fs = NULL; FILE *f; int r; assert(ret); - r = cg_get_path(controller, path, "cgroup.procs", &fs); + r = cg_get_path(path, "cgroup.procs", &fs); if (r < 0) return r; @@ -209,7 +222,7 @@ bool cg_kill_supported(void) { if (supported >= 0) return supported; - if (cg_all_unified() <= 0) + if (cg_is_available() <= 0) return (supported = false); if (access("/sys/fs/cgroup/init.scope/cgroup.kill", F_OK) >= 0) @@ -219,7 +232,7 @@ bool cg_kill_supported(void) { return (supported = false); } -int cg_enumerate_subgroups(const char *controller, const char *path, DIR **ret) { +int cg_enumerate_subgroups(const char *path, DIR **ret) { _cleanup_free_ char *fs = NULL; DIR *d; int r; @@ -228,7 +241,7 @@ int cg_enumerate_subgroups(const char *controller, const char *path, DIR **ret) /* This is not recursive! */ - r = cg_get_path(controller, path, NULL, &fs); + r = cg_get_path(path, /* suffix = */ NULL, &fs); if (r < 0) return r; @@ -295,7 +308,7 @@ int cg_kill( done = true; - r = cg_enumerate_processes(SYSTEMD_CGROUP_CONTROLLER, path, &f); + r = cg_enumerate_processes(path, &f); if (r == -ENOENT) break; if (r < 0) @@ -386,7 +399,7 @@ int cg_kill_recursive( ret = cg_kill(path, sig, flags, killed_pids, log_kill, userdata); - r = cg_enumerate_subgroups(SYSTEMD_CGROUP_CONTROLLER, path, &d); + r = cg_enumerate_subgroups(path, &d); if (r < 0) { if (r != -ENOENT) RET_GATHER(ret, log_debug_errno(r, "Failed to enumerate cgroup '%s' subgroups: %m", path)); @@ -431,7 +444,7 @@ int cg_kill_kernel_sigkill(const char *path) { if (!cg_kill_supported()) return -EOPNOTSUPP; - r = cg_get_path(SYSTEMD_CGROUP_CONTROLLER, path, "cgroup.kill", &killfile); + r = cg_get_path(path, "cgroup.kill", &killfile); if (r < 0) return r; @@ -442,153 +455,22 @@ int cg_kill_kernel_sigkill(const char *path) { return 0; } -static const char *controller_to_dirname(const char *controller) { - assert(controller); - - /* Converts a controller name to the directory name below /sys/fs/cgroup/ we want to mount it - * to. Effectively, this just cuts off the name= prefixed used for named hierarchies, if it is - * specified. */ - - if (streq(controller, SYSTEMD_CGROUP_CONTROLLER)) { - if (cg_hybrid_unified() > 0) - controller = SYSTEMD_CGROUP_CONTROLLER_HYBRID; - else - controller = SYSTEMD_CGROUP_CONTROLLER_LEGACY; - } - - return startswith(controller, "name=") ?: controller; -} - -static int join_path_legacy(const char *controller, const char *path, const char *suffix, char **ret) { - const char *dn; - char *t = NULL; - - assert(ret); - assert(controller); - - dn = controller_to_dirname(controller); - - if (isempty(path) && isempty(suffix)) - t = path_join("/sys/fs/cgroup", dn); - else if (isempty(path)) - t = path_join("/sys/fs/cgroup", dn, suffix); - else if (isempty(suffix)) - t = path_join("/sys/fs/cgroup", dn, path); - else - t = path_join("/sys/fs/cgroup", dn, path, suffix); - if (!t) - return -ENOMEM; - - *ret = t; - return 0; -} - -static int join_path_unified(const char *path, const char *suffix, char **ret) { +int cg_get_path(const char *path, const char *suffix, char **ret) { char *t; assert(ret); - if (isempty(path) && isempty(suffix)) - t = strdup("/sys/fs/cgroup"); - else if (isempty(path)) - t = path_join("/sys/fs/cgroup", suffix); - else if (isempty(suffix)) - t = path_join("/sys/fs/cgroup", path); - else - t = path_join("/sys/fs/cgroup", path, suffix); + if (isempty(path)) + path = TAKE_PTR(suffix); + + t = path_join("/sys/fs/cgroup", path, suffix); if (!t) return -ENOMEM; - *ret = t; + *ret = path_simplify(t); return 0; } -int cg_get_path(const char *controller, const char *path, const char *suffix, char **ret) { - int r; - - assert(ret); - - if (!controller) { - char *t; - - /* If no controller is specified, we return the path *below* the controllers, without any - * prefix. */ - - if (isempty(path) && isempty(suffix)) - return -EINVAL; - - if (isempty(suffix)) - t = strdup(path); - else if (isempty(path)) - t = strdup(suffix); - else - t = path_join(path, suffix); - if (!t) - return -ENOMEM; - - *ret = path_simplify(t); - return 0; - } - - if (!cg_controller_is_valid(controller)) - return -EINVAL; - - r = cg_all_unified(); - if (r < 0) - return r; - if (r > 0) - r = join_path_unified(path, suffix, ret); - else - r = join_path_legacy(controller, path, suffix, ret); - if (r < 0) - return r; - - path_simplify(*ret); - return 0; -} - -static int controller_is_v1_accessible(const char *root, const char *controller) { - const char *cpath, *dn; - - assert(controller); - - dn = controller_to_dirname(controller); - - /* If root if specified, we check that: - * - possible subcgroup is created at root, - * - we can modify the hierarchy. */ - - cpath = strjoina("/sys/fs/cgroup/", dn, root, root ? "/cgroup.procs" : NULL); - return access_nofollow(cpath, root ? W_OK : F_OK); -} - -int cg_get_path_and_check(const char *controller, const char *path, const char *suffix, char **ret) { - int r; - - assert(controller); - assert(ret); - - if (!cg_controller_is_valid(controller)) - return -EINVAL; - - r = cg_all_unified(); - if (r < 0) - return r; - if (r > 0) { - /* In the unified hierarchy all controllers are considered accessible, - * except for the named hierarchies */ - if (startswith(controller, "name=")) - return -EOPNOTSUPP; - } else { - /* Check if the specified controller is actually accessible */ - r = controller_is_v1_accessible(NULL, controller); - if (r < 0) - return r; - } - - return cg_get_path(controller, path, suffix, ret); -} - int cg_set_xattr(const char *path, const char *name, const void *value, size_t size, int flags) { _cleanup_free_ char *fs = NULL; int r; @@ -597,7 +479,7 @@ int cg_set_xattr(const char *path, const char *name, const void *value, size_t s assert(name); assert(value || size <= 0); - r = cg_get_path(SYSTEMD_CGROUP_CONTROLLER, path, NULL, &fs); + r = cg_get_path(path, /* suffix = */ NULL, &fs); if (r < 0) return r; @@ -611,7 +493,7 @@ int cg_get_xattr(const char *path, const char *name, char **ret, size_t *ret_siz assert(path); assert(name); - r = cg_get_path(SYSTEMD_CGROUP_CONTROLLER, path, NULL, &fs); + r = cg_get_path(path, /* suffix = */ NULL, &fs); if (r < 0) return r; @@ -625,7 +507,7 @@ int cg_get_xattr_bool(const char *path, const char *name) { assert(path); assert(name); - r = cg_get_path(SYSTEMD_CGROUP_CONTROLLER, path, NULL, &fs); + r = cg_get_path(path, /* suffix = */ NULL, &fs); if (r < 0) return r; @@ -639,37 +521,21 @@ int cg_remove_xattr(const char *path, const char *name) { assert(path); assert(name); - r = cg_get_path(SYSTEMD_CGROUP_CONTROLLER, path, NULL, &fs); + r = cg_get_path(path, /* suffix = */ NULL, &fs); if (r < 0) return r; return RET_NERRNO(removexattr(fs, name)); } -int cg_pid_get_path(const char *controller, pid_t pid, char **ret_path) { +int cg_pid_get_path(pid_t pid, char **ret_path) { _cleanup_fclose_ FILE *f = NULL; - const char *fs, *controller_str = NULL; /* avoid false maybe-uninitialized warning */ - int unified, r; + const char *fs; + int r; assert(pid >= 0); assert(ret_path); - if (controller) { - if (!cg_controller_is_valid(controller)) - return -EINVAL; - } else - controller = SYSTEMD_CGROUP_CONTROLLER; - - unified = cg_unified_controller(controller); - if (unified < 0) - return unified; - if (unified == 0) { - if (streq(controller, SYSTEMD_CGROUP_CONTROLLER)) - controller_str = SYSTEMD_CGROUP_CONTROLLER_LEGACY; - else - controller_str = controller; - } - fs = procfs_file_alloca(pid, "cgroup"); r = fopen_unlocked(fs, "re", &f); if (r == -ENOENT) @@ -687,34 +553,13 @@ int cg_pid_get_path(const char *controller, pid_t pid, char **ret_path) { if (r == 0) return -ENODATA; - if (unified) { - e = startswith(line, "0:"); - if (!e) - continue; + e = startswith(line, "0:"); + if (!e) + continue; - e = strchr(e, ':'); - if (!e) - continue; - } else { - char *l; - - l = strchr(line, ':'); - if (!l) - continue; - - l++; - e = strchr(l, ':'); - if (!e) - continue; - *e = 0; - - assert(controller_str); - r = string_contains_word(l, ",", controller_str); - if (r < 0) - return r; - if (r == 0) - continue; - } + e = strchr(e, ':'); + if (!e) + continue; _cleanup_free_ char *path = strdup(e + 1); if (!path) @@ -734,7 +579,7 @@ int cg_pid_get_path(const char *controller, pid_t pid, char **ret_path) { } } -int cg_pidref_get_path(const char *controller, const PidRef *pidref, char **ret_path) { +int cg_pidref_get_path(const PidRef *pidref, char **ret_path) { _cleanup_free_ char *path = NULL; int r; @@ -749,7 +594,7 @@ int cg_pidref_get_path(const char *controller, const PidRef *pidref, char **ret_ // bit of information from pidfd directly. However, the latter requires privilege and it's // not entirely clear how to handle cgroups from outer namespace. - r = cg_pid_get_path(controller, pidref->pid, &path); + r = cg_pid_get_path(pidref->pid, &path); if (r < 0) return r; @@ -762,7 +607,7 @@ int cg_pidref_get_path(const char *controller, const PidRef *pidref, char **ret_ return 0; } -int cg_is_empty(const char *controller, const char *path) { +int cg_is_empty(const char *path) { _cleanup_free_ char *t = NULL; int r; @@ -775,7 +620,7 @@ int cg_is_empty(const char *controller, const char *path) { if (empty_or_root(path)) return false; - r = cg_get_keyed_attribute(controller, path, "cgroup.events", STRV_MAKE("populated"), &t); + r = cg_get_keyed_attribute(path, "cgroup.events", STRV_MAKE("populated"), &t); if (r == -ENOENT) return true; if (r < 0) @@ -785,89 +630,74 @@ int cg_is_empty(const char *controller, const char *path) { } int cg_split_spec(const char *spec, char **ret_controller, char **ret_path) { - _cleanup_free_ char *controller = NULL, *path = NULL; + _cleanup_free_ char *controller = NULL; + const char *path; int r; assert(spec); - if (*spec == '/') { - if (!path_is_normalized(spec)) - return -EINVAL; + /* This extracts the path part from the deprecated controller:path spec. The path must be absolute or + * an empty string. No validation is done for the controller part. */ - if (ret_path) { - r = path_simplify_alloc(spec, &path); - if (r < 0) - return r; - } + if (isempty(spec) || path_is_absolute(spec)) { + /* Assume this does not contain controller. */ + path = spec; + goto finalize; + } - } else { - const char *e; - - e = strchr(spec, ':'); - if (e) { - controller = strndup(spec, e-spec); + const char *e = strchr(spec, ':'); + if (!e) { + /* Controller only. */ + if (ret_controller) { + controller = strdup(spec); if (!controller) return -ENOMEM; - if (!cg_controller_is_valid(controller)) - return -EINVAL; - - if (!isempty(e + 1)) { - path = strdup(e+1); - if (!path) - return -ENOMEM; - - if (!path_is_normalized(path) || - !path_is_absolute(path)) - return -EINVAL; - - path_simplify(path); - } - - } else { - if (!cg_controller_is_valid(spec)) - return -EINVAL; - - if (ret_controller) { - controller = strdup(spec); - if (!controller) - return -ENOMEM; - } } + + path = NULL; + } else { + /* Both controller and path. */ + if (ret_controller) { + controller = strndup(spec, e - spec); + if (!controller) + return -ENOMEM; + } + + path = e + 1; + } + +finalize: + path = empty_to_null(path); + + if (path) { + /* Non-empty path must be absolute. */ + if (!path_is_absolute(path)) + return -EINVAL; + + /* Path must not contain dot-dot. */ + if (!path_is_safe(path)) + return -EINVAL; + } + + if (ret_path) { + r = path_simplify_alloc(path, ret_path); + if (r < 0) + return r; } if (ret_controller) *ret_controller = TAKE_PTR(controller); - if (ret_path) - *ret_path = TAKE_PTR(path); + return 0; } -int cg_mangle_path(const char *path, char **ret) { - _cleanup_free_ char *c = NULL, *p = NULL; - int r; - - assert(path); - assert(ret); - - /* First, check if it already is a filesystem path */ - if (path_startswith(path, "/sys/fs/cgroup")) - return path_simplify_alloc(path, ret); - - /* Otherwise, treat it as cg spec */ - r = cg_split_spec(path, &c, &p); - if (r < 0) - return r; - - return cg_get_path(c ?: SYSTEMD_CGROUP_CONTROLLER, p ?: "/", NULL, ret); -} - int cg_get_root_path(char **ret_path) { char *p, *e; int r; assert(ret_path); - r = cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, 1, &p); + r = cg_pid_get_path(1, &p); if (r < 0) return r; @@ -909,7 +739,7 @@ int cg_pid_get_path_shifted(pid_t pid, const char *root, char **ret_cgroup) { assert(pid >= 0); assert(ret_cgroup); - r = cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, pid, &raw); + r = cg_pid_get_path(pid, &raw); if (r < 0) return r; @@ -1488,36 +1318,6 @@ char* cg_unescape(const char *p) { return (char*) p; } -#define CONTROLLER_VALID \ - DIGITS LETTERS \ - "_" - -bool cg_controller_is_valid(const char *p) { - const char *t, *s; - - if (!p) - return false; - - if (streq(p, SYSTEMD_CGROUP_CONTROLLER)) - return true; - - s = startswith(p, "name="); - if (s) - p = s; - - if (IN_SET(*p, 0, '_')) - return false; - - for (t = p; *t; t++) - if (!strchr(CONTROLLER_VALID, *t)) - return false; - - if (t - p > NAME_MAX) - return false; - - return true; -} - int cg_slice_to_path(const char *unit, char **ret) { _cleanup_free_ char *p = NULL, *s = NULL, *e = NULL; const char *dash; @@ -1591,7 +1391,7 @@ int cg_is_threaded(const char *path) { _cleanup_strv_free_ char **v = NULL; int r; - r = cg_get_path(SYSTEMD_CGROUP_CONTROLLER, path, "cgroup.type", &fs); + r = cg_get_path(path, "cgroup.type", &fs); if (r < 0) return r; @@ -1610,13 +1410,13 @@ int cg_is_threaded(const char *path) { return strv_contains(v, "threaded") || strv_contains(v, "invalid"); } -int cg_set_attribute(const char *controller, const char *path, const char *attribute, const char *value) { +int cg_set_attribute(const char *path, const char *attribute, const char *value) { _cleanup_free_ char *p = NULL; int r; assert(attribute); - r = cg_get_path(controller, path, attribute, &p); + r = cg_get_path(path, attribute, &p); if (r < 0) return r; @@ -1628,27 +1428,27 @@ int cg_set_attribute(const char *controller, const char *path, const char *attri return write_string_file(p, value, WRITE_STRING_FILE_DISABLE_BUFFER|WRITE_STRING_FILE_OPEN_NONBLOCKING); } -int cg_get_attribute(const char *controller, const char *path, const char *attribute, char **ret) { +int cg_get_attribute(const char *path, const char *attribute, char **ret) { _cleanup_free_ char *p = NULL; int r; assert(attribute); - r = cg_get_path(controller, path, attribute, &p); + r = cg_get_path(path, attribute, &p); if (r < 0) return r; return read_one_line_file(p, ret); } -int cg_get_attribute_as_uint64(const char *controller, const char *path, const char *attribute, uint64_t *ret) { +int cg_get_attribute_as_uint64(const char *path, const char *attribute, uint64_t *ret) { _cleanup_free_ char *value = NULL; uint64_t v; int r; assert(ret); - r = cg_get_attribute(controller, path, attribute, &value); + r = cg_get_attribute(path, attribute, &value); if (r == -ENOENT) return -ENODATA; if (r < 0) @@ -1667,11 +1467,11 @@ int cg_get_attribute_as_uint64(const char *controller, const char *path, const c return 0; } -int cg_get_attribute_as_bool(const char *controller, const char *path, const char *attribute) { +int cg_get_attribute_as_bool(const char *path, const char *attribute) { _cleanup_free_ char *value = NULL; int r; - r = cg_get_attribute(controller, path, attribute, &value); + r = cg_get_attribute(path, attribute, &value); if (r == -ENOENT) return -ENODATA; if (r < 0) @@ -1687,7 +1487,7 @@ int cg_get_owner(const char *path, uid_t *ret_uid) { assert(ret_uid); - r = cg_get_path(SYSTEMD_CGROUP_CONTROLLER, path, NULL, &f); + r = cg_get_path(path, /* suffix = */ NULL, &f); if (r < 0) return r; @@ -1703,7 +1503,6 @@ int cg_get_owner(const char *path, uid_t *ret_uid) { } int cg_get_keyed_attribute( - const char *controller, const char *path, const char *attribute, char * const *keys, @@ -1722,7 +1521,7 @@ int cg_get_keyed_attribute( * * If the attribute file doesn't exist at all returns ENOENT, if any key is not found returns ENXIO. */ - r = cg_get_path(controller, path, attribute, &filename); + r = cg_get_path(path, attribute, &filename); if (r < 0) return r; @@ -1865,48 +1664,22 @@ int cg_mask_supported_subtree(const char *root, CGroupMask *ret) { * are actually accessible. Only covers real controllers, i.e. not the CGROUP_CONTROLLER_BPF_xyz * pseudo-controllers. */ - r = cg_all_unified(); + /* We can read the supported and accessible controllers from the top-level cgroup attribute */ + _cleanup_free_ char *controllers = NULL, *path = NULL; + r = cg_get_path(root, "cgroup.controllers", &path); if (r < 0) return r; - if (r > 0) { - _cleanup_free_ char *controllers = NULL, *path = NULL; - /* In the unified hierarchy we can read the supported and accessible controllers from - * the top-level cgroup attribute */ + r = read_one_line_file(path, &controllers); + if (r < 0) + return r; - r = cg_get_path(SYSTEMD_CGROUP_CONTROLLER, root, "cgroup.controllers", &path); - if (r < 0) - return r; + r = cg_mask_from_string(controllers, &mask); + if (r < 0) + return r; - r = read_one_line_file(path, &controllers); - if (r < 0) - return r; - - r = cg_mask_from_string(controllers, &mask); - if (r < 0) - return r; - - /* Mask controllers that are not supported in unified hierarchy. */ - mask &= CGROUP_MASK_V2; - - } else { - CGroupController c; - - /* In the legacy hierarchy, we check which hierarchies are accessible. */ - - mask = 0; - for (c = 0; c < _CGROUP_CONTROLLER_MAX; c++) { - CGroupMask bit = CGROUP_CONTROLLER_TO_MASK(c); - const char *n; - - if (!FLAGS_SET(CGROUP_MASK_V1, bit)) - continue; - - n = cgroup_controller_to_string(c); - if (controller_is_v1_accessible(root, n) >= 0) - mask |= bit; - } - } + /* Mask controllers that are not supported in cgroup v2. */ + mask &= CGROUP_MASK_V2; *ret = mask; return 0; @@ -1923,115 +1696,6 @@ int cg_mask_supported(CGroupMask *ret) { return cg_mask_supported_subtree(root, ret); } -/* The hybrid mode was initially implemented in v232 and simply mounted cgroup2 on - * /sys/fs/cgroup/systemd. This unfortunately broke other tools (such as docker) which expected the v1 - * "name=systemd" hierarchy on /sys/fs/cgroup/systemd. From v233 and on, the hybrid mode mounts v2 on - * /sys/fs/cgroup/unified and maintains "name=systemd" hierarchy on /sys/fs/cgroup/systemd for compatibility - * with other tools. - * - * To keep live upgrade working, we detect and support v232 layout. When v232 layout is detected, to keep - * cgroup v2 process management but disable the compat dual layout, we return true on - * cg_unified_controller(SYSTEMD_CGROUP_CONTROLLER) and false on cg_hybrid_unified(). - */ -static thread_local bool unified_systemd_v232; - -int cg_unified_cached(bool flush) { - static thread_local CGroupUnified unified_cache = CGROUP_UNIFIED_UNKNOWN; - - struct statfs fs; - - /* Checks if we support the unified hierarchy. Returns an - * error when the cgroup hierarchies aren't mounted yet or we - * have any other trouble determining if the unified hierarchy - * is supported. */ - - if (flush) - unified_cache = CGROUP_UNIFIED_UNKNOWN; - else if (unified_cache >= CGROUP_UNIFIED_NONE) - return unified_cache; - - if (statfs("/sys/fs/cgroup/", &fs) < 0) - return log_debug_errno(errno, "statfs(\"/sys/fs/cgroup/\") failed: %m"); - - if (F_TYPE_EQUAL(fs.f_type, CGROUP2_SUPER_MAGIC)) { - log_debug("Found cgroup2 on /sys/fs/cgroup/, full unified hierarchy"); - unified_cache = CGROUP_UNIFIED_ALL; - } else if (F_TYPE_EQUAL(fs.f_type, TMPFS_MAGIC)) { - if (statfs("/sys/fs/cgroup/unified/", &fs) == 0 && - F_TYPE_EQUAL(fs.f_type, CGROUP2_SUPER_MAGIC)) { - log_debug("Found cgroup2 on /sys/fs/cgroup/unified, unified hierarchy for systemd controller"); - unified_cache = CGROUP_UNIFIED_SYSTEMD; - unified_systemd_v232 = false; - } else { - if (statfs("/sys/fs/cgroup/systemd/", &fs) < 0) { - if (errno == ENOENT) { - /* Some other software may have set up /sys/fs/cgroup in a configuration we do not recognize. */ - log_debug_errno(errno, "Unsupported cgroupsv1 setup detected: name=systemd hierarchy not found."); - return -ENOMEDIUM; - } - return log_debug_errno(errno, "statfs(\"/sys/fs/cgroup/systemd\" failed: %m"); - } - - if (F_TYPE_EQUAL(fs.f_type, CGROUP2_SUPER_MAGIC)) { - log_debug("Found cgroup2 on /sys/fs/cgroup/systemd, unified hierarchy for systemd controller (v232 variant)"); - unified_cache = CGROUP_UNIFIED_SYSTEMD; - unified_systemd_v232 = true; - } else if (F_TYPE_EQUAL(fs.f_type, CGROUP_SUPER_MAGIC)) { - log_debug("Found cgroup on /sys/fs/cgroup/systemd, legacy hierarchy"); - unified_cache = CGROUP_UNIFIED_NONE; - } else { - log_debug("Unexpected filesystem type %llx mounted on /sys/fs/cgroup/systemd, assuming legacy hierarchy", - (unsigned long long) fs.f_type); - unified_cache = CGROUP_UNIFIED_NONE; - } - } - } else if (F_TYPE_EQUAL(fs.f_type, SYSFS_MAGIC)) { - return log_debug_errno(SYNTHETIC_ERRNO(ENOMEDIUM), - "No filesystem is currently mounted on /sys/fs/cgroup."); - } else - return log_debug_errno(SYNTHETIC_ERRNO(ENOMEDIUM), - "Unknown filesystem type %llx mounted on /sys/fs/cgroup.", - (unsigned long long)fs.f_type); - - return unified_cache; -} - -int cg_unified_controller(const char *controller) { - int r; - - r = cg_unified_cached(false); - if (r < 0) - return r; - - if (r == CGROUP_UNIFIED_NONE) - return false; - - if (r >= CGROUP_UNIFIED_ALL) - return true; - - return streq_ptr(controller, SYSTEMD_CGROUP_CONTROLLER); -} - -int cg_all_unified(void) { - int r; - - r = cg_unified_cached(false); - if (r < 0) - return r; - - return r >= CGROUP_UNIFIED_ALL; -} - -int cg_hybrid_unified(void) { - int r; - - r = cg_unified_cached(false); - if (r < 0) - return r; - - return r == CGROUP_UNIFIED_SYSTEMD && !unified_systemd_v232; -} - int cg_is_delegated(const char *path) { int r; diff --git a/src/basic/cgroup-util.h b/src/basic/cgroup-util.h index 8ed8d7704c..f494617ffa 100644 --- a/src/basic/cgroup-util.h +++ b/src/basic/cgroup-util.h @@ -3,8 +3,6 @@ #include "basic-forward.h" -#define SYSTEMD_CGROUP_CONTROLLER_LEGACY "name=systemd" -#define SYSTEMD_CGROUP_CONTROLLER_HYBRID "name=unified" #define SYSTEMD_CGROUP_CONTROLLER "_systemd" /* An enum of well known cgroup controllers */ @@ -113,29 +111,16 @@ static inline uint64_t BFQ_WEIGHT(uint64_t io_weight) { CGROUP_BFQ_WEIGHT_DEFAULT + (io_weight - CGROUP_WEIGHT_DEFAULT) * (CGROUP_BFQ_WEIGHT_MAX - CGROUP_BFQ_WEIGHT_DEFAULT) / (CGROUP_WEIGHT_MAX - CGROUP_WEIGHT_DEFAULT); } -typedef enum CGroupUnified { - CGROUP_UNIFIED_UNKNOWN = -1, - CGROUP_UNIFIED_NONE = 0, /* Both systemd and controllers on legacy */ - CGROUP_UNIFIED_SYSTEMD = 1, /* Only systemd on unified */ - CGROUP_UNIFIED_ALL = 2, /* Both systemd and controllers on unified */ -} CGroupUnified; - /* * General rules: * - * We accept named hierarchies in the syntax "foo" and "name=foo". - * - * We expect that named hierarchies do not conflict in name with a - * kernel hierarchy, modulo the "name=" prefix. - * - * We always generate "normalized" controller names, i.e. without the - * "name=" prefix. - * * We require absolute cgroup paths. When returning, we will always * generate paths with multiple adjacent / removed. */ -int cg_path_open(const char *controller, const char *path); +int cg_is_available(void); + +int cg_path_open(const char *path); int cg_cgroupid_open(int cgroupfs_fd, uint64_t id); int cg_path_from_cgroupid(int cgroupfs_fd, uint64_t id, char **ret); @@ -153,11 +138,11 @@ typedef enum CGroupFlags { CGROUP_DONT_SKIP_UNMAPPED = 1 << 2, } CGroupFlags; -int cg_enumerate_processes(const char *controller, const char *path, FILE **ret); +int cg_enumerate_processes(const char *path, FILE **ret); int cg_read_pid(FILE *f, pid_t *ret, CGroupFlags flags); int cg_read_pidref(FILE *f, PidRef *ret, CGroupFlags flags); -int cg_enumerate_subgroups(const char *controller, const char *path, DIR **ret); +int cg_enumerate_subgroups(const char *path, DIR **ret); int cg_read_subgroup(DIR *d, char **ret); typedef int (*cg_kill_log_func_t)(const PidRef *pid, int sig, void *userdata); @@ -167,13 +152,11 @@ int cg_kill_kernel_sigkill(const char *path); int cg_kill_recursive(const char *path, int sig, CGroupFlags flags, Set *killed_pids, cg_kill_log_func_t log_kill, void *userdata); int cg_split_spec(const char *spec, char **ret_controller, char **ret_path); -int cg_mangle_path(const char *path, char **ret); -int cg_get_path(const char *controller, const char *path, const char *suffix, char **ret); -int cg_get_path_and_check(const char *controller, const char *path, const char *suffix, char **ret); +int cg_get_path(const char *path, const char *suffix, char **ret); -int cg_pid_get_path(const char *controller, pid_t pid, char **ret); -int cg_pidref_get_path(const char *controller, const PidRef *pidref, char **ret); +int cg_pid_get_path(pid_t pid, char **ret); +int cg_pidref_get_path(const PidRef *pidref, char **ret); int cg_is_threaded(const char *path); @@ -182,12 +165,12 @@ int cg_is_delegated_fd(int fd); int cg_has_coredump_receive(const char *path); -int cg_set_attribute(const char *controller, const char *path, const char *attribute, const char *value); -int cg_get_attribute(const char *controller, const char *path, const char *attribute, char **ret); -int cg_get_keyed_attribute(const char *controller, const char *path, const char *attribute, char * const *keys, char **values); +int cg_set_attribute(const char *path, const char *attribute, const char *value); +int cg_get_attribute(const char *path, const char *attribute, char **ret); +int cg_get_attribute_as_uint64(const char *path, const char *attribute, uint64_t *ret); +int cg_get_attribute_as_bool(const char *path, const char *attribute); -int cg_get_attribute_as_uint64(const char *controller, const char *path, const char *attribute, uint64_t *ret); -int cg_get_attribute_as_bool(const char *controller, const char *path, const char *attribute); +int cg_get_keyed_attribute(const char *path, const char *attribute, char * const *keys, char **values); int cg_get_owner(const char *path, uid_t *ret_uid); @@ -197,7 +180,7 @@ int cg_get_xattr(const char *path, const char *name, char **ret, size_t *ret_siz 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(const char *path); int cg_get_root_path(char **path); @@ -249,8 +232,6 @@ bool cg_needs_escape(const char *p) _pure_; int cg_escape(const char *p, char **ret); char* cg_unescape(const char *p) _pure_; -bool cg_controller_is_valid(const char *p); - int cg_slice_to_path(const char *unit, char **ret); int cg_mask_supported(CGroupMask *ret); @@ -260,14 +241,6 @@ int cg_mask_to_string(CGroupMask mask, char **ret); bool cg_kill_supported(void); -int cg_all_unified(void); -int cg_hybrid_unified(void); -int cg_unified_controller(const char *controller); -int cg_unified_cached(bool flush); -static inline int cg_unified(void) { - return cg_unified_cached(true); -} - const char* cgroup_controller_to_string(CGroupController c) _const_; CGroupController cgroup_controller_from_string(const char *s) _pure_; diff --git a/src/basic/limits-util.c b/src/basic/limits-util.c index ffa89b0446..d48d67dbf7 100644 --- a/src/basic/limits-util.c +++ b/src/basic/limits-util.c @@ -36,32 +36,19 @@ uint64_t physical_memory(void) { return mem; } - r = cg_all_unified(); + r = cg_get_attribute(root, "memory.max", &value); + if (r == -ENOENT) /* Field does not exist on the system's top-level cgroup, hence don't + * complain. (Note that it might exist on our own root though, if we live + * in a cgroup namespace, hence check anyway instead of not even + * trying.) */ + return mem; if (r < 0) { - log_debug_errno(r, "Failed to determine root unified mode, ignoring cgroup memory limit: %m"); + log_debug_errno(r, "Failed to read memory.max cgroup attribute, ignoring cgroup memory limit: %m"); return mem; } - if (r > 0) { - r = cg_get_attribute("memory", root, "memory.max", &value); - if (r == -ENOENT) /* Field does not exist on the system's top-level cgroup, hence don't - * complain. (Note that it might exist on our own root though, if we live - * in a cgroup namespace, hence check anyway instead of not even - * trying.) */ - return mem; - if (r < 0) { - log_debug_errno(r, "Failed to read memory.max cgroup attribute, ignoring cgroup memory limit: %m"); - return mem; - } - if (streq(value, "max")) - return mem; - } else { - r = cg_get_attribute("memory", root, "memory.limit_in_bytes", &value); - if (r < 0) { - log_debug_errno(r, "Failed to read memory.limit_in_bytes cgroup attribute, ignoring cgroup memory limit: %m"); - return mem; - } - } + if (streq(value, "max")) + return mem; r = safe_atou64(value, &lim); if (r < 0) { @@ -159,7 +146,7 @@ uint64_t system_tasks_max(void) { /* We'll have the "pids.max" attribute on the our root cgroup only if we are in a * CLONE_NEWCGROUP namespace. On the top-level namespace this attribute is missing, hence * suppress any message about that */ - r = cg_get_attribute_as_uint64("pids", root, "pids.max", &c); + r = cg_get_attribute_as_uint64(root, "pids.max", &c); if (r < 0 && r != -ENODATA) log_debug_errno(r, "Failed to read pids.max attribute of root cgroup, ignoring: %m"); } diff --git a/src/basic/process-util.c b/src/basic/process-util.c index 35d3f8bfd9..5759de38f4 100644 --- a/src/basic/process-util.c +++ b/src/basic/process-util.c @@ -2146,11 +2146,7 @@ int posix_spawn_wrapper( if (cgroup && have_clone_into_cgroup) { _cleanup_free_ char *resolved_cgroup = NULL; - r = cg_get_path_and_check( - SYSTEMD_CGROUP_CONTROLLER, - cgroup, - /* suffix= */ NULL, - &resolved_cgroup); + r = cg_get_path(cgroup, /* suffix= */ NULL, &resolved_cgroup); if (r < 0) return r; diff --git a/src/cgls/cgls.c b/src/cgls/cgls.c index 9e023af031..c224a892e4 100644 --- a/src/cgls/cgls.c +++ b/src/cgls/cgls.c @@ -187,11 +187,7 @@ static int parse_argv(int argc, char *argv[]) { return 1; } -static void show_cg_info(const char *controller, const char *path) { - - if (cg_all_unified() == 0 && controller && !streq(controller, SYSTEMD_CGROUP_CONTROLLER)) - printf("Controller %s; ", controller); - +static void show_cg_info(const char *path) { printf("CGroup %s:\n", empty_to_root(path)); fflush(stdout); } @@ -248,7 +244,7 @@ static int run(int argc, char *argv[]) { printf("Unit %s (%s):\n", unit_name, cgroup); fflush(stdout); - q = show_cgroup_by_path(cgroup, NULL, 0, arg_output_flags); + q = show_cgroup(cgroup, NULL, 0, arg_output_flags); } else if (path_startswith(*name, "/sys/fs/cgroup")) { @@ -258,7 +254,7 @@ static int run(int argc, char *argv[]) { q = show_cgroup_by_path(*name, NULL, 0, arg_output_flags); } else { _cleanup_free_ char *c = NULL, *p = NULL, *j = NULL; - const char *controller, *path; + const char *path; if (!root) { /* Query root only if needed, treat error as fatal */ @@ -273,7 +269,9 @@ static int run(int argc, char *argv[]) { goto failed; } - controller = c ?: SYSTEMD_CGROUP_CONTROLLER; + if (c && !streq(c, SYSTEMD_CGROUP_CONTROLLER)) + log_warning("Legacy cgroup v1 controller '%s' was specified, ignoring.", c); + if (p) { j = path_join(root, p); if (!j) @@ -284,9 +282,9 @@ static int run(int argc, char *argv[]) { } else path = root; - show_cg_info(controller, path); + show_cg_info(path); - q = show_cgroup(controller, path, NULL, 0, arg_output_flags); + q = show_cgroup(path, NULL, 0, arg_output_flags); } failed: @@ -320,10 +318,10 @@ static int run(int argc, char *argv[]) { if (r < 0) return log_error_errno(r, "Failed to list cgroup tree: %m"); - show_cg_info(SYSTEMD_CGROUP_CONTROLLER, root); + show_cg_info(root); printf("-.slice\n"); - r = show_cgroup(SYSTEMD_CGROUP_CONTROLLER, root, NULL, 0, arg_output_flags); + r = show_cgroup(root, NULL, 0, arg_output_flags); } } if (r < 0) diff --git a/src/cgtop/cgtop.c b/src/cgtop/cgtop.c index 19ad6f68a9..87806caeba 100644 --- a/src/cgtop/cgtop.c +++ b/src/cgtop/cgtop.c @@ -172,7 +172,7 @@ static int process_memory(Group *g) { else { _cleanup_free_ char *p = NULL, *v = NULL; - r = cg_get_path(SYSTEMD_CGROUP_CONTROLLER, g->path, "memory.current", &p); + r = cg_get_path(g->path, "memory.current", &p); if (r < 0) return r; @@ -202,7 +202,7 @@ static int process_io(Group *g, unsigned iteration) { assert(g); - r = cg_get_path(SYSTEMD_CGROUP_CONTROLLER, g->path, "io.stat", &p); + r = cg_get_path(g->path, "io.stat", &p); if (r < 0) return r; @@ -288,7 +288,7 @@ static int process_cpu(Group *g, unsigned iteration) { _cleanup_free_ char *val = NULL; uint64_t u; - r = cg_get_keyed_attribute(SYSTEMD_CGROUP_CONTROLLER, g->path, "cpu.stat", STRV_MAKE("usage_usec"), &val); + r = cg_get_keyed_attribute(g->path, "cpu.stat", STRV_MAKE("usage_usec"), &val); if (IN_SET(r, -ENOENT, -ENXIO)) return 0; if (r < 0) @@ -367,7 +367,7 @@ static int process( _cleanup_fclose_ FILE *f = NULL; pid_t pid; - r = cg_enumerate_processes(SYSTEMD_CGROUP_CONTROLLER, path, &f); + r = cg_enumerate_processes(path, &f); if (r < 0 && r != -ENOENT) return r; if (r >= 0) { @@ -395,7 +395,7 @@ static int process( } else { _cleanup_free_ char *p = NULL, *v = NULL; - r = cg_get_path(SYSTEMD_CGROUP_CONTROLLER, path, "pids.current", &p); + r = cg_get_path(path, "pids.current", &p); if (r < 0) return r; @@ -458,7 +458,7 @@ static int refresh( if (r < 0) return r; - r = cg_enumerate_subgroups(SYSTEMD_CGROUP_CONTROLLER, path, &d); + r = cg_enumerate_subgroups(path, &d); if (r == -ENOENT) { if (ret) *ret = NULL; diff --git a/src/core/bpf-devices.c b/src/core/bpf-devices.c index ef8ba3d572..71ffd04898 100644 --- a/src/core/bpf-devices.c +++ b/src/core/bpf-devices.c @@ -236,7 +236,7 @@ int bpf_devices_apply_policy( if (r < 0) return log_error_errno(r, "Extending device control BPF program failed: %m"); - r = cg_get_path(SYSTEMD_CGROUP_CONTROLLER, cgroup_path, NULL, &controller_path); + r = cg_get_path(cgroup_path, /* suffix = */ NULL, &controller_path); if (r < 0) return log_error_errno(r, "Failed to determine cgroup path: %m"); diff --git a/src/core/bpf-firewall.c b/src/core/bpf-firewall.c index fce885da87..b2a4cd6e27 100644 --- a/src/core/bpf-firewall.c +++ b/src/core/bpf-firewall.c @@ -696,7 +696,7 @@ int bpf_firewall_install(Unit *u) { return log_unit_debug_errno(u, SYNTHETIC_ERRNO(EOPNOTSUPP), "bpf-firewall: BPF firewalling not supported, proceeding without."); - r = cg_get_path(SYSTEMD_CGROUP_CONTROLLER, crt->cgroup_path, NULL, &path); + r = cg_get_path(crt->cgroup_path, /* suffix = */ NULL, &path); if (r < 0) return log_unit_error_errno(u, r, "bpf-firewall: Failed to determine cgroup path: %m"); diff --git a/src/core/bpf-foreign.c b/src/core/bpf-foreign.c index 2e8c07978c..1da16a7b8d 100644 --- a/src/core/bpf-foreign.c +++ b/src/core/bpf-foreign.c @@ -151,7 +151,7 @@ int bpf_foreign_install(Unit *u) { if (!crt) return 0; - r = cg_get_path(SYSTEMD_CGROUP_CONTROLLER, crt->cgroup_path, NULL, &cgroup_path); + r = cg_get_path(crt->cgroup_path, /* suffix = */ NULL, &cgroup_path); if (r < 0) return log_unit_error_errno(u, r, "bpf-foreign: Failed to get cgroup path: %m"); diff --git a/src/core/bpf-restrict-ifaces.c b/src/core/bpf-restrict-ifaces.c index 0c66ae0630..a0ed94ce3a 100644 --- a/src/core/bpf-restrict-ifaces.c +++ b/src/core/bpf-restrict-ifaces.c @@ -115,7 +115,7 @@ static int restrict_ifaces_install_impl(Unit *u) { if (!crt) return 0; - r = cg_get_path(SYSTEMD_CGROUP_CONTROLLER, crt->cgroup_path, NULL, &cgroup_path); + r = cg_get_path(crt->cgroup_path, /* suffix = */ NULL, &cgroup_path); if (r < 0) return log_unit_error_errno(u, r, "restrict-interfaces: Failed to get cgroup path: %m"); diff --git a/src/core/bpf-socket-bind.c b/src/core/bpf-socket-bind.c index 1fc73c19ab..1cba47306d 100644 --- a/src/core/bpf-socket-bind.c +++ b/src/core/bpf-socket-bind.c @@ -179,7 +179,7 @@ static int socket_bind_install_impl(Unit *u) { if (!crt) return 0; - r = cg_get_path(SYSTEMD_CGROUP_CONTROLLER, crt->cgroup_path, NULL, &cgroup_path); + r = cg_get_path(crt->cgroup_path, /* suffix = */ NULL, &cgroup_path); if (r < 0) return log_unit_error_errno(u, r, "bpf-socket-bind: Failed to get cgroup path: %m"); diff --git a/src/core/cgroup.c b/src/core/cgroup.c index ce9056ddaf..7242734e5a 100644 --- a/src/core/cgroup.c +++ b/src/core/cgroup.c @@ -136,7 +136,7 @@ static int set_attribute_and_warn(Unit *u, const char *attribute, const char *va if (!crt || !crt->cgroup_path) return -EOWNERDEAD; - r = cg_set_attribute(SYSTEMD_CGROUP_CONTROLLER, crt->cgroup_path, attribute, value); + r = cg_set_attribute(crt->cgroup_path, attribute, value); if (r < 0) log_unit_full_errno(u, LOG_LEVEL_CGROUP_WRITE(r), r, "Failed to set '%s' attribute on '%s' to '%.*s': %m", attribute, empty_to_root(crt->cgroup_path), (int) strcspn(value, NEWLINE), value); @@ -287,7 +287,7 @@ static int unit_get_kernel_memory_limit(Unit *u, const char *file, uint64_t *ret if (!crt || !crt->cgroup_path) return -EOWNERDEAD; - return cg_get_attribute_as_uint64("memory", crt->cgroup_path, file, ret); + return cg_get_attribute_as_uint64(crt->cgroup_path, file, ret); } static int unit_compare_memory_limit(Unit *u, const char *property_name, uint64_t *ret_unit_value, uint64_t *ret_kernel_value) { @@ -1139,7 +1139,7 @@ static void cgroup_apply_cpu_idle(Unit *u, uint64_t weight) { is_idle = weight == CGROUP_WEIGHT_IDLE; idle_val = one_zero(is_idle); - r = cg_set_attribute("cpu", crt->cgroup_path, "cpu.idle", idle_val); + r = cg_set_attribute(crt->cgroup_path, "cpu.idle", idle_val); if (r < 0 && (r != -ENOENT || is_idle)) log_unit_full_errno(u, LOG_LEVEL_CGROUP_WRITE(r), r, "Failed to set '%s' attribute on '%s' to '%s': %m", "cpu.idle", empty_to_root(crt->cgroup_path), idle_val); @@ -1211,7 +1211,7 @@ static int set_bfq_weight(Unit *u, dev_t dev, uint64_t io_weight) { else xsprintf(buf, "%" PRIu64 "\n", bfq_weight); - r = cg_set_attribute(SYSTEMD_CGROUP_CONTROLLER, crt->cgroup_path, "io.bfq.weight", buf); + r = cg_set_attribute(crt->cgroup_path, "io.bfq.weight", buf); if (r >= 0 && io_weight != bfq_weight) log_unit_debug(u, "%s=%" PRIu64 " scaled to io.bfq.weight=%" PRIu64, major(dev) > 0 ? "IODeviceWeight" : "IOWeight", @@ -1236,7 +1236,7 @@ static void cgroup_apply_io_device_weight(Unit *u, const char *dev_path, uint64_ r1 = set_bfq_weight(u, dev, io_weight); xsprintf(buf, DEVNUM_FORMAT_STR " %" PRIu64 "\n", DEVNUM_FORMAT_VAL(dev), io_weight); - r2 = cg_set_attribute("io", crt->cgroup_path, "io.weight", buf); + r2 = cg_set_attribute(crt->cgroup_path, "io.weight", buf); /* Look at the configured device, when both fail, prefer io.weight errno. */ r = r2 == -EOPNOTSUPP ? r1 : r2; @@ -1989,7 +1989,7 @@ static int unit_watch_cgroup(Unit *u) { if (r < 0) return log_oom(); - r = cg_get_path(SYSTEMD_CGROUP_CONTROLLER, crt->cgroup_path, "cgroup.events", &events); + r = cg_get_path(crt->cgroup_path, "cgroup.events", &events); if (r < 0) return log_oom(); @@ -2044,7 +2044,7 @@ static int unit_watch_cgroup_memory(Unit *u) { if (r < 0) return log_oom(); - r = cg_get_path(SYSTEMD_CGROUP_CONTROLLER, crt->cgroup_path, "memory.events", &events); + r = cg_get_path(crt->cgroup_path, "memory.events", &events); if (r < 0) return log_oom(); @@ -2103,7 +2103,7 @@ static int unit_update_cgroup( CGroupRuntime *crt = ASSERT_PTR(unit_get_cgroup_runtime(u)); uint64_t cgroup_id = 0; - r = cg_get_path(SYSTEMD_CGROUP_CONTROLLER, crt->cgroup_path, NULL, &cgroup_full_path); + r = cg_get_path(crt->cgroup_path, /* suffix = */ NULL, &cgroup_full_path); if (r == 0) { r = cg_path_get_cgroupid(cgroup_full_path, &cgroup_id); if (r < 0) @@ -2714,7 +2714,7 @@ int unit_cgroup_is_empty(Unit *u) { if (!crt->cgroup_path) return -EOWNERDEAD; - r = cg_is_empty(SYSTEMD_CGROUP_CONTROLLER, crt->cgroup_path); + r = cg_is_empty(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; @@ -2857,7 +2857,7 @@ int unit_search_main_pid(Unit *u, PidRef *ret) { if (!crt || !crt->cgroup_path) return -ENXIO; - r = cg_enumerate_processes(SYSTEMD_CGROUP_CONTROLLER, crt->cgroup_path, &f); + r = cg_enumerate_processes(crt->cgroup_path, &f); if (r < 0) return r; @@ -3033,7 +3033,6 @@ int unit_check_oom(Unit *u) { if (ctx->memory_oom_group) { r = cg_get_keyed_attribute( - "memory", crt->cgroup_path, "memory.events.local", STRV_MAKE("oom_group_kill"), @@ -3044,7 +3043,6 @@ int unit_check_oom(Unit *u) { if (isempty(oom_kill)) { r = cg_get_keyed_attribute( - "memory", crt->cgroup_path, "memory.events", STRV_MAKE("oom_kill"), @@ -3156,7 +3154,6 @@ static int unit_check_cgroup_events(Unit *u) { return 0; r = cg_get_keyed_attribute( - SYSTEMD_CGROUP_CONTROLLER, crt->cgroup_path, "cgroup.events", STRV_MAKE("populated", "frozen"), @@ -3260,7 +3257,7 @@ int manager_setup_cgroup(Manager *m) { /* 1. Determine hierarchy */ m->cgroup_root = mfree(m->cgroup_root); - r = cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, 0, &m->cgroup_root); + r = cg_pid_get_path(0, &m->cgroup_root); if (r < 0) return log_error_errno(r, "Cannot determine cgroup we are running in: %m"); @@ -3404,7 +3401,7 @@ Unit* manager_get_unit_by_pidref_cgroup(Manager *m, const PidRef *pid) { assert(m); - if (cg_pidref_get_path(SYSTEMD_CGROUP_CONTROLLER, pid, &cgroup) < 0) + if (cg_pidref_get_path(pid, &cgroup) < 0) return NULL; return manager_get_unit_by_cgroup(m, cgroup); @@ -3538,7 +3535,7 @@ int unit_get_memory_accounting(Unit *u, CGroupMemoryAccountingMetric metric, uin if (!FLAGS_SET(crt->cgroup_realized_mask, CGROUP_MASK_MEMORY)) return -ENODATA; - r = cg_get_attribute_as_uint64("memory", crt->cgroup_path, attributes_table[metric], &bytes); + r = cg_get_attribute_as_uint64(crt->cgroup_path, attributes_table[metric], &bytes); if (r < 0 && r != -ENODATA) return r; updated = r >= 0; @@ -3581,7 +3578,7 @@ int unit_get_tasks_current(Unit *u, uint64_t *ret) { if ((crt->cgroup_realized_mask & CGROUP_MASK_PIDS) == 0) return -ENODATA; - return cg_get_attribute_as_uint64("pids", crt->cgroup_path, "pids.current", ret); + return cg_get_attribute_as_uint64(crt->cgroup_path, "pids.current", ret); } static int unit_get_cpu_usage_raw(const Unit *u, const CGroupRuntime *crt, nsec_t *ret) { @@ -3601,7 +3598,7 @@ static int unit_get_cpu_usage_raw(const Unit *u, const CGroupRuntime *crt, nsec_ _cleanup_free_ char *val = NULL; uint64_t us; - r = cg_get_keyed_attribute("cpu", crt->cgroup_path, "cpu.stat", STRV_MAKE("usage_usec"), &val); + r = cg_get_keyed_attribute(crt->cgroup_path, "cpu.stat", STRV_MAKE("usage_usec"), &val); if (r < 0) return r; @@ -3772,7 +3769,7 @@ static int unit_get_io_accounting_raw( if (!FLAGS_SET(crt->cgroup_realized_mask, CGROUP_MASK_IO)) return -ENODATA; - r = cg_get_path("io", crt->cgroup_path, "io.stat", &path); + r = cg_get_path(crt->cgroup_path, "io.stat", &path); if (r < 0) return r; @@ -4037,7 +4034,6 @@ static int unit_cgroup_freezer_kernel_state(Unit *u, FreezerState *ret) { return -EOWNERDEAD; r = cg_get_keyed_attribute( - SYSTEMD_CGROUP_CONTROLLER, crt->cgroup_path, "cgroup.events", STRV_MAKE("frozen"), @@ -4111,7 +4107,7 @@ int unit_cgroup_freezer_action(Unit *u, FreezerAction action) { assert_not_reached(); } - r = cg_get_path(SYSTEMD_CGROUP_CONTROLLER, crt->cgroup_path, "cgroup.freeze", &path); + r = cg_get_path(crt->cgroup_path, "cgroup.freeze", &path); if (r < 0) return r; @@ -4142,7 +4138,7 @@ int unit_get_cpuset(Unit *u, CPUSet *cpus, const char *name) { if ((crt->cgroup_realized_mask & CGROUP_MASK_CPUSET) == 0) return -ENODATA; - r = cg_get_attribute("cpuset", crt->cgroup_path, name, &v); + r = cg_get_attribute(crt->cgroup_path, name, &v); if (r == -ENOENT) return -ENODATA; if (r < 0) diff --git a/src/core/dbus-unit.c b/src/core/dbus-unit.c index a524cfad22..ed4646f75a 100644 --- a/src/core/dbus-unit.c +++ b/src/core/dbus-unit.c @@ -1345,7 +1345,7 @@ static int append_process(sd_bus_message *reply, const char *p, PidRef *pid, Set return r; if (!p) { - r = cg_pidref_get_path(SYSTEMD_CGROUP_CONTROLLER, pid, &buf); + r = cg_pidref_get_path(pid, &buf); if (r == -ESRCH) return 0; if (r < 0) @@ -1375,7 +1375,7 @@ static int append_cgroup(sd_bus_message *reply, const char *p, Set *pids) { assert(reply); assert(p); - r = cg_enumerate_processes(SYSTEMD_CGROUP_CONTROLLER, p, &f); + r = cg_enumerate_processes(p, &f); if (r == -ENOENT) return 0; if (r < 0) @@ -1411,7 +1411,7 @@ static int append_cgroup(sd_bus_message *reply, const char *p, Set *pids) { return r; } - r = cg_enumerate_subgroups(SYSTEMD_CGROUP_CONTROLLER, p, &d); + r = cg_enumerate_subgroups(p, &d); if (r == -ENOENT) return 0; if (r < 0) diff --git a/src/core/exec-invoke.c b/src/core/exec-invoke.c index 88178a82f9..97a7107384 100644 --- a/src/core/exec-invoke.c +++ b/src/core/exec-invoke.c @@ -5579,7 +5579,7 @@ int exec_invoke( if (is_pressure_supported() > 0) { if (cgroup_context_want_memory_pressure(cgroup_context)) { - r = cg_get_path("memory", params->cgroup_path, "memory.pressure", &memory_pressure_path); + r = cg_get_path(params->cgroup_path, "memory.pressure", &memory_pressure_path); if (r < 0) { *exit_status = EXIT_MEMORY; return log_oom(); @@ -5597,7 +5597,7 @@ int exec_invoke( * memory_pressure_path != NULL in the conditional below. */ if (memory_pressure_path && needs_sandboxing && exec_needs_cgroup_namespace(context)) { memory_pressure_path = mfree(memory_pressure_path); - r = cg_get_path("memory", "/", "memory.pressure", &memory_pressure_path); + r = cg_get_path("/", "memory.pressure", &memory_pressure_path); if (r < 0) { *exit_status = EXIT_MEMORY; return log_oom(); diff --git a/src/core/service.c b/src/core/service.c index c92fb45085..59a81028e6 100644 --- a/src/core/service.c +++ b/src/core/service.c @@ -2015,7 +2015,7 @@ static int cgroup_good(Service *s) { if (!s->cgroup_runtime || !s->cgroup_runtime->cgroup_path) return 0; - r = cg_is_empty(SYSTEMD_CGROUP_CONTROLLER, s->cgroup_runtime->cgroup_path); + r = cg_is_empty(s->cgroup_runtime->cgroup_path); if (r < 0) return r; diff --git a/src/coredump/coredump-send.c b/src/coredump/coredump-send.c index 6316511bad..eadec5f0f5 100644 --- a/src/coredump/coredump-send.c +++ b/src/coredump/coredump-send.c @@ -132,7 +132,7 @@ static int can_forward_coredump(PidRef *pidref, PidRef *leader) { } _cleanup_free_ char *cgroup = NULL; - r = cg_pidref_get_path(SYSTEMD_CGROUP_CONTROLLER, leader, &cgroup); + r = cg_pidref_get_path(leader, &cgroup); if (r < 0) return log_debug_errno(r, "Failed to get cgroup of the leader process, ignoring: %m"); diff --git a/src/libsystemd/sd-bus/bus-creds.c b/src/libsystemd/sd-bus/bus-creds.c index 86f1b70f95..2bbbd0f484 100644 --- a/src/libsystemd/sd-bus/bus-creds.c +++ b/src/libsystemd/sd-bus/bus-creds.c @@ -1096,7 +1096,7 @@ int bus_creds_add_more(sd_bus_creds *c, uint64_t mask, PidRef *pidref, pid_t tid if (missing & (SD_BUS_CREDS_CGROUP|SD_BUS_CREDS_UNIT|SD_BUS_CREDS_USER_UNIT|SD_BUS_CREDS_SLICE|SD_BUS_CREDS_USER_SLICE|SD_BUS_CREDS_SESSION|SD_BUS_CREDS_OWNER_UID)) { if (!c->cgroup) { - r = cg_pid_get_path(NULL, pidref->pid, &c->cgroup); + r = cg_pid_get_path(pidref->pid, &c->cgroup); if (r < 0 && !ERRNO_IS_NEG_PRIVILEGE(r)) return r; } diff --git a/src/libsystemd/sd-bus/test-bus-creds.c b/src/libsystemd/sd-bus/test-bus-creds.c index 7eb7a38c39..3fa1e66b0a 100644 --- a/src/libsystemd/sd-bus/test-bus-creds.c +++ b/src/libsystemd/sd-bus/test-bus-creds.c @@ -13,8 +13,8 @@ int main(int argc, char *argv[]) { test_setup_logging(LOG_DEBUG); - if (IN_SET(cg_unified(), -ENOMEDIUM, -ENOENT)) - return log_tests_skipped("/sys/fs/cgroup/ not available"); + if (cg_is_available() <= 0) + return log_tests_skipped("cgroupfs v2 is not mounted"); r = sd_bus_creds_new_from_pid(&creds, 0, _SD_BUS_CREDS_ALL); log_full_errno(r < 0 ? LOG_ERR : LOG_DEBUG, r, "sd_bus_creds_new_from_pid: %m"); diff --git a/src/libsystemd/sd-event/sd-event.c b/src/libsystemd/sd-event/sd-event.c index 044cdf246d..c9d14ebf17 100644 --- a/src/libsystemd/sd-event/sd-event.c +++ b/src/libsystemd/sd-event/sd-event.c @@ -1972,7 +1972,7 @@ _public_ int sd_event_add_memory_pressure( * not delegated to us, or PSI simply not available in the kernel). */ _cleanup_free_ char *cg = NULL; - r = cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, 0, &cg); + r = cg_pid_get_path(0, &cg); if (r < 0) return r; diff --git a/src/libsystemd/sd-login/sd-login.c b/src/libsystemd/sd-login/sd-login.c index 133e97b432..b559b4576b 100644 --- a/src/libsystemd/sd-login/sd-login.c +++ b/src/libsystemd/sd-login/sd-login.c @@ -105,7 +105,7 @@ _public_ int sd_pid_get_cgroup(pid_t pid, char **ret_cgroup) { assert_return(pid >= 0, -EINVAL); _cleanup_free_ char *c = NULL; - r = cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, pid, &c); + r = cg_pid_get_path(pid, &c); if (r < 0) return r; @@ -418,7 +418,7 @@ _public_ int sd_peer_get_cgroup(int fd, char **ret_cgroup) { return r; _cleanup_free_ char *c = NULL; - r = cg_pidref_get_path(SYSTEMD_CGROUP_CONTROLLER, &pidref, &c); + r = cg_pidref_get_path(&pidref, &c); if (r < 0) return r; diff --git a/src/libsystemd/sd-login/test-login.c b/src/libsystemd/sd-login/test-login.c index 98846d1011..7c2b68a5c7 100644 --- a/src/libsystemd/sd-login/test-login.c +++ b/src/libsystemd/sd-login/test-login.c @@ -327,8 +327,8 @@ TEST(monitor) { } static int intro(void) { - if (IN_SET(cg_unified(), -ENOENT, -ENOMEDIUM)) - return log_tests_skipped("cgroupfs is not mounted"); + if (cg_is_available() <= 0) + return log_tests_skipped("cgroupfs v2 is not mounted"); log_info("/* Information printed is from the live system */"); return EXIT_SUCCESS; diff --git a/src/login/loginctl.c b/src/login/loginctl.c index c86f694c2b..fa406cfd74 100644 --- a/src/login/loginctl.c +++ b/src/login/loginctl.c @@ -457,10 +457,10 @@ static int show_unit_cgroup( /* Fallback for older systemd versions where the GetUnitProcesses() call is not yet available */ - if (cg_is_empty(SYSTEMD_CGROUP_CONTROLLER, cgroup) != 0 && leader <= 0) + if (cg_is_empty(cgroup) != 0 && leader <= 0) return 0; - show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER, cgroup, prefix, c, &leader, leader > 0, get_output_flags()); + show_cgroup_and_extra(cgroup, prefix, c, &leader, leader > 0, get_output_flags()); } else if (r < 0) return log_error_errno(r, "Failed to dump process list: %s", bus_error_message(&error, r)); diff --git a/src/machine/machine.c b/src/machine/machine.c index f097bfe380..5cbe076506 100644 --- a/src/machine/machine.c +++ b/src/machine/machine.c @@ -596,7 +596,7 @@ static int machine_dispatch_cgroup_empty(sd_event_source *s, const struct inotif assert(m->cgroup); - r = cg_is_empty(SYSTEMD_CGROUP_CONTROLLER, m->cgroup); + r = cg_is_empty(m->cgroup); if (r < 0) return log_error_errno(r, "Failed to determine if cgroup '%s' is empty: %m", m->cgroup); @@ -616,7 +616,7 @@ static int machine_watch_cgroup(Machine *m) { return 0; _cleanup_free_ char *p = NULL; - r = cg_get_path(SYSTEMD_CGROUP_CONTROLLER, m->cgroup, "cgroup.events", &p); + r = cg_get_path(m->cgroup, "cgroup.events", &p); if (r < 0) return log_error_errno(r, "Failed to get cgroup path for cgroup '%s': %m", m->cgroup); @@ -782,7 +782,7 @@ bool machine_may_gc(Machine *m, bool drop_not_started) { } if (m->cgroup) { - r = cg_is_empty(SYSTEMD_CGROUP_CONTROLLER, m->cgroup); + r = cg_is_empty(m->cgroup); if (IN_SET(r, 0, -ENOENT)) return true; if (r < 0) diff --git a/src/machine/machinectl.c b/src/machine/machinectl.c index 487a50813e..cf8f7d48b9 100644 --- a/src/machine/machinectl.c +++ b/src/machine/machinectl.c @@ -452,10 +452,10 @@ static int show_unit_cgroup( /* Fallback for older systemd versions where the GetUnitProcesses() call is not yet available */ - if (cg_is_empty(SYSTEMD_CGROUP_CONTROLLER, cgroup) != 0 && leader <= 0) + if (cg_is_empty(cgroup) != 0 && leader <= 0) return 0; - show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER, cgroup, "\t\t ", c, &leader, leader > 0, get_output_flags()); + show_cgroup_and_extra(cgroup, "\t\t ", c, &leader, leader > 0, get_output_flags()); } else if (r < 0) return log_error_errno(r, "Failed to dump process list: %s", bus_error_message(&error, r)); diff --git a/src/machine/machined-dbus.c b/src/machine/machined-dbus.c index 1619d3fd6b..0f1ac1776a 100644 --- a/src/machine/machined-dbus.c +++ b/src/machine/machined-dbus.c @@ -722,7 +722,7 @@ static int method_register_machine(sd_bus_message *message, void *userdata, sd_b /* If this is not a top-level cgroup, then we need the cgroup path to be able to watch when * it empties */ - r = cg_pidref_get_path(SYSTEMD_CGROUP_CONTROLLER, &m->leader, &m->cgroup); + r = cg_pidref_get_path(&m->leader, &m->cgroup); if (r < 0) { r = sd_bus_error_set_errnof(error, r, "Failed to determine cgroup of process "PID_FMT" : %m", diff --git a/src/network/networkd-sysctl.c b/src/network/networkd-sysctl.c index b29d49d79d..8131658829 100644 --- a/src/network/networkd-sysctl.c +++ b/src/network/networkd-sysctl.c @@ -109,11 +109,11 @@ int manager_install_sysctl_monitor(Manager *manager) { if (r < 0) return log_warning_errno(r, "Failed to load libbpf, not installing sysctl monitor: %m"); - r = cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, 0, &cgroup); + r = cg_pid_get_path(0, &cgroup); if (r < 0) return log_warning_errno(r, "Failed to get cgroup path, ignoring: %m."); - root_cgroup_fd = cg_path_open(SYSTEMD_CGROUP_CONTROLLER, "/"); + root_cgroup_fd = cg_path_open("/"); if (root_cgroup_fd < 0) return log_warning_errno(root_cgroup_fd, "Failed to open cgroup, ignoring: %m"); @@ -122,7 +122,7 @@ int manager_install_sysctl_monitor(Manager *manager) { return log_full_errno(errno == EINVAL ? LOG_DEBUG : LOG_INFO, errno, "Unable to load sysctl monitor BPF program, ignoring: %m"); - cgroup_fd = cg_path_open(SYSTEMD_CGROUP_CONTROLLER, cgroup); + cgroup_fd = cg_path_open(cgroup); if (cgroup_fd < 0) return log_warning_errno(cgroup_fd, "Failed to open cgroup: %m"); diff --git a/src/nspawn/nspawn-cgroup.c b/src/nspawn/nspawn-cgroup.c index 7cef863c93..db99b7d846 100644 --- a/src/nspawn/nspawn-cgroup.c +++ b/src/nspawn/nspawn-cgroup.c @@ -75,9 +75,9 @@ int create_subcgroup( return log_error_errno(r, "Failed to determine supported controllers: %m"); if (keep_unit) - r = cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, 0, &cgroup); + r = cg_pid_get_path(0, &cgroup); else - r = cg_pidref_get_path(SYSTEMD_CGROUP_CONTROLLER, pid, &cgroup); + r = cg_pidref_get_path(pid, &cgroup); if (r < 0) return log_error_errno(r, "Failed to get our control group: %m"); @@ -100,7 +100,7 @@ int create_subcgroup( if (userns_mode == USER_NAMESPACE_MANAGED) { _cleanup_close_ int cgroup_fd = -EBADF; - cgroup_fd = cg_path_open(SYSTEMD_CGROUP_CONTROLLER, payload); + cgroup_fd = cg_path_open(payload); if (cgroup_fd < 0) return log_error_errno(cgroup_fd, "Failed to open cgroup %s: %m", payload); @@ -113,7 +113,7 @@ int create_subcgroup( return log_error_errno(r, "Failed to add cgroup %s to userns: %m", payload); } else { _cleanup_free_ char *fs = NULL; - r = cg_get_path(SYSTEMD_CGROUP_CONTROLLER, payload, NULL, &fs); + r = cg_get_path(payload, /* suffix = */ NULL, &fs); if (r < 0) return log_error_errno(r, "Failed to get file system path for container cgroup: %m"); @@ -172,7 +172,7 @@ int bind_mount_cgroup_hierarchy(void) { /* NB: This must be called from the inner child, with /sys/fs/cgroup/ being a bind mount in mountns! */ - r = cg_pid_get_path(NULL, 0, &own_cgroup_path); + r = cg_pid_get_path(0, &own_cgroup_path); if (r < 0) return log_error_errno(r, "Failed to determine our own cgroup path: %m"); diff --git a/src/oom/oomd-manager.c b/src/oom/oomd-manager.c index 7ff245c437..49c2241bdd 100644 --- a/src/oom/oomd-manager.c +++ b/src/oom/oomd-manager.c @@ -210,7 +210,7 @@ static int recursively_get_cgroup_context(Hashmap *new_h, const char *path) { assert(new_h); assert(path); - r = cg_enumerate_subgroups(SYSTEMD_CGROUP_CONTROLLER, path, &d); + r = cg_enumerate_subgroups(path, &d); if (r < 0) return r; @@ -235,7 +235,7 @@ static int recursively_get_cgroup_context(Hashmap *new_h, const char *path) { subpath = mfree(subpath); - r = cg_get_attribute_as_bool("memory", cg_path, "memory.oom.group"); + r = cg_get_attribute_as_bool(cg_path, "memory.oom.group"); /* The cgroup might be gone. Skip it as a candidate since we can't get information on it. */ if (r == -ENOMEM) return r; diff --git a/src/oom/oomd-util.c b/src/oom/oomd-util.c index 4f9808e5c3..e463ce01f2 100644 --- a/src/oom/oomd-util.c +++ b/src/oom/oomd-util.c @@ -240,7 +240,7 @@ int oomd_cgroup_kill(const char *path, bool recurse, bool dry_run) { if (dry_run) { _cleanup_free_ char *cg_path = NULL; - r = cg_get_path(SYSTEMD_CGROUP_CONTROLLER, path, NULL, &cg_path); + r = cg_get_path(path, /* suffix = */ NULL, &cg_path); if (r < 0) return r; @@ -418,7 +418,7 @@ int oomd_cgroup_context_acquire(const char *path, OomdCGroupContext **ret) { is_root = empty_or_root(path); ctx->preference = MANAGED_OOM_PREFERENCE_NONE; - r = cg_get_path(SYSTEMD_CGROUP_CONTROLLER, path, "memory.pressure", &p); + r = cg_get_path(path, "memory.pressure", &p); if (r < 0) return log_debug_errno(r, "Error getting cgroup memory pressure path from %s: %m", path); @@ -431,19 +431,19 @@ int oomd_cgroup_context_acquire(const char *path, OomdCGroupContext **ret) { if (r < 0) return log_debug_errno(r, "Error getting memory used from procfs: %m"); } else { - r = cg_get_attribute_as_uint64(SYSTEMD_CGROUP_CONTROLLER, path, "memory.current", &ctx->current_memory_usage); + r = cg_get_attribute_as_uint64(path, "memory.current", &ctx->current_memory_usage); if (r < 0) return log_debug_errno(r, "Error getting memory.current from %s: %m", path); - r = cg_get_attribute_as_uint64(SYSTEMD_CGROUP_CONTROLLER, path, "memory.min", &ctx->memory_min); + r = cg_get_attribute_as_uint64(path, "memory.min", &ctx->memory_min); if (r < 0) return log_debug_errno(r, "Error getting memory.min from %s: %m", path); - r = cg_get_attribute_as_uint64(SYSTEMD_CGROUP_CONTROLLER, path, "memory.low", &ctx->memory_low); + r = cg_get_attribute_as_uint64(path, "memory.low", &ctx->memory_low); if (r < 0) return log_debug_errno(r, "Error getting memory.low from %s: %m", path); - r = cg_get_attribute_as_uint64(SYSTEMD_CGROUP_CONTROLLER, path, "memory.swap.current", &ctx->swap_usage); + r = cg_get_attribute_as_uint64(path, "memory.swap.current", &ctx->swap_usage); if (r == -ENODATA) /* The kernel can be compiled without support for memory.swap.* files, * or it can be disabled with boot param 'swapaccount=0' */ @@ -451,7 +451,7 @@ int oomd_cgroup_context_acquire(const char *path, OomdCGroupContext **ret) { else if (r < 0) return log_debug_errno(r, "Error getting memory.swap.current from %s: %m", path); - r = cg_get_keyed_attribute(SYSTEMD_CGROUP_CONTROLLER, path, "memory.stat", STRV_MAKE("pgscan"), &val); + r = cg_get_keyed_attribute(path, "memory.stat", STRV_MAKE("pgscan"), &val); if (r < 0) return log_debug_errno(r, "Error getting pgscan from memory.stat under %s: %m", path); diff --git a/src/oom/test-oomd-util.c b/src/oom/test-oomd-util.c index abb5c2ccd8..7e68525ba0 100644 --- a/src/oom/test-oomd-util.c +++ b/src/oom/test-oomd-util.c @@ -97,7 +97,7 @@ TEST(oomd_cgroup_kill) { bool empty = false; for (size_t t = 0; t < 100; t++) { usleep_safe(100 * USEC_PER_MSEC); - ASSERT_OK(r = cg_is_empty(SYSTEMD_CGROUP_CONTROLLER, subcgroup)); + ASSERT_OK(r = cg_is_empty(subcgroup)); if (r > 0) { empty = true; break; diff --git a/src/shared/cgroup-setup.c b/src/shared/cgroup-setup.c index 323204725f..a334805871 100644 --- a/src/shared/cgroup-setup.c +++ b/src/shared/cgroup-setup.c @@ -78,7 +78,7 @@ int cg_trim(const char *path, bool delete_root) { _cleanup_free_ char *fs = NULL; int r; - r = cg_get_path(SYSTEMD_CGROUP_CONTROLLER, path, NULL, &fs); + r = cg_get_path(path, /* suffix = */ NULL, &fs); if (r < 0) return r; @@ -115,7 +115,7 @@ int cg_create(const char *path) { _cleanup_free_ char *fs = NULL; int r; - r = cg_get_path_and_check(SYSTEMD_CGROUP_CONTROLLER, path, NULL, &fs); + r = cg_get_path(path, /* suffix = */ NULL, &fs); if (r < 0) return r; @@ -140,7 +140,7 @@ int cg_attach(const char *path, pid_t pid) { assert(path); assert(pid >= 0); - r = cg_get_path_and_check(SYSTEMD_CGROUP_CONTROLLER, path, "cgroup.procs", &fs); + r = cg_get_path(path, "cgroup.procs", &fs); if (r < 0) return r; @@ -216,7 +216,7 @@ int cg_set_access( return 0; /* Configure access to the cgroup itself */ - r = cg_get_path(SYSTEMD_CGROUP_CONTROLLER, path, NULL, &fs); + r = cg_get_path(path, /* suffix = */ NULL, &fs); if (r < 0) return r; @@ -289,7 +289,7 @@ int cg_set_access_recursive( if (!uid_is_valid(uid) && !gid_is_valid(gid)) return 0; - r = cg_get_path(SYSTEMD_CGROUP_CONTROLLER, path, NULL, &fs); + r = cg_get_path(path, /* suffix = */ NULL, &fs); if (r < 0) return r; @@ -334,7 +334,7 @@ int cg_migrate( done = true; - r = cg_enumerate_processes(SYSTEMD_CGROUP_CONTROLLER, from, &f); + r = cg_enumerate_processes(from, &f); if (r < 0) return RET_GATHER(ret, r); @@ -396,7 +396,7 @@ int cg_enable( return 0; } - r = cg_get_path(SYSTEMD_CGROUP_CONTROLLER, p, "cgroup.subtree_control", &fs); + r = cg_get_path(p, "cgroup.subtree_control", &fs); if (r < 0) return r; diff --git a/src/shared/cgroup-show.c b/src/shared/cgroup-show.c index b97edbdba7..94b8d15bec 100644 --- a/src/shared/cgroup-show.c +++ b/src/shared/cgroup-show.c @@ -87,16 +87,13 @@ static int show_cgroup_one_by_path( _cleanup_free_ pid_t *pids = NULL; _cleanup_fclose_ FILE *f = NULL; - _cleanup_free_ char *p = NULL; size_t n = 0; char *fn; int r; - r = cg_mangle_path(path, &p); - if (r < 0) - return r; + assert(path); - fn = strjoina(p, "/cgroup.procs"); + fn = strjoina(path, "/cgroup.procs"); f = fopen(fn, "re"); if (!f) return -errno; @@ -225,7 +222,7 @@ int show_cgroup_by_path( size_t n_columns, OutputFlags flags) { - _cleanup_free_ char *fn = NULL, *p1 = NULL, *last = NULL, *p2 = NULL; + _cleanup_free_ char *p1 = NULL, *last = NULL, *p2 = NULL; _cleanup_closedir_ DIR *d = NULL; bool shown_pids = false; char *gn = NULL; @@ -238,23 +235,19 @@ int show_cgroup_by_path( prefix = strempty(prefix); - r = cg_mangle_path(path, &fn); - if (r < 0) - return r; - - d = opendir(fn); + d = opendir(path); if (!d) return -errno; while ((r = cg_read_subgroup(d, &gn)) > 0) { _cleanup_free_ char *k = NULL; - k = path_join(fn, gn); + k = path_join(path, gn); free(gn); if (!k) return -ENOMEM; - if (!(flags & OUTPUT_SHOW_ALL) && cg_is_empty(NULL, k) > 0) + if (!(flags & OUTPUT_SHOW_ALL) && cg_is_empty(path_startswith(k, "/sys/fs/cgroup/")) > 0) continue; if (!shown_pids) { @@ -303,17 +296,17 @@ int show_cgroup_by_path( return 0; } -int show_cgroup(const char *controller, - const char *path, +int show_cgroup(const char *path, const char *prefix, size_t n_columns, OutputFlags flags) { + _cleanup_free_ char *p = NULL; int r; assert(path); - r = cg_get_path(controller, path, NULL, &p); + r = cg_get_path(path, /* suffix = */ NULL, &p); if (r < 0) return r; @@ -321,7 +314,6 @@ int show_cgroup(const char *controller, } static int show_extra_pids( - const char *controller, const char *path, const char *prefix, size_t n_columns, @@ -350,7 +342,7 @@ static int show_extra_pids( for (i = 0, j = 0; i < n_pids; i++) { _cleanup_free_ char *k = NULL; - r = cg_pid_get_path(controller, pids[i], &k); + r = cg_pid_get_path(pids[i], &k); if (r < 0) return r; @@ -366,7 +358,6 @@ static int show_extra_pids( } int show_cgroup_and_extra( - const char *controller, const char *path, const char *prefix, size_t n_columns, @@ -378,11 +369,11 @@ int show_cgroup_and_extra( assert(path); - r = show_cgroup(controller, path, prefix, n_columns, flags); + r = show_cgroup(path, prefix, n_columns, flags); if (r < 0) return r; - return show_extra_pids(controller, path, prefix, n_columns, extra_pids, n_extra_pids, flags); + return show_extra_pids(path, prefix, n_columns, extra_pids, n_extra_pids, flags); } int show_cgroup_get_unit_path_and_warn( diff --git a/src/shared/cgroup-show.h b/src/shared/cgroup-show.h index ecff0298ae..27fc878c93 100644 --- a/src/shared/cgroup-show.h +++ b/src/shared/cgroup-show.h @@ -4,9 +4,14 @@ #include "shared-forward.h" int show_cgroup_by_path(const char *path, const char *prefix, size_t n_columns, OutputFlags flags); -int show_cgroup(const char *controller, const char *path, const char *prefix, size_t n_columns, OutputFlags flags); - -int show_cgroup_and_extra(const char *controller, const char *path, const char *prefix, size_t n_columns, const pid_t extra_pids[], size_t n_extra_pids, OutputFlags flags); +int show_cgroup(const char *path, const char *prefix, size_t n_columns, OutputFlags flags); +int show_cgroup_and_extra( + const char *path, + const char *prefix, + size_t n_columns, + const pid_t extra_pids[], + size_t n_extra_pids, + OutputFlags flags); int show_cgroup_get_unit_path_and_warn( sd_bus *bus, diff --git a/src/shared/condition.c b/src/shared/condition.c index b09eff1bfb..186f0b6c4a 100644 --- a/src/shared/condition.c +++ b/src/shared/condition.c @@ -1091,7 +1091,7 @@ static int condition_test_psi(Condition *c, char **env) { return log_debug_errno(r, "Cannot determine slice \"%s\" cgroup path: %m", slice); /* We might be running under the user manager, so get the root path and prefix it accordingly. */ - r = cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, getpid_cached(), &root_scope); + r = cg_pid_get_path(getpid_cached(), &root_scope); if (r < 0) return log_debug_errno(r, "Failed to get root cgroup path: %m"); @@ -1110,7 +1110,7 @@ static int condition_test_psi(Condition *c, char **env) { free_and_replace(slice_path, slice_joined); } - r = cg_get_path(SYSTEMD_CGROUP_CONTROLLER, slice_path, controller, &pressure_path); + r = cg_get_path(slice_path, controller, &pressure_path); if (r < 0) return log_debug_errno(r, "Error getting cgroup pressure path from %s: %m", slice_path); diff --git a/src/shared/killall.c b/src/shared/killall.c index 0a41d251ef..729e0e2480 100644 --- a/src/shared/killall.c +++ b/src/shared/killall.c @@ -53,7 +53,7 @@ static bool is_in_survivor_cgroup(const PidRef *pid) { assert(pidref_is_set(pid)); - r = cg_pidref_get_path(/* controller= */ NULL, pid, &cgroup_path); + r = cg_pidref_get_path(pid, &cgroup_path); if (r == -EUNATCH) { log_warning_errno(r, "Process " PID_FMT " appears to originate in foreign namespace, ignoring.", pid->pid); return true; diff --git a/src/shared/tests.c b/src/shared/tests.c index 4eb07b11ff..53dda342a4 100644 --- a/src/shared/tests.c +++ b/src/shared/tests.c @@ -213,7 +213,7 @@ static int allocate_scope(void) { /* Let's try to run this test in a scope of its own, with delegation turned on, so that PID 1 doesn't * interfere with our cgroup management. */ - if (cg_pid_get_path(NULL, 0, &cgroup_root) >= 0 && cg_is_delegated(cgroup_root) && stderr_is_journal()) { + if (cg_pid_get_path(0, &cgroup_root) >= 0 && cg_is_delegated(cgroup_root) && stderr_is_journal()) { log_debug("Already running as a unit with delegated cgroup, not allocating a cgroup subroot."); return 0; } @@ -287,13 +287,19 @@ static int enter_cgroup(char **ret_cgroup, bool enter_subroot) { CGroupMask supported; int r; + r = cg_is_available(); + if (r < 0) + return r; + if (r == 0) + return log_warning_errno(SYNTHETIC_ERRNO(ENOMEDIUM), "cgroupfs v2 is not mounted."); + r = allocate_scope(); if (r < 0) log_warning_errno(r, "Couldn't allocate a scope unit for this test, proceeding without."); - r = cg_pid_get_path(NULL, 0, &cgroup_root); + r = cg_pid_get_path(0, &cgroup_root); if (IN_SET(r, -ENOMEDIUM, -ENOENT)) - return log_warning_errno(r, "cg_pid_get_path(NULL, 0, ...) failed: %m"); + return log_warning_errno(r, "cg_pid_get_path(0, ...) failed: %m"); ASSERT_OK(r); if (enter_subroot) diff --git a/src/systemctl/systemctl-show.c b/src/systemctl/systemctl-show.c index 2e7d3ffe75..97137ef170 100644 --- a/src/systemctl/systemctl-show.c +++ b/src/systemctl/systemctl-show.c @@ -929,7 +929,7 @@ static void print_status_info( if (i->control_pid > 0) extra[k++] = i->control_pid; - show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER, i->control_group, prefix, c, extra, k, get_output_flags()); + show_cgroup_and_extra(i->control_group, prefix, c, extra, k, get_output_flags()); } else if (r < 0) log_warning_errno(r, "Failed to dump process list for '%s', ignoring: %s", i->id, bus_error_message(&error, r)); @@ -2482,7 +2482,7 @@ static int show_system_status(sd_bus *bus) { r = unit_show_processes(bus, SPECIAL_ROOT_SLICE, mi.control_group, prefix, c, get_output_flags(), &error); if (r == -EBADR && arg_transport == BUS_TRANSPORT_LOCAL) /* Compatibility for really old systemd versions */ - show_cgroup(SYSTEMD_CGROUP_CONTROLLER, strempty(mi.control_group), prefix, c, get_output_flags()); + show_cgroup(strempty(mi.control_group), prefix, c, get_output_flags()); else if (r < 0) log_warning_errno(r, "Failed to dump process list for '%s', ignoring: %s", arg_host ?: hn, bus_error_message(&error, r)); diff --git a/src/test/test-bpf-devices.c b/src/test/test-bpf-devices.c index 74e58fd41d..78e7487655 100644 --- a/src/test/test-bpf-devices.c +++ b/src/test/test-bpf-devices.c @@ -266,10 +266,6 @@ int main(int argc, char *argv[]) { rl.rlim_cur = rl.rlim_max = MAX(rl.rlim_max, CAN_MEMLOCK_SIZE); (void) setrlimit(RLIMIT_MEMLOCK, &rl); - r = cg_all_unified(); - if (r <= 0) - return log_tests_skipped("We don't seem to be running with unified cgroup hierarchy"); - if (!can_memlock()) return log_tests_skipped("Can't use mlock()"); @@ -279,7 +275,7 @@ int main(int argc, char *argv[]) { if (r < 0) return log_tests_skipped_errno(r, "Failed to prepare cgroup subtree"); - r = cg_get_path(SYSTEMD_CGROUP_CONTROLLER, cgroup, NULL, &controller_path); + r = cg_get_path(cgroup, /* suffix = */ NULL, &controller_path); ASSERT_OK(r); _cleanup_(bpf_program_freep) BPFProgram *prog = NULL; diff --git a/src/test/test-bpf-firewall.c b/src/test/test-bpf-firewall.c index 7f06589907..c3d8e7d5d5 100644 --- a/src/test/test-bpf-firewall.c +++ b/src/test/test-bpf-firewall.c @@ -49,10 +49,9 @@ int main(int argc, char *argv[]) { if (!can_memlock()) return log_tests_skipped("Can't use mlock()"); - _cleanup_free_ char *cgroup_path = NULL; - r = enter_cgroup_subroot(&cgroup_path); + r = enter_cgroup_subroot(NULL); if (r == -ENOMEDIUM) - return log_tests_skipped("cgroupfs not available"); + return log_tests_skipped("cgroupfs v2 is not mounted"); r = find_executable("ping", NULL); if (r < 0) diff --git a/src/test/test-bpf-foreign-programs.c b/src/test/test-bpf-foreign-programs.c index 6ebd807326..bf56451d25 100644 --- a/src/test/test-bpf-foreign-programs.c +++ b/src/test/test-bpf-foreign-programs.c @@ -294,10 +294,6 @@ int main(int argc, char *argv[]) { if (!can_memlock()) return log_tests_skipped("Can't use mlock()"); - r = cg_all_unified(); - if (r <= 0) - return log_tests_skipped("Unified hierarchy is required"); - r = enter_cgroup_subroot(NULL); if (r == -ENOMEDIUM) return log_tests_skipped("cgroupfs not available"); diff --git a/src/test/test-cgroup-setup.c b/src/test/test-cgroup-setup.c index ce20c956d2..ae33e1fcd1 100644 --- a/src/test/test-cgroup-setup.c +++ b/src/test/test-cgroup-setup.c @@ -11,11 +11,6 @@ TEST(cg_create) { int r; - r = cg_unified_cached(false); - if (IN_SET(r, -ENOMEDIUM, -ENOENT)) - return (void) log_tests_skipped("cgroupfs is not mounted"); - ASSERT_OK(r); - _cleanup_free_ char *here = NULL; ASSERT_OK(cg_pid_get_path_shifted(0, NULL, &here)); @@ -43,38 +38,29 @@ TEST(cg_create) { ASSERT_OK_EQ(cg_create(test_c), 1); ASSERT_OK_ZERO(cg_create_and_attach(test_b, 0)); - ASSERT_OK_ZERO(cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, getpid_cached(), &path)); + ASSERT_OK_ZERO(cg_pid_get_path(getpid_cached(), &path)); ASSERT_STREQ(path, test_b); free(path); ASSERT_OK_ZERO(cg_attach(test_a, 0)); - ASSERT_OK_ZERO(cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, getpid_cached(), &path)); + ASSERT_OK_ZERO(cg_pid_get_path(getpid_cached(), &path)); ASSERT_TRUE(path_equal(path, test_a)); free(path); ASSERT_OK_EQ(cg_create_and_attach(test_d, 0), 1); - ASSERT_OK_ZERO(cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, getpid_cached(), &path)); + ASSERT_OK_ZERO(cg_pid_get_path(getpid_cached(), &path)); ASSERT_TRUE(path_equal(path, test_d)); free(path); - ASSERT_OK_ZERO(cg_get_path(SYSTEMD_CGROUP_CONTROLLER, test_d, NULL, &path)); + ASSERT_OK_ZERO(cg_get_path(test_d, /* suffix = */ NULL, &path)); log_debug("test_d: %s", path); - const char *full_d; - if (cg_all_unified()) - full_d = strjoina("/sys/fs/cgroup", test_d); - else if (cg_hybrid_unified()) - full_d = strjoina("/sys/fs/cgroup/unified", test_d); - else - full_d = strjoina("/sys/fs/cgroup/systemd", test_d); - ASSERT_TRUE(path_equal(path, full_d)); + ASSERT_TRUE(path_equal(path, strjoina("/sys/fs/cgroup", test_d))); free(path); - ASSERT_OK_POSITIVE(cg_is_empty(SYSTEMD_CGROUP_CONTROLLER, test_a)); - ASSERT_OK_ZERO(cg_is_empty(SYSTEMD_CGROUP_CONTROLLER, test_b)); - ASSERT_OK_POSITIVE(cg_is_empty(NULL, test_a)); - ASSERT_OK_POSITIVE(cg_is_empty(NULL, test_b)); + ASSERT_OK_POSITIVE(cg_is_empty(test_a)); + ASSERT_OK_ZERO(cg_is_empty(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)); @@ -86,4 +72,11 @@ TEST(cg_create) { ASSERT_OK(cg_trim(test_b, true)); } -DEFINE_TEST_MAIN(LOG_DEBUG); +static int intro(void) { + if (cg_is_available() <= 0) + return log_tests_skipped("cgroupfs v2 is not mounted"); + + return 0; +} + +DEFINE_TEST_MAIN_WITH_INTRO(LOG_DEBUG, intro); diff --git a/src/test/test-cgroup-util.c b/src/test/test-cgroup-util.c index 997bcf2215..0fd81284e8 100644 --- a/src/test/test-cgroup-util.c +++ b/src/test/test-cgroup-util.c @@ -252,7 +252,7 @@ TEST(proc, .sd_booted = true) { if (pidref_is_kernel_thread(&pid) != 0) continue; - r = cg_pidref_get_path(SYSTEMD_CGROUP_CONTROLLER, &pid, &path); + r = cg_pidref_get_path(&pid, &path); if (r == -ESRCH) continue; ASSERT_OK(r); @@ -322,47 +322,52 @@ TEST(escape, .sd_booted = true) { test_escape_one(".", "_."); } -TEST(controller_is_valid) { - assert_se(cg_controller_is_valid("foobar")); - assert_se(cg_controller_is_valid("foo_bar")); - assert_se(cg_controller_is_valid("name=foo")); - assert_se(!cg_controller_is_valid("")); - assert_se(!cg_controller_is_valid("name=")); - assert_se(!cg_controller_is_valid("=")); - assert_se(!cg_controller_is_valid("cpu,cpuacct")); - assert_se(!cg_controller_is_valid("_")); - assert_se(!cg_controller_is_valid("_foobar")); - assert_se(!cg_controller_is_valid("tatü")); -} - TEST(cg_split_spec) { char *c, *p; - ASSERT_OK_ZERO(cg_split_spec("foobar:/", &c, &p)); + ASSERT_OK(cg_split_spec("foobar:/", &c, &p)); ASSERT_STREQ(c, "foobar"); ASSERT_STREQ(p, "/"); c = mfree(c); p = mfree(p); - ASSERT_OK_ZERO(cg_split_spec("foobar:", &c, &p)); + ASSERT_OK(cg_split_spec("foobar:", &c, &p)); + ASSERT_STREQ(c, "foobar"); + ASSERT_NULL(p); + c = mfree(c); + + ASSERT_OK(cg_split_spec("foobar", &c, &p)); + ASSERT_STREQ(c, "foobar"); + ASSERT_NULL(p); + c = mfree(c); + + ASSERT_OK(cg_split_spec(":///", &c, &p)); + ASSERT_STREQ(c, ""); + ASSERT_STREQ(p, "/"); c = mfree(c); p = mfree(p); - ASSERT_FAIL(cg_split_spec("foobar:asdfd", &c, &p)); - ASSERT_FAIL(cg_split_spec(":///", &c, &p)); - ASSERT_FAIL(cg_split_spec(":", &c, &p)); - ASSERT_FAIL(cg_split_spec("", &c, &p)); - ASSERT_FAIL(cg_split_spec("fo/obar:/", &c, &p)); + ASSERT_OK(cg_split_spec(":", &c, &p)); + ASSERT_STREQ(c, ""); + ASSERT_NULL(p); + c = mfree(c); + + ASSERT_OK(cg_split_spec("", &c, &p)); + ASSERT_NULL(c); + ASSERT_NULL(p); + + ASSERT_OK(cg_split_spec("fo/obar:/", &c, &p)); + ASSERT_STREQ(c, "fo/obar"); + ASSERT_STREQ(p, "/"); + c = mfree(c); + p = mfree(p); + + ASSERT_ERROR(cg_split_spec("foobar:asdfd", &c, &p), EINVAL); ASSERT_OK(cg_split_spec("/", &c, &p)); ASSERT_NULL(c); ASSERT_STREQ(p, "/"); p = mfree(p); - - ASSERT_OK(cg_split_spec("foo", &c, &p)); - ASSERT_STREQ(c, "foo"); - ASSERT_NULL(p); - c = mfree(c); } static void test_slice_to_path_one(const char *unit, const char *path, int error) { @@ -428,68 +433,38 @@ TEST(mask_supported, .sd_booted = true) { yes_no(m & CGROUP_CONTROLLER_TO_MASK(c))); } -TEST(cg_tests) { - int all, hybrid, systemd, r; - - r = cg_unified(); - if (IN_SET(r, -ENOENT, -ENOMEDIUM)) - return (void) log_tests_skipped("cgroup not mounted"); - assert_se(r >= 0); - - all = cg_all_unified(); - assert_se(IN_SET(all, 0, 1)); - - hybrid = cg_hybrid_unified(); - assert_se(IN_SET(hybrid, 0, 1)); - - systemd = cg_unified_controller(SYSTEMD_CGROUP_CONTROLLER); - assert_se(IN_SET(systemd, 0, 1)); - - if (all) { - assert_se(systemd); - assert_se(!hybrid); - - } else if (hybrid) { - assert_se(systemd); - assert_se(!all); - - } else - assert_se(!systemd); -} - TEST(cg_get_keyed_attribute) { _cleanup_free_ char *val = NULL; char *vals3[3] = {}, *vals3a[3] = {}; int r; - r = cg_get_keyed_attribute("cpu", "/init.scope", "no_such_file", STRV_MAKE("no_such_attr"), &val); - if (r == -ENOMEDIUM || ERRNO_IS_PRIVILEGE(r)) { - log_info_errno(r, "Skipping most of %s, /sys/fs/cgroup not accessible: %m", __func__); - return; - } + if (cg_is_available() <= 0) + return (void) log_tests_skipped("cgroupfs v2 is not mounted"); + + r = cg_get_keyed_attribute("/init.scope", "no_such_file", STRV_MAKE("no_such_attr"), &val); + if (ERRNO_IS_PRIVILEGE(r)) + return (void) log_tests_skipped_errno(r, "/sys/fs/cgroup not accessible"); assert_se(r == -ENOENT); ASSERT_NULL(val); - if (access("/sys/fs/cgroup/init.scope/cpu.stat", R_OK) < 0) { - log_info_errno(errno, "Skipping most of %s, /init.scope/cpu.stat not accessible: %m", __func__); - return; - } + if (access("/sys/fs/cgroup/init.scope/cpu.stat", R_OK) < 0) + return (void) log_tests_skipped_errno(errno, "/init.scope/cpu.stat not accessible"); - assert_se(cg_get_keyed_attribute("cpu", "/init.scope", "cpu.stat", STRV_MAKE("no_such_attr"), &val) == -ENXIO); + assert_se(cg_get_keyed_attribute("/init.scope", "cpu.stat", STRV_MAKE("no_such_attr"), &val) == -ENXIO); ASSERT_NULL(val); - assert_se(cg_get_keyed_attribute("cpu", "/init.scope", "cpu.stat", STRV_MAKE("usage_usec"), &val) == 0); + assert_se(cg_get_keyed_attribute("/init.scope", "cpu.stat", STRV_MAKE("usage_usec"), &val) == 0); val = mfree(val); - assert_se(cg_get_keyed_attribute("cpu", "/init.scope", "cpu.stat", STRV_MAKE("usage_usec", "no_such_attr"), vals3) == -ENXIO); + assert_se(cg_get_keyed_attribute("/init.scope", "cpu.stat", STRV_MAKE("usage_usec", "no_such_attr"), vals3) == -ENXIO); - assert_se(cg_get_keyed_attribute("cpu", "/init.scope", "cpu.stat", + assert_se(cg_get_keyed_attribute("/init.scope", "cpu.stat", STRV_MAKE("usage_usec", "user_usec", "system_usec"), vals3) == 0); for (size_t i = 0; i < 3; i++) free(vals3[i]); - assert_se(cg_get_keyed_attribute("cpu", "/init.scope", "cpu.stat", + assert_se(cg_get_keyed_attribute("/init.scope", "cpu.stat", STRV_MAKE("system_usec", "user_usec", "usage_usec"), vals3a) == 0); for (size_t i = 0; i < 3; i++) free(vals3a[i]); @@ -508,16 +483,11 @@ TEST(cgroupid) { _cleanup_free_ char *p = NULL, *p2 = NULL; _cleanup_close_ int fd = -EBADF, fd2 = -EBADF; uint64_t id, id2; - int r; - r = cg_all_unified(); - if (IN_SET(r, -ENOMEDIUM, -ENOENT)) - return (void) log_tests_skipped("cgroupfs is not mounted"); - if (r == 0) - return (void) log_tests_skipped("skipping cgroupid test, not running in unified mode"); - ASSERT_OK_POSITIVE(r); + if (cg_is_available() <= 0) + return (void) log_tests_skipped("cgroupfs v2 is not mounted"); - fd = cg_path_open(SYSTEMD_CGROUP_CONTROLLER, "/"); + fd = cg_path_open("/"); ASSERT_OK(fd); ASSERT_OK(fd_get_path(fd, &p)); diff --git a/src/test/test-condition.c b/src/test/test-condition.c index 1bae2e3dd8..efebf6b49a 100644 --- a/src/test/test-condition.c +++ b/src/test/test-condition.c @@ -131,12 +131,9 @@ TEST(condition_test_control_group_controller) { Condition *condition; CGroupMask system_mask; _cleanup_free_ char *controller_name = NULL; - int r; - r = cg_unified(); - if (IN_SET(r, -ENOMEDIUM, -ENOENT)) - return (void) log_tests_skipped("cgroupfs is not mounted"); - ASSERT_OK(r); + if (cg_is_available() <= 0) + return (void) log_tests_skipped("cgroupfs v2 is not mounted"); /* Invalid controllers are ignored */ ASSERT_NOT_NULL((condition = condition_new(CONDITION_CONTROL_GROUP_CONTROLLER, "thisisnotarealcontroller", false, false))); @@ -1341,7 +1338,6 @@ TEST(condition_test_os_release) { TEST(condition_test_psi) { Condition *condition; CGroupMask mask; - int r; if (!is_pressure_supported()) return (void) log_notice("Pressure Stall Information (PSI) is not supported, skipping %s", __func__); @@ -1426,11 +1422,8 @@ TEST(condition_test_psi) { ASSERT_OK(condition_test(condition, environ)); condition_free(condition); - r = cg_all_unified(); - if (r < 0) - return (void) log_notice("Failed to determine whether the unified cgroups hierarchy is used, skipping %s", __func__); - if (r == 0) - return (void) log_notice("Requires the unified cgroups hierarchy, skipping %s", __func__); + if (cg_is_available() <= 0) + return (void) log_tests_skipped("cgroupfs v2 is not mounted"); if (cg_mask_supported(&mask) < 0) return (void) log_notice("Failed to get supported cgroup controllers, skipping %s", __func__); diff --git a/src/udev/iocost/iocost.c b/src/udev/iocost/iocost.c index 7558160d7b..8e2fabbe2c 100644 --- a/src/udev/iocost/iocost.c +++ b/src/udev/iocost/iocost.c @@ -222,13 +222,13 @@ static int apply_solution_for_path(const char *path, const char *name) { "\tio.cost.model: %s\n", path, name, qos, model); - r = cg_set_attribute("io", NULL, "io.cost.qos", qos); + r = cg_set_attribute(/* path = */ NULL, "io.cost.qos", qos); if (r < 0) { log_device_full_errno(device, r == -ENOENT ? LOG_DEBUG : LOG_ERR, r, "Failed to set io.cost.qos: %m"); return r == -ENOENT ? 0 : r; } - r = cg_set_attribute("io", NULL, "io.cost.model", model); + r = cg_set_attribute(/* path = */ NULL, "io.cost.model", model); if (r < 0) { log_device_full_errno(device, r == -ENOENT ? LOG_DEBUG : LOG_ERR, r, "Failed to set io.cost.model: %m"); return r == -ENOENT ? 0 : r; diff --git a/src/udev/udev-manager.c b/src/udev/udev-manager.c index a7118055d1..0dac43a3fb 100644 --- a/src/udev/udev-manager.c +++ b/src/udev/udev-manager.c @@ -1452,7 +1452,7 @@ int manager_main(Manager *manager) { assert(manager); _cleanup_free_ char *cgroup = NULL; - r = cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, 0, &cgroup); + r = cg_pid_get_path(0, &cgroup); if (r < 0) log_debug_errno(r, "Failed to get cgroup, ignoring: %m"); else if (endswith(cgroup, "/udev")) { /* If we are in a subcgroup /udev/ we assume it was delegated to us */