X Tutup
Skip to content

Commit c87700a

Browse files
anitazhapoettering
authored andcommitted
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 systemd#8658
1 parent ee8d493 commit c87700a

File tree

14 files changed

+50
-31
lines changed

14 files changed

+50
-31
lines changed

docs/TRANSIENT-SETTINGS.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,7 @@ All process killing settings are available for transient units:
257257
✓ KillMode=
258258
✓ KillSignal=
259259
✓ FinalKillSignal=
260+
✓ WatchdogSignal=
260261
```
261262

262263
## Service Unit Settings

man/systemd.kill.xml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,14 @@
160160
</para></listitem>
161161
</varlistentry>
162162

163+
<varlistentry>
164+
<term><varname>WatchdogSignal=</varname></term>
165+
<listitem><para>Specifies which signal to use to terminate the
166+
service when the watchdog timeout expires (enabled through
167+
<varname>WatchdogSec=</varname>). Defaults to <constant>SIGABRT</constant>.
168+
</para></listitem>
169+
</varlistentry>
170+
163171
</variablelist>
164172
</refsect1>
165173

man/systemd.service.xml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -599,7 +599,8 @@
599599
"keep-alive ping"). If the time between two such calls is
600600
larger than the configured time, then the service is placed in
601601
a failed state and it will be terminated with
602-
<constant>SIGABRT</constant>. By setting
602+
<constant>SIGABRT</constant> (or the signal specified by
603+
<varname>WatchdogSignal=</varname>). By setting
603604
<varname>Restart=</varname> to <option>on-failure</option>,
604605
<option>on-watchdog</option>, <option>on-abnormal</option> or
605606
<option>always</option>, the service will be automatically

src/basic/unit-def.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ static const char* const service_state_table[_SERVICE_STATE_MAX] = {
169169
[SERVICE_EXITED] = "exited",
170170
[SERVICE_RELOAD] = "reload",
171171
[SERVICE_STOP] = "stop",
172-
[SERVICE_STOP_SIGABRT] = "stop-sigabrt",
172+
[SERVICE_STOP_WATCHDOG] = "stop-watchdog",
173173
[SERVICE_STOP_SIGTERM] = "stop-sigterm",
174174
[SERVICE_STOP_SIGKILL] = "stop-sigkill",
175175
[SERVICE_STOP_POST] = "stop-post",

src/basic/unit-def.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ typedef enum ServiceState {
108108
SERVICE_EXITED, /* Nothing is running anymore, but RemainAfterExit is true hence this is OK */
109109
SERVICE_RELOAD,
110110
SERVICE_STOP, /* No STOP_PRE state, instead just register multiple STOP executables */
111-
SERVICE_STOP_SIGABRT, /* Watchdog timeout */
111+
SERVICE_STOP_WATCHDOG,
112112
SERVICE_STOP_SIGTERM,
113113
SERVICE_STOP_SIGKILL,
114114
SERVICE_STOP_POST,

src/core/dbus-kill.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,14 @@ const sd_bus_vtable bus_kill_vtable[] = {
1515
SD_BUS_PROPERTY("FinalKillSignal", "i", bus_property_get_int, offsetof(KillContext, final_kill_signal), SD_BUS_VTABLE_PROPERTY_CONST),
1616
SD_BUS_PROPERTY("SendSIGKILL", "b", bus_property_get_bool, offsetof(KillContext, send_sigkill), SD_BUS_VTABLE_PROPERTY_CONST),
1717
SD_BUS_PROPERTY("SendSIGHUP", "b", bus_property_get_bool, offsetof(KillContext, send_sighup), SD_BUS_VTABLE_PROPERTY_CONST),
18+
SD_BUS_PROPERTY("WatchdogSignal", "i", bus_property_get_int, offsetof(KillContext, watchdog_signal), SD_BUS_VTABLE_PROPERTY_CONST),
1819
SD_BUS_VTABLE_END
1920
};
2021

2122
static BUS_DEFINE_SET_TRANSIENT_PARSE(kill_mode, KillMode, kill_mode_from_string);
2223
static BUS_DEFINE_SET_TRANSIENT_TO_STRING(kill_signal, "i", int32_t, int, "%" PRIi32, signal_to_string_with_check);
2324
static BUS_DEFINE_SET_TRANSIENT_TO_STRING(final_kill_signal, "i", int32_t, int, "%" PRIi32, signal_to_string_with_check);
25+
static BUS_DEFINE_SET_TRANSIENT_TO_STRING(watchdog_signal, "i", int32_t, int, "%" PRIi32, signal_to_string_with_check);
2426

2527
int bus_kill_context_set_transient_property(
2628
Unit *u,
@@ -52,5 +54,8 @@ int bus_kill_context_set_transient_property(
5254
if (streq(name, "FinalKillSignal"))
5355
return bus_set_transient_final_kill_signal(u, name, &c->final_kill_signal, message, flags, error);
5456

57+
if (streq(name, "WatchdogSignal"))
58+
return bus_set_transient_watchdog_signal(u, name, &c->watchdog_signal, message, flags, error);
59+
5560
return 0;
5661
}

src/core/kill.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ void kill_context_init(KillContext *c) {
1212
c->final_kill_signal = SIGKILL;
1313
c->send_sigkill = true;
1414
c->send_sighup = false;
15+
c->watchdog_signal = SIGABRT;
1516
}
1617

1718
void kill_context_dump(KillContext *c, FILE *f, const char *prefix) {

src/core/kill.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ struct KillContext {
2424
int final_kill_signal;
2525
bool send_sigkill;
2626
bool send_sighup;
27+
int watchdog_signal;
2728
};
2829

2930
typedef enum KillWho {

src/core/load-fragment-gperf.gperf.m4

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,8 @@ m4_define(`KILL_CONTEXT_CONFIG_ITEMS',
152152
$1.SendSIGHUP, config_parse_bool, 0, offsetof($1, kill_context.send_sighup)
153153
$1.KillMode, config_parse_kill_mode, 0, offsetof($1, kill_context.kill_mode)
154154
$1.KillSignal, config_parse_signal, 0, offsetof($1, kill_context.kill_signal)
155-
$1.FinalKillSignal, config_parse_signal, 0, offsetof($1, kill_context.final_kill_signal)'
155+
$1.FinalKillSignal, config_parse_signal, 0, offsetof($1, kill_context.final_kill_signal)
156+
$1.WatchdogSignal, config_parse_signal, 0, offsetof($1, kill_context.watchdog_signal)'
156157
)m4_dnl
157158
m4_define(`CGROUP_CONTEXT_CONFIG_ITEMS',
158159
`$1.Slice, config_parse_unit_slice, 0, 0

src/core/service.c

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ static const UnitActiveState state_translation_table[_SERVICE_STATE_MAX] = {
4848
[SERVICE_EXITED] = UNIT_ACTIVE,
4949
[SERVICE_RELOAD] = UNIT_RELOADING,
5050
[SERVICE_STOP] = UNIT_DEACTIVATING,
51-
[SERVICE_STOP_SIGABRT] = UNIT_DEACTIVATING,
51+
[SERVICE_STOP_WATCHDOG] = UNIT_DEACTIVATING,
5252
[SERVICE_STOP_SIGTERM] = UNIT_DEACTIVATING,
5353
[SERVICE_STOP_SIGKILL] = UNIT_DEACTIVATING,
5454
[SERVICE_STOP_POST] = UNIT_DEACTIVATING,
@@ -69,7 +69,7 @@ static const UnitActiveState state_translation_table_idle[_SERVICE_STATE_MAX] =
6969
[SERVICE_EXITED] = UNIT_ACTIVE,
7070
[SERVICE_RELOAD] = UNIT_RELOADING,
7171
[SERVICE_STOP] = UNIT_DEACTIVATING,
72-
[SERVICE_STOP_SIGABRT] = UNIT_DEACTIVATING,
72+
[SERVICE_STOP_WATCHDOG] = UNIT_DEACTIVATING,
7373
[SERVICE_STOP_SIGTERM] = UNIT_DEACTIVATING,
7474
[SERVICE_STOP_SIGKILL] = UNIT_DEACTIVATING,
7575
[SERVICE_STOP_POST] = UNIT_DEACTIVATING,
@@ -1031,15 +1031,15 @@ static void service_set_state(Service *s, ServiceState state) {
10311031
SERVICE_START_PRE, SERVICE_START, SERVICE_START_POST,
10321032
SERVICE_RUNNING,
10331033
SERVICE_RELOAD,
1034-
SERVICE_STOP, SERVICE_STOP_SIGABRT, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL, SERVICE_STOP_POST,
1034+
SERVICE_STOP, SERVICE_STOP_WATCHDOG, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL, SERVICE_STOP_POST,
10351035
SERVICE_FINAL_SIGTERM, SERVICE_FINAL_SIGKILL,
10361036
SERVICE_AUTO_RESTART))
10371037
s->timer_event_source = sd_event_source_unref(s->timer_event_source);
10381038

10391039
if (!IN_SET(state,
10401040
SERVICE_START, SERVICE_START_POST,
10411041
SERVICE_RUNNING, SERVICE_RELOAD,
1042-
SERVICE_STOP, SERVICE_STOP_SIGABRT, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL, SERVICE_STOP_POST,
1042+
SERVICE_STOP, SERVICE_STOP_WATCHDOG, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL, SERVICE_STOP_POST,
10431043
SERVICE_FINAL_SIGTERM, SERVICE_FINAL_SIGKILL)) {
10441044
service_unwatch_main_pid(s);
10451045
s->main_command = NULL;
@@ -1048,7 +1048,7 @@ static void service_set_state(Service *s, ServiceState state) {
10481048
if (!IN_SET(state,
10491049
SERVICE_START_PRE, SERVICE_START, SERVICE_START_POST,
10501050
SERVICE_RELOAD,
1051-
SERVICE_STOP, SERVICE_STOP_SIGABRT, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL, SERVICE_STOP_POST,
1051+
SERVICE_STOP, SERVICE_STOP_WATCHDOG, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL, SERVICE_STOP_POST,
10521052
SERVICE_FINAL_SIGTERM, SERVICE_FINAL_SIGKILL)) {
10531053
service_unwatch_control_pid(s);
10541054
s->control_command = NULL;
@@ -1063,7 +1063,7 @@ static void service_set_state(Service *s, ServiceState state) {
10631063
if (!IN_SET(state,
10641064
SERVICE_START_PRE, SERVICE_START, SERVICE_START_POST,
10651065
SERVICE_RUNNING, SERVICE_RELOAD,
1066-
SERVICE_STOP, SERVICE_STOP_SIGABRT, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL, SERVICE_STOP_POST,
1066+
SERVICE_STOP, SERVICE_STOP_WATCHDOG, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL, SERVICE_STOP_POST,
10671067
SERVICE_FINAL_SIGTERM, SERVICE_FINAL_SIGKILL) &&
10681068
!(state == SERVICE_DEAD && UNIT(s)->job))
10691069
service_close_socket_fd(s);
@@ -1102,7 +1102,7 @@ static usec_t service_coldplug_timeout(Service *s) {
11021102
return usec_add(UNIT(s)->active_enter_timestamp.monotonic, s->runtime_max_usec);
11031103

11041104
case SERVICE_STOP:
1105-
case SERVICE_STOP_SIGABRT:
1105+
case SERVICE_STOP_WATCHDOG:
11061106
case SERVICE_STOP_SIGTERM:
11071107
case SERVICE_STOP_SIGKILL:
11081108
case SERVICE_STOP_POST:
@@ -1137,7 +1137,7 @@ static int service_coldplug(Unit *u) {
11371137
(IN_SET(s->deserialized_state,
11381138
SERVICE_START, SERVICE_START_POST,
11391139
SERVICE_RUNNING, SERVICE_RELOAD,
1140-
SERVICE_STOP, SERVICE_STOP_SIGABRT, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL, SERVICE_STOP_POST,
1140+
SERVICE_STOP, SERVICE_STOP_WATCHDOG, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL, SERVICE_STOP_POST,
11411141
SERVICE_FINAL_SIGTERM, SERVICE_FINAL_SIGKILL))) {
11421142
r = unit_watch_pid(UNIT(s), s->main_pid);
11431143
if (r < 0)
@@ -1149,7 +1149,7 @@ static int service_coldplug(Unit *u) {
11491149
IN_SET(s->deserialized_state,
11501150
SERVICE_START_PRE, SERVICE_START, SERVICE_START_POST,
11511151
SERVICE_RELOAD,
1152-
SERVICE_STOP, SERVICE_STOP_SIGABRT, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL, SERVICE_STOP_POST,
1152+
SERVICE_STOP, SERVICE_STOP_WATCHDOG, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL, SERVICE_STOP_POST,
11531153
SERVICE_FINAL_SIGTERM, SERVICE_FINAL_SIGKILL)) {
11541154
r = unit_watch_pid(UNIT(s), s->control_pid);
11551155
if (r < 0)
@@ -1780,8 +1780,8 @@ static void service_enter_stop_post(Service *s, ServiceResult f) {
17801780
static int state_to_kill_operation(ServiceState state) {
17811781
switch (state) {
17821782

1783-
case SERVICE_STOP_SIGABRT:
1784-
return KILL_ABORT;
1783+
case SERVICE_STOP_WATCHDOG:
1784+
return KILL_WATCHDOG;
17851785

17861786
case SERVICE_STOP_SIGTERM:
17871787
case SERVICE_FINAL_SIGTERM:
@@ -1827,9 +1827,9 @@ static void service_enter_signal(Service *s, ServiceState state, ServiceResult f
18271827
goto fail;
18281828

18291829
service_set_state(s, state);
1830-
} else if (IN_SET(state, SERVICE_STOP_SIGABRT, SERVICE_STOP_SIGTERM) && s->kill_context.send_sigkill)
1830+
} else if (IN_SET(state, SERVICE_STOP_WATCHDOG, SERVICE_STOP_SIGTERM) && s->kill_context.send_sigkill)
18311831
service_enter_signal(s, SERVICE_STOP_SIGKILL, SERVICE_SUCCESS);
1832-
else if (IN_SET(state, SERVICE_STOP_SIGABRT, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL))
1832+
else if (IN_SET(state, SERVICE_STOP_WATCHDOG, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL))
18331833
service_enter_stop_post(s, SERVICE_SUCCESS);
18341834
else if (state == SERVICE_FINAL_SIGTERM && s->kill_context.send_sigkill)
18351835
service_enter_signal(s, SERVICE_FINAL_SIGKILL, SERVICE_SUCCESS);
@@ -1841,7 +1841,7 @@ static void service_enter_signal(Service *s, ServiceState state, ServiceResult f
18411841
fail:
18421842
log_unit_warning_errno(UNIT(s), r, "Failed to kill processes: %m");
18431843

1844-
if (IN_SET(state, SERVICE_STOP_SIGABRT, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL))
1844+
if (IN_SET(state, SERVICE_STOP_WATCHDOG, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL))
18451845
service_enter_stop_post(s, SERVICE_FAILURE_RESOURCES);
18461846
else
18471847
service_enter_dead(s, SERVICE_FAILURE_RESOURCES, true);
@@ -2291,7 +2291,7 @@ static int service_start(Unit *u) {
22912291
/* We cannot fulfill this request right now, try again later
22922292
* please! */
22932293
if (IN_SET(s->state,
2294-
SERVICE_STOP, SERVICE_STOP_SIGABRT, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL, SERVICE_STOP_POST,
2294+
SERVICE_STOP, SERVICE_STOP_WATCHDOG, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL, SERVICE_STOP_POST,
22952295
SERVICE_FINAL_SIGTERM, SERVICE_FINAL_SIGKILL))
22962296
return -EAGAIN;
22972297

@@ -2361,7 +2361,7 @@ static int service_stop(Unit *u) {
23612361

23622362
/* Already on it */
23632363
if (IN_SET(s->state,
2364-
SERVICE_STOP, SERVICE_STOP_SIGABRT, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL, SERVICE_STOP_POST,
2364+
SERVICE_STOP, SERVICE_STOP_WATCHDOG, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL, SERVICE_STOP_POST,
23652365
SERVICE_FINAL_SIGTERM, SERVICE_FINAL_SIGKILL))
23662366
return 0;
23672367

@@ -3130,7 +3130,7 @@ static void service_notify_cgroup_empty_event(Unit *u) {
31303130
service_enter_running(s, SERVICE_SUCCESS);
31313131
break;
31323132

3133-
case SERVICE_STOP_SIGABRT:
3133+
case SERVICE_STOP_WATCHDOG:
31343134
case SERVICE_STOP_SIGTERM:
31353135
case SERVICE_STOP_SIGKILL:
31363136

@@ -3274,7 +3274,7 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) {
32743274
service_enter_running(s, f);
32753275
break;
32763276

3277-
case SERVICE_STOP_SIGABRT:
3277+
case SERVICE_STOP_WATCHDOG:
32783278
case SERVICE_STOP_SIGTERM:
32793279
case SERVICE_STOP_SIGKILL:
32803280

@@ -3409,7 +3409,7 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) {
34093409
service_enter_signal(s, SERVICE_STOP_SIGTERM, f);
34103410
break;
34113411

3412-
case SERVICE_STOP_SIGABRT:
3412+
case SERVICE_STOP_WATCHDOG:
34133413
case SERVICE_STOP_SIGTERM:
34143414
case SERVICE_STOP_SIGKILL:
34153415
if (main_pid_good(s) <= 0)
@@ -3480,8 +3480,8 @@ static int service_dispatch_timer(sd_event_source *source, usec_t usec, void *us
34803480
service_enter_signal(s, SERVICE_STOP_SIGTERM, SERVICE_FAILURE_TIMEOUT);
34813481
break;
34823482

3483-
case SERVICE_STOP_SIGABRT:
3484-
log_unit_warning(UNIT(s), "State 'stop-sigabrt' timed out. Terminating.");
3483+
case SERVICE_STOP_WATCHDOG:
3484+
log_unit_warning(UNIT(s), "State 'stop-watchdog' timed out. Terminating.");
34853485
service_enter_signal(s, SERVICE_STOP_SIGTERM, SERVICE_FAILURE_TIMEOUT);
34863486
break;
34873487

@@ -3560,7 +3560,7 @@ static int service_dispatch_watchdog(sd_event_source *source, usec_t usec, void
35603560
log_unit_error(UNIT(s), "Watchdog timeout (limit %s)!",
35613561
format_timespan(t, sizeof(t), watchdog_usec, 1));
35623562

3563-
service_enter_signal(s, SERVICE_STOP_SIGABRT, SERVICE_FAILURE_WATCHDOG);
3563+
service_enter_signal(s, SERVICE_STOP_WATCHDOG, SERVICE_FAILURE_WATCHDOG);
35643564
} else
35653565
log_unit_warning(UNIT(s), "Watchdog disabled! Ignoring watchdog timeout (limit %s)!",
35663566
format_timespan(t, sizeof(t), watchdog_usec, 1));
@@ -3967,7 +3967,7 @@ static bool service_needs_console(Unit *u) {
39673967
SERVICE_RUNNING,
39683968
SERVICE_RELOAD,
39693969
SERVICE_STOP,
3970-
SERVICE_STOP_SIGABRT,
3970+
SERVICE_STOP_WATCHDOG,
39713971
SERVICE_STOP_SIGTERM,
39723972
SERVICE_STOP_SIGKILL,
39733973
SERVICE_STOP_POST,

0 commit comments

Comments
 (0)
X Tutup