]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
Make final kill signal configurable
authorJon Ringle <jringle@gridpoint.com>
Fri, 20 Jul 2018 15:22:43 +0000 (11:22 -0400)
committerLennart Poettering <lennart@poettering.net>
Mon, 23 Jul 2018 11:44:54 +0000 (13:44 +0200)
Usecase is to allow changing the final kill from SIGKILL to SIGQUIT which
should create a core dump useful for debugging why the service didn't stop
with the SIGTERM

doc/TRANSIENT-SETTINGS.md
man/systemd.kill.xml
shell-completion/bash/systemd-run
shell-completion/zsh/_systemd-run
src/core/dbus-kill.c
src/core/kill.c
src/core/kill.h
src/core/load-fragment-gperf.gperf.m4
src/core/load-fragment.h
src/core/unit.c
src/shared/bus-unit-util.c

index 2d73980f163f05d0fd23c55b22c2c5bea153ad86..bb13cfdbfe7885ca61e0f8f28c49bf8831774f17 100644 (file)
@@ -256,6 +256,7 @@ All process killing settings are available for transient units:
 ✓ SendSIGHUP=
 ✓ KillMode=
 ✓ KillSignal=
+✓ FinalKillSignal=
 ```
 
 ## Service Unit Settings
index 2112dea31a4a4e27e1ad46f38dd8ab43d80ea824..1a429062406a84185f95a99c624025e428672e0f 100644 (file)
@@ -94,7 +94,8 @@
         enabled with <varname>SendSIGHUP=</varname>). If then, after a
         delay (configured via the <varname>TimeoutStopSec=</varname>
         option), processes still remain, the termination request is
-        repeated with the <constant>SIGKILL</constant> signal (unless
+        repeated with the <constant>SIGKILL</constant> signal or the
+        signal specified via <varname>FinalKillSignal=</varname> (unless
         this is disabled via the <varname>SendSIGKILL=</varname>
         option). See
         <citerefentry><refentrytitle>kill</refentrytitle><manvolnum>2</manvolnum></citerefentry>
       <varlistentry>
         <term><varname>SendSIGKILL=</varname></term>
         <listitem><para>Specifies whether to send
-        <constant>SIGKILL</constant> to remaining processes after a
-        timeout, if the normal shutdown procedure left processes of
-        the service around. Takes a boolean value. Defaults to "yes".
+        <constant>SIGKILL</constant> (or the signal specified by
+        <varname>FinalKillSignal=</varname>) to remaining processes
+        after a timeout, if the normal shutdown procedure left
+        processes of the service around. Takes a boolean value.
+        Defaults to "yes".
+        </para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>FinalKillSignal=</varname></term>
+        <listitem><para>Specifies which signal to send to remaining
+        processes after a timeout if <varname>SendSIGKILL=</varname>
+        is enabled. The signal configured here should be one that is
+        not typically caught and processed by services (<constant>SIGTERM</constant>
+        is not suitable). Developers can find it useful to use this to
+        generate a coredump to troubleshoot why a service did not
+        terminate upon receiving the initial <constant>SIGTERM</constant>
+        signal. This can be achieved by configuring <varname>LimitCORE=</varname>
+        and setting <varname>FinalKillSignal=</varname> to either
+        <constant>SIGQUIT</constant> or <constant>SIGABRT</constant>
+        Defaults to <constant>SIGKILL</constant>.
         </para></listitem>
       </varlistentry>
 
index d317466b26f1d09b1fdb5a7386db33864bc3515c..4c60130dfa2b88e5e0c663a99ba1ac67f878c0de 100644 (file)
@@ -79,8 +79,8 @@ _systemd_run() {
                          SendSIGKILL= MemoryLimit= CPUShares= BlockIOWeight= User= Group=
                          DevicePolicy= KillMode= DeviceAllow= BlockIOReadBandwidth=
                          BlockIOWriteBandwidth= BlockIODeviceWeight= Nice= Environment=
-                         KillSignal= LimitCPU= LimitFSIZE= LimitDATA= LimitSTACK=
-                         LimitCORE= LimitRSS= LimitNOFILE= LimitAS= LimitNPROC=
+                         KillSignal= FinalKillSignal= LimitCPU= LimitFSIZE= LimitDATA=
+                         LimitSTACK= LimitCORE= LimitRSS= LimitNOFILE= LimitAS= LimitNPROC=
                          LimitMEMLOCK= LimitLOCKS= LimitSIGPENDING= LimitMSGQUEUE=
                          LimitNICE= LimitRTPRIO= LimitRTTIME= PrivateTmp= PrivateDevices=
                          PrivateNetwork= NoNewPrivileges= WorkingDirectory= RootDirectory=
index 0ad4b27a6fef32cb556c91232c7142df60b7af5b..a8a8e6fe34a9ac23d0734ff04b2606d0461fa669 100644 (file)
@@ -32,8 +32,8 @@ _arguments \
                 SendSIGKILL= MemoryLimit= CPUShares= BlockIOWeight= User= Group= \
                 DevicePolicy= KillMode= DeviceAllow= BlockIOReadBandwidth= \
                 BlockIOWriteBandwidth= BlockIODeviceWeight= Nice= Environment= \
-                KillSignal= LimitCPU= LimitFSIZE= LimitDATA= LimitSTACK= \
-                LimitCORE= LimitRSS= LimitNOFILE= LimitAS= LimitNPROC= \
+                KillSignal= FinalKillSignal= LimitCPU= LimitFSIZE= LimitDATA= \
+                LimitSTACK= LimitCORE= LimitRSS= LimitNOFILE= LimitAS= LimitNPROC= \
                 LimitMEMLOCK= LimitLOCKS= LimitSIGPENDING= LimitMSGQUEUE= \
                 LimitNICE= LimitRTPRIO= LimitRTTIME= PrivateTmp= PrivateDevices= \
                 PrivateNetwork= NoNewPrivileges= WorkingDirectory= RootDirectory= \
index 028e7ec1c16e95cc4e7ee006dfa339e4b2293038..3e2a7694a7b053f969ddf4c177b43c89c9b11089 100644 (file)
@@ -12,6 +12,7 @@ const sd_bus_vtable bus_kill_vtable[] = {
         SD_BUS_VTABLE_START(0),
         SD_BUS_PROPERTY("KillMode", "s", property_get_kill_mode, offsetof(KillContext, kill_mode), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("KillSignal", "i", bus_property_get_int, offsetof(KillContext, kill_signal), SD_BUS_VTABLE_PROPERTY_CONST),
+        SD_BUS_PROPERTY("FinalKillSignal", "i", bus_property_get_int, offsetof(KillContext, final_kill_signal), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("SendSIGKILL", "b", bus_property_get_bool, offsetof(KillContext, send_sigkill), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("SendSIGHUP", "b", bus_property_get_bool,  offsetof(KillContext, send_sighup), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_VTABLE_END
@@ -19,6 +20,7 @@ const sd_bus_vtable bus_kill_vtable[] = {
 
 static BUS_DEFINE_SET_TRANSIENT_PARSE(kill_mode, KillMode, kill_mode_from_string);
 static BUS_DEFINE_SET_TRANSIENT_TO_STRING(kill_signal, "i", int32_t, int, "%" PRIi32, signal_to_string_with_check);
+static BUS_DEFINE_SET_TRANSIENT_TO_STRING(final_kill_signal, "i", int32_t, int, "%" PRIi32, signal_to_string_with_check);
 
 int bus_kill_context_set_transient_property(
                 Unit *u,
@@ -47,5 +49,8 @@ int bus_kill_context_set_transient_property(
         if (streq(name, "KillSignal"))
                 return bus_set_transient_kill_signal(u, name, &c->kill_signal, message, flags, error);
 
+        if (streq(name, "FinalKillSignal"))
+                return bus_set_transient_final_kill_signal(u, name, &c->final_kill_signal, message, flags, error);
+
         return 0;
 }
index 929eebfe37c7bfce6e520480fb4a7febe12f09dd..73fa556d135f1841a05554009e1f78fe61e44115 100644 (file)
@@ -9,6 +9,7 @@ void kill_context_init(KillContext *c) {
         assert(c);
 
         c->kill_signal = SIGTERM;
+        c->final_kill_signal = SIGKILL;
         c->send_sigkill = true;
         c->send_sighup = false;
 }
@@ -21,10 +22,12 @@ void kill_context_dump(KillContext *c, FILE *f, const char *prefix) {
         fprintf(f,
                 "%sKillMode: %s\n"
                 "%sKillSignal: SIG%s\n"
+                "%sFinalKillSignal: SIG%s\n"
                 "%sSendSIGKILL: %s\n"
                 "%sSendSIGHUP:  %s\n",
                 prefix, kill_mode_to_string(c->kill_mode),
                 prefix, signal_to_string(c->kill_signal),
+                prefix, signal_to_string(c->final_kill_signal),
                 prefix, yes_no(c->send_sigkill),
                 prefix, yes_no(c->send_sighup));
 }
index 2d6aa943a6188765a7ffa0b652b7724e0e761e91..f4e312d75a591f78aeac248b6e849f32bbb3e1ee 100644 (file)
@@ -21,6 +21,7 @@ typedef enum KillMode {
 struct KillContext {
         KillMode kill_mode;
         int kill_signal;
+        int final_kill_signal;
         bool send_sigkill;
         bool send_sighup;
 };
index 290e8001d8ce4b08d3eb8728ee7fa223ff3e82be..7a276ea3c8c13bd7e4e3f2c8881703c05356a3c4 100644 (file)
@@ -151,7 +151,8 @@ m4_define(`KILL_CONTEXT_CONFIG_ITEMS',
 `$1.SendSIGKILL,                 config_parse_bool,                  0,                             offsetof($1, kill_context.send_sigkill)
 $1.SendSIGHUP,                   config_parse_bool,                  0,                             offsetof($1, kill_context.send_sighup)
 $1.KillMode,                     config_parse_kill_mode,             0,                             offsetof($1, kill_context.kill_mode)
-$1.KillSignal,                   config_parse_signal,                0,                             offsetof($1, kill_context.kill_signal)'
+$1.KillSignal,                   config_parse_signal,                0,                             offsetof($1, kill_context.kill_signal)
+$1.FinalKillSignal,              config_parse_signal,                0,                             offsetof($1, kill_context.final_kill_signal)'
 )m4_dnl
 m4_define(`CGROUP_CONTEXT_CONFIG_ITEMS',
 `$1.Slice,                       config_parse_unit_slice,            0,                             0
index dad281ef72a8a71eaaf63f9ac13634701c2b7edf..1cb5ccadf60c55e777645f20dba1669ce4c11954 100644 (file)
@@ -39,6 +39,7 @@ CONFIG_PARSER_PROTOTYPE(config_parse_exec_cpu_affinity);
 CONFIG_PARSER_PROTOTYPE(config_parse_exec_secure_bits);
 CONFIG_PARSER_PROTOTYPE(config_parse_capability_set);
 CONFIG_PARSER_PROTOTYPE(config_parse_kill_signal);
+CONFIG_PARSER_PROTOTYPE(config_parse_final_kill_signal);
 CONFIG_PARSER_PROTOTYPE(config_parse_exec_mount_flags);
 CONFIG_PARSER_PROTOTYPE(config_parse_timer);
 CONFIG_PARSER_PROTOTYPE(config_parse_trigger_unit);
index 113205bf254ca78eafa08e392cb853ee87cde0c2..23433be31c48ea6d0f4c520bb1a4435d86442c0a 100644 (file)
@@ -4479,7 +4479,7 @@ static int operation_to_signal(KillContext *c, KillOperation k) {
                 return c->kill_signal;
 
         case KILL_KILL:
-                return SIGKILL;
+                return c->final_kill_signal;
 
         case KILL_ABORT:
                 return SIGABRT;
index 0c713678e2da6639b750f5ef9e5e789165c433e1..8f90f2c31ae7d41ccaa88b6119dd18dc43d154dc 100644 (file)
@@ -1189,7 +1189,7 @@ static int bus_append_kill_property(sd_bus_message *m, const char *field, const
 
                 return bus_append_parse_boolean(m, field, eq);
 
-        if (streq(field, "KillSignal"))
+        if (STR_IN_SET(field, "KillSignal", "FinalKillSignal"))
 
                 return bus_append_signal_from_string(m, field, eq);