summaryrefslogtreecommitdiff
path: root/src/core/service.c
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2012-05-03 21:54:44 +0200
committerLennart Poettering <lennart@poettering.net>2012-05-03 21:54:44 +0200
commit88f3e0c91f08c65a479e1aa09f171550b744d829 (patch)
tree5fb94a693b555dd43952fcec34b4213b12f07839 /src/core/service.c
parent3beddc7861783347eb0aaf5fa492e8b2aef9e691 (diff)
service: explicitly remove control/ subcgroup after each control command
The kernel will only notify us of cgroups running empty if no subcgroups exist anymore. Hence make sure we don't leave our own control/ subcgroup around longer than necessary. https://bugzilla.redhat.com/show_bug.cgi?id=818381
Diffstat (limited to 'src/core/service.c')
-rw-r--r--src/core/service.c13
1 files changed, 9 insertions, 4 deletions
diff --git a/src/core/service.c b/src/core/service.c
index 02d1aa845b..40f1682784 100644
--- a/src/core/service.c
+++ b/src/core/service.c
@@ -1964,7 +1964,7 @@ static void service_enter_signal(Service *s, ServiceState state, ServiceResult f
if ((r = set_put(pid_set, LONG_TO_PTR(s->control_pid))) < 0)
goto fail;
- r = cgroup_bonding_kill_list(UNIT(s)->cgroup_bondings, sig, true, pid_set, NULL);
+ r = cgroup_bonding_kill_list(UNIT(s)->cgroup_bondings, sig, true, false, pid_set, NULL);
if (r < 0) {
if (r != -EAGAIN && r != -ESRCH && r != -ENOENT)
log_warning("Failed to kill control group: %s", strerror(-r));
@@ -2111,7 +2111,7 @@ static void service_enter_start(Service *s) {
/* We want to ensure that nobody leaks processes from
* START_PRE here, so let's go on a killing spree, People
* should not spawn long running processes from START_PRE. */
- cgroup_bonding_kill_list(UNIT(s)->cgroup_bondings, SIGKILL, true, NULL, "control");
+ cgroup_bonding_kill_list(UNIT(s)->cgroup_bondings, SIGKILL, true, true, NULL, "control");
if (s->type == SERVICE_FORKING) {
s->control_command_id = SERVICE_EXEC_START;
@@ -2187,7 +2187,7 @@ static void service_enter_start_pre(Service *s) {
/* Before we start anything, let's clear up what might
* be left from previous runs. */
- cgroup_bonding_kill_list(UNIT(s)->cgroup_bondings, SIGKILL, true, NULL, "control");
+ cgroup_bonding_kill_list(UNIT(s)->cgroup_bondings, SIGKILL, true, true, NULL, "control");
s->control_command_id = SERVICE_EXEC_START_PRE;
@@ -2924,6 +2924,11 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) {
if (f != SERVICE_SUCCESS)
s->result = f;
+ /* Immediately get rid of the cgroup, so that the
+ * kernel doesn't delay the cgroup empty messages for
+ * the service cgroup any longer than necessary */
+ cgroup_bonding_kill_list(UNIT(s)->cgroup_bondings, SIGKILL, true, true, NULL, "control");
+
if (s->control_command &&
s->control_command->command_next &&
f == SERVICE_SUCCESS) {
@@ -3674,7 +3679,7 @@ static int service_kill(Unit *u, KillWho who, KillMode mode, int signo, DBusErro
r = q;
goto finish;
}
- q = cgroup_bonding_kill_list(UNIT(s)->cgroup_bondings, signo, false, pid_set, NULL);
+ q = cgroup_bonding_kill_list(UNIT(s)->cgroup_bondings, signo, false, false, pid_set, NULL);
if (q < 0)
if (q != -EAGAIN && q != -ESRCH && q != -ENOENT)
r = q;