summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/core/service.c31
-rw-r--r--src/core/service.h1
2 files changed, 24 insertions, 8 deletions
diff --git a/src/core/service.c b/src/core/service.c
index 9ad4cf5070..180854b57c 100644
--- a/src/core/service.c
+++ b/src/core/service.c
@@ -1694,7 +1694,9 @@ static void service_enter_running(Service *s, ServiceResult f) {
service_arm_timer(s, usec_add(UNIT(s)->active_enter_timestamp.monotonic, s->runtime_max_usec));
}
- } else if (s->remain_after_exit)
+ } else if (f != SERVICE_SUCCESS)
+ service_enter_signal(s, SERVICE_FINAL_SIGTERM, f);
+ else if (s->remain_after_exit)
service_set_state(s, SERVICE_EXITED);
else
service_enter_stop(s, SERVICE_SUCCESS);
@@ -2578,16 +2580,18 @@ static void service_notify_cgroup_empty_event(Unit *u) {
case SERVICE_START:
case SERVICE_START_POST:
- /* If we were hoping for the daemon to write its PID file,
- * we can give up now. */
- if (s->pid_file_pathspec) {
+ if (s->type == SERVICE_NOTIFY)
+ /* No chance of getting a ready notification anymore */
+ service_enter_signal(s, SERVICE_FINAL_SIGTERM, SERVICE_FAILURE_PROTOCOL);
+ else if (s->pid_file_pathspec) {
+ /* Give up hoping for the daemon to write its PID file */
log_unit_warning(u, "Daemon never wrote its PID file. Failing.");
service_unwatch_pid_file(s);
if (s->state == SERVICE_START)
- service_enter_signal(s, SERVICE_FINAL_SIGTERM, SERVICE_FAILURE_RESOURCES);
+ service_enter_signal(s, SERVICE_FINAL_SIGTERM, SERVICE_FAILURE_PROTOCOL);
else
- service_enter_stop(s, SERVICE_FAILURE_RESOURCES);
+ service_enter_stop(s, SERVICE_FAILURE_PROTOCOL);
}
break;
@@ -2721,6 +2725,16 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) {
else
service_enter_signal(s, SERVICE_FINAL_SIGTERM, f);
break;
+ } else if (s->type == SERVICE_NOTIFY) {
+ /* Only enter running through a notification, so that the
+ * SERVICE_START state signifies that no ready notification
+ * has been received */
+ if (f != SERVICE_SUCCESS)
+ service_enter_signal(s, SERVICE_FINAL_SIGTERM, f);
+ else if (!s->remain_after_exit)
+ /* The service has never been active */
+ service_enter_signal(s, SERVICE_FINAL_SIGTERM, SERVICE_FAILURE_PROTOCOL);
+ break;
}
/* Fall through */
@@ -2825,7 +2839,7 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) {
if (!has_start_post && r < 0) {
r = service_demand_pid_file(s);
if (r < 0 || !cgroup_good(s))
- service_enter_signal(s, SERVICE_FINAL_SIGTERM, SERVICE_FAILURE_RESOURCES);
+ service_enter_signal(s, SERVICE_FINAL_SIGTERM, SERVICE_FAILURE_PROTOCOL);
break;
}
} else
@@ -2847,7 +2861,7 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) {
if (r < 0) {
r = service_demand_pid_file(s);
if (r < 0 || !cgroup_good(s))
- service_enter_stop(s, SERVICE_FAILURE_RESOURCES);
+ service_enter_stop(s, SERVICE_FAILURE_PROTOCOL);
break;
}
} else
@@ -3384,6 +3398,7 @@ DEFINE_STRING_TABLE_LOOKUP(notify_state, NotifyState);
static const char* const service_result_table[_SERVICE_RESULT_MAX] = {
[SERVICE_SUCCESS] = "success",
[SERVICE_FAILURE_RESOURCES] = "resources",
+ [SERVICE_FAILURE_PROTOCOL] = "protocol",
[SERVICE_FAILURE_TIMEOUT] = "timeout",
[SERVICE_FAILURE_EXIT_CODE] = "exit-code",
[SERVICE_FAILURE_SIGNAL] = "signal",
diff --git a/src/core/service.h b/src/core/service.h
index 2869144fcb..278cc1ceb8 100644
--- a/src/core/service.h
+++ b/src/core/service.h
@@ -81,6 +81,7 @@ typedef enum NotifyState {
typedef enum ServiceResult {
SERVICE_SUCCESS,
SERVICE_FAILURE_RESOURCES, /* a bit of a misnomer, just our catch-all error for errnos we didn't expect */
+ SERVICE_FAILURE_PROTOCOL,
SERVICE_FAILURE_TIMEOUT,
SERVICE_FAILURE_EXIT_CODE,
SERVICE_FAILURE_SIGNAL,