summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMichal Schmidt <mschmidt@redhat.com>2012-04-22 02:09:04 +0200
committerMichal Schmidt <mschmidt@redhat.com>2012-04-24 01:54:14 +0200
commit4e7bd268ae1f39675988b9ac61b9378a67e3ae3e (patch)
tree02384f8f60f2459ea2d3245174a05468a6a79d08 /src
parent055163ad15a5ca1eb5626c63fa7163e152698e2b (diff)
transaction: fix detection of cycles involving installed jobs
A transaction can be acyclic, but when it's added to installed jobs, a cycle may result. transaction_verify_order_one() attempts to detect these cases, but it fails because the installed jobs often have the exact generation number that makes them look as if they were walked already. Fix it by resetting the generation numbers of all installed jobs before detecting cycles. An alternative fix could be to add the generation counter to the Manager and use it instead of starting always from 1 in transaction_activate(). But I prefer not having to worry about it wrapping around.
Diffstat (limited to 'src')
-rw-r--r--src/core/transaction.c8
1 files changed, 8 insertions, 0 deletions
diff --git a/src/core/transaction.c b/src/core/transaction.c
index 3984947783..394c181352 100644
--- a/src/core/transaction.c
+++ b/src/core/transaction.c
@@ -603,6 +603,8 @@ rollback:
}
int transaction_activate(Transaction *tr, Manager *m, JobMode mode, DBusError *e) {
+ Iterator i;
+ Job *j;
int r;
unsigned generation = 1;
@@ -611,6 +613,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++);