Merge pull request #29453 from poettering/cgroup-no-controller
cgroup-util: drop "controller" argument from various cgroup helper calls
This commit is contained in:
+54
-55
@@ -280,7 +280,6 @@ int cg_rmdir(const char *controller, const char *path) {
|
||||
}
|
||||
|
||||
static int cg_kill_items(
|
||||
const char *controller,
|
||||
const char *path,
|
||||
int sig,
|
||||
CGroupFlags flags,
|
||||
@@ -318,7 +317,7 @@ static int cg_kill_items(
|
||||
pid_t pid = 0;
|
||||
done = true;
|
||||
|
||||
r = cg_enumerate_items(controller, path, &f, item);
|
||||
r = cg_enumerate_items(SYSTEMD_CGROUP_CONTROLLER, path, &f, item);
|
||||
if (r < 0) {
|
||||
if (ret >= 0 && r != -ENOENT)
|
||||
return r;
|
||||
@@ -382,7 +381,6 @@ static int cg_kill_items(
|
||||
}
|
||||
|
||||
int cg_kill(
|
||||
const char *controller,
|
||||
const char *path,
|
||||
int sig,
|
||||
CGroupFlags flags,
|
||||
@@ -392,7 +390,7 @@ int cg_kill(
|
||||
|
||||
int r, ret;
|
||||
|
||||
r = cg_kill_items(controller, path, sig, flags, s, log_kill, userdata, "cgroup.procs");
|
||||
r = cg_kill_items(path, sig, flags, s, log_kill, userdata, "cgroup.procs");
|
||||
if (r < 0 || sig != SIGKILL)
|
||||
return r;
|
||||
|
||||
@@ -401,32 +399,32 @@ int cg_kill(
|
||||
/* Only in case of killing with SIGKILL and when using cgroupsv2, kill remaining threads manually as
|
||||
a workaround for kernel bug. It was fixed in 5.2-rc5 (c03cd7738a83), backported to 4.19.66
|
||||
(4340d175b898) and 4.14.138 (feb6b123b7dd). */
|
||||
r = cg_unified_controller(controller);
|
||||
r = cg_unified_controller(SYSTEMD_CGROUP_CONTROLLER);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r == 0)
|
||||
return ret;
|
||||
|
||||
r = cg_kill_items(controller, path, sig, flags, s, log_kill, userdata, "cgroup.threads");
|
||||
r = cg_kill_items(path, sig, flags, s, log_kill, userdata, "cgroup.threads");
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return r > 0 || ret > 0;
|
||||
}
|
||||
|
||||
int cg_kill_kernel_sigkill(const char *controller, const char *path) {
|
||||
/* Kills the cgroup at `path` directly by writing to its cgroup.kill file.
|
||||
* This sends SIGKILL to all processes in the cgroup and has the advantage of
|
||||
* being completely atomic, unlike cg_kill_items. */
|
||||
int r;
|
||||
int cg_kill_kernel_sigkill(const char *path) {
|
||||
/* Kills the cgroup at `path` directly by writing to its cgroup.kill file. This sends SIGKILL to all
|
||||
* processes in the cgroup and has the advantage of being completely atomic, unlike cg_kill_items(). */
|
||||
|
||||
_cleanup_free_ char *killfile = NULL;
|
||||
int r;
|
||||
|
||||
assert(path);
|
||||
|
||||
if (!cg_kill_supported())
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
r = cg_get_path(controller, path, "cgroup.kill", &killfile);
|
||||
r = cg_get_path(SYSTEMD_CGROUP_CONTROLLER, path, "cgroup.kill", &killfile);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -438,7 +436,6 @@ int cg_kill_kernel_sigkill(const char *controller, const char *path) {
|
||||
}
|
||||
|
||||
int cg_kill_recursive(
|
||||
const char *controller,
|
||||
const char *path,
|
||||
int sig,
|
||||
CGroupFlags flags,
|
||||
@@ -446,57 +443,60 @@ int cg_kill_recursive(
|
||||
cg_kill_log_func_t log_kill,
|
||||
void *userdata) {
|
||||
|
||||
_cleanup_set_free_ Set *allocated_set = NULL;
|
||||
_cleanup_closedir_ DIR *d = NULL;
|
||||
int r, ret;
|
||||
char *fn;
|
||||
|
||||
assert(path);
|
||||
assert(sig >= 0);
|
||||
|
||||
if (sig == SIGKILL && cg_kill_supported() &&
|
||||
!FLAGS_SET(flags, CGROUP_IGNORE_SELF) && !s && !log_kill) {
|
||||
!FLAGS_SET(flags, CGROUP_IGNORE_SELF) && !s && !log_kill)
|
||||
/* ignore CGROUP_SIGCONT, since this is a no-op alongside SIGKILL */
|
||||
ret = cg_kill_kernel_sigkill(controller, path);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
} else {
|
||||
ret = cg_kill_kernel_sigkill(path);
|
||||
else {
|
||||
_cleanup_set_free_ Set *allocated_set = NULL;
|
||||
_cleanup_closedir_ DIR *d = NULL;
|
||||
|
||||
if (!s) {
|
||||
s = allocated_set = set_new(NULL);
|
||||
if (!s)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
ret = cg_kill(controller, path, sig, flags, s, log_kill, userdata);
|
||||
ret = cg_kill(path, sig, flags, s, log_kill, userdata);
|
||||
|
||||
r = cg_enumerate_subgroups(controller, path, &d);
|
||||
r = cg_enumerate_subgroups(SYSTEMD_CGROUP_CONTROLLER, path, &d);
|
||||
if (r < 0) {
|
||||
if (ret >= 0 && r != -ENOENT)
|
||||
return r;
|
||||
if (r != -ENOENT)
|
||||
RET_GATHER(ret, r);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
while ((r = cg_read_subgroup(d, &fn)) > 0) {
|
||||
_cleanup_free_ char *p = NULL;
|
||||
for (;;) {
|
||||
_cleanup_free_ char *fn = NULL, *p = NULL;
|
||||
|
||||
r = cg_read_subgroup(d, &fn);
|
||||
if (r < 0) {
|
||||
RET_GATHER(ret, r);
|
||||
break;
|
||||
}
|
||||
if (r == 0)
|
||||
break;
|
||||
|
||||
p = path_join(empty_to_root(path), fn);
|
||||
free(fn);
|
||||
if (!p)
|
||||
return -ENOMEM;
|
||||
|
||||
r = cg_kill_recursive(controller, p, sig, flags, s, log_kill, userdata);
|
||||
r = cg_kill_recursive(p, sig, flags, s, log_kill, userdata);
|
||||
if (r != 0 && ret >= 0)
|
||||
ret = r;
|
||||
}
|
||||
if (ret >= 0 && r < 0)
|
||||
ret = r;
|
||||
}
|
||||
|
||||
if (FLAGS_SET(flags, CGROUP_REMOVE)) {
|
||||
r = cg_rmdir(controller, path);
|
||||
if (r < 0 && ret >= 0 && !IN_SET(r, -ENOENT, -EBUSY))
|
||||
return r;
|
||||
r = cg_rmdir(SYSTEMD_CGROUP_CONTROLLER, path);
|
||||
if (!IN_SET(r, -ENOENT, -EBUSY))
|
||||
RET_GATHER(ret, r);
|
||||
}
|
||||
|
||||
return ret;
|
||||
@@ -649,7 +649,7 @@ int cg_get_path_and_check(const char *controller, const char *path, const char *
|
||||
return cg_get_path(controller, path, suffix, fs);
|
||||
}
|
||||
|
||||
int cg_set_xattr(const char *controller, const char *path, const char *name, const void *value, size_t size, int flags) {
|
||||
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;
|
||||
|
||||
@@ -657,14 +657,14 @@ int cg_set_xattr(const char *controller, const char *path, const char *name, con
|
||||
assert(name);
|
||||
assert(value || size <= 0);
|
||||
|
||||
r = cg_get_path(controller, path, NULL, &fs);
|
||||
r = cg_get_path(SYSTEMD_CGROUP_CONTROLLER, path, NULL, &fs);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return RET_NERRNO(setxattr(fs, name, value, size, flags));
|
||||
}
|
||||
|
||||
int cg_get_xattr(const char *controller, const char *path, const char *name, void *value, size_t size) {
|
||||
int cg_get_xattr(const char *path, const char *name, void *value, size_t size) {
|
||||
_cleanup_free_ char *fs = NULL;
|
||||
ssize_t n;
|
||||
int r;
|
||||
@@ -672,7 +672,7 @@ int cg_get_xattr(const char *controller, const char *path, const char *name, voi
|
||||
assert(path);
|
||||
assert(name);
|
||||
|
||||
r = cg_get_path(controller, path, NULL, &fs);
|
||||
r = cg_get_path(SYSTEMD_CGROUP_CONTROLLER, path, NULL, &fs);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -683,46 +683,42 @@ int cg_get_xattr(const char *controller, const char *path, const char *name, voi
|
||||
return (int) n;
|
||||
}
|
||||
|
||||
int cg_get_xattr_malloc(const char *controller, const char *path, const char *name, char **ret) {
|
||||
int cg_get_xattr_malloc(const char *path, const char *name, char **ret) {
|
||||
_cleanup_free_ char *fs = NULL;
|
||||
int r;
|
||||
|
||||
assert(path);
|
||||
assert(name);
|
||||
|
||||
r = cg_get_path(controller, path, NULL, &fs);
|
||||
r = cg_get_path(SYSTEMD_CGROUP_CONTROLLER, path, NULL, &fs);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = lgetxattr_malloc(fs, name, ret);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return r;
|
||||
return lgetxattr_malloc(fs, name, ret);
|
||||
}
|
||||
|
||||
int cg_get_xattr_bool(const char *controller, const char *path, const char *name) {
|
||||
int cg_get_xattr_bool(const char *path, const char *name) {
|
||||
_cleanup_free_ char *val = NULL;
|
||||
int r;
|
||||
|
||||
assert(path);
|
||||
assert(name);
|
||||
|
||||
r = cg_get_xattr_malloc(controller, path, name, &val);
|
||||
r = cg_get_xattr_malloc(path, name, &val);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return parse_boolean(val);
|
||||
}
|
||||
|
||||
int cg_remove_xattr(const char *controller, const char *path, const char *name) {
|
||||
int cg_remove_xattr(const char *path, const char *name) {
|
||||
_cleanup_free_ char *fs = NULL;
|
||||
int r;
|
||||
|
||||
assert(path);
|
||||
assert(name);
|
||||
|
||||
r = cg_get_path(controller, path, NULL, &fs);
|
||||
r = cg_get_path(SYSTEMD_CGROUP_CONTROLLER, path, NULL, &fs);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -1753,12 +1749,12 @@ int cg_slice_to_path(const char *unit, char **ret) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cg_is_threaded(const char *controller, const char *path) {
|
||||
int cg_is_threaded(const char *path) {
|
||||
_cleanup_free_ char *fs = NULL, *contents = NULL;
|
||||
_cleanup_strv_free_ char **v = NULL;
|
||||
int r;
|
||||
|
||||
r = cg_get_path(controller, path, "cgroup.type", &fs);
|
||||
r = cg_get_path(SYSTEMD_CGROUP_CONTROLLER, path, "cgroup.type", &fs);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -1845,21 +1841,24 @@ int cg_get_attribute_as_bool(const char *controller, const char *path, const cha
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cg_get_owner(const char *controller, const char *path, uid_t *ret_uid) {
|
||||
int cg_get_owner(const char *path, uid_t *ret_uid) {
|
||||
_cleanup_free_ char *f = NULL;
|
||||
struct stat stats;
|
||||
int r;
|
||||
|
||||
assert(ret_uid);
|
||||
|
||||
r = cg_get_path(controller, path, NULL, &f);
|
||||
r = cg_get_path(SYSTEMD_CGROUP_CONTROLLER, path, NULL, &f);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = stat(f, &stats);
|
||||
if (r < 0)
|
||||
if (stat(f, &stats) < 0)
|
||||
return -errno;
|
||||
|
||||
r = stat_verify_directory(&stats);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
*ret_uid = stats.st_uid;
|
||||
return 0;
|
||||
}
|
||||
|
||||
+10
-10
@@ -193,9 +193,9 @@ typedef enum CGroupFlags {
|
||||
|
||||
typedef int (*cg_kill_log_func_t)(pid_t pid, int sig, void *userdata);
|
||||
|
||||
int cg_kill(const char *controller, const char *path, int sig, CGroupFlags flags, Set *s, cg_kill_log_func_t kill_log, void *userdata);
|
||||
int cg_kill_kernel_sigkill(const char *controller, const char *path);
|
||||
int cg_kill_recursive(const char *controller, const char *path, int sig, CGroupFlags flags, Set *s, cg_kill_log_func_t kill_log, void *userdata);
|
||||
int cg_kill(const char *path, int sig, CGroupFlags flags, Set *s, cg_kill_log_func_t kill_log, void *userdata);
|
||||
int cg_kill_kernel_sigkill(const char *path);
|
||||
int cg_kill_recursive(const char *path, int sig, CGroupFlags flags, Set *s, cg_kill_log_func_t kill_log, void *userdata);
|
||||
|
||||
int cg_split_spec(const char *spec, char **ret_controller, char **ret_path);
|
||||
int cg_mangle_path(const char *path, char **result);
|
||||
@@ -207,7 +207,7 @@ int cg_pid_get_path(const char *controller, pid_t pid, char **path);
|
||||
|
||||
int cg_rmdir(const char *controller, const char *path);
|
||||
|
||||
int cg_is_threaded(const char *controller, const char *path);
|
||||
int cg_is_threaded(const char *path);
|
||||
|
||||
typedef enum {
|
||||
CG_KEY_MODE_GRACEFUL = 1 << 0,
|
||||
@@ -240,14 +240,14 @@ int cg_get_attribute_as_uint64(const char *controller, const char *path, const c
|
||||
/* Does a parse_boolean() on the attribute contents and sets ret accordingly */
|
||||
int cg_get_attribute_as_bool(const char *controller, const char *path, const char *attribute, bool *ret);
|
||||
|
||||
int cg_get_owner(const char *controller, const char *path, uid_t *ret_uid);
|
||||
int cg_get_owner(const char *path, uid_t *ret_uid);
|
||||
|
||||
int cg_set_xattr(const char *controller, const char *path, const char *name, const void *value, size_t size, int flags);
|
||||
int cg_get_xattr(const char *controller, const char *path, const char *name, void *value, size_t size);
|
||||
int cg_get_xattr_malloc(const char *controller, const char *path, const char *name, char **ret);
|
||||
int cg_set_xattr(const char *path, const char *name, const void *value, size_t size, int flags);
|
||||
int cg_get_xattr(const char *path, const char *name, void *value, size_t size);
|
||||
int cg_get_xattr_malloc(const char *path, const char *name, char **ret);
|
||||
/* Returns negative on error, and 0 or 1 on success for the bool value */
|
||||
int cg_get_xattr_bool(const char *controller, const char *path, const char *name);
|
||||
int cg_remove_xattr(const char *controller, const char *path, const char *name);
|
||||
int cg_get_xattr_bool(const char *path, const char *name);
|
||||
int cg_remove_xattr(const char *path, const char *name);
|
||||
|
||||
int cg_install_release_agent(const char *controller, const char *agent);
|
||||
int cg_uninstall_release_agent(const char *controller);
|
||||
|
||||
+11
-11
@@ -795,7 +795,7 @@ static void unit_set_xattr_graceful(Unit *u, const char *cgroup_path, const char
|
||||
cgroup_path = u->cgroup_path;
|
||||
}
|
||||
|
||||
r = cg_set_xattr(SYSTEMD_CGROUP_CONTROLLER, cgroup_path, name, data, size, 0);
|
||||
r = cg_set_xattr(cgroup_path, name, data, size, 0);
|
||||
if (r < 0)
|
||||
log_unit_debug_errno(u, r, "Failed to set '%s' xattr on control group %s, ignoring: %m", name, empty_to_root(cgroup_path));
|
||||
}
|
||||
@@ -813,7 +813,7 @@ static void unit_remove_xattr_graceful(Unit *u, const char *cgroup_path, const c
|
||||
cgroup_path = u->cgroup_path;
|
||||
}
|
||||
|
||||
r = cg_remove_xattr(SYSTEMD_CGROUP_CONTROLLER, cgroup_path, name);
|
||||
r = cg_remove_xattr(cgroup_path, name);
|
||||
if (r < 0 && !ERRNO_IS_XATTR_ABSENT(r))
|
||||
log_unit_debug_errno(u, r, "Failed to remove '%s' xattr flag on control group %s, ignoring: %m", name, empty_to_root(cgroup_path));
|
||||
}
|
||||
@@ -924,15 +924,15 @@ static void cgroup_xattr_apply(Unit *u) {
|
||||
}
|
||||
|
||||
if (u->survive_final_kill_signal) {
|
||||
r = cg_set_xattr(SYSTEMD_CGROUP_CONTROLLER,
|
||||
u->cgroup_path,
|
||||
"user.survive_final_kill_signal",
|
||||
"1",
|
||||
1,
|
||||
/* flags= */ 0);
|
||||
r = cg_set_xattr(
|
||||
u->cgroup_path,
|
||||
"user.survive_final_kill_signal",
|
||||
"1",
|
||||
1,
|
||||
/* flags= */ 0);
|
||||
/* user xattr support was added in kernel v5.7 */
|
||||
if (ERRNO_IS_NEG_NOT_SUPPORTED(r))
|
||||
r = cg_set_xattr(SYSTEMD_CGROUP_CONTROLLER,
|
||||
r = cg_set_xattr(
|
||||
u->cgroup_path,
|
||||
"trusted.survive_final_kill_signal",
|
||||
"1",
|
||||
@@ -3309,7 +3309,7 @@ int unit_check_oomd_kill(Unit *u) {
|
||||
else if (r == 0)
|
||||
return 0;
|
||||
|
||||
r = cg_get_xattr_malloc(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, "user.oomd_ooms", &value);
|
||||
r = cg_get_xattr_malloc(u->cgroup_path, "user.oomd_ooms", &value);
|
||||
if (r < 0 && !ERRNO_IS_XATTR_ABSENT(r))
|
||||
return r;
|
||||
|
||||
@@ -3327,7 +3327,7 @@ int unit_check_oomd_kill(Unit *u) {
|
||||
|
||||
n = 0;
|
||||
value = mfree(value);
|
||||
r = cg_get_xattr_malloc(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, "user.oomd_kill", &value);
|
||||
r = cg_get_xattr_malloc(u->cgroup_path, "user.oomd_kill", &value);
|
||||
if (r >= 0 && !isempty(value))
|
||||
(void) safe_atou64(value, &n);
|
||||
|
||||
|
||||
+21
-12
@@ -4172,7 +4172,7 @@ int unit_kill(
|
||||
if (!pid_set)
|
||||
return log_oom();
|
||||
|
||||
r = cg_kill_recursive(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, signo, 0, pid_set, kill_common_log, u);
|
||||
r = cg_kill_recursive(u->cgroup_path, signo, 0, pid_set, kill_common_log, u);
|
||||
if (r < 0) {
|
||||
if (!IN_SET(r, -ESRCH, -ENOENT)) {
|
||||
if (ret == 0) {
|
||||
@@ -4888,11 +4888,12 @@ int unit_kill_context(
|
||||
if (!pid_set)
|
||||
return -ENOMEM;
|
||||
|
||||
r = cg_kill_recursive(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path,
|
||||
sig,
|
||||
CGROUP_SIGCONT|CGROUP_IGNORE_SELF,
|
||||
pid_set,
|
||||
log_func, u);
|
||||
r = cg_kill_recursive(
|
||||
u->cgroup_path,
|
||||
sig,
|
||||
CGROUP_SIGCONT|CGROUP_IGNORE_SELF,
|
||||
pid_set,
|
||||
log_func, u);
|
||||
if (r < 0) {
|
||||
if (!IN_SET(r, -EAGAIN, -ESRCH, -ENOENT))
|
||||
log_unit_warning_errno(u, r, "Failed to kill control group %s, ignoring: %m", empty_to_root(u->cgroup_path));
|
||||
@@ -4917,11 +4918,13 @@ int unit_kill_context(
|
||||
if (!pid_set)
|
||||
return -ENOMEM;
|
||||
|
||||
(void) cg_kill_recursive(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path,
|
||||
SIGHUP,
|
||||
CGROUP_IGNORE_SELF,
|
||||
pid_set,
|
||||
NULL, NULL);
|
||||
(void) cg_kill_recursive(
|
||||
u->cgroup_path,
|
||||
SIGHUP,
|
||||
CGROUP_IGNORE_SELF,
|
||||
pid_set,
|
||||
/* kill_log= */ NULL,
|
||||
/* userdata= */ NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5903,7 +5906,13 @@ int unit_warn_leftover_processes(Unit *u, cg_kill_log_func_t log_func) {
|
||||
if (!u->cgroup_path)
|
||||
return 0;
|
||||
|
||||
return cg_kill_recursive(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, 0, 0, NULL, log_func, u);
|
||||
return cg_kill_recursive(
|
||||
u->cgroup_path,
|
||||
/* sig= */ 0,
|
||||
/* flags= */ 0,
|
||||
/* set= */ NULL,
|
||||
log_func,
|
||||
u);
|
||||
}
|
||||
|
||||
bool unit_needs_console(Unit *u) {
|
||||
|
||||
@@ -56,7 +56,7 @@ int client_context_read_log_filter_patterns(ClientContext *c, const char *cgroup
|
||||
if (r < 0)
|
||||
return log_debug_errno(r, "Failed to get the unit's cgroup path for %s: %m", cgroup);
|
||||
|
||||
r = cg_get_xattr_malloc(SYSTEMD_CGROUP_CONTROLLER, unit_cgroup, "user.journald_log_filter_patterns", &xattr);
|
||||
r = cg_get_xattr_malloc(unit_cgroup, "user.journald_log_filter_patterns", &xattr);
|
||||
if (ERRNO_IS_NEG_XATTR_ABSENT(r)) {
|
||||
client_set_filtering_patterns(c, NULL, NULL);
|
||||
return 0;
|
||||
|
||||
+8
-8
@@ -40,7 +40,7 @@ static int increment_oomd_xattr(const char *path, const char *xattr, uint64_t nu
|
||||
assert(path);
|
||||
assert(xattr);
|
||||
|
||||
r = cg_get_xattr_malloc(SYSTEMD_CGROUP_CONTROLLER, path, xattr, &value);
|
||||
r = cg_get_xattr_malloc(path, xattr, &value);
|
||||
if (r < 0 && !ERRNO_IS_XATTR_ABSENT(r))
|
||||
return r;
|
||||
|
||||
@@ -54,7 +54,7 @@ static int increment_oomd_xattr(const char *path, const char *xattr, uint64_t nu
|
||||
return -EOVERFLOW;
|
||||
|
||||
xsprintf(buf, "%"PRIu64, curr_count + num_procs_killed);
|
||||
r = cg_set_xattr(SYSTEMD_CGROUP_CONTROLLER, path, xattr, buf, strlen(buf), 0);
|
||||
r = cg_set_xattr(path, xattr, buf, strlen(buf), 0);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -157,14 +157,14 @@ int oomd_fetch_cgroup_oom_preference(OomdCGroupContext *ctx, const char *prefix)
|
||||
return log_debug_errno(SYNTHETIC_ERRNO(EINVAL),
|
||||
"%s is not a descendant of %s", ctx->path, prefix);
|
||||
|
||||
r = cg_get_owner(SYSTEMD_CGROUP_CONTROLLER, ctx->path, &uid);
|
||||
r = cg_get_owner(ctx->path, &uid);
|
||||
if (r < 0)
|
||||
return log_debug_errno(r, "Failed to get owner/group from %s: %m", ctx->path);
|
||||
|
||||
if (uid != 0) {
|
||||
uid_t prefix_uid;
|
||||
|
||||
r = cg_get_owner(SYSTEMD_CGROUP_CONTROLLER, prefix, &prefix_uid);
|
||||
r = cg_get_owner(prefix, &prefix_uid);
|
||||
if (r < 0)
|
||||
return log_debug_errno(r, "Failed to get owner/group from %s: %m", prefix);
|
||||
|
||||
@@ -176,14 +176,14 @@ int oomd_fetch_cgroup_oom_preference(OomdCGroupContext *ctx, const char *prefix)
|
||||
|
||||
/* Ignore most errors when reading the xattr since it is usually unset and cgroup xattrs are only used
|
||||
* as an optional feature of systemd-oomd (and the system might not even support them). */
|
||||
r = cg_get_xattr_bool(SYSTEMD_CGROUP_CONTROLLER, ctx->path, "user.oomd_avoid");
|
||||
r = cg_get_xattr_bool(ctx->path, "user.oomd_avoid");
|
||||
if (r == -ENOMEM)
|
||||
return log_oom_debug();
|
||||
if (r < 0 && !ERRNO_IS_XATTR_ABSENT(r))
|
||||
log_debug_errno(r, "Failed to get xattr user.oomd_avoid, ignoring: %m");
|
||||
ctx->preference = r > 0 ? MANAGED_OOM_PREFERENCE_AVOID : ctx->preference;
|
||||
|
||||
r = cg_get_xattr_bool(SYSTEMD_CGROUP_CONTROLLER, ctx->path, "user.oomd_omit");
|
||||
r = cg_get_xattr_bool(ctx->path, "user.oomd_omit");
|
||||
if (r == -ENOMEM)
|
||||
return log_oom_debug();
|
||||
if (r < 0 && !ERRNO_IS_XATTR_ABSENT(r))
|
||||
@@ -256,9 +256,9 @@ int oomd_cgroup_kill(const char *path, bool recurse, bool dry_run) {
|
||||
log_debug_errno(r, "Failed to set user.oomd_ooms before kill: %m");
|
||||
|
||||
if (recurse)
|
||||
r = cg_kill_recursive(SYSTEMD_CGROUP_CONTROLLER, path, SIGKILL, CGROUP_IGNORE_SELF, pids_killed, log_kill, NULL);
|
||||
r = cg_kill_recursive(path, SIGKILL, CGROUP_IGNORE_SELF, pids_killed, log_kill, NULL);
|
||||
else
|
||||
r = cg_kill(SYSTEMD_CGROUP_CONTROLLER, path, SIGKILL, CGROUP_IGNORE_SELF, pids_killed, log_kill, NULL);
|
||||
r = cg_kill(path, SIGKILL, CGROUP_IGNORE_SELF, pids_killed, log_kill, NULL);
|
||||
|
||||
/* The cgroup could have been cleaned up after we have sent SIGKILL to all of the processes, but before
|
||||
* we could do one last iteration of cgroup.procs to check. Or the service unit could have exited and
|
||||
|
||||
+10
-10
@@ -58,7 +58,7 @@ static void test_oomd_cgroup_kill(void) {
|
||||
assert_se(cg_create(SYSTEMD_CGROUP_CONTROLLER, cgroup) >= 0);
|
||||
|
||||
/* If we don't have permissions to set xattrs we're likely in a userns or missing capabilities */
|
||||
r = cg_set_xattr(SYSTEMD_CGROUP_CONTROLLER, cgroup, "user.oomd_test", "test", 4, 0);
|
||||
r = cg_set_xattr(cgroup, "user.oomd_test", "test", 4, 0);
|
||||
if (ERRNO_IS_PRIVILEGE(r) || ERRNO_IS_NOT_SUPPORTED(r))
|
||||
return (void) log_tests_skipped("Cannot set user xattrs");
|
||||
|
||||
@@ -77,7 +77,7 @@ static void test_oomd_cgroup_kill(void) {
|
||||
abort();
|
||||
}
|
||||
|
||||
assert_se(cg_get_xattr_malloc(SYSTEMD_CGROUP_CONTROLLER, cgroup, "user.oomd_ooms", &v) >= 0);
|
||||
assert_se(cg_get_xattr_malloc(cgroup, "user.oomd_ooms", &v) >= 0);
|
||||
assert_se(streq(v, i == 0 ? "1" : "2"));
|
||||
v = mfree(v);
|
||||
|
||||
@@ -85,7 +85,7 @@ static void test_oomd_cgroup_kill(void) {
|
||||
sleep(2);
|
||||
assert_se(cg_is_empty(SYSTEMD_CGROUP_CONTROLLER, cgroup) == true);
|
||||
|
||||
assert_se(cg_get_xattr_malloc(SYSTEMD_CGROUP_CONTROLLER, cgroup, "user.oomd_kill", &v) >= 0);
|
||||
assert_se(cg_get_xattr_malloc(cgroup, "user.oomd_kill", &v) >= 0);
|
||||
assert_se(streq(v, i == 0 ? "2" : "4"));
|
||||
}
|
||||
}
|
||||
@@ -433,13 +433,13 @@ static void test_oomd_fetch_cgroup_oom_preference(void) {
|
||||
|
||||
/* If we don't have permissions to set xattrs we're likely in a userns or missing capabilities
|
||||
* so skip the xattr portions of the test. */
|
||||
r = cg_set_xattr(SYSTEMD_CGROUP_CONTROLLER, cgroup, "user.oomd_test", "1", 1, 0);
|
||||
r = cg_set_xattr(cgroup, "user.oomd_test", "1", 1, 0);
|
||||
test_xattrs = !ERRNO_IS_PRIVILEGE(r) && !ERRNO_IS_NOT_SUPPORTED(r);
|
||||
|
||||
if (test_xattrs) {
|
||||
assert_se(oomd_fetch_cgroup_oom_preference(ctx, NULL) == 0);
|
||||
assert_se(cg_set_xattr(SYSTEMD_CGROUP_CONTROLLER, cgroup, "user.oomd_omit", "1", 1, 0) >= 0);
|
||||
assert_se(cg_set_xattr(SYSTEMD_CGROUP_CONTROLLER, cgroup, "user.oomd_avoid", "1", 1, 0) >= 0);
|
||||
assert_se(cg_set_xattr(cgroup, "user.oomd_omit", "1", 1, 0) >= 0);
|
||||
assert_se(cg_set_xattr(cgroup, "user.oomd_avoid", "1", 1, 0) >= 0);
|
||||
|
||||
/* omit takes precedence over avoid when both are set to true */
|
||||
assert_se(oomd_fetch_cgroup_oom_preference(ctx, NULL) == 0);
|
||||
@@ -452,8 +452,8 @@ static void test_oomd_fetch_cgroup_oom_preference(void) {
|
||||
|
||||
/* also check when only avoid is set to true */
|
||||
if (test_xattrs) {
|
||||
assert_se(cg_set_xattr(SYSTEMD_CGROUP_CONTROLLER, cgroup, "user.oomd_omit", "0", 1, 0) >= 0);
|
||||
assert_se(cg_set_xattr(SYSTEMD_CGROUP_CONTROLLER, cgroup, "user.oomd_avoid", "1", 1, 0) >= 0);
|
||||
assert_se(cg_set_xattr(cgroup, "user.oomd_omit", "0", 1, 0) >= 0);
|
||||
assert_se(cg_set_xattr(cgroup, "user.oomd_avoid", "1", 1, 0) >= 0);
|
||||
assert_se(oomd_cgroup_context_acquire(cgroup, &ctx) == 0);
|
||||
assert_se(oomd_fetch_cgroup_oom_preference(ctx, NULL) == 0);
|
||||
assert_se(ctx->preference == MANAGED_OOM_PREFERENCE_AVOID);
|
||||
@@ -464,9 +464,9 @@ static void test_oomd_fetch_cgroup_oom_preference(void) {
|
||||
/* Root cgroup is live and not made on demand like the cgroup the test runs in. It can have varying
|
||||
* xattrs set already so let's read in the booleans first to get the final preference value. */
|
||||
assert_se(oomd_cgroup_context_acquire("", &ctx) == 0);
|
||||
root_xattrs = cg_get_xattr_bool(SYSTEMD_CGROUP_CONTROLLER, "", "user.oomd_omit");
|
||||
root_xattrs = cg_get_xattr_bool("", "user.oomd_omit");
|
||||
root_pref = root_xattrs > 0 ? MANAGED_OOM_PREFERENCE_OMIT : MANAGED_OOM_PREFERENCE_NONE;
|
||||
root_xattrs = cg_get_xattr_bool(SYSTEMD_CGROUP_CONTROLLER, "", "user.oomd_avoid");
|
||||
root_xattrs = cg_get_xattr_bool("", "user.oomd_avoid");
|
||||
root_pref = root_xattrs > 0 ? MANAGED_OOM_PREFERENCE_AVOID : MANAGED_OOM_PREFERENCE_NONE;
|
||||
assert_se(oomd_fetch_cgroup_oom_preference(ctx, NULL) == 0);
|
||||
assert_se(ctx->preference == root_pref);
|
||||
|
||||
@@ -352,7 +352,7 @@ int cg_attach(const char *controller, const char *path, pid_t pid) {
|
||||
xsprintf(c, PID_FMT "\n", pid);
|
||||
|
||||
r = write_string_file(fs, c, WRITE_STRING_FILE_DISABLE_BUFFER);
|
||||
if (r == -EOPNOTSUPP && cg_is_threaded(controller, path) > 0)
|
||||
if (r == -EOPNOTSUPP && cg_is_threaded(path) > 0)
|
||||
/* When the threaded mode is used, we cannot read/write the file. Let's return recognizable error. */
|
||||
return -EUCLEAN;
|
||||
if (r < 0)
|
||||
|
||||
@@ -56,12 +56,10 @@ static bool is_survivor_cgroup(pid_t pid) {
|
||||
return false;
|
||||
}
|
||||
|
||||
r = cg_get_xattr_bool(SYSTEMD_CGROUP_CONTROLLER, cgroup_path, "user.survive_final_kill_signal");
|
||||
r = cg_get_xattr_bool(cgroup_path, "user.survive_final_kill_signal");
|
||||
/* user xattr support was added to kernel v5.7, try with the trusted namespace as a fallback */
|
||||
if (ERRNO_IS_NEG_XATTR_ABSENT(r))
|
||||
r = cg_get_xattr_bool(SYSTEMD_CGROUP_CONTROLLER,
|
||||
cgroup_path,
|
||||
"trusted.survive_final_kill_signal");
|
||||
r = cg_get_xattr_bool(cgroup_path, "trusted.survive_final_kill_signal");
|
||||
if (r < 0)
|
||||
log_debug_errno(r,
|
||||
"Failed to get survive_final_kill_signal xattr of %s, ignoring: %m",
|
||||
|
||||
@@ -106,18 +106,18 @@ TEST(cg_create) {
|
||||
assert_se(cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, test_a) > 0);
|
||||
assert_se(cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, test_b) == 0);
|
||||
|
||||
assert_se(cg_kill_recursive(SYSTEMD_CGROUP_CONTROLLER, test_a, 0, 0, NULL, NULL, NULL) == 0);
|
||||
assert_se(cg_kill_recursive(SYSTEMD_CGROUP_CONTROLLER, test_b, 0, 0, NULL, NULL, NULL) > 0);
|
||||
assert_se(cg_kill_recursive(test_a, 0, 0, NULL, NULL, NULL) == 0);
|
||||
assert_se(cg_kill_recursive(test_b, 0, 0, NULL, NULL, NULL) > 0);
|
||||
|
||||
assert_se(cg_migrate_recursive(SYSTEMD_CGROUP_CONTROLLER, test_b, SYSTEMD_CGROUP_CONTROLLER, test_a, 0) > 0);
|
||||
|
||||
assert_se(cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, test_a) == 0);
|
||||
assert_se(cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, test_b) > 0);
|
||||
|
||||
assert_se(cg_kill_recursive(SYSTEMD_CGROUP_CONTROLLER, test_a, 0, 0, NULL, NULL, NULL) > 0);
|
||||
assert_se(cg_kill_recursive(SYSTEMD_CGROUP_CONTROLLER, test_b, 0, 0, NULL, NULL, NULL) == 0);
|
||||
assert_se(cg_kill_recursive(test_a, 0, 0, NULL, NULL, NULL) > 0);
|
||||
assert_se(cg_kill_recursive(test_b, 0, 0, NULL, NULL, NULL) == 0);
|
||||
|
||||
cg_trim(SYSTEMD_CGROUP_CONTROLLER, test_b, false);
|
||||
(void) cg_trim(SYSTEMD_CGROUP_CONTROLLER, test_b, false);
|
||||
|
||||
assert_se(cg_rmdir(SYSTEMD_CGROUP_CONTROLLER, test_b) == 0);
|
||||
assert_se(cg_rmdir(SYSTEMD_CGROUP_CONTROLLER, test_a) < 0);
|
||||
|
||||
@@ -1183,7 +1183,7 @@ static int on_post(sd_event_source *s, void *userdata) {
|
||||
|
||||
if (manager->cgroup)
|
||||
/* cleanup possible left-over processes in our cgroup */
|
||||
(void) cg_kill(SYSTEMD_CGROUP_CONTROLLER, manager->cgroup, SIGKILL, CGROUP_IGNORE_SELF, NULL, NULL, NULL);
|
||||
(void) cg_kill(manager->cgroup, SIGKILL, CGROUP_IGNORE_SELF, /* set=*/ NULL, /* kill_log= */ NULL, /* userdata= */ NULL);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user