X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fcore%2Fservice.c;h=887b1c8514cfd35ed6e13ede49faeb1b05ee6719;hb=4c94096027f21d4ed0efe991534a926d39d52369;hp=e22189959143f94de0d48dfd8c4d9d33a4f27978;hpb=37520c1bec9a92adbe02fceaece588a7aa2fea2b;p=elogind.git diff --git a/src/core/service.c b/src/core/service.c index e22189959..887b1c851 100644 --- a/src/core/service.c +++ b/src/core/service.c @@ -335,7 +335,7 @@ static int service_verify(Service *s) { return -EINVAL; } - if (s->type == SERVICE_ONESHOT && !(set_isempty(s->restart_force_status.signal) && set_isempty(s->restart_force_status.code))) { + if (s->type == SERVICE_ONESHOT && !exit_status_set_is_empty(&s->restart_force_status)) { log_error_unit(UNIT(s)->id, "%s has RestartForceStatus= set, which isn't allowed for Type=oneshot services. Refusing.", UNIT(s)->id); return -EINVAL; } @@ -463,16 +463,14 @@ static int service_load(Unit *u) { } static void service_dump(Unit *u, FILE *f, const char *prefix) { - ServiceExecCommand c; Service *s = SERVICE(u); const char *prefix2; - _cleanup_free_ char *p2 = NULL; assert(s); - p2 = strappend(prefix, "\t"); - prefix2 = p2 ? p2 : prefix; + prefix = strempty(prefix); + prefix2 = strappenda(prefix, "\t"); fprintf(f, "%sService State: %s\n" @@ -1071,9 +1069,9 @@ static void service_enter_dead(Service *s, ServiceResult f, bool allow_restart) (s->restart == SERVICE_RESTART_ON_ABNORMAL && !IN_SET(s->result, SERVICE_SUCCESS, SERVICE_FAILURE_EXIT_CODE)) || (s->restart == SERVICE_RESTART_ON_WATCHDOG && s->result == SERVICE_FAILURE_WATCHDOG) || (s->restart == SERVICE_RESTART_ON_ABORT && IN_SET(s->result, SERVICE_FAILURE_SIGNAL, SERVICE_FAILURE_CORE_DUMP)) || - (s->main_exec_status.code == CLD_EXITED && set_contains(s->restart_force_status.code, INT_TO_PTR(s->main_exec_status.status))) || + (s->main_exec_status.code == CLD_EXITED && set_contains(s->restart_force_status.status, INT_TO_PTR(s->main_exec_status.status))) || (IN_SET(s->main_exec_status.code, CLD_KILLED, CLD_DUMPED) && set_contains(s->restart_force_status.signal, INT_TO_PTR(s->main_exec_status.status)))) && - (s->main_exec_status.code != CLD_EXITED || !set_contains(s->restart_prevent_status.code, INT_TO_PTR(s->main_exec_status.status))) && + (s->main_exec_status.code != CLD_EXITED || !set_contains(s->restart_prevent_status.status, INT_TO_PTR(s->main_exec_status.status))) && (!IN_SET(s->main_exec_status.code, CLD_KILLED, CLD_DUMPED) || !set_contains(s->restart_prevent_status.signal, INT_TO_PTR(s->main_exec_status.status)))) { r = service_arm_timer(s, s->restart_usec); @@ -1699,6 +1697,10 @@ static int service_start(Unit *u) { s->main_pid_alien = false; s->forbid_restart = false; + free(s->status_text); + s->status_text = NULL; + s->status_errno = 0; + service_enter_start_pre(s); return 0; } @@ -2547,11 +2549,15 @@ static int service_dispatch_timer(sd_event_source *source, usec_t usec, void *us static int service_dispatch_watchdog(sd_event_source *source, usec_t usec, void *userdata) { Service *s = SERVICE(userdata); + char t[FORMAT_TIMESPAN_MAX]; assert(s); assert(source == s->watchdog_event_source); - log_error_unit(UNIT(s)->id, "%s watchdog timeout!", UNIT(s)->id); + 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); return 0; @@ -2575,7 +2581,6 @@ static void service_notify_message(Unit *u, pid_t pid, char **tags) { } if (s->notify_access == NOTIFY_MAIN && pid != s->main_pid) { - if (s->main_pid != 0) log_warning_unit(u->id, "%s: Got notification message from PID "PID_FMT", but reception only permitted for main PID "PID_FMT, u->id, pid, s->main_pid); else @@ -2584,14 +2589,10 @@ static void service_notify_message(Unit *u, pid_t pid, char **tags) { } /* Interpret MAINPID= */ - if ((e = strv_find_prefix(tags, "MAINPID=")) && - (s->state == SERVICE_START || - s->state == SERVICE_START_POST || - s->state == SERVICE_RUNNING || - s->state == SERVICE_RELOAD)) { - + e = strv_find_prefix(tags, "MAINPID="); + if (e && IN_SET(s->state, SERVICE_START, SERVICE_START_POST, SERVICE_RUNNING, SERVICE_RELOAD)) { if (parse_pid(e + 8, &pid) < 0) - log_warning_unit(u->id, "Failed to parse notification message %s", e); + log_warning_unit(u->id, "Failed to parse MAINPID= field in notification message: %s", e); else { log_debug_unit(u->id, "%s: got %s", u->id, e); service_set_main_pid(s, pid); @@ -2637,6 +2638,23 @@ static void service_notify_message(Unit *u, pid_t pid, char **tags) { free(t); } + /* Interpret ERRNO= */ + e = strv_find_prefix(tags, "ERRNO="); + if (e) { + int status_errno; + + if (safe_atoi(e + 6, &status_errno) < 0 || status_errno < 0) + log_warning_unit(u->id, "Failed to parse ERRNO= field in notification message: %s", e); + else { + log_debug_unit(u->id, "%s: got %s", u->id, e); + + if (s->status_errno != status_errno) { + s->status_errno = status_errno; + notify_dbus = true; + } + } + } + /* Interpret WATCHDOG= */ if (strv_find(tags, "WATCHDOG=1")) { log_debug_unit(u->id, "%s: got WATCHDOG=1", u->id);