summaryrefslogtreecommitdiff
path: root/src/basic
diff options
context:
space:
mode:
authorMartin Pitt <martin.pitt@ubuntu.com>2016-07-22 09:18:30 +0200
committerGitHub <noreply@github.com>2016-07-22 09:18:30 +0200
commitbf3dd08a81f7500973d8a4add8c73a0856ae5f7d (patch)
tree0610e6bcaa4aaf00acbe4859e4b7253bf8040d03 /src/basic
parent5c3c778014f4c59dd97f31ca5ab2e7374f08bbf6 (diff)
parent756ed0e238b7243c2e4616083e838d90de6e33ed (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.c69
-rw-r--r--src/basic/cgroup-util.h18
-rw-r--r--src/basic/process-util.c6
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;
}