chiark / gitweb /
execute: make sending of SIGKILL on shutdown optional
authorLennart Poettering <lennart@poettering.net>
Tue, 18 Jan 2011 21:55:54 +0000 (22:55 +0100)
committerLennart Poettering <lennart@poettering.net>
Tue, 18 Jan 2011 21:55:54 +0000 (22:55 +0100)
13 files changed:
TODO
man/systemd.mount.xml
man/systemd.service.xml
man/systemd.socket.xml
man/systemd.swap.xml
src/execute.c
src/execute.h
src/load-fragment.c
src/mount.c
src/service.c
src/service.h
src/socket.c
src/swap.c

diff --git a/TODO b/TODO
index f87f7d1182982104bbe0618f036c172b0b59170b..4605115d0d2f537ff29b521d37674cbee854cafd 100644 (file)
--- a/TODO
+++ b/TODO
@@ -4,8 +4,6 @@
 
 * Fix multiple reload statements
 
-* make usage of SIGKILL when shutting down services optional
-
 * figure out what happened to bluez patch
 
 * in pam_systemd: add option to kill normal user sessions on logout but only those with uid != 0
@@ -23,8 +21,6 @@
 
 * finish syslog socket stuff
 
-* when starting systemd --user we get "Failed to set udev event buffer size."
-
 * configurable jitter for timer events
 
 * dbus should run with oom adjust set
index e2a9f2272d7d0f69c584924d3e7bc9741e8a06ae..c7045e84220a2f61c6b20ffcd1864afa6f742942 100644 (file)
                                 </para></listitem>
                         </varlistentry>
 
+                        <varlistentry>
+                                <term><varname>SendSIGKILL=</varname></term>
+                                <listitem><para>Specifies whether to
+                                send SIGKILL to remaining processes
+                                after a timeout, if the normal
+                                shutdown procedure left processes of
+                                the mount around. Takes a boolean
+                                value. Defaults to "yes".
+                                </para></listitem>
+                        </varlistentry>
                 </variablelist>
         </refsect1>
 
index e5262f6d60f8034852016155dcc5ce92bba33f8b..ee4d3937565b97c6f35649170212f6f8c2ab56f8 100644 (file)
                                 <option>control-group</option>.</para>
 
                                 <para>Processes will first be
-                                terminated via SIGTERM (unless this is
-                                changed via
+                                terminated via SIGTERM (unless the
+                                signal to send is changed via
                                 <varname>KillSignal=</varname>). If
                                 then after a delay (configured via the
                                 <varname>TimeoutSec=</varname> option)
                                 processes still remain, the
                                 termination request is repeated with
-                                the SIGKILL signal. See
+                                the SIGKILL signal (unless this is
+                                disabled via the
+                                <varname>SendSIGKILL=</varname>
+                                option). See
                                 <citerefentry><refentrytitle>kill</refentrytitle><manvolnum>2</manvolnum></citerefentry>
                                 for more
                                 information.</para></listitem>
                                 </para></listitem>
                         </varlistentry>
 
+                        <varlistentry>
+                                <term><varname>SendSIGKILL=</varname></term>
+                                <listitem><para>Specifies whether to
+                                send SIGKILL 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>NonBlocking=</varname></term>
                                 <listitem><para>Set O_NONBLOCK flag
index 47ad91374808b0904dd17ab86ff65aa891254285..1aea2f89b158d5cc97324726b2bf8275a0842600 100644 (file)
                                 </para></listitem>
                         </varlistentry>
 
+                        <varlistentry>
+                                <term><varname>SendSIGKILL=</varname></term>
+                                <listitem><para>Specifies whether to
+                                send SIGKILL to remaining processes
+                                after a timeout, if the normal
+                                shutdown procedure left processes of
+                                the socket around. Takes a boolean
+                                value. Defaults to "yes".
+                                </para></listitem>
+                        </varlistentry>
+
                         <varlistentry>
                                 <term><varname>Service=</varname></term>
                                 <listitem><para>Specifies the service
index 45467039e9e17b2842064c9682508d8911270ecb..45f8f40ae1caf78084bfa4e81cafc634f7dd574d 100644 (file)
                                 swap. Defaults to SIGTERM.
                                 </para></listitem>
                         </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>SendSIGKILL=</varname></term>
+                                <listitem><para>Specifies whether to
+                                send SIGKILL to remaining processes
+                                after a timeout, if the normal
+                                shutdown procedure left processes of
+                                the swap around. Takes a boolean
+                                value. Defaults to "yes".
+                                </para></listitem>
+                        </varlistentry>
                 </variablelist>
         </refsect1>
 
index 1e8dfaf7700fa7f62f712105b570e73062873fbb..10ce951c599fb02ecede8ca9718b9a14b8286956 100644 (file)
@@ -1349,6 +1349,7 @@ void exec_context_init(ExecContext *c) {
         c->syslog_level_prefix = true;
         c->mount_flags = MS_SHARED;
         c->kill_signal = SIGTERM;
+        c->send_sigkill = true;
 }
 
 void exec_context_done(ExecContext *c) {
@@ -1618,9 +1619,11 @@ void exec_context_dump(ExecContext *c, FILE* f, const char *prefix) {
 
         fprintf(f,
                 "%sKillMode: %s\n"
-                "%sKillSignal: SIG%s\n",
+                "%sKillSignal: SIG%s\n"
+                "%sSendSIGKILL: %s\n",
                 prefix, kill_mode_to_string(c->kill_mode),
-                prefix, signal_to_string(c->kill_signal));
+                prefix, signal_to_string(c->kill_signal),
+                prefix, yes_no(c->send_sigkill));
 
         if (c->utmp_id)
                 fprintf(f,
index dd84c3d29c4fa74971c96b7d1c023c9f62785662..a6766f9e995b0ed799dc9be37aefdd47636ab0f3 100644 (file)
@@ -145,6 +145,7 @@ struct ExecContext {
         /* Not relevant for spawning processes, just for killing */
         KillMode kill_mode;
         int kill_signal;
+        bool send_sigkill;
 
         cap_t capabilities;
         int secure_bits;
index b7c3cbbc3b2079f6fba18fce39dda632988dd15e..44b2cf06c115f88adb2e9d93052fed934ac93963 100644 (file)
@@ -1820,6 +1820,7 @@ static int load_from_path(Unit *u, const char *path) {
                 { "PAMName",                config_parse_string_printf,   &(context).pam_name,                             section   }, \
                 { "KillMode",               config_parse_kill_mode,       &(context).kill_mode,                            section   }, \
                 { "KillSignal",             config_parse_kill_signal,     &(context).kill_signal,                          section   }, \
+                { "SendSIGKILL",            config_parse_bool,            &(context).send_sigkill,                         section   }, \
                 { "UtmpIdentifier",         config_parse_string_printf,   &(context).utmp_id,                              section   }
 
         const ConfigItem items[] = {
index 077ab9160f848329304252e439bf11747a4fe203..5b433c970a85466f24a290b032896ff9f9446ee3 100644 (file)
@@ -1156,18 +1156,45 @@ static void mount_timer_event(Unit *u, uint64_t elapsed, Watch *w) {
                 break;
 
         case MOUNT_MOUNTING_SIGTERM:
-                log_warning("%s mounting timed out. Killing.", u->meta.id);
-                mount_enter_signal(m, MOUNT_MOUNTING_SIGKILL, false);
+                if (m->exec_context.send_sigkill) {
+                        log_warning("%s mounting timed out. Killing.", u->meta.id);
+                        mount_enter_signal(m, MOUNT_MOUNTING_SIGKILL, false);
+                } else {
+                        log_warning("%s mounting timed out. Skipping SIGKILL. Ignoring.", u->meta.id);
+
+                        if (m->from_proc_self_mountinfo)
+                                mount_enter_mounted(m, false);
+                        else
+                                mount_enter_dead(m, false);
+                }
                 break;
 
         case MOUNT_REMOUNTING_SIGTERM:
-                log_warning("%s remounting timed out. Killing.", u->meta.id);
-                mount_enter_signal(m, MOUNT_REMOUNTING_SIGKILL, false);
+                if (m->exec_context.send_sigkill) {
+                        log_warning("%s remounting timed out. Killing.", u->meta.id);
+                        mount_enter_signal(m, MOUNT_REMOUNTING_SIGKILL, false);
+                } else {
+                        log_warning("%s remounting timed out. Skipping SIGKILL. Ignoring.", u->meta.id);
+
+                        if (m->from_proc_self_mountinfo)
+                                mount_enter_mounted(m, false);
+                        else
+                                mount_enter_dead(m, false);
+                }
                 break;
 
         case MOUNT_UNMOUNTING_SIGTERM:
-                log_warning("%s unmounting timed out. Killing.", u->meta.id);
-                mount_enter_signal(m, MOUNT_UNMOUNTING_SIGKILL, false);
+                if (m->exec_context.send_sigkill) {
+                        log_warning("%s unmounting timed out. Killing.", u->meta.id);
+                        mount_enter_signal(m, MOUNT_UNMOUNTING_SIGKILL, false);
+                } else {
+                        log_warning("%s unmounting timed out. Skipping SIGKILL. Ignoring.", u->meta.id);
+
+                        if (m->from_proc_self_mountinfo)
+                                mount_enter_mounted(m, false);
+                        else
+                                mount_enter_dead(m, false);
+                }
                 break;
 
         case MOUNT_MOUNTING_SIGKILL:
index e4dfa40314afb7cd0e8b8e5d39d13e11ababaf63..e765004e4fe4434df26f0d66aa7472cfef74e960 100644 (file)
@@ -2712,8 +2712,14 @@ static void service_timer_event(Unit *u, uint64_t elapsed, Watch* w) {
                 break;
 
         case SERVICE_STOP_SIGTERM:
-                log_warning("%s stopping timed out. Killing.", u->meta.id);
-                service_enter_signal(s, SERVICE_STOP_SIGKILL, false);
+                if (s->exec_context.send_sigkill) {
+                        log_warning("%s stopping timed out. Killing.", u->meta.id);
+                        service_enter_signal(s, SERVICE_STOP_SIGKILL, false);
+                } else {
+                        log_warning("%s stopping timed out. Skipping SIGKILL.", u->meta.id);
+                        service_enter_stop_post(s, false);
+                }
+
                 break;
 
         case SERVICE_STOP_SIGKILL:
@@ -2731,8 +2737,14 @@ static void service_timer_event(Unit *u, uint64_t elapsed, Watch* w) {
                 break;
 
         case SERVICE_FINAL_SIGTERM:
-                log_warning("%s stopping timed out (2). Killing.", u->meta.id);
-                service_enter_signal(s, SERVICE_FINAL_SIGKILL, false);
+                if (s->exec_context.send_sigkill) {
+                        log_warning("%s stopping timed out (2). Killing.", u->meta.id);
+                        service_enter_signal(s, SERVICE_FINAL_SIGKILL, false);
+                } else {
+                        log_warning("%s stopping timed out (2). Skipping SIGKILL. Entering failed mode.", u->meta.id);
+                        service_enter_dead(s, false, true);
+                }
+
                 break;
 
         case SERVICE_FINAL_SIGKILL:
index 500bebff0886a3894f38562823c6ee1238ed863b..1b59dad9320586372d91fcdc46608e8fb726c8ce 100644 (file)
@@ -33,7 +33,7 @@ typedef enum ServiceState {
         SERVICE_START,
         SERVICE_START_POST,
         SERVICE_RUNNING,
-        SERVICE_EXITED,            /* Nothing is running anymore, but RemainAfterExit is true, ehnce this is OK */
+        SERVICE_EXITED,            /* Nothing is running anymore, but RemainAfterExit is true hence this is OK */
         SERVICE_RELOAD,
         SERVICE_STOP,              /* No STOP_PRE state, instead just register multiple STOP executables */
         SERVICE_STOP_SIGTERM,
index cb38ab3d69fe7bf79da3a001af392c07033c20fd..6ec49de4664375fa26697ff655e05a8bcc3cba57 100644 (file)
@@ -1688,8 +1688,13 @@ static void socket_timer_event(Unit *u, uint64_t elapsed, Watch *w) {
                 break;
 
         case SOCKET_STOP_PRE_SIGTERM:
-                log_warning("%s stopping timed out. Killing.", u->meta.id);
-                socket_enter_signal(s, SOCKET_STOP_PRE_SIGKILL, false);
+                if (s->exec_context.send_sigkill) {
+                        log_warning("%s stopping timed out. Killing.", u->meta.id);
+                        socket_enter_signal(s, SOCKET_STOP_PRE_SIGKILL, false);
+                } else {
+                        log_warning("%s stopping timed out. Skipping SIGKILL. Ignoring.", u->meta.id);
+                        socket_enter_stop_post(s, false);
+                }
                 break;
 
         case SOCKET_STOP_PRE_SIGKILL:
@@ -1703,8 +1708,13 @@ static void socket_timer_event(Unit *u, uint64_t elapsed, Watch *w) {
                 break;
 
         case SOCKET_FINAL_SIGTERM:
-                log_warning("%s stopping timed out (2). Killing.", u->meta.id);
-                socket_enter_signal(s, SOCKET_FINAL_SIGKILL, false);
+                if (s->exec_context.send_sigkill) {
+                        log_warning("%s stopping timed out (2). Killing.", u->meta.id);
+                        socket_enter_signal(s, SOCKET_FINAL_SIGKILL, false);
+                } else {
+                        log_warning("%s stopping timed out (2). Skipping SIGKILL. Ignoring.", u->meta.id);
+                        socket_enter_dead(s, false);
+                }
                 break;
 
         case SOCKET_FINAL_SIGKILL:
index 0d3cb2f40622c608865313ff23876f5139bc5c17..9bdb5aabf644c52b0693dd5ea84ef31f8f9539f6 100644 (file)
@@ -995,13 +995,23 @@ static void swap_timer_event(Unit *u, uint64_t elapsed, Watch *w) {
                 break;
 
         case SWAP_ACTIVATING_SIGTERM:
-                log_warning("%s activation timed out. Killing.", u->meta.id);
-                swap_enter_signal(s, SWAP_ACTIVATING_SIGKILL, false);
+                if (s->exec_context.send_sigkill) {
+                        log_warning("%s activation timed out. Killing.", u->meta.id);
+                        swap_enter_signal(s, SWAP_ACTIVATING_SIGKILL, false);
+                } else {
+                        log_warning("%s activation timed out. Skipping SIGKILL. Ignoring.", u->meta.id);
+                        swap_enter_dead(s, false);
+                }
                 break;
 
         case SWAP_DEACTIVATING_SIGTERM:
-                log_warning("%s deactivation timed out. Killing.", u->meta.id);
-                swap_enter_signal(s, SWAP_DEACTIVATING_SIGKILL, false);
+                if (s->exec_context.send_sigkill) {
+                        log_warning("%s deactivation timed out. Killing.", u->meta.id);
+                        swap_enter_signal(s, SWAP_DEACTIVATING_SIGKILL, false);
+                } else {
+                        log_warning("%s deactivation timed out. Skipping SIGKILL. Ignoring.", u->meta.id);
+                        swap_enter_dead(s, false);
+                }
                 break;
 
         case SWAP_ACTIVATING_SIGKILL: