return r;
}
+static void job_print_status_message(Unit *u, JobType t, JobResult result) {
+ assert(u);
+
+ if (t == JOB_START) {
+
+ switch (result) {
+
+ case JOB_DONE:
+ unit_status_printf(u, ANSI_HIGHLIGHT_GREEN_ON " OK " ANSI_HIGHLIGHT_OFF, "Started %s", unit_description(u));
+ break;
+
+ case JOB_FAILED:
+ unit_status_printf(u, ANSI_HIGHLIGHT_ON "FAILED" ANSI_HIGHLIGHT_OFF, "Failed to start %s", unit_description(u));
+ unit_status_printf(u, NULL, "See 'systemctl status %s' for details.", u->meta.id);
+ break;
+
+ case JOB_DEPENDENCY:
+ unit_status_printf(u, ANSI_HIGHLIGHT_ON " ABORT" ANSI_HIGHLIGHT_OFF, "Dependency failed. Aborted start of %s", unit_description(u));
+ break;
+
+ case JOB_TIMEOUT:
+ unit_status_printf(u, ANSI_HIGHLIGHT_ON " TIME " ANSI_HIGHLIGHT_OFF, "Timed out starting %s", unit_description(u));
+ break;
+
+ default:
+ ;
+ }
+
+ } else if (t == JOB_STOP) {
+
+ switch (result) {
+
+ case JOB_TIMEOUT:
+ unit_status_printf(u, ANSI_HIGHLIGHT_ON " TIME " ANSI_HIGHLIGHT_OFF, "Timed out stopping %s", unit_description(u));
+ break;
+
+ case JOB_DONE:
+ case JOB_FAILED:
+ unit_status_printf(u, ANSI_HIGHLIGHT_GREEN_ON " OK " ANSI_HIGHLIGHT_OFF, "Stopped %s", unit_description(u));
+ break;
+
+ default:
+ ;
+ }
+ }
+}
+
int job_finish_and_invalidate(Job *j, JobResult result) {
Unit *u;
Unit *other;
JobType t;
Iterator i;
+ bool recursed = false;
assert(j);
assert(j->installed);
j->type = JOB_START;
job_add_to_run_queue(j);
- return 0;
+
+ u = j->unit;
+ goto finish;
}
j->result = result;
t = j->type;
job_free(j);
- if (result == JOB_FAILED && t == JOB_START)
- unit_status_printf(u, "Starting %s " ANSI_HIGHLIGHT_ON "failed" ANSI_HIGHLIGHT_OFF ", see 'systemctl status %s' for details.\n", unit_description(u), u->meta.id);
- else if (result == JOB_TIMEOUT && t == JOB_START)
- unit_status_printf(u, "Starting %s " ANSI_HIGHLIGHT_ON "timed out" ANSI_HIGHLIGHT_OFF ".\n", unit_description(u), u->meta.id);
- else if (result == JOB_TIMEOUT && t == JOB_STOP)
- unit_status_printf(u, "Stopping %s " ANSI_HIGHLIGHT_ON "timed out" ANSI_HIGHLIGHT_OFF ".\n", unit_description(u), u->meta.id);
+ job_print_status_message(u, t, result);
/* Fail depending jobs on failure */
if (result != JOB_DONE) {
if (other->meta.job &&
(other->meta.job->type == JOB_START ||
other->meta.job->type == JOB_VERIFY_ACTIVE ||
- other->meta.job->type == JOB_RELOAD_OR_START))
+ other->meta.job->type == JOB_RELOAD_OR_START)) {
job_finish_and_invalidate(other->meta.job, JOB_DEPENDENCY);
+ recursed = true;
+ }
SET_FOREACH(other, u->meta.dependencies[UNIT_BOUND_BY], i)
if (other->meta.job &&
(other->meta.job->type == JOB_START ||
other->meta.job->type == JOB_VERIFY_ACTIVE ||
- other->meta.job->type == JOB_RELOAD_OR_START))
+ other->meta.job->type == JOB_RELOAD_OR_START)) {
job_finish_and_invalidate(other->meta.job, JOB_DEPENDENCY);
+ recursed = true;
+ }
SET_FOREACH(other, u->meta.dependencies[UNIT_REQUIRED_BY_OVERRIDABLE], i)
if (other->meta.job &&
!other->meta.job->override &&
(other->meta.job->type == JOB_START ||
other->meta.job->type == JOB_VERIFY_ACTIVE ||
- other->meta.job->type == JOB_RELOAD_OR_START))
+ other->meta.job->type == JOB_RELOAD_OR_START)) {
job_finish_and_invalidate(other->meta.job, JOB_DEPENDENCY);
+ recursed = true;
+ }
} else if (t == JOB_STOP) {
if (other->meta.job &&
(other->meta.job->type == JOB_START ||
other->meta.job->type == JOB_VERIFY_ACTIVE ||
- other->meta.job->type == JOB_RELOAD_OR_START))
+ other->meta.job->type == JOB_RELOAD_OR_START)) {
job_finish_and_invalidate(other->meta.job, JOB_DEPENDENCY);
+ recursed = true;
+ }
}
}
* the unit itself. We don't tread JOB_CANCELED as failure in
* this context. And JOB_FAILURE is already handled by the
* unit itself. */
- if (result == JOB_TIMEOUT || result == JOB_DEPENDENCY)
+ if (result == JOB_TIMEOUT || result == JOB_DEPENDENCY) {
+ log_notice("Job %s/%s failed with result '%s'.",
+ u->meta.id,
+ job_type_to_string(t),
+ job_result_to_string(result));
+
unit_trigger_on_failure(u);
+ }
+finish:
/* Try to start the next jobs that can be started */
SET_FOREACH(other, u->meta.dependencies[UNIT_AFTER], i)
if (other->meta.job)
manager_check_finished(u->meta.manager);
- return 0;
+ return recursed;
}
int job_start_timer(Job *j) {