From 6fa7e1a944a2dbb89e794ad0f9da5d0fda5dc4a9 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 29 Jan 2014 13:38:55 +0100 Subject: [PATCH 1/3] core: introduce new KillMode=mixed which sends SIGTERM only to the main process, but SIGKILL to all daemon processes This should fix some race with terminating systemd --user, where the system systemd instance might race against the user systemd instance when sending SIGTERM. --- man/systemd.kill.xml | 77 +++++++++++++++++++++++++++++++++----------------- src/core/kill.c | 1 + src/core/kill.h | 1 + src/core/unit.c | 3 +- units/user@.service.in | 1 + 5 files changed, 56 insertions(+), 27 deletions(-) diff --git a/man/systemd.kill.xml b/man/systemd.kill.xml index 1b10fba..a4009aa 100644 --- a/man/systemd.kill.xml +++ b/man/systemd.kill.xml @@ -44,39 +44,44 @@ systemd.kill - Kill environment configuration + Process killing procedure + configuration service.service, socket.socket, mount.mount, - swap.swap + swap.swap, + scope.scope Description Unit configuration files for services, sockets, - mount points and swap devices share a subset of - configuration options which define the process killing - parameters of spawned processes. + mount points, swap devices and scopes share a subset + of configuration options which define the + killing procedure of processes belonging to the unit. This man page lists the configuration options - shared by these four unit types. See + shared by these five unit types. See systemd.unit5 - for the common options of all unit configuration - files, and + for the common options shared by all unit + configuration files, and systemd.service5, systemd.socket5, - systemd.swap5 - and + systemd.swap5, systemd.mount5 - for more information on the specific unit - configuration files. The execution specific + and + systemd.scope5 + for more information on the configuration file options + specific to each unit type. + + The kill procedure configuration options are configured in the [Service], - [Socket], [Mount], or [Swap] section, depending on the unit - type. + [Socket], [Mount] or [Swap] section, depending on the + unit type. @@ -87,32 +92,40 @@ KillMode= Specifies how - processes of this service shall be + processes of this unit shall be killed. One of , , + , . If set to , all remaining processes in the control - group of this unit will be terminated - on unit stop (for services: after the + group of this unit will be killed on + unit stop (for services: after the stop command is executed, as configured with ExecStop=). If set to , only the main process itself is killed. If set - to , no process is + to the + SIGTERM signal + (see below) is sent to the main + process while the subsequent + SIGKILL signal + (see below) is sent to all remaining + processes of the unit's control + group. If set to + , no process is killed. In this case only the stop - command will be executed on unit - stop, but no process be killed + command will be executed on unit stop, + but no process be killed otherwise. Processes remaining alive after stop are left in their control group and the control group continues to exist after stop unless it is - empty. Defaults to - . + empty. Processes will first be terminated via @@ -133,14 +146,24 @@ option). See kill2 for more - information. + information. + + Defaults to + . KillSignal= Specifies which signal - to use when killing a - service. Defaults to SIGTERM. + to use when killing a service. This + controls the signal that is sent as + first step of shutting down a unit + (see above), and is usually followed + by SIGKILL (see + above and below). For a list of valid + signals, see + signal7. Defaults + to SIGTERM. @@ -184,7 +207,9 @@ systemd.swap5, systemd.mount5, systemd.exec5, - systemd.directives7 + systemd.directives7, + kill2, + signal7 diff --git a/src/core/kill.c b/src/core/kill.c index ea947c2..4271346 100644 --- a/src/core/kill.c +++ b/src/core/kill.c @@ -52,6 +52,7 @@ void kill_context_dump(KillContext *c, FILE *f, const char *prefix) { static const char* const kill_mode_table[_KILL_MODE_MAX] = { [KILL_CONTROL_GROUP] = "control-group", [KILL_PROCESS] = "process", + [KILL_MIXED] = "mixed", [KILL_NONE] = "none" }; diff --git a/src/core/kill.h b/src/core/kill.h index 41773f0..d5f125f 100644 --- a/src/core/kill.h +++ b/src/core/kill.h @@ -32,6 +32,7 @@ typedef enum KillMode { /* The kill mode is a property of a unit. */ KILL_CONTROL_GROUP = 0, KILL_PROCESS, + KILL_MIXED, KILL_NONE, _KILL_MODE_MAX, _KILL_MODE_INVALID = -1 diff --git a/src/core/unit.c b/src/core/unit.c index 4b97710..0b10e57 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -3007,7 +3007,7 @@ int unit_kill_context( } } - if (c->kill_mode == KILL_CONTROL_GROUP && u->cgroup_path) { + if ((c->kill_mode == KILL_CONTROL_GROUP || (c->kill_mode == KILL_MIXED && sigkill)) && u->cgroup_path) { _cleanup_set_free_ Set *pid_set = NULL; /* Exclude the main/control pids from being killed via the cgroup */ @@ -3021,6 +3021,7 @@ int unit_kill_context( log_warning_unit(u->id, "Failed to kill control group: %s", strerror(-r)); } else if (r > 0) { wait_for_exit = true; + if (c->send_sighup) { set_free(pid_set); diff --git a/units/user@.service.in b/units/user@.service.in index 3718a57..3bb8696 100644 --- a/units/user@.service.in +++ b/units/user@.service.in @@ -17,3 +17,4 @@ Environment=SHELL=%s ExecStart=-@rootlibexecdir@/systemd --user Environment=DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/%I/dbus/user_bus_socket Slice=user-%i.slice +KillMode=mixed -- 1.8.4