diff options
author | Martin Pitt <martin.pitt@ubuntu.com> | 2016-07-22 09:18:30 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2016-07-22 09:18:30 +0200 |
commit | bf3dd08a81f7500973d8a4add8c73a0856ae5f7d (patch) | |
tree | 0610e6bcaa4aaf00acbe4859e4b7253bf8040d03 /src/basic | |
parent | 5c3c778014f4c59dd97f31ca5ab2e7374f08bbf6 (diff) | |
parent | 756ed0e238b7243c2e4616083e838d90de6e33ed (diff) |
Merge pull request #3762 from poettering/sigkill-log
log about all processes we forcibly kill
Diffstat (limited to 'src/basic')
-rw-r--r-- | src/basic/cgroup-util.c | 69 | ||||
-rw-r--r-- | src/basic/cgroup-util.h | 18 | ||||
-rw-r--r-- | src/basic/process-util.c | 6 |
3 files changed, 65 insertions, 28 deletions
diff --git a/src/basic/cgroup-util.c b/src/basic/cgroup-util.c index 7cdc97ee3c..472e24b7a3 100644 --- a/src/basic/cgroup-util.c +++ b/src/basic/cgroup-util.c @@ -197,7 +197,15 @@ int cg_rmdir(const char *controller, const char *path) { return 0; } -int cg_kill(const char *controller, const char *path, int sig, bool sigcont, bool ignore_self, Set *s) { +int cg_kill( + const char *controller, + const char *path, + int sig, + CGroupFlags flags, + Set *s, + cg_kill_log_func_t log_kill, + void *userdata) { + _cleanup_set_free_ Set *allocated_set = NULL; bool done = false; int r, ret = 0; @@ -205,6 +213,11 @@ int cg_kill(const char *controller, const char *path, int sig, bool sigcont, boo assert(sig >= 0); + /* Don't send SIGCONT twice. Also, SIGKILL always works even when process is suspended, hence don't send + * SIGCONT on SIGKILL. */ + if (IN_SET(sig, SIGCONT, SIGKILL)) + flags &= ~CGROUP_SIGCONT; + /* This goes through the tasks list and kills them all. This * is repeated until no further processes are added to the * tasks list, to properly handle forking processes */ @@ -232,19 +245,22 @@ int cg_kill(const char *controller, const char *path, int sig, bool sigcont, boo while ((r = cg_read_pid(f, &pid)) > 0) { - if (ignore_self && pid == my_pid) + if ((flags & CGROUP_IGNORE_SELF) && pid == my_pid) continue; if (set_get(s, PID_TO_PTR(pid)) == PID_TO_PTR(pid)) continue; + if (log_kill) + log_kill(pid, sig, userdata); + /* If we haven't killed this process yet, kill * it */ if (kill(pid, sig) < 0) { if (ret >= 0 && errno != ESRCH) ret = -errno; } else { - if (sigcont && sig != SIGKILL) + if (flags & CGROUP_SIGCONT) (void) kill(pid, SIGCONT); if (ret == 0) @@ -278,7 +294,15 @@ int cg_kill(const char *controller, const char *path, int sig, bool sigcont, boo return ret; } -int cg_kill_recursive(const char *controller, const char *path, int sig, bool sigcont, bool ignore_self, bool rem, Set *s) { +int cg_kill_recursive( + const char *controller, + const char *path, + int sig, + CGroupFlags flags, + Set *s, + cg_kill_log_func_t log_kill, + void *userdata) { + _cleanup_set_free_ Set *allocated_set = NULL; _cleanup_closedir_ DIR *d = NULL; int r, ret; @@ -293,7 +317,7 @@ int cg_kill_recursive(const char *controller, const char *path, int sig, bool si return -ENOMEM; } - ret = cg_kill(controller, path, sig, sigcont, ignore_self, s); + ret = cg_kill(controller, path, sig, flags, s, log_kill, userdata); r = cg_enumerate_subgroups(controller, path, &d); if (r < 0) { @@ -311,15 +335,14 @@ int cg_kill_recursive(const char *controller, const char *path, int sig, bool si if (!p) return -ENOMEM; - r = cg_kill_recursive(controller, p, sig, sigcont, ignore_self, rem, s); + r = cg_kill_recursive(controller, p, sig, flags, s, log_kill, userdata); if (r != 0 && ret >= 0) ret = r; } - if (ret >= 0 && r < 0) ret = r; - if (rem) { + if (flags & CGROUP_REMOVE) { r = cg_rmdir(controller, path); if (r < 0 && ret >= 0 && r != -ENOENT && r != -EBUSY) return r; @@ -328,7 +351,13 @@ int cg_kill_recursive(const char *controller, const char *path, int sig, bool si return ret; } -int cg_migrate(const char *cfrom, const char *pfrom, const char *cto, const char *pto, bool ignore_self) { +int cg_migrate( + const char *cfrom, + const char *pfrom, + const char *cto, + const char *pto, + CGroupFlags flags) { + bool done = false; _cleanup_set_free_ Set *s = NULL; int r, ret = 0; @@ -363,7 +392,7 @@ int cg_migrate(const char *cfrom, const char *pfrom, const char *cto, const char /* This might do weird stuff if we aren't a * single-threaded program. However, we * luckily know we are not */ - if (ignore_self && pid == my_pid) + if ((flags & CGROUP_IGNORE_SELF) && pid == my_pid) continue; if (set_get(s, PID_TO_PTR(pid)) == PID_TO_PTR(pid)) @@ -411,8 +440,7 @@ int cg_migrate_recursive( const char *pfrom, const char *cto, const char *pto, - bool ignore_self, - bool rem) { + CGroupFlags flags) { _cleanup_closedir_ DIR *d = NULL; int r, ret = 0; @@ -423,7 +451,7 @@ int cg_migrate_recursive( assert(cto); assert(pto); - ret = cg_migrate(cfrom, pfrom, cto, pto, ignore_self); + ret = cg_migrate(cfrom, pfrom, cto, pto, flags); r = cg_enumerate_subgroups(cfrom, pfrom, &d); if (r < 0) { @@ -441,7 +469,7 @@ int cg_migrate_recursive( if (!p) return -ENOMEM; - r = cg_migrate_recursive(cfrom, p, cto, pto, ignore_self, rem); + r = cg_migrate_recursive(cfrom, p, cto, pto, flags); if (r != 0 && ret >= 0) ret = r; } @@ -449,7 +477,7 @@ int cg_migrate_recursive( if (r < 0 && ret >= 0) ret = r; - if (rem) { + if (flags & CGROUP_REMOVE) { r = cg_rmdir(cfrom, pfrom); if (r < 0 && ret >= 0 && r != -ENOENT && r != -EBUSY) return r; @@ -463,8 +491,7 @@ int cg_migrate_recursive_fallback( const char *pfrom, const char *cto, const char *pto, - bool ignore_self, - bool rem) { + CGroupFlags flags) { int r; @@ -473,7 +500,7 @@ int cg_migrate_recursive_fallback( assert(cto); assert(pto); - r = cg_migrate_recursive(cfrom, pfrom, cto, pto, ignore_self, rem); + r = cg_migrate_recursive(cfrom, pfrom, cto, pto, flags); if (r < 0) { char prefix[strlen(pto) + 1]; @@ -482,7 +509,7 @@ int cg_migrate_recursive_fallback( PATH_FOREACH_PREFIX(prefix, pto) { int q; - q = cg_migrate_recursive(cfrom, pfrom, cto, prefix, ignore_self, rem); + q = cg_migrate_recursive(cfrom, pfrom, cto, prefix, flags); if (q >= 0) return q; } @@ -1955,7 +1982,7 @@ int cg_migrate_everywhere(CGroupMask supported, const char *from, const char *to int r = 0, unified; if (!path_equal(from, to)) { - r = cg_migrate_recursive(SYSTEMD_CGROUP_CONTROLLER, from, SYSTEMD_CGROUP_CONTROLLER, to, false, true); + r = cg_migrate_recursive(SYSTEMD_CGROUP_CONTROLLER, from, SYSTEMD_CGROUP_CONTROLLER, to, CGROUP_REMOVE); if (r < 0) return r; } @@ -1979,7 +2006,7 @@ int cg_migrate_everywhere(CGroupMask supported, const char *from, const char *to if (!p) p = to; - (void) cg_migrate_recursive_fallback(SYSTEMD_CGROUP_CONTROLLER, to, cgroup_controller_to_string(c), p, false, false); + (void) cg_migrate_recursive_fallback(SYSTEMD_CGROUP_CONTROLLER, to, cgroup_controller_to_string(c), p, 0); } return 0; diff --git a/src/basic/cgroup-util.h b/src/basic/cgroup-util.h index 4bb5291296..14ebde5fc9 100644 --- a/src/basic/cgroup-util.h +++ b/src/basic/cgroup-util.h @@ -135,12 +135,20 @@ int cg_read_event(const char *controller, const char *path, const char *event, int cg_enumerate_subgroups(const char *controller, const char *path, DIR **_d); int cg_read_subgroup(DIR *d, char **fn); -int cg_kill(const char *controller, const char *path, int sig, bool sigcont, bool ignore_self, Set *s); -int cg_kill_recursive(const char *controller, const char *path, int sig, bool sigcont, bool ignore_self, bool remove, Set *s); +typedef enum CGroupFlags { + CGROUP_SIGCONT = 1, + CGROUP_IGNORE_SELF = 2, + CGROUP_REMOVE = 4, +} CGroupFlags; -int cg_migrate(const char *cfrom, const char *pfrom, const char *cto, const char *pto, bool ignore_self); -int cg_migrate_recursive(const char *cfrom, const char *pfrom, const char *cto, const char *pto, bool ignore_self, bool remove); -int cg_migrate_recursive_fallback(const char *cfrom, const char *pfrom, const char *cto, const char *pto, bool ignore_self, bool rem); +typedef void (*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_recursive(const char *controller, const char *path, int sig, CGroupFlags flags, Set *s, cg_kill_log_func_t kill_log, void *userdata); + +int cg_migrate(const char *cfrom, const char *pfrom, const char *cto, const char *pto, CGroupFlags flags); +int cg_migrate_recursive(const char *cfrom, const char *pfrom, const char *cto, const char *pto, CGroupFlags flags); +int cg_migrate_recursive_fallback(const char *cfrom, const char *pfrom, const char *cto, const char *pto, CGroupFlags flags); int cg_split_spec(const char *spec, char **controller, char **path); int cg_mangle_path(const char *path, char **result); diff --git a/src/basic/process-util.c b/src/basic/process-util.c index e38b67405e..54b644ad56 100644 --- a/src/basic/process-util.c +++ b/src/basic/process-util.c @@ -625,8 +625,10 @@ int kill_and_sigcont(pid_t pid, int sig) { r = kill(pid, sig) < 0 ? -errno : 0; - if (r >= 0) - kill(pid, SIGCONT); + /* If this worked, also send SIGCONT, unless we already just sent a SIGCONT, or SIGKILL was sent which isn't + * affected by a process being suspended anyway. */ + if (r >= 0 && !IN_SET(SIGCONT, SIGKILL)) + (void) kill(pid, SIGCONT); return r; } |