Merge pull request #4843 from joukewitteveen/protocol

Go through stop_post on failure (#4770)
This commit is contained in:
Lennart Poettering 2016-12-07 21:35:07 +01:00 committed by GitHub
commit e332833f07
3 changed files with 26 additions and 17 deletions

View file

@ -1806,23 +1806,32 @@
<title>Summary of possible service result variable values</title>
<tgroup cols='3'>
<colspec colname='result' />
<colspec colname='status' />
<colspec colname='code' />
<colspec colname='status' />
<thead>
<row>
<entry><varname>$SERVICE_RESULT</varname></entry>
<entry><varname>$EXIT_STATUS</varname></entry>
<entry><varname>$EXIT_CODE</varname></entry>
<entry><varname>$EXIT_STATUS</varname></entry>
</row>
</thead>
<tbody>
<row>
<entry morerows="1" valign="top"><literal>protocol</literal></entry>
<entry valign="top">not set</entry>
<entry>not set</entry>
</row>
<row>
<entry><literal>exited</literal></entry>
<entry><literal>0</literal></entry>
</row>
<row>
<entry morerows="1" valign="top"><literal>timeout</literal></entry>
<entry valign="top"><literal>killed</literal></entry>
<entry><literal>TERM</literal>, <literal>KILL</literal></entry>
</row>
<row>
<entry valign="top"><literal>exited</literal></entry>
<entry><literal>0</literal>, <literal>1</literal>, <literal>2</literal>, <literal

View file

@ -1714,7 +1714,7 @@ static void service_enter_running(Service *s, ServiceResult f) {
}
} else if (f != SERVICE_SUCCESS)
service_enter_signal(s, SERVICE_FINAL_SIGTERM, f);
service_enter_signal(s, SERVICE_STOP_SIGTERM, f);
else if (s->remain_after_exit)
service_set_state(s, SERVICE_EXITED);
else
@ -1851,7 +1851,7 @@ static void service_enter_start(Service *s) {
fail:
log_unit_warning_errno(UNIT(s), r, "Failed to run 'start' task: %m");
service_enter_signal(s, SERVICE_FINAL_SIGTERM, SERVICE_FAILURE_RESOURCES);
service_enter_signal(s, SERVICE_STOP_SIGTERM, SERVICE_FAILURE_RESOURCES);
}
static void service_enter_start_pre(Service *s) {
@ -1997,9 +1997,7 @@ static void service_run_next_control(Service *s) {
fail:
log_unit_warning_errno(UNIT(s), r, "Failed to run next control task: %m");
if (s->state == SERVICE_START_PRE)
service_enter_signal(s, SERVICE_FINAL_SIGTERM, SERVICE_FAILURE_RESOURCES);
else if (s->state == SERVICE_STOP)
if (IN_SET(s->state, SERVICE_START_PRE, SERVICE_STOP))
service_enter_signal(s, SERVICE_STOP_SIGTERM, SERVICE_FAILURE_RESOURCES);
else if (s->state == SERVICE_STOP_POST)
service_enter_dead(s, SERVICE_FAILURE_RESOURCES, true);
@ -2600,7 +2598,7 @@ static void service_notify_cgroup_empty_event(Unit *u) {
case SERVICE_START:
if (s->type == SERVICE_NOTIFY) {
/* No chance of getting a ready notification anymore */
service_enter_signal(s, SERVICE_FINAL_SIGTERM, SERVICE_FAILURE_PROTOCOL);
service_enter_stop_post(s, SERVICE_FAILURE_PROTOCOL);
break;
}
@ -2613,7 +2611,7 @@ static void service_notify_cgroup_empty_event(Unit *u) {
service_unwatch_pid_file(s);
if (s->state == SERVICE_START)
service_enter_signal(s, SERVICE_FINAL_SIGTERM, SERVICE_FAILURE_PROTOCOL);
service_enter_stop_post(s, SERVICE_FAILURE_PROTOCOL);
else
service_enter_stop(s, SERVICE_FAILURE_PROTOCOL);
}
@ -2747,17 +2745,17 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) {
if (f == SERVICE_SUCCESS)
service_enter_start_post(s);
else
service_enter_signal(s, SERVICE_FINAL_SIGTERM, f);
service_enter_signal(s, SERVICE_STOP_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);
service_enter_signal(s, SERVICE_STOP_SIGTERM, f);
else if (!s->remain_after_exit)
/* The service has never been active */
service_enter_signal(s, SERVICE_FINAL_SIGTERM, SERVICE_FAILURE_PROTOCOL);
service_enter_signal(s, SERVICE_STOP_SIGTERM, SERVICE_FAILURE_PROTOCOL);
break;
}
@ -2837,7 +2835,7 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) {
if (f == SERVICE_SUCCESS)
service_enter_start(s);
else
service_enter_signal(s, SERVICE_FINAL_SIGTERM, f);
service_enter_signal(s, SERVICE_STOP_SIGTERM, f);
break;
case SERVICE_START:
@ -2846,7 +2844,7 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) {
break;
if (f != SERVICE_SUCCESS) {
service_enter_signal(s, SERVICE_FINAL_SIGTERM, f);
service_enter_signal(s, SERVICE_STOP_SIGTERM, f);
break;
}
@ -2863,7 +2861,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_PROTOCOL);
service_enter_signal(s, SERVICE_STOP_SIGTERM, SERVICE_FAILURE_PROTOCOL);
break;
}
} else
@ -2959,7 +2957,7 @@ static int service_dispatch_timer(sd_event_source *source, usec_t usec, void *us
case SERVICE_START_PRE:
case SERVICE_START:
log_unit_warning(UNIT(s), "%s operation timed out. Terminating.", s->state == SERVICE_START ? "Start" : "Start-pre");
service_enter_signal(s, SERVICE_FINAL_SIGTERM, SERVICE_FAILURE_TIMEOUT);
service_enter_signal(s, SERVICE_STOP_SIGTERM, SERVICE_FAILURE_TIMEOUT);
break;
case SERVICE_START_POST:

View file

@ -79,6 +79,8 @@ typedef enum NotifyState {
_NOTIFY_STATE_INVALID = -1
} NotifyState;
/* The values of this enum are referenced in man/systemd.exec.xml and src/shared/bus-unit-util.c.
* Update those sources for each change to this enum. */
typedef enum ServiceResult {
SERVICE_SUCCESS,
SERVICE_FAILURE_RESOURCES, /* a bit of a misnomer, just our catch-all error for errnos we didn't expect */