X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Fcore%2Fservice.c;h=807b34267f19622eaf984a82acd3a5abc4e7e6b4;hp=e74da54eac5b288ed54c7c839335fb73a460807e;hb=8d1b002a2e389e79a2414491523de549783abf73;hpb=d568a3350ee8a45877eef87cd026a954124e2cf8 diff --git a/src/core/service.c b/src/core/service.c index e74da54ea..807b34267 100644 --- a/src/core/service.c +++ b/src/core/service.c @@ -294,6 +294,16 @@ static void service_done(Unit *u) { s->control_command = NULL; s->main_command = NULL; + set_free(s->restart_ignore_status.code); + s->restart_ignore_status.code = NULL; + set_free(s->restart_ignore_status.signal); + s->restart_ignore_status.signal = NULL; + + set_free(s->success_status.code); + s->success_status.code = NULL; + set_free(s->success_status.signal); + s->success_status.signal = NULL; + /* This will leak a process, but at least no memory or any of * our resources */ service_unwatch_main_pid(s); @@ -1902,7 +1912,12 @@ static void service_enter_dead(Service *s, ServiceResult f, bool allow_restart) (s->restart == SERVICE_RESTART_ON_SUCCESS && s->result == SERVICE_SUCCESS) || (s->restart == SERVICE_RESTART_ON_FAILURE && s->result != SERVICE_SUCCESS) || (s->restart == SERVICE_RESTART_ON_ABORT && (s->result == SERVICE_FAILURE_SIGNAL || - s->result == SERVICE_FAILURE_CORE_DUMP)))) { + s->result == SERVICE_FAILURE_CORE_DUMP))) && + (s->result != SERVICE_FAILURE_EXIT_CODE || + !set_contains(s->restart_ignore_status.code, INT_TO_PTR(s->main_exec_status.status))) && + (s->result != SERVICE_FAILURE_SIGNAL || + !set_contains(s->restart_ignore_status.signal, INT_TO_PTR(s->main_exec_status.status))) + ) { r = unit_watch_timer(UNIT(s), s->restart_usec, &s->timer_watch); if (r < 0) @@ -2493,7 +2508,7 @@ static int service_start(Unit *u) { /* Make sure we don't enter a busy loop of some kind. */ r = service_start_limit_test(s); if (r < 0) { - service_notify_sockets_dead(s, true); + service_enter_dead(s, SERVICE_FAILURE_START_LIMIT, false); return r; } @@ -2874,7 +2889,8 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) { assert(s); assert(pid >= 0); - if (UNIT(s)->fragment_path ? is_clean_exit(code, status) : is_clean_exit_lsb(code, status)) + if (UNIT(s)->fragment_path ? is_clean_exit(code, status, &s->success_status) : + is_clean_exit_lsb(code, status, &s->success_status)) f = SERVICE_SUCCESS; else if (code == CLD_EXITED) f = SERVICE_FAILURE_EXIT_CODE; @@ -3805,7 +3821,8 @@ static const char* const service_result_table[_SERVICE_RESULT_MAX] = { [SERVICE_FAILURE_EXIT_CODE] = "exit-code", [SERVICE_FAILURE_SIGNAL] = "signal", [SERVICE_FAILURE_CORE_DUMP] = "core-dump", - [SERVICE_FAILURE_WATCHDOG] = "watchdog" + [SERVICE_FAILURE_WATCHDOG] = "watchdog", + [SERVICE_FAILURE_START_LIMIT] = "start-limit" }; DEFINE_STRING_TABLE_LOOKUP(service_result, ServiceResult);