X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fcore%2Ftransaction.c;h=ddb02c068a8b5075158d438ce45f0fbc7673904f;hb=38809d9dfed4c75d9e97c4e5da2ff957723c4cad;hp=1344e2fb9627c66e24d8212d587952293b4d164c;hpb=668ad332a404736474749cbcc8404af3e4447170;p=elogind.git diff --git a/src/core/transaction.c b/src/core/transaction.c index 1344e2fb9..ddb02c068 100644 --- a/src/core/transaction.c +++ b/src/core/transaction.c @@ -38,22 +38,18 @@ void transaction_abort(Transaction *tr) { assert(!tr->anchor); } -static void transaction_find_jobs_that_matter_to_anchor(Transaction *tr, Job *j, unsigned generation) { +static void transaction_find_jobs_that_matter_to_anchor(Job *j, unsigned generation) { JobDependency *l; - assert(tr); - /* A recursive sweep through the graph that marks all units * that matter to the anchor job, i.e. are directly or * indirectly a dependency of the anchor job via paths that * are fully marked as mattering. */ - if (j) - l = j->subject_list; - else - l = tr->anchor; + j->matters_to_anchor = true; + j->generation = generation; - LIST_FOREACH(subject, l, l) { + LIST_FOREACH(subject, l, j->subject_list) { /* This link does not matter */ if (!l->matters) @@ -63,10 +59,7 @@ static void transaction_find_jobs_that_matter_to_anchor(Transaction *tr, Job *j, if (l->object->generation == generation) continue; - l->object->matters_to_anchor = true; - l->object->generation = generation; - - transaction_find_jobs_that_matter_to_anchor(tr, l->object, generation); + transaction_find_jobs_that_matter_to_anchor(l->object, generation); } } @@ -461,7 +454,7 @@ static void transaction_collect_garbage(Transaction *tr) { again = false; HASHMAP_FOREACH(j, tr->jobs, i) { - if (j->object_list) { + if (tr->anchor_job == j || j->object_list) { /* log_debug("Keeping job %s/%s because of %s/%s", */ /* j->unit->id, job_type_to_string(j->type), */ /* j->object_list->subject ? j->object_list->subject->unit->id : "root", */ @@ -659,7 +652,7 @@ int transaction_activate(Transaction *tr, Manager *m, JobMode mode, DBusError *e * the actual list of jobs, if possible. */ /* First step: figure out which jobs matter */ - transaction_find_jobs_that_matter_to_anchor(tr, NULL, generation++); + transaction_find_jobs_that_matter_to_anchor(tr->anchor_job, generation++); /* Second step: Try not to stop any running services if * we don't have to. Don't try to reverse running @@ -760,13 +753,9 @@ static Job* transaction_add_one_job(Transaction *tr, JobType type, Unit *unit, b } } - if (unit->job && unit->job->type == type) - j = unit->job; - else { - j = job_new(unit, type); - if (!j) - return NULL; - } + j = job_new(unit, type); + if (!j) + return NULL; j->generation = 0; j->marker = NULL; @@ -789,6 +778,12 @@ static Job* transaction_add_one_job(Transaction *tr, JobType type, Unit *unit, b return j; } +static void transaction_job_dependency_free(Transaction *tr, JobDependency *l) { + if (!l->subject) + LIST_REMOVE(JobDependency, subject, tr->anchor, l); + job_dependency_free(l); +} + static void transaction_unlink_job(Transaction *tr, Job *j, bool delete_dependencies) { assert(tr); assert(j); @@ -806,12 +801,12 @@ static void transaction_unlink_job(Transaction *tr, Job *j, bool delete_dependen j->transaction_prev = j->transaction_next = NULL; while (j->subject_list) - job_dependency_free(j->subject_list, tr); + transaction_job_dependency_free(tr, j->subject_list); while (j->object_list) { Job *other = j->object_list->matters ? j->object_list->subject : NULL; - job_dependency_free(j->object_list, tr); + transaction_job_dependency_free(tr, j->object_list); if (other && delete_dependencies) { log_debug("Deleting job %s/%s as dependency of job %s/%s", @@ -832,9 +827,9 @@ int transaction_add_job_and_dependencies( bool conflicts, bool ignore_requirements, bool ignore_order, - DBusError *e, - Job **_ret) { + DBusError *e) { Job *ret; + JobDependency *l; Iterator i; Unit *dep; int r; @@ -884,9 +879,17 @@ int transaction_add_job_and_dependencies( ret->ignore_order = ret->ignore_order || ignore_order; /* Then, add a link to the job. */ - if (!job_dependency_new(by, ret, matters, conflicts, tr)) + l = job_dependency_new(by, ret, matters, conflicts); + if (!l) return -ENOMEM; + /* If the link has no subject job, it's the anchor link. */ + if (!by) { + LIST_PREPEND(JobDependency, subject, tr->anchor, l); + assert(!tr->anchor_job); + tr->anchor_job = ret; + } + if (is_new && !ignore_requirements) { Set *following; @@ -894,7 +897,7 @@ int transaction_add_job_and_dependencies( * add all dependencies of everybody following. */ if (unit_following_set(ret->unit, &following) > 0) { SET_FOREACH(dep, following, i) { - r = transaction_add_job_and_dependencies(tr, type, dep, ret, false, override, false, false, ignore_order, e, NULL); + r = transaction_add_job_and_dependencies(tr, type, dep, ret, false, override, false, false, ignore_order, e); if (r < 0) { log_warning("Cannot add dependency job for unit %s, ignoring: %s", dep->id, bus_error(e, r)); @@ -909,7 +912,7 @@ int transaction_add_job_and_dependencies( /* Finally, recursively add in all dependencies. */ if (type == JOB_START || type == JOB_RELOAD_OR_START) { SET_FOREACH(dep, ret->unit->dependencies[UNIT_REQUIRES], i) { - r = transaction_add_job_and_dependencies(tr, JOB_START, dep, ret, true, override, false, false, ignore_order, e, NULL); + r = transaction_add_job_and_dependencies(tr, JOB_START, dep, ret, true, override, false, false, ignore_order, e); if (r < 0) { if (r != -EBADR) goto fail; @@ -920,7 +923,7 @@ int transaction_add_job_and_dependencies( } SET_FOREACH(dep, ret->unit->dependencies[UNIT_BIND_TO], i) { - r = transaction_add_job_and_dependencies(tr, JOB_START, dep, ret, true, override, false, false, ignore_order, e, NULL); + r = transaction_add_job_and_dependencies(tr, JOB_START, dep, ret, true, override, false, false, ignore_order, e); if (r < 0) { if (r != -EBADR) goto fail; @@ -931,7 +934,7 @@ int transaction_add_job_and_dependencies( } SET_FOREACH(dep, ret->unit->dependencies[UNIT_REQUIRES_OVERRIDABLE], i) { - r = transaction_add_job_and_dependencies(tr, JOB_START, dep, ret, !override, override, false, false, ignore_order, e, NULL); + r = transaction_add_job_and_dependencies(tr, JOB_START, dep, ret, !override, override, false, false, ignore_order, e); if (r < 0) { log_warning("Cannot add dependency job for unit %s, ignoring: %s", dep->id, bus_error(e, r)); @@ -941,7 +944,7 @@ int transaction_add_job_and_dependencies( } SET_FOREACH(dep, ret->unit->dependencies[UNIT_WANTS], i) { - r = transaction_add_job_and_dependencies(tr, JOB_START, dep, ret, false, false, false, false, ignore_order, e, NULL); + r = transaction_add_job_and_dependencies(tr, JOB_START, dep, ret, false, false, false, false, ignore_order, e); if (r < 0) { log_warning("Cannot add dependency job for unit %s, ignoring: %s", dep->id, bus_error(e, r)); @@ -951,7 +954,7 @@ int transaction_add_job_and_dependencies( } SET_FOREACH(dep, ret->unit->dependencies[UNIT_REQUISITE], i) { - r = transaction_add_job_and_dependencies(tr, JOB_VERIFY_ACTIVE, dep, ret, true, override, false, false, ignore_order, e, NULL); + r = transaction_add_job_and_dependencies(tr, JOB_VERIFY_ACTIVE, dep, ret, true, override, false, false, ignore_order, e); if (r < 0) { if (r != -EBADR) goto fail; @@ -962,7 +965,7 @@ int transaction_add_job_and_dependencies( } SET_FOREACH(dep, ret->unit->dependencies[UNIT_REQUISITE_OVERRIDABLE], i) { - r = transaction_add_job_and_dependencies(tr, JOB_VERIFY_ACTIVE, dep, ret, !override, override, false, false, ignore_order, e, NULL); + r = transaction_add_job_and_dependencies(tr, JOB_VERIFY_ACTIVE, dep, ret, !override, override, false, false, ignore_order, e); if (r < 0) { log_warning("Cannot add dependency job for unit %s, ignoring: %s", dep->id, bus_error(e, r)); @@ -972,7 +975,7 @@ int transaction_add_job_and_dependencies( } SET_FOREACH(dep, ret->unit->dependencies[UNIT_CONFLICTS], i) { - r = transaction_add_job_and_dependencies(tr, JOB_STOP, dep, ret, true, override, true, false, ignore_order, e, NULL); + r = transaction_add_job_and_dependencies(tr, JOB_STOP, dep, ret, true, override, true, false, ignore_order, e); if (r < 0) { if (r != -EBADR) goto fail; @@ -983,7 +986,7 @@ int transaction_add_job_and_dependencies( } SET_FOREACH(dep, ret->unit->dependencies[UNIT_CONFLICTED_BY], i) { - r = transaction_add_job_and_dependencies(tr, JOB_STOP, dep, ret, false, override, false, false, ignore_order, e, NULL); + r = transaction_add_job_and_dependencies(tr, JOB_STOP, dep, ret, false, override, false, false, ignore_order, e); if (r < 0) { log_warning("Cannot add dependency job for unit %s, ignoring: %s", dep->id, bus_error(e, r)); @@ -997,7 +1000,7 @@ int transaction_add_job_and_dependencies( if (type == JOB_STOP || type == JOB_RESTART || type == JOB_TRY_RESTART) { SET_FOREACH(dep, ret->unit->dependencies[UNIT_REQUIRED_BY], i) { - r = transaction_add_job_and_dependencies(tr, type, dep, ret, true, override, false, false, ignore_order, e, NULL); + r = transaction_add_job_and_dependencies(tr, type, dep, ret, true, override, false, false, ignore_order, e); if (r < 0) { if (r != -EBADR) goto fail; @@ -1008,7 +1011,7 @@ int transaction_add_job_and_dependencies( } SET_FOREACH(dep, ret->unit->dependencies[UNIT_BOUND_BY], i) { - r = transaction_add_job_and_dependencies(tr, type, dep, ret, true, override, false, false, ignore_order, e, NULL); + r = transaction_add_job_and_dependencies(tr, type, dep, ret, true, override, false, false, ignore_order, e); if (r < 0) { if (r != -EBADR) goto fail; @@ -1022,7 +1025,7 @@ int transaction_add_job_and_dependencies( if (type == JOB_RELOAD || type == JOB_RELOAD_OR_START) { SET_FOREACH(dep, ret->unit->dependencies[UNIT_PROPAGATE_RELOAD_TO], i) { - r = transaction_add_job_and_dependencies(tr, JOB_RELOAD, dep, ret, false, override, false, false, ignore_order, e, NULL); + r = transaction_add_job_and_dependencies(tr, JOB_RELOAD, dep, ret, false, override, false, false, ignore_order, e); if (r < 0) { log_warning("Cannot add dependency reload job for unit %s, ignoring: %s", dep->id, bus_error(e, r)); @@ -1035,9 +1038,6 @@ int transaction_add_job_and_dependencies( /* JOB_VERIFY_STARTED, JOB_RELOAD require no dependency handling */ } - if (_ret) - *_ret = ret; - return 0; fail: @@ -1070,7 +1070,7 @@ int transaction_add_isolate_jobs(Transaction *tr, Manager *m) { if (hashmap_get(tr->jobs, u)) continue; - r = transaction_add_job_and_dependencies(tr, JOB_STOP, u, NULL, true, false, false, false, false, NULL, NULL); + r = transaction_add_job_and_dependencies(tr, JOB_STOP, u, tr->anchor_job, true, false, false, false, false, NULL); if (r < 0) log_warning("Cannot add isolate job for unit %s, ignoring: %s", u->id, strerror(-r)); }