Merge pull request #4259 from joukewitteveen/notify

service: fix main processes exit behavior for type notify services
This commit is contained in:
Lennart Poettering 2016-11-23 16:45:19 +01:00 committed by GitHub
commit fadc06bb81
2 changed files with 24 additions and 8 deletions

View File

@ -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",

View File

@ -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,