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.
This commit is contained in:
Lennart Poettering 2014-01-29 13:38:55 +01:00
parent 373f14222e
commit 58ea275a68
5 changed files with 56 additions and 27 deletions

View file

@ -44,39 +44,44 @@
<refnamediv> <refnamediv>
<refname>systemd.kill</refname> <refname>systemd.kill</refname>
<refpurpose>Kill environment configuration</refpurpose> <refpurpose>Process killing procedure
configuration</refpurpose>
</refnamediv> </refnamediv>
<refsynopsisdiv> <refsynopsisdiv>
<para><filename><replaceable>service</replaceable>.service</filename>, <para><filename><replaceable>service</replaceable>.service</filename>,
<filename><replaceable>socket</replaceable>.socket</filename>, <filename><replaceable>socket</replaceable>.socket</filename>,
<filename><replaceable>mount</replaceable>.mount</filename>, <filename><replaceable>mount</replaceable>.mount</filename>,
<filename><replaceable>swap</replaceable>.swap</filename></para> <filename><replaceable>swap</replaceable>.swap</filename>,
<filename><replaceable>scope</replaceable>.scope</filename></para>
</refsynopsisdiv> </refsynopsisdiv>
<refsect1> <refsect1>
<title>Description</title> <title>Description</title>
<para>Unit configuration files for services, sockets, <para>Unit configuration files for services, sockets,
mount points and swap devices share a subset of mount points, swap devices and scopes share a subset
configuration options which define the process killing of configuration options which define the
parameters of spawned processes.</para> killing procedure of processes belonging to the unit.</para>
<para>This man page lists the configuration options <para>This man page lists the configuration options
shared by these four unit types. See shared by these five unit types. See
<citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry> <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>
for the common options of all unit configuration for the common options shared by all unit
files, and configuration files, and
<citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>, <citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
<citerefentry><refentrytitle>systemd.socket</refentrytitle><manvolnum>5</manvolnum></citerefentry>, <citerefentry><refentrytitle>systemd.socket</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
<citerefentry><refentrytitle>systemd.swap</refentrytitle><manvolnum>5</manvolnum></citerefentry> <citerefentry><refentrytitle>systemd.swap</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
and
<citerefentry><refentrytitle>systemd.mount</refentrytitle><manvolnum>5</manvolnum></citerefentry> <citerefentry><refentrytitle>systemd.mount</refentrytitle><manvolnum>5</manvolnum></citerefentry>
for more information on the specific unit and
configuration files. The execution specific <citerefentry><refentrytitle>systemd.scope</refentrytitle><manvolnum>5</manvolnum></citerefentry>
for more information on the configuration file options
specific to each unit type.</para>
<para>The kill procedure
configuration options are configured in the [Service], configuration options are configured in the [Service],
[Socket], [Mount], or [Swap] section, depending on the unit [Socket], [Mount] or [Swap] section, depending on the
type.</para> unit type.</para>
</refsect1> </refsect1>
<refsect1> <refsect1>
@ -87,32 +92,40 @@
<varlistentry> <varlistentry>
<term><varname>KillMode=</varname></term> <term><varname>KillMode=</varname></term>
<listitem><para>Specifies how <listitem><para>Specifies how
processes of this service shall be processes of this unit shall be
killed. One of killed. One of
<option>control-group</option>, <option>control-group</option>,
<option>process</option>, <option>process</option>,
<option>mixed</option>,
<option>none</option>.</para> <option>none</option>.</para>
<para>If set to <para>If set to
<option>control-group</option>, all <option>control-group</option>, all
remaining processes in the control remaining processes in the control
group of this unit will be terminated group of this unit will be killed on
on unit stop (for services: after the unit stop (for services: after the
stop command is executed, as stop command is executed, as
configured with configured with
<varname>ExecStop=</varname>). If set <varname>ExecStop=</varname>). If set
to <option>process</option>, only the to <option>process</option>, only the
main process itself is killed. If set main process itself is killed. If set
to <option>none</option>, no process is to <option>mixed</option> the
<constant>SIGTERM</constant> signal
(see below) is sent to the main
process while the subsequent
<constant>SIGKILL</constant> signal
(see below) is sent to all remaining
processes of the unit's control
group. If set to
<option>none</option>, no process is
killed. In this case only the stop killed. In this case only the stop
command will be executed on unit command will be executed on unit stop,
stop, but no process be killed but no process be killed
otherwise. Processes remaining alive otherwise. Processes remaining alive
after stop are left in their control after stop are left in their control
group and the control group continues group and the control group continues
to exist after stop unless it is to exist after stop unless it is
empty. Defaults to empty.</para>
<option>control-group</option>.</para>
<para>Processes will first be <para>Processes will first be
terminated via terminated via
@ -133,14 +146,24 @@
option). See option). See
<citerefentry><refentrytitle>kill</refentrytitle><manvolnum>2</manvolnum></citerefentry> <citerefentry><refentrytitle>kill</refentrytitle><manvolnum>2</manvolnum></citerefentry>
for more for more
information.</para></listitem> information.</para>
<para>Defaults to
<option>control-group</option>.</para></listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term><varname>KillSignal=</varname></term> <term><varname>KillSignal=</varname></term>
<listitem><para>Specifies which signal <listitem><para>Specifies which signal
to use when killing a to use when killing a service. This
service. Defaults to <constant>SIGTERM</constant>. controls the signal that is sent as
first step of shutting down a unit
(see above), and is usually followed
by <constant>SIGKILL</constant> (see
above and below). For a list of valid
signals, see
<citerefentry><refentrytitle>signal</refentrytitle><manvolnum>7</manvolnum></citerefentry>. Defaults
to <constant>SIGTERM</constant>.
</para></listitem> </para></listitem>
</varlistentry> </varlistentry>
@ -184,7 +207,9 @@
<citerefentry><refentrytitle>systemd.swap</refentrytitle><manvolnum>5</manvolnum></citerefentry>, <citerefentry><refentrytitle>systemd.swap</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
<citerefentry><refentrytitle>systemd.mount</refentrytitle><manvolnum>5</manvolnum></citerefentry>, <citerefentry><refentrytitle>systemd.mount</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
<citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry>, <citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
<citerefentry><refentrytitle>systemd.directives</refentrytitle><manvolnum>7</manvolnum></citerefentry> <citerefentry><refentrytitle>systemd.directives</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
<citerefentry><refentrytitle>kill</refentrytitle><manvolnum>2</manvolnum></citerefentry>,
<citerefentry><refentrytitle>signal</refentrytitle><manvolnum>7</manvolnum></citerefentry>
</para> </para>
</refsect1> </refsect1>

View file

@ -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] = { static const char* const kill_mode_table[_KILL_MODE_MAX] = {
[KILL_CONTROL_GROUP] = "control-group", [KILL_CONTROL_GROUP] = "control-group",
[KILL_PROCESS] = "process", [KILL_PROCESS] = "process",
[KILL_MIXED] = "mixed",
[KILL_NONE] = "none" [KILL_NONE] = "none"
}; };

View file

@ -32,6 +32,7 @@ typedef enum KillMode {
/* The kill mode is a property of a unit. */ /* The kill mode is a property of a unit. */
KILL_CONTROL_GROUP = 0, KILL_CONTROL_GROUP = 0,
KILL_PROCESS, KILL_PROCESS,
KILL_MIXED,
KILL_NONE, KILL_NONE,
_KILL_MODE_MAX, _KILL_MODE_MAX,
_KILL_MODE_INVALID = -1 _KILL_MODE_INVALID = -1

View file

@ -2966,7 +2966,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; _cleanup_set_free_ Set *pid_set = NULL;
/* Exclude the main/control pids from being killed via the cgroup */ /* Exclude the main/control pids from being killed via the cgroup */
@ -2980,6 +2980,7 @@ int unit_kill_context(
log_warning_unit(u->id, "Failed to kill control group: %s", strerror(-r)); log_warning_unit(u->id, "Failed to kill control group: %s", strerror(-r));
} else if (r > 0) { } else if (r > 0) {
wait_for_exit = true; wait_for_exit = true;
if (c->send_sighup) { if (c->send_sighup) {
set_free(pid_set); set_free(pid_set);

View file

@ -15,3 +15,4 @@ PAMName=systemd-user
Type=notify Type=notify
ExecStart=-@rootlibexecdir@/systemd --user ExecStart=-@rootlibexecdir@/systemd --user
Slice=user-%i.slice Slice=user-%i.slice
KillMode=mixed