X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fcore%2Ftransaction.c;h=aee155f5196070254d3aabee858c057ea8aeba56;hb=5273510e9f228a300ec6207d4502f1c6253aed5e;hp=398494778337b76c7163ab0286da105c36a1a60c;hpb=055163ad15a5ca1eb5626c63fa7163e152698e2b;p=elogind.git diff --git a/src/core/transaction.c b/src/core/transaction.c index 398494778..aee155f51 100644 --- a/src/core/transaction.c +++ b/src/core/transaction.c @@ -51,7 +51,7 @@ void transaction_abort(Transaction *tr) { assert(tr); while ((j = hashmap_first(tr->jobs))) - transaction_delete_job(tr, j, true); + transaction_delete_job(tr, j, false); assert(hashmap_isempty(tr->jobs)); } @@ -546,18 +546,16 @@ static int transaction_apply(Transaction *tr, Manager *m, JobMode mode) { /* When isolating first kill all installed jobs which * aren't part of the new transaction */ - rescan: HASHMAP_FOREACH(j, m->jobs, i) { assert(j->installed); if (hashmap_get(tr->jobs, j->unit)) continue; - /* 'j' itself is safe to remove, but if other jobs - are invalidated recursively, our iterator may become - invalid and we need to start over. */ - if (job_finish_and_invalidate(j, JOB_CANCELED) > 0) - goto rescan; + /* Not invalidating recursively. Avoids triggering + * OnFailure= actions of dependent jobs. Also avoids + * invalidating our iterator. */ + job_finish_and_invalidate(j, JOB_CANCELED, false); } } @@ -603,6 +601,8 @@ rollback: } int transaction_activate(Transaction *tr, Manager *m, JobMode mode, DBusError *e) { + Iterator i; + Job *j; int r; unsigned generation = 1; @@ -611,6 +611,12 @@ int transaction_activate(Transaction *tr, Manager *m, JobMode mode, DBusError *e /* This applies the changes recorded in tr->jobs to * the actual list of jobs, if possible. */ + /* Reset the generation counter of all installed jobs. The detection of cycles + * looks at installed jobs. If they had a non-zero generation from some previous + * walk of the graph, the algorithm would break. */ + HASHMAP_FOREACH(j, m->jobs, i) + j->generation = 0; + /* First step: figure out which jobs matter */ transaction_find_jobs_that_matter_to_anchor(tr->anchor_job, generation++);