summaryrefslogtreecommitdiff
path: root/src/cgroup.c
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2010-08-31 23:24:47 +0200
committerLennart Poettering <lennart@poettering.net>2010-08-31 23:24:47 +0200
commitca949c9dcf17ea8d6512ac4c5c1a806ded9b8dc1 (patch)
treef5c0f995815f9b50ff54602a2a34bdc1ead51405 /src/cgroup.c
parent22f4096ca96acd504ac74e7dfad96f07edb6da51 (diff)
service: rework killing logic so that we always kill the main process, even if it left our service cgroup
Related to: http://bugzilla.redhat.com/show_bug.cgi?id=626477
Diffstat (limited to 'src/cgroup.c')
-rw-r--r--src/cgroup.c27
1 files changed, 19 insertions, 8 deletions
diff --git a/src/cgroup.c b/src/cgroup.c
index c1ea95ab56..d64ab63bea 100644
--- a/src/cgroup.c
+++ b/src/cgroup.c
@@ -138,7 +138,7 @@ int cgroup_bonding_install_list(CGroupBonding *first, pid_t pid) {
return 0;
}
-int cgroup_bonding_kill(CGroupBonding *b, int sig) {
+int cgroup_bonding_kill(CGroupBonding *b, int sig, Set *s) {
int r;
assert(b);
@@ -149,25 +149,36 @@ int cgroup_bonding_kill(CGroupBonding *b, int sig) {
assert(b->realized);
- return cg_kill_recursive(b->controller, b->path, sig, true, false);
+ return cg_kill_recursive(b->controller, b->path, sig, true, false, s);
}
-int cgroup_bonding_kill_list(CGroupBonding *first, int sig) {
+int cgroup_bonding_kill_list(CGroupBonding *first, int sig, Set *s) {
CGroupBonding *b;
- int r = -EAGAIN;
+ Set *allocated_set = NULL;
+ int ret = -EAGAIN, r;
+
+ if (!s)
+ if (!(s = allocated_set = set_new(trivial_hash_func, trivial_compare_func)))
+ return -ENOMEM;
LIST_FOREACH(by_unit, b, first) {
- if ((r = cgroup_bonding_kill(b, sig)) < 0) {
+ if ((r = cgroup_bonding_kill(b, sig, s)) < 0) {
if (r == -EAGAIN || r == -ESRCH)
continue;
- return r;
+ ret = r;
+ goto finish;
}
- return 0;
+ if (ret < 0 || r > 0)
+ ret = r;
}
- return r;
+finish:
+ if (allocated_set)
+ set_free(allocated_set);
+
+ return ret;
}
/* Returns 1 if the group is empty, 0 if it is not, -EAGAIN if we