execute: make sending of SIGKILL on shutdown optional
This commit is contained in:
parent
0058d7b91c
commit
ba035df230
4
TODO
4
TODO
|
@ -4,8 +4,6 @@
|
||||||
|
|
||||||
* Fix multiple reload statements
|
* Fix multiple reload statements
|
||||||
|
|
||||||
* make usage of SIGKILL when shutting down services optional
|
|
||||||
|
|
||||||
* figure out what happened to bluez patch
|
* 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
|
* 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
|
* finish syslog socket stuff
|
||||||
|
|
||||||
* when starting systemd --user we get "Failed to set udev event buffer size."
|
|
||||||
|
|
||||||
* configurable jitter for timer events
|
* configurable jitter for timer events
|
||||||
|
|
||||||
* dbus should run with oom adjust set
|
* dbus should run with oom adjust set
|
||||||
|
|
|
@ -240,6 +240,16 @@
|
||||||
</para></listitem>
|
</para></listitem>
|
||||||
</varlistentry>
|
</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>
|
</variablelist>
|
||||||
</refsect1>
|
</refsect1>
|
||||||
|
|
||||||
|
|
|
@ -560,14 +560,17 @@
|
||||||
<option>control-group</option>.</para>
|
<option>control-group</option>.</para>
|
||||||
|
|
||||||
<para>Processes will first be
|
<para>Processes will first be
|
||||||
terminated via SIGTERM (unless this is
|
terminated via SIGTERM (unless the
|
||||||
changed via
|
signal to send is changed via
|
||||||
<varname>KillSignal=</varname>). If
|
<varname>KillSignal=</varname>). If
|
||||||
then after a delay (configured via the
|
then after a delay (configured via the
|
||||||
<varname>TimeoutSec=</varname> option)
|
<varname>TimeoutSec=</varname> option)
|
||||||
processes still remain, the
|
processes still remain, the
|
||||||
termination request is repeated with
|
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>
|
<citerefentry><refentrytitle>kill</refentrytitle><manvolnum>2</manvolnum></citerefentry>
|
||||||
for more
|
for more
|
||||||
information.</para></listitem>
|
information.</para></listitem>
|
||||||
|
@ -581,6 +584,17 @@
|
||||||
</para></listitem>
|
</para></listitem>
|
||||||
</varlistentry>
|
</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>
|
<varlistentry>
|
||||||
<term><varname>NonBlocking=</varname></term>
|
<term><varname>NonBlocking=</varname></term>
|
||||||
<listitem><para>Set O_NONBLOCK flag
|
<listitem><para>Set O_NONBLOCK flag
|
||||||
|
|
|
@ -527,6 +527,17 @@
|
||||||
</para></listitem>
|
</para></listitem>
|
||||||
</varlistentry>
|
</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>
|
<varlistentry>
|
||||||
<term><varname>Service=</varname></term>
|
<term><varname>Service=</varname></term>
|
||||||
<listitem><para>Specifies the service
|
<listitem><para>Specifies the service
|
||||||
|
|
|
@ -176,6 +176,17 @@
|
||||||
swap. Defaults to SIGTERM.
|
swap. Defaults to SIGTERM.
|
||||||
</para></listitem>
|
</para></listitem>
|
||||||
</varlistentry>
|
</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>
|
</variablelist>
|
||||||
</refsect1>
|
</refsect1>
|
||||||
|
|
||||||
|
|
|
@ -1349,6 +1349,7 @@ void exec_context_init(ExecContext *c) {
|
||||||
c->syslog_level_prefix = true;
|
c->syslog_level_prefix = true;
|
||||||
c->mount_flags = MS_SHARED;
|
c->mount_flags = MS_SHARED;
|
||||||
c->kill_signal = SIGTERM;
|
c->kill_signal = SIGTERM;
|
||||||
|
c->send_sigkill = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void exec_context_done(ExecContext *c) {
|
void exec_context_done(ExecContext *c) {
|
||||||
|
@ -1618,9 +1619,11 @@ void exec_context_dump(ExecContext *c, FILE* f, const char *prefix) {
|
||||||
|
|
||||||
fprintf(f,
|
fprintf(f,
|
||||||
"%sKillMode: %s\n"
|
"%sKillMode: %s\n"
|
||||||
"%sKillSignal: SIG%s\n",
|
"%sKillSignal: SIG%s\n"
|
||||||
|
"%sSendSIGKILL: %s\n",
|
||||||
prefix, kill_mode_to_string(c->kill_mode),
|
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)
|
if (c->utmp_id)
|
||||||
fprintf(f,
|
fprintf(f,
|
||||||
|
|
|
@ -145,6 +145,7 @@ struct ExecContext {
|
||||||
/* Not relevant for spawning processes, just for killing */
|
/* Not relevant for spawning processes, just for killing */
|
||||||
KillMode kill_mode;
|
KillMode kill_mode;
|
||||||
int kill_signal;
|
int kill_signal;
|
||||||
|
bool send_sigkill;
|
||||||
|
|
||||||
cap_t capabilities;
|
cap_t capabilities;
|
||||||
int secure_bits;
|
int secure_bits;
|
||||||
|
|
|
@ -1820,6 +1820,7 @@ static int load_from_path(Unit *u, const char *path) {
|
||||||
{ "PAMName", config_parse_string_printf, &(context).pam_name, section }, \
|
{ "PAMName", config_parse_string_printf, &(context).pam_name, section }, \
|
||||||
{ "KillMode", config_parse_kill_mode, &(context).kill_mode, section }, \
|
{ "KillMode", config_parse_kill_mode, &(context).kill_mode, section }, \
|
||||||
{ "KillSignal", config_parse_kill_signal, &(context).kill_signal, 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 }
|
{ "UtmpIdentifier", config_parse_string_printf, &(context).utmp_id, section }
|
||||||
|
|
||||||
const ConfigItem items[] = {
|
const ConfigItem items[] = {
|
||||||
|
|
39
src/mount.c
39
src/mount.c
|
@ -1156,18 +1156,45 @@ static void mount_timer_event(Unit *u, uint64_t elapsed, Watch *w) {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MOUNT_MOUNTING_SIGTERM:
|
case MOUNT_MOUNTING_SIGTERM:
|
||||||
log_warning("%s mounting timed out. Killing.", u->meta.id);
|
if (m->exec_context.send_sigkill) {
|
||||||
mount_enter_signal(m, MOUNT_MOUNTING_SIGKILL, false);
|
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;
|
break;
|
||||||
|
|
||||||
case MOUNT_REMOUNTING_SIGTERM:
|
case MOUNT_REMOUNTING_SIGTERM:
|
||||||
log_warning("%s remounting timed out. Killing.", u->meta.id);
|
if (m->exec_context.send_sigkill) {
|
||||||
mount_enter_signal(m, MOUNT_REMOUNTING_SIGKILL, false);
|
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;
|
break;
|
||||||
|
|
||||||
case MOUNT_UNMOUNTING_SIGTERM:
|
case MOUNT_UNMOUNTING_SIGTERM:
|
||||||
log_warning("%s unmounting timed out. Killing.", u->meta.id);
|
if (m->exec_context.send_sigkill) {
|
||||||
mount_enter_signal(m, MOUNT_UNMOUNTING_SIGKILL, false);
|
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;
|
break;
|
||||||
|
|
||||||
case MOUNT_MOUNTING_SIGKILL:
|
case MOUNT_MOUNTING_SIGKILL:
|
||||||
|
|
|
@ -2712,8 +2712,14 @@ static void service_timer_event(Unit *u, uint64_t elapsed, Watch* w) {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SERVICE_STOP_SIGTERM:
|
case SERVICE_STOP_SIGTERM:
|
||||||
log_warning("%s stopping timed out. Killing.", u->meta.id);
|
if (s->exec_context.send_sigkill) {
|
||||||
service_enter_signal(s, SERVICE_STOP_SIGKILL, false);
|
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;
|
break;
|
||||||
|
|
||||||
case SERVICE_STOP_SIGKILL:
|
case SERVICE_STOP_SIGKILL:
|
||||||
|
@ -2731,8 +2737,14 @@ static void service_timer_event(Unit *u, uint64_t elapsed, Watch* w) {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SERVICE_FINAL_SIGTERM:
|
case SERVICE_FINAL_SIGTERM:
|
||||||
log_warning("%s stopping timed out (2). Killing.", u->meta.id);
|
if (s->exec_context.send_sigkill) {
|
||||||
service_enter_signal(s, SERVICE_FINAL_SIGKILL, false);
|
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;
|
break;
|
||||||
|
|
||||||
case SERVICE_FINAL_SIGKILL:
|
case SERVICE_FINAL_SIGKILL:
|
||||||
|
|
|
@ -33,7 +33,7 @@ typedef enum ServiceState {
|
||||||
SERVICE_START,
|
SERVICE_START,
|
||||||
SERVICE_START_POST,
|
SERVICE_START_POST,
|
||||||
SERVICE_RUNNING,
|
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_RELOAD,
|
||||||
SERVICE_STOP, /* No STOP_PRE state, instead just register multiple STOP executables */
|
SERVICE_STOP, /* No STOP_PRE state, instead just register multiple STOP executables */
|
||||||
SERVICE_STOP_SIGTERM,
|
SERVICE_STOP_SIGTERM,
|
||||||
|
|
18
src/socket.c
18
src/socket.c
|
@ -1688,8 +1688,13 @@ static void socket_timer_event(Unit *u, uint64_t elapsed, Watch *w) {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SOCKET_STOP_PRE_SIGTERM:
|
case SOCKET_STOP_PRE_SIGTERM:
|
||||||
log_warning("%s stopping timed out. Killing.", u->meta.id);
|
if (s->exec_context.send_sigkill) {
|
||||||
socket_enter_signal(s, SOCKET_STOP_PRE_SIGKILL, false);
|
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;
|
break;
|
||||||
|
|
||||||
case SOCKET_STOP_PRE_SIGKILL:
|
case SOCKET_STOP_PRE_SIGKILL:
|
||||||
|
@ -1703,8 +1708,13 @@ static void socket_timer_event(Unit *u, uint64_t elapsed, Watch *w) {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SOCKET_FINAL_SIGTERM:
|
case SOCKET_FINAL_SIGTERM:
|
||||||
log_warning("%s stopping timed out (2). Killing.", u->meta.id);
|
if (s->exec_context.send_sigkill) {
|
||||||
socket_enter_signal(s, SOCKET_FINAL_SIGKILL, false);
|
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;
|
break;
|
||||||
|
|
||||||
case SOCKET_FINAL_SIGKILL:
|
case SOCKET_FINAL_SIGKILL:
|
||||||
|
|
18
src/swap.c
18
src/swap.c
|
@ -995,13 +995,23 @@ static void swap_timer_event(Unit *u, uint64_t elapsed, Watch *w) {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SWAP_ACTIVATING_SIGTERM:
|
case SWAP_ACTIVATING_SIGTERM:
|
||||||
log_warning("%s activation timed out. Killing.", u->meta.id);
|
if (s->exec_context.send_sigkill) {
|
||||||
swap_enter_signal(s, SWAP_ACTIVATING_SIGKILL, false);
|
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;
|
break;
|
||||||
|
|
||||||
case SWAP_DEACTIVATING_SIGTERM:
|
case SWAP_DEACTIVATING_SIGTERM:
|
||||||
log_warning("%s deactivation timed out. Killing.", u->meta.id);
|
if (s->exec_context.send_sigkill) {
|
||||||
swap_enter_signal(s, SWAP_DEACTIVATING_SIGKILL, false);
|
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;
|
break;
|
||||||
|
|
||||||
case SWAP_ACTIVATING_SIGKILL:
|
case SWAP_ACTIVATING_SIGKILL:
|
||||||
|
|
Loading…
Reference in New Issue