Drop remaining CGroup v1 specific code (#38969)
This commit is contained in:
@@ -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
|
||||
}
|
||||
|
||||
@@ -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 \
|
||||
|
||||
+115
-451
@@ -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;
|
||||
|
||||
|
||||
+14
-41
@@ -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_;
|
||||
|
||||
|
||||
+10
-23
@@ -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");
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
+10
-12
@@ -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)
|
||||
|
||||
+6
-6
@@ -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;
|
||||
|
||||
@@ -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");
|
||||
|
||||
|
||||
@@ -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");
|
||||
|
||||
|
||||
@@ -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");
|
||||
|
||||
|
||||
@@ -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");
|
||||
|
||||
|
||||
@@ -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");
|
||||
|
||||
|
||||
+18
-22
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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();
|
||||
|
||||
+1
-1
@@ -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;
|
||||
|
||||
|
||||
@@ -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");
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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));
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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));
|
||||
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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");
|
||||
|
||||
|
||||
@@ -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");
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
+7
-7
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
+12
-21
@@ -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(
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
+9
-3
@@ -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)
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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);
|
||||
|
||||
+47
-77
@@ -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));
|
||||
|
||||
@@ -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__);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 */
|
||||
|
||||
Reference in New Issue
Block a user