diff options
-rw-r--r-- | TODO | 4 | ||||
-rw-r--r-- | man/systemd.mount.xml | 10 | ||||
-rw-r--r-- | man/systemd.service.xml | 20 | ||||
-rw-r--r-- | man/systemd.socket.xml | 11 | ||||
-rw-r--r-- | man/systemd.swap.xml | 11 | ||||
-rw-r--r-- | src/execute.c | 7 | ||||
-rw-r--r-- | src/execute.h | 1 | ||||
-rw-r--r-- | src/load-fragment.c | 1 | ||||
-rw-r--r-- | src/mount.c | 39 | ||||
-rw-r--r-- | src/service.c | 20 | ||||
-rw-r--r-- | src/service.h | 2 | ||||
-rw-r--r-- | src/socket.c | 18 | ||||
-rw-r--r-- | src/swap.c | 18 |
13 files changed, 134 insertions, 28 deletions
@@ -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 diff --git a/man/systemd.mount.xml b/man/systemd.mount.xml index e2a9f2272d..c7045e8422 100644 --- a/man/systemd.mount.xml +++ b/man/systemd.mount.xml @@ -240,6 +240,16 @@ </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> diff --git a/man/systemd.service.xml b/man/systemd.service.xml index e5262f6d60..ee4d393756 100644 --- a/man/systemd.service.xml +++ b/man/systemd.service.xml @@ -560,14 +560,17 @@ <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> @@ -582,6 +585,17 @@ </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 for all file descriptors passed via diff --git a/man/systemd.socket.xml b/man/systemd.socket.xml index 47ad913748..1aea2f89b1 100644 --- a/man/systemd.socket.xml +++ b/man/systemd.socket.xml @@ -528,6 +528,17 @@ </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 unit name to activate on incoming diff --git a/man/systemd.swap.xml b/man/systemd.swap.xml index 45467039e9..45f8f40ae1 100644 --- a/man/systemd.swap.xml +++ b/man/systemd.swap.xml @@ -176,6 +176,17 @@ 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> diff --git a/src/execute.c b/src/execute.c index 1e8dfaf770..10ce951c59 100644 --- a/src/execute.c +++ b/src/execute.c @@ -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, diff --git a/src/execute.h b/src/execute.h index dd84c3d29c..a6766f9e99 100644 --- a/src/execute.h +++ b/src/execute.h @@ -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; diff --git a/src/load-fragment.c b/src/load-fragment.c index b7c3cbbc3b..44b2cf06c1 100644 --- a/src/load-fragment.c +++ b/src/load-fragment.c @@ -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[] = { diff --git a/src/mount.c b/src/mount.c index 077ab9160f..5b433c970a 100644 --- a/src/mount.c +++ b/src/mount.c @@ -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: diff --git a/src/service.c b/src/service.c index e4dfa40314..e765004e4f 100644 --- a/src/service.c +++ b/src/service.c @@ -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: diff --git a/src/service.h b/src/service.h index 500bebff08..1b59dad932 100644 --- a/src/service.h +++ b/src/service.h @@ -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, diff --git a/src/socket.c b/src/socket.c index cb38ab3d69..6ec49de466 100644 --- a/src/socket.c +++ b/src/socket.c @@ -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: diff --git a/src/swap.c b/src/swap.c index 0d3cb2f406..9bdb5aabf6 100644 --- a/src/swap.c +++ b/src/swap.c @@ -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: |