X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Fjob.c;h=8cc9d742ede5dcba0bcee7da0c6b1e801c76b5ee;hp=9937ed735b6bffd107c3043559e67fc77f8da729;hb=3b6fdb5b5afebc49a7e987e3e3bf7aa2615d1671;hpb=9eb63b3cb4a41707b6c01d81cef15acf1a757613 diff --git a/src/job.c b/src/job.c index 9937ed735..8cc9d742e 100644 --- a/src/job.c +++ b/src/job.c @@ -56,7 +56,7 @@ void job_free(Job *j) { /* Detach from next 'bigger' objects */ if (j->installed) { - bus_job_send_removed_signal(j); + bus_job_send_removed_signal(j, !j->failed); if (j->unit->meta.job == j) { j->unit->meta.job = NULL; @@ -76,6 +76,7 @@ void job_free(Job *j) { if (j->in_dbus_queue) LIST_REMOVE(Job, dbus_queue, j->manager->dbus_job_queue, j); + free(j->bus_client); free(j); } @@ -275,25 +276,26 @@ bool job_type_is_redundant(JobType a, UnitActiveState b) { case JOB_START: return b == UNIT_ACTIVE || - b == UNIT_ACTIVE_RELOADING; + b == UNIT_RELOADING; case JOB_STOP: return - b == UNIT_INACTIVE; + b == UNIT_INACTIVE || + b == UNIT_MAINTENANCE; case JOB_VERIFY_ACTIVE: return b == UNIT_ACTIVE || - b == UNIT_ACTIVE_RELOADING; + b == UNIT_RELOADING; case JOB_RELOAD: return - b == UNIT_ACTIVE_RELOADING; + b == UNIT_RELOADING; case JOB_RELOAD_OR_START: return b == UNIT_ACTIVATING || - b == UNIT_ACTIVE_RELOADING; + b == UNIT_RELOADING; case JOB_RESTART: return @@ -415,7 +417,7 @@ int job_run_and_invalidate(Job *j) { case JOB_RESTART: { UnitActiveState t = unit_active_state(j->unit); - if (t == UNIT_INACTIVE || t == UNIT_ACTIVATING) { + if (t == UNIT_INACTIVE || t == UNIT_MAINTENANCE || t == UNIT_ACTIVATING) { j->type = JOB_START; r = unit_start(j->unit); } else @@ -425,7 +427,7 @@ int job_run_and_invalidate(Job *j) { case JOB_TRY_RESTART: { UnitActiveState t = unit_active_state(j->unit); - if (t == UNIT_INACTIVE || t == UNIT_DEACTIVATING) + if (t == UNIT_INACTIVE || t == UNIT_MAINTENANCE || t == UNIT_DEACTIVATING) r = -ENOEXEC; else if (t == UNIT_ACTIVATING) { j->type = JOB_START; @@ -459,7 +461,6 @@ int job_finish_and_invalidate(Job *j, bool success) { assert(j); assert(j->installed); - log_debug("Job %s/%s finished, success=%s", j->unit->meta.id, job_type_to_string(j->type), yes_no(success)); job_add_to_dbus_queue(j); /* Patch restart jobs so that they become normal start jobs */ @@ -469,17 +470,23 @@ int job_finish_and_invalidate(Job *j, bool success) { j->unit->meta.id, job_type_to_string(j->type), j->unit->meta.id, job_type_to_string(JOB_START)); - j->state = JOB_RUNNING; + j->state = JOB_WAITING; j->type = JOB_START; job_add_to_run_queue(j); return 0; } + log_debug("Job %s/%s finished, success=%s", j->unit->meta.id, job_type_to_string(j->type), yes_no(success)); + + j->failed = !success; u = j->unit; t = j->type; job_free(j); + if (!success) + unit_status_printf(u, "Starting %s " ANSI_HIGHLIGHT_ON "failed" ANSI_HIGHLIGHT_OFF ".\n", unit_description(u)); + /* Fail depending jobs on failure */ if (!success) { @@ -488,14 +495,16 @@ int job_finish_and_invalidate(Job *j, bool success) { t == JOB_RELOAD_OR_START) { SET_FOREACH(other, u->meta.dependencies[UNIT_REQUIRED_BY], i) - if (other->meta.job && + if (!other->meta.ignore_dependency_failure && + other->meta.job && (other->meta.job->type == JOB_START || other->meta.job->type == JOB_VERIFY_ACTIVE || other->meta.job->type == JOB_RELOAD_OR_START)) job_finish_and_invalidate(other->meta.job, false); SET_FOREACH(other, u->meta.dependencies[UNIT_REQUIRED_BY_OVERRIDABLE], i) - if (other->meta.job && + if (!other->meta.ignore_dependency_failure && + other->meta.job && !other->meta.job->override && (other->meta.job->type == JOB_START || other->meta.job->type == JOB_VERIFY_ACTIVE || @@ -505,7 +514,8 @@ int job_finish_and_invalidate(Job *j, bool success) { } else if (t == JOB_STOP) { SET_FOREACH(other, u->meta.dependencies[UNIT_CONFLICTS], i) - if (other->meta.job && + if (!other->meta.ignore_dependency_failure && + other->meta.job && (other->meta.job->type == JOB_START || other->meta.job->type == JOB_VERIFY_ACTIVE || other->meta.job->type == JOB_RELOAD_OR_START)) @@ -542,10 +552,9 @@ void job_add_to_dbus_queue(Job *j) { if (j->in_dbus_queue) return; - if (set_isempty(j->manager->subscribed)) { - j->sent_dbus_new_signal = true; - return; - } + /* We don't check if anybody is subscribed here, since this + * job might just have been created and not yet assigned to a + * connection/client. */ LIST_PREPEND(Job, dbus_queue, j->manager->dbus_job_queue, j); j->in_dbus_queue = true;