1
1
mirror of https://github.com/systemd/systemd-stable.git synced 2025-01-25 06:03:40 +03:00

Make Watchdog Signal Configurable

Allows configuring the watchdog signal (with a default of SIGABRT).
This allows an alternative to SIGABRT when coredumps are not desirable.

Appropriate references to SIGABRT or aborting were renamed to reflect
more liberal watchdog signals.

Closes #8658
This commit is contained in:
Anita Zhang 2018-09-19 12:03:01 -07:00 committed by Lennart Poettering
parent ee8d493cbd
commit c87700a133
14 changed files with 50 additions and 31 deletions

View File

@ -257,6 +257,7 @@ All process killing settings are available for transient units:
✓ KillMode= ✓ KillMode=
✓ KillSignal= ✓ KillSignal=
✓ FinalKillSignal= ✓ FinalKillSignal=
✓ WatchdogSignal=
``` ```
## Service Unit Settings ## Service Unit Settings

View File

@ -160,6 +160,14 @@
</para></listitem> </para></listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term><varname>WatchdogSignal=</varname></term>
<listitem><para>Specifies which signal to use to terminate the
service when the watchdog timeout expires (enabled through
<varname>WatchdogSec=</varname>). Defaults to <constant>SIGABRT</constant>.
</para></listitem>
</varlistentry>
</variablelist> </variablelist>
</refsect1> </refsect1>

View File

@ -599,7 +599,8 @@
"keep-alive ping"). If the time between two such calls is "keep-alive ping"). If the time between two such calls is
larger than the configured time, then the service is placed in larger than the configured time, then the service is placed in
a failed state and it will be terminated with a failed state and it will be terminated with
<constant>SIGABRT</constant>. By setting <constant>SIGABRT</constant> (or the signal specified by
<varname>WatchdogSignal=</varname>). By setting
<varname>Restart=</varname> to <option>on-failure</option>, <varname>Restart=</varname> to <option>on-failure</option>,
<option>on-watchdog</option>, <option>on-abnormal</option> or <option>on-watchdog</option>, <option>on-abnormal</option> or
<option>always</option>, the service will be automatically <option>always</option>, the service will be automatically

View File

@ -169,7 +169,7 @@ static const char* const service_state_table[_SERVICE_STATE_MAX] = {
[SERVICE_EXITED] = "exited", [SERVICE_EXITED] = "exited",
[SERVICE_RELOAD] = "reload", [SERVICE_RELOAD] = "reload",
[SERVICE_STOP] = "stop", [SERVICE_STOP] = "stop",
[SERVICE_STOP_SIGABRT] = "stop-sigabrt", [SERVICE_STOP_WATCHDOG] = "stop-watchdog",
[SERVICE_STOP_SIGTERM] = "stop-sigterm", [SERVICE_STOP_SIGTERM] = "stop-sigterm",
[SERVICE_STOP_SIGKILL] = "stop-sigkill", [SERVICE_STOP_SIGKILL] = "stop-sigkill",
[SERVICE_STOP_POST] = "stop-post", [SERVICE_STOP_POST] = "stop-post",

View File

@ -108,7 +108,7 @@ typedef enum ServiceState {
SERVICE_EXITED, /* Nothing is running anymore, but RemainAfterExit is true hence 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_SIGABRT, /* Watchdog timeout */ SERVICE_STOP_WATCHDOG,
SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGTERM,
SERVICE_STOP_SIGKILL, SERVICE_STOP_SIGKILL,
SERVICE_STOP_POST, SERVICE_STOP_POST,

View File

@ -15,12 +15,14 @@ const sd_bus_vtable bus_kill_vtable[] = {
SD_BUS_PROPERTY("FinalKillSignal", "i", bus_property_get_int, offsetof(KillContext, final_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("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_PROPERTY("SendSIGHUP", "b", bus_property_get_bool, offsetof(KillContext, send_sighup), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("WatchdogSignal", "i", bus_property_get_int, offsetof(KillContext, watchdog_signal), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_VTABLE_END SD_BUS_VTABLE_END
}; };
static BUS_DEFINE_SET_TRANSIENT_PARSE(kill_mode, KillMode, kill_mode_from_string); 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(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); static BUS_DEFINE_SET_TRANSIENT_TO_STRING(final_kill_signal, "i", int32_t, int, "%" PRIi32, signal_to_string_with_check);
static BUS_DEFINE_SET_TRANSIENT_TO_STRING(watchdog_signal, "i", int32_t, int, "%" PRIi32, signal_to_string_with_check);
int bus_kill_context_set_transient_property( int bus_kill_context_set_transient_property(
Unit *u, Unit *u,
@ -52,5 +54,8 @@ int bus_kill_context_set_transient_property(
if (streq(name, "FinalKillSignal")) if (streq(name, "FinalKillSignal"))
return bus_set_transient_final_kill_signal(u, name, &c->final_kill_signal, message, flags, error); return bus_set_transient_final_kill_signal(u, name, &c->final_kill_signal, message, flags, error);
if (streq(name, "WatchdogSignal"))
return bus_set_transient_watchdog_signal(u, name, &c->watchdog_signal, message, flags, error);
return 0; return 0;
} }

View File

@ -12,6 +12,7 @@ void kill_context_init(KillContext *c) {
c->final_kill_signal = SIGKILL; c->final_kill_signal = SIGKILL;
c->send_sigkill = true; c->send_sigkill = true;
c->send_sighup = false; c->send_sighup = false;
c->watchdog_signal = SIGABRT;
} }
void kill_context_dump(KillContext *c, FILE *f, const char *prefix) { void kill_context_dump(KillContext *c, FILE *f, const char *prefix) {

View File

@ -24,6 +24,7 @@ struct KillContext {
int final_kill_signal; int final_kill_signal;
bool send_sigkill; bool send_sigkill;
bool send_sighup; bool send_sighup;
int watchdog_signal;
}; };
typedef enum KillWho { typedef enum KillWho {

View File

@ -152,7 +152,8 @@ m4_define(`KILL_CONTEXT_CONFIG_ITEMS',
$1.SendSIGHUP, config_parse_bool, 0, offsetof($1, kill_context.send_sighup) $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.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)' $1.FinalKillSignal, config_parse_signal, 0, offsetof($1, kill_context.final_kill_signal)
$1.WatchdogSignal, config_parse_signal, 0, offsetof($1, kill_context.watchdog_signal)'
)m4_dnl )m4_dnl
m4_define(`CGROUP_CONTEXT_CONFIG_ITEMS', m4_define(`CGROUP_CONTEXT_CONFIG_ITEMS',
`$1.Slice, config_parse_unit_slice, 0, 0 `$1.Slice, config_parse_unit_slice, 0, 0

View File

@ -48,7 +48,7 @@ static const UnitActiveState state_translation_table[_SERVICE_STATE_MAX] = {
[SERVICE_EXITED] = UNIT_ACTIVE, [SERVICE_EXITED] = UNIT_ACTIVE,
[SERVICE_RELOAD] = UNIT_RELOADING, [SERVICE_RELOAD] = UNIT_RELOADING,
[SERVICE_STOP] = UNIT_DEACTIVATING, [SERVICE_STOP] = UNIT_DEACTIVATING,
[SERVICE_STOP_SIGABRT] = UNIT_DEACTIVATING, [SERVICE_STOP_WATCHDOG] = UNIT_DEACTIVATING,
[SERVICE_STOP_SIGTERM] = UNIT_DEACTIVATING, [SERVICE_STOP_SIGTERM] = UNIT_DEACTIVATING,
[SERVICE_STOP_SIGKILL] = UNIT_DEACTIVATING, [SERVICE_STOP_SIGKILL] = UNIT_DEACTIVATING,
[SERVICE_STOP_POST] = UNIT_DEACTIVATING, [SERVICE_STOP_POST] = UNIT_DEACTIVATING,
@ -69,7 +69,7 @@ static const UnitActiveState state_translation_table_idle[_SERVICE_STATE_MAX] =
[SERVICE_EXITED] = UNIT_ACTIVE, [SERVICE_EXITED] = UNIT_ACTIVE,
[SERVICE_RELOAD] = UNIT_RELOADING, [SERVICE_RELOAD] = UNIT_RELOADING,
[SERVICE_STOP] = UNIT_DEACTIVATING, [SERVICE_STOP] = UNIT_DEACTIVATING,
[SERVICE_STOP_SIGABRT] = UNIT_DEACTIVATING, [SERVICE_STOP_WATCHDOG] = UNIT_DEACTIVATING,
[SERVICE_STOP_SIGTERM] = UNIT_DEACTIVATING, [SERVICE_STOP_SIGTERM] = UNIT_DEACTIVATING,
[SERVICE_STOP_SIGKILL] = UNIT_DEACTIVATING, [SERVICE_STOP_SIGKILL] = UNIT_DEACTIVATING,
[SERVICE_STOP_POST] = UNIT_DEACTIVATING, [SERVICE_STOP_POST] = UNIT_DEACTIVATING,
@ -1031,7 +1031,7 @@ static void service_set_state(Service *s, ServiceState state) {
SERVICE_START_PRE, SERVICE_START, SERVICE_START_POST, SERVICE_START_PRE, SERVICE_START, SERVICE_START_POST,
SERVICE_RUNNING, SERVICE_RUNNING,
SERVICE_RELOAD, SERVICE_RELOAD,
SERVICE_STOP, SERVICE_STOP_SIGABRT, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL, SERVICE_STOP_POST, SERVICE_STOP, SERVICE_STOP_WATCHDOG, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL, SERVICE_STOP_POST,
SERVICE_FINAL_SIGTERM, SERVICE_FINAL_SIGKILL, SERVICE_FINAL_SIGTERM, SERVICE_FINAL_SIGKILL,
SERVICE_AUTO_RESTART)) SERVICE_AUTO_RESTART))
s->timer_event_source = sd_event_source_unref(s->timer_event_source); s->timer_event_source = sd_event_source_unref(s->timer_event_source);
@ -1039,7 +1039,7 @@ static void service_set_state(Service *s, ServiceState state) {
if (!IN_SET(state, if (!IN_SET(state,
SERVICE_START, SERVICE_START_POST, SERVICE_START, SERVICE_START_POST,
SERVICE_RUNNING, SERVICE_RELOAD, SERVICE_RUNNING, SERVICE_RELOAD,
SERVICE_STOP, SERVICE_STOP_SIGABRT, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL, SERVICE_STOP_POST, SERVICE_STOP, SERVICE_STOP_WATCHDOG, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL, SERVICE_STOP_POST,
SERVICE_FINAL_SIGTERM, SERVICE_FINAL_SIGKILL)) { SERVICE_FINAL_SIGTERM, SERVICE_FINAL_SIGKILL)) {
service_unwatch_main_pid(s); service_unwatch_main_pid(s);
s->main_command = NULL; s->main_command = NULL;
@ -1048,7 +1048,7 @@ static void service_set_state(Service *s, ServiceState state) {
if (!IN_SET(state, if (!IN_SET(state,
SERVICE_START_PRE, SERVICE_START, SERVICE_START_POST, SERVICE_START_PRE, SERVICE_START, SERVICE_START_POST,
SERVICE_RELOAD, SERVICE_RELOAD,
SERVICE_STOP, SERVICE_STOP_SIGABRT, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL, SERVICE_STOP_POST, SERVICE_STOP, SERVICE_STOP_WATCHDOG, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL, SERVICE_STOP_POST,
SERVICE_FINAL_SIGTERM, SERVICE_FINAL_SIGKILL)) { SERVICE_FINAL_SIGTERM, SERVICE_FINAL_SIGKILL)) {
service_unwatch_control_pid(s); service_unwatch_control_pid(s);
s->control_command = NULL; s->control_command = NULL;
@ -1063,7 +1063,7 @@ static void service_set_state(Service *s, ServiceState state) {
if (!IN_SET(state, if (!IN_SET(state,
SERVICE_START_PRE, SERVICE_START, SERVICE_START_POST, SERVICE_START_PRE, SERVICE_START, SERVICE_START_POST,
SERVICE_RUNNING, SERVICE_RELOAD, SERVICE_RUNNING, SERVICE_RELOAD,
SERVICE_STOP, SERVICE_STOP_SIGABRT, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL, SERVICE_STOP_POST, SERVICE_STOP, SERVICE_STOP_WATCHDOG, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL, SERVICE_STOP_POST,
SERVICE_FINAL_SIGTERM, SERVICE_FINAL_SIGKILL) && SERVICE_FINAL_SIGTERM, SERVICE_FINAL_SIGKILL) &&
!(state == SERVICE_DEAD && UNIT(s)->job)) !(state == SERVICE_DEAD && UNIT(s)->job))
service_close_socket_fd(s); service_close_socket_fd(s);
@ -1102,7 +1102,7 @@ static usec_t service_coldplug_timeout(Service *s) {
return usec_add(UNIT(s)->active_enter_timestamp.monotonic, s->runtime_max_usec); return usec_add(UNIT(s)->active_enter_timestamp.monotonic, s->runtime_max_usec);
case SERVICE_STOP: case SERVICE_STOP:
case SERVICE_STOP_SIGABRT: case SERVICE_STOP_WATCHDOG:
case SERVICE_STOP_SIGTERM: case SERVICE_STOP_SIGTERM:
case SERVICE_STOP_SIGKILL: case SERVICE_STOP_SIGKILL:
case SERVICE_STOP_POST: case SERVICE_STOP_POST:
@ -1137,7 +1137,7 @@ static int service_coldplug(Unit *u) {
(IN_SET(s->deserialized_state, (IN_SET(s->deserialized_state,
SERVICE_START, SERVICE_START_POST, SERVICE_START, SERVICE_START_POST,
SERVICE_RUNNING, SERVICE_RELOAD, SERVICE_RUNNING, SERVICE_RELOAD,
SERVICE_STOP, SERVICE_STOP_SIGABRT, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL, SERVICE_STOP_POST, SERVICE_STOP, SERVICE_STOP_WATCHDOG, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL, SERVICE_STOP_POST,
SERVICE_FINAL_SIGTERM, SERVICE_FINAL_SIGKILL))) { SERVICE_FINAL_SIGTERM, SERVICE_FINAL_SIGKILL))) {
r = unit_watch_pid(UNIT(s), s->main_pid); r = unit_watch_pid(UNIT(s), s->main_pid);
if (r < 0) if (r < 0)
@ -1149,7 +1149,7 @@ static int service_coldplug(Unit *u) {
IN_SET(s->deserialized_state, IN_SET(s->deserialized_state,
SERVICE_START_PRE, SERVICE_START, SERVICE_START_POST, SERVICE_START_PRE, SERVICE_START, SERVICE_START_POST,
SERVICE_RELOAD, SERVICE_RELOAD,
SERVICE_STOP, SERVICE_STOP_SIGABRT, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL, SERVICE_STOP_POST, SERVICE_STOP, SERVICE_STOP_WATCHDOG, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL, SERVICE_STOP_POST,
SERVICE_FINAL_SIGTERM, SERVICE_FINAL_SIGKILL)) { SERVICE_FINAL_SIGTERM, SERVICE_FINAL_SIGKILL)) {
r = unit_watch_pid(UNIT(s), s->control_pid); r = unit_watch_pid(UNIT(s), s->control_pid);
if (r < 0) if (r < 0)
@ -1780,8 +1780,8 @@ fail:
static int state_to_kill_operation(ServiceState state) { static int state_to_kill_operation(ServiceState state) {
switch (state) { switch (state) {
case SERVICE_STOP_SIGABRT: case SERVICE_STOP_WATCHDOG:
return KILL_ABORT; return KILL_WATCHDOG;
case SERVICE_STOP_SIGTERM: case SERVICE_STOP_SIGTERM:
case SERVICE_FINAL_SIGTERM: case SERVICE_FINAL_SIGTERM:
@ -1827,9 +1827,9 @@ static void service_enter_signal(Service *s, ServiceState state, ServiceResult f
goto fail; goto fail;
service_set_state(s, state); service_set_state(s, state);
} else if (IN_SET(state, SERVICE_STOP_SIGABRT, SERVICE_STOP_SIGTERM) && s->kill_context.send_sigkill) } else if (IN_SET(state, SERVICE_STOP_WATCHDOG, SERVICE_STOP_SIGTERM) && s->kill_context.send_sigkill)
service_enter_signal(s, SERVICE_STOP_SIGKILL, SERVICE_SUCCESS); service_enter_signal(s, SERVICE_STOP_SIGKILL, SERVICE_SUCCESS);
else if (IN_SET(state, SERVICE_STOP_SIGABRT, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL)) else if (IN_SET(state, SERVICE_STOP_WATCHDOG, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL))
service_enter_stop_post(s, SERVICE_SUCCESS); service_enter_stop_post(s, SERVICE_SUCCESS);
else if (state == SERVICE_FINAL_SIGTERM && s->kill_context.send_sigkill) else if (state == SERVICE_FINAL_SIGTERM && s->kill_context.send_sigkill)
service_enter_signal(s, SERVICE_FINAL_SIGKILL, SERVICE_SUCCESS); service_enter_signal(s, SERVICE_FINAL_SIGKILL, SERVICE_SUCCESS);
@ -1841,7 +1841,7 @@ static void service_enter_signal(Service *s, ServiceState state, ServiceResult f
fail: fail:
log_unit_warning_errno(UNIT(s), r, "Failed to kill processes: %m"); log_unit_warning_errno(UNIT(s), r, "Failed to kill processes: %m");
if (IN_SET(state, SERVICE_STOP_SIGABRT, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL)) if (IN_SET(state, SERVICE_STOP_WATCHDOG, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL))
service_enter_stop_post(s, SERVICE_FAILURE_RESOURCES); service_enter_stop_post(s, SERVICE_FAILURE_RESOURCES);
else else
service_enter_dead(s, SERVICE_FAILURE_RESOURCES, true); service_enter_dead(s, SERVICE_FAILURE_RESOURCES, true);
@ -2291,7 +2291,7 @@ static int service_start(Unit *u) {
/* We cannot fulfill this request right now, try again later /* We cannot fulfill this request right now, try again later
* please! */ * please! */
if (IN_SET(s->state, if (IN_SET(s->state,
SERVICE_STOP, SERVICE_STOP_SIGABRT, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL, SERVICE_STOP_POST, SERVICE_STOP, SERVICE_STOP_WATCHDOG, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL, SERVICE_STOP_POST,
SERVICE_FINAL_SIGTERM, SERVICE_FINAL_SIGKILL)) SERVICE_FINAL_SIGTERM, SERVICE_FINAL_SIGKILL))
return -EAGAIN; return -EAGAIN;
@ -2361,7 +2361,7 @@ static int service_stop(Unit *u) {
/* Already on it */ /* Already on it */
if (IN_SET(s->state, if (IN_SET(s->state,
SERVICE_STOP, SERVICE_STOP_SIGABRT, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL, SERVICE_STOP_POST, SERVICE_STOP, SERVICE_STOP_WATCHDOG, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL, SERVICE_STOP_POST,
SERVICE_FINAL_SIGTERM, SERVICE_FINAL_SIGKILL)) SERVICE_FINAL_SIGTERM, SERVICE_FINAL_SIGKILL))
return 0; return 0;
@ -3130,7 +3130,7 @@ static void service_notify_cgroup_empty_event(Unit *u) {
service_enter_running(s, SERVICE_SUCCESS); service_enter_running(s, SERVICE_SUCCESS);
break; break;
case SERVICE_STOP_SIGABRT: case SERVICE_STOP_WATCHDOG:
case SERVICE_STOP_SIGTERM: case SERVICE_STOP_SIGTERM:
case SERVICE_STOP_SIGKILL: case SERVICE_STOP_SIGKILL:
@ -3274,7 +3274,7 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) {
service_enter_running(s, f); service_enter_running(s, f);
break; break;
case SERVICE_STOP_SIGABRT: case SERVICE_STOP_WATCHDOG:
case SERVICE_STOP_SIGTERM: case SERVICE_STOP_SIGTERM:
case SERVICE_STOP_SIGKILL: case SERVICE_STOP_SIGKILL:
@ -3409,7 +3409,7 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) {
service_enter_signal(s, SERVICE_STOP_SIGTERM, f); service_enter_signal(s, SERVICE_STOP_SIGTERM, f);
break; break;
case SERVICE_STOP_SIGABRT: case SERVICE_STOP_WATCHDOG:
case SERVICE_STOP_SIGTERM: case SERVICE_STOP_SIGTERM:
case SERVICE_STOP_SIGKILL: case SERVICE_STOP_SIGKILL:
if (main_pid_good(s) <= 0) if (main_pid_good(s) <= 0)
@ -3480,8 +3480,8 @@ static int service_dispatch_timer(sd_event_source *source, usec_t usec, void *us
service_enter_signal(s, SERVICE_STOP_SIGTERM, SERVICE_FAILURE_TIMEOUT); service_enter_signal(s, SERVICE_STOP_SIGTERM, SERVICE_FAILURE_TIMEOUT);
break; break;
case SERVICE_STOP_SIGABRT: case SERVICE_STOP_WATCHDOG:
log_unit_warning(UNIT(s), "State 'stop-sigabrt' timed out. Terminating."); log_unit_warning(UNIT(s), "State 'stop-watchdog' timed out. Terminating.");
service_enter_signal(s, SERVICE_STOP_SIGTERM, SERVICE_FAILURE_TIMEOUT); service_enter_signal(s, SERVICE_STOP_SIGTERM, SERVICE_FAILURE_TIMEOUT);
break; break;
@ -3560,7 +3560,7 @@ static int service_dispatch_watchdog(sd_event_source *source, usec_t usec, void
log_unit_error(UNIT(s), "Watchdog timeout (limit %s)!", log_unit_error(UNIT(s), "Watchdog timeout (limit %s)!",
format_timespan(t, sizeof(t), watchdog_usec, 1)); format_timespan(t, sizeof(t), watchdog_usec, 1));
service_enter_signal(s, SERVICE_STOP_SIGABRT, SERVICE_FAILURE_WATCHDOG); service_enter_signal(s, SERVICE_STOP_WATCHDOG, SERVICE_FAILURE_WATCHDOG);
} else } else
log_unit_warning(UNIT(s), "Watchdog disabled! Ignoring watchdog timeout (limit %s)!", log_unit_warning(UNIT(s), "Watchdog disabled! Ignoring watchdog timeout (limit %s)!",
format_timespan(t, sizeof(t), watchdog_usec, 1)); format_timespan(t, sizeof(t), watchdog_usec, 1));
@ -3967,7 +3967,7 @@ static bool service_needs_console(Unit *u) {
SERVICE_RUNNING, SERVICE_RUNNING,
SERVICE_RELOAD, SERVICE_RELOAD,
SERVICE_STOP, SERVICE_STOP,
SERVICE_STOP_SIGABRT, SERVICE_STOP_WATCHDOG,
SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGTERM,
SERVICE_STOP_SIGKILL, SERVICE_STOP_SIGKILL,
SERVICE_STOP_POST, SERVICE_STOP_POST,

View File

@ -4509,8 +4509,8 @@ static int operation_to_signal(KillContext *c, KillOperation k) {
case KILL_KILL: case KILL_KILL:
return c->final_kill_signal; return c->final_kill_signal;
case KILL_ABORT: case KILL_WATCHDOG:
return SIGABRT; return c->watchdog_signal;
default: default:
assert_not_reached("KillOperation unknown"); assert_not_reached("KillOperation unknown");

View File

@ -19,7 +19,7 @@ typedef enum KillOperation {
KILL_TERMINATE, KILL_TERMINATE,
KILL_TERMINATE_AND_LOG, KILL_TERMINATE_AND_LOG,
KILL_KILL, KILL_KILL,
KILL_ABORT, KILL_WATCHDOG,
_KILL_OPERATION_MAX, _KILL_OPERATION_MAX,
_KILL_OPERATION_INVALID = -1 _KILL_OPERATION_INVALID = -1
} KillOperation; } KillOperation;

View File

@ -1222,7 +1222,7 @@ static int bus_append_kill_property(sd_bus_message *m, const char *field, const
return bus_append_parse_boolean(m, field, eq); return bus_append_parse_boolean(m, field, eq);
if (STR_IN_SET(field, "KillSignal", "FinalKillSignal")) if (STR_IN_SET(field, "KillSignal", "FinalKillSignal", "WatchdogSignal"))
return bus_append_signal_from_string(m, field, eq); return bus_append_signal_from_string(m, field, eq);

View File

@ -769,6 +769,7 @@ KeyringMode=
KillExcludeUsers= KillExcludeUsers=
KillOnlyUsers= KillOnlyUsers=
KillSignal= KillSignal=
WatchdogSignal=
KillUserProcesses= KillUserProcesses=
LOCATION= LOCATION=
LidSwitchIgnoreInhibited= LidSwitchIgnoreInhibited=