diff options
author | Umut Tezduyar Lindskog <umut.tezduyar@axis.com> | 2014-10-28 16:35:40 +0100 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2014-10-28 17:37:39 +0100 |
commit | db2cb23b5b179707000d28a11efb3d888d06ee80 (patch) | |
tree | d2ee7df6404f5bfaa43a3d0d050fe877866fdce2 /src/core/service.c | |
parent | f10af76de5e6589e35ed620c75f3f6eb02cdf345 (diff) |
core: send sigabrt on watchdog timeout to get the stacktrace
if sigabrt doesn't do the job, follow regular shutdown
routine, sigterm > sigkill.
Diffstat (limited to 'src/core/service.c')
-rw-r--r-- | src/core/service.c | 37 |
1 files changed, 26 insertions, 11 deletions
diff --git a/src/core/service.c b/src/core/service.c index d160c4e93b..2b16778731 100644 --- a/src/core/service.c +++ b/src/core/service.c @@ -56,6 +56,7 @@ static const UnitActiveState state_translation_table[_SERVICE_STATE_MAX] = { [SERVICE_EXITED] = UNIT_ACTIVE, [SERVICE_RELOAD] = UNIT_RELOADING, [SERVICE_STOP] = UNIT_DEACTIVATING, + [SERVICE_STOP_SIGABRT] = UNIT_DEACTIVATING, [SERVICE_STOP_SIGTERM] = UNIT_DEACTIVATING, [SERVICE_STOP_SIGKILL] = UNIT_DEACTIVATING, [SERVICE_STOP_POST] = UNIT_DEACTIVATING, @@ -76,6 +77,7 @@ static const UnitActiveState state_translation_table_idle[_SERVICE_STATE_MAX] = [SERVICE_EXITED] = UNIT_ACTIVE, [SERVICE_RELOAD] = UNIT_RELOADING, [SERVICE_STOP] = UNIT_DEACTIVATING, + [SERVICE_STOP_SIGABRT] = UNIT_DEACTIVATING, [SERVICE_STOP_SIGTERM] = UNIT_DEACTIVATING, [SERVICE_STOP_SIGKILL] = UNIT_DEACTIVATING, [SERVICE_STOP_POST] = UNIT_DEACTIVATING, @@ -663,7 +665,7 @@ static void service_set_state(Service *s, ServiceState state) { SERVICE_START_PRE, SERVICE_START, SERVICE_START_POST, SERVICE_RELOAD, SERVICE_STOP, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL, - SERVICE_STOP_POST, + SERVICE_STOP_SIGABRT, SERVICE_STOP_POST, SERVICE_FINAL_SIGTERM, SERVICE_FINAL_SIGKILL, SERVICE_AUTO_RESTART)) s->timer_event_source = sd_event_source_unref(s->timer_event_source); @@ -672,7 +674,7 @@ static void service_set_state(Service *s, ServiceState state) { SERVICE_START, SERVICE_START_POST, SERVICE_RUNNING, SERVICE_RELOAD, SERVICE_STOP, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL, - SERVICE_STOP_POST, + SERVICE_STOP_SIGABRT, SERVICE_STOP_POST, SERVICE_FINAL_SIGTERM, SERVICE_FINAL_SIGKILL)) { service_unwatch_main_pid(s); s->main_command = NULL; @@ -682,7 +684,7 @@ static void service_set_state(Service *s, ServiceState state) { SERVICE_START_PRE, SERVICE_START, SERVICE_START_POST, SERVICE_RELOAD, SERVICE_STOP, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL, - SERVICE_STOP_POST, + SERVICE_STOP_SIGABRT, SERVICE_STOP_POST, SERVICE_FINAL_SIGTERM, SERVICE_FINAL_SIGKILL)) { service_unwatch_control_pid(s); s->control_command = NULL; @@ -696,7 +698,7 @@ static void service_set_state(Service *s, ServiceState state) { SERVICE_START_PRE, SERVICE_START, SERVICE_START_POST, SERVICE_RUNNING, SERVICE_RELOAD, SERVICE_STOP, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL, SERVICE_STOP_POST, - SERVICE_FINAL_SIGTERM, SERVICE_FINAL_SIGKILL) && + SERVICE_STOP_SIGABRT, SERVICE_FINAL_SIGTERM, SERVICE_FINAL_SIGKILL) && !(state == SERVICE_DEAD && UNIT(s)->job)) { service_close_socket_fd(s); service_connection_unref(s); @@ -750,7 +752,7 @@ static int service_coldplug(Unit *u) { SERVICE_START_PRE, SERVICE_START, SERVICE_START_POST, SERVICE_RELOAD, SERVICE_STOP, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL, - SERVICE_STOP_POST, + SERVICE_STOP_SIGABRT, SERVICE_STOP_POST, SERVICE_FINAL_SIGTERM, SERVICE_FINAL_SIGKILL)) { usec_t k; @@ -779,7 +781,7 @@ static int service_coldplug(Unit *u) { SERVICE_START, SERVICE_START_POST, SERVICE_RUNNING, SERVICE_RELOAD, SERVICE_STOP, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL, - SERVICE_STOP_POST, + SERVICE_STOP_SIGABRT, SERVICE_STOP_POST, SERVICE_FINAL_SIGTERM, SERVICE_FINAL_SIGKILL))) { r = unit_watch_pid(UNIT(s), s->main_pid); if (r < 0) @@ -791,7 +793,7 @@ static int service_coldplug(Unit *u) { SERVICE_START_PRE, SERVICE_START, SERVICE_START_POST, SERVICE_RELOAD, SERVICE_STOP, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL, - SERVICE_STOP_POST, + SERVICE_STOP_SIGABRT, SERVICE_STOP_POST, SERVICE_FINAL_SIGTERM, SERVICE_FINAL_SIGKILL)) { r = unit_watch_pid(UNIT(s), s->control_pid); if (r < 0) @@ -1181,7 +1183,8 @@ static void service_enter_signal(Service *s, ServiceState state, ServiceResult f r = unit_kill_context( UNIT(s), &s->kill_context, - state != SERVICE_STOP_SIGTERM && state != SERVICE_FINAL_SIGTERM, + (state != SERVICE_STOP_SIGTERM && state != SERVICE_FINAL_SIGTERM && state != SERVICE_STOP_SIGABRT) ? + KILL_KILL : (state == SERVICE_STOP_SIGABRT ? KILL_ABORT : KILL_TERMINATE), s->main_pid, s->control_pid, s->main_pid_alien); @@ -1197,7 +1200,7 @@ static void service_enter_signal(Service *s, ServiceState state, ServiceResult f } service_set_state(s, state); - } else if (state == SERVICE_STOP_SIGTERM) + } else if (state == SERVICE_STOP_SIGTERM || state == SERVICE_STOP_SIGABRT) service_enter_signal(s, SERVICE_STOP_SIGKILL, SERVICE_SUCCESS); else if (state == SERVICE_STOP_SIGKILL) service_enter_stop_post(s, SERVICE_SUCCESS); @@ -1211,7 +1214,8 @@ static void service_enter_signal(Service *s, ServiceState state, ServiceResult f fail: log_warning_unit(UNIT(s)->id, "%s failed to kill processes: %s", UNIT(s)->id, strerror(-r)); - if (state == SERVICE_STOP_SIGTERM || state == SERVICE_STOP_SIGKILL) + if (state == SERVICE_STOP_SIGTERM || state == SERVICE_STOP_SIGKILL || + state == SERVICE_STOP_SIGABRT) service_enter_stop_post(s, SERVICE_FAILURE_RESOURCES); else service_enter_dead(s, SERVICE_FAILURE_RESOURCES, true); @@ -1637,6 +1641,7 @@ static int service_start(Unit *u) { /* We cannot fulfill this request right now, try again later * please! */ if (s->state == SERVICE_STOP || + s->state == SERVICE_STOP_SIGABRT || s->state == SERVICE_STOP_SIGTERM || s->state == SERVICE_STOP_SIGKILL || s->state == SERVICE_STOP_POST || @@ -1695,6 +1700,7 @@ static int service_stop(Unit *u) { /* Already on it */ if (s->state == SERVICE_STOP || + s->state == SERVICE_STOP_SIGABRT || s->state == SERVICE_STOP_SIGTERM || s->state == SERVICE_STOP_SIGKILL || s->state == SERVICE_STOP_POST || @@ -2126,6 +2132,7 @@ static void service_notify_cgroup_empty_event(Unit *u) { service_enter_running(s, SERVICE_SUCCESS); break; + case SERVICE_STOP_SIGABRT: case SERVICE_STOP_SIGTERM: case SERVICE_STOP_SIGKILL: @@ -2252,6 +2259,7 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) { service_enter_running(s, f); break; + case SERVICE_STOP_SIGABRT: case SERVICE_STOP_SIGTERM: case SERVICE_STOP_SIGKILL: @@ -2392,6 +2400,7 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) { service_enter_signal(s, SERVICE_STOP_SIGTERM, f); break; + case SERVICE_STOP_SIGABRT: case SERVICE_STOP_SIGTERM: case SERVICE_STOP_SIGKILL: if (main_pid_good(s) <= 0) @@ -2461,6 +2470,12 @@ static int service_dispatch_timer(sd_event_source *source, usec_t usec, void *us service_enter_signal(s, SERVICE_STOP_SIGTERM, SERVICE_FAILURE_TIMEOUT); break; + case SERVICE_STOP_SIGABRT: + log_warning_unit(UNIT(s)->id, + "%s stop-sigabrt timed out. Terminating.", UNIT(s)->id); + service_enter_signal(s, SERVICE_STOP_SIGTERM, s->result); + break; + case SERVICE_STOP_SIGTERM: if (s->kill_context.send_sigkill) { log_warning_unit(UNIT(s)->id, "%s stop-sigterm timed out. Killing.", UNIT(s)->id); @@ -2528,7 +2543,7 @@ static int service_dispatch_watchdog(sd_event_source *source, usec_t usec, void log_error_unit(UNIT(s)->id, "%s watchdog timeout (limit %s)!", UNIT(s)->id, format_timespan(t, sizeof(t), s->watchdog_usec, 1)); - service_enter_signal(s, SERVICE_STOP_SIGTERM, SERVICE_FAILURE_WATCHDOG); + service_enter_signal(s, SERVICE_STOP_SIGABRT, SERVICE_FAILURE_WATCHDOG); return 0; } |