summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--TODO4
-rw-r--r--man/systemd.mount.xml10
-rw-r--r--man/systemd.service.xml20
-rw-r--r--man/systemd.socket.xml11
-rw-r--r--man/systemd.swap.xml11
-rw-r--r--src/execute.c7
-rw-r--r--src/execute.h1
-rw-r--r--src/load-fragment.c1
-rw-r--r--src/mount.c39
-rw-r--r--src/service.c20
-rw-r--r--src/service.h2
-rw-r--r--src/socket.c18
-rw-r--r--src/swap.c18
13 files changed, 134 insertions, 28 deletions
diff --git a/TODO b/TODO
index f87f7d1182..4605115d0d 100644
--- 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
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: