diff options
author | Lennart Poettering <lennart@poettering.net> | 2010-01-29 04:11:36 +0100 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2010-01-29 04:11:36 +0100 |
commit | 9f04bd5251b3c2e17c53cf28feb95e36e1991038 (patch) | |
tree | f4f9cce2b39e14226956b1d15954e850997910d3 | |
parent | bacffaab22278bca8c6bbb274d650d259a54350b (diff) |
fix ordering cycle detection
-rw-r--r-- | manager.c | 28 |
1 files changed, 24 insertions, 4 deletions
@@ -424,8 +424,12 @@ static int transaction_verify_order_one(Manager *m, Job *j, Job *from, unsigned * since smart how we are we stored our way back in * there. */ + log_debug("Found cycle on %s/%s", unit_id(j->unit), job_type_to_string(j->type)); + for (k = from; k; k = (k->generation == generation ? k->marker : NULL)) { + log_debug("Walked on cycle path to %s/%s", unit_id(j->unit), job_type_to_string(j->type)); + if (!k->installed && !unit_matters_to_anchor(k->unit, k)) { /* Ok, we can drop this one, so let's @@ -441,6 +445,8 @@ static int transaction_verify_order_one(Manager *m, Job *j, Job *from, unsigned break; } + log_debug("Unable to break cycle"); + return -ENOEXEC; } @@ -467,6 +473,10 @@ static int transaction_verify_order_one(Manager *m, Job *j, Job *from, unsigned return r; } + /* Ok, let's backtrack, and remember that this entry is not on + * our path anymore. */ + j->marker = NULL; + return 0; } @@ -661,8 +671,10 @@ static int transaction_activate(Manager *m, JobMode mode) { if ((r = transaction_verify_order(m, &generation)) >= 0) break; - if (r != -EAGAIN) + if (r != -EAGAIN) { + log_debug("Requested transaction contains an unfixable cyclic ordering dependency: %s", strerror(-r)); goto rollback; + } /* Let's see if the resulting transaction ordering * graph is still cyclic... */ @@ -675,8 +687,10 @@ static int transaction_activate(Manager *m, JobMode mode) { if ((r = transaction_merge_jobs(m)) >= 0) break; - if (r != -EAGAIN) + if (r != -EAGAIN) { + log_debug("Requested transaction contains unmergable jobs: %s", strerror(-r)); goto rollback; + } /* Sixth step: an entry got dropped, let's garbage * collect its dependencies. */ @@ -688,12 +702,16 @@ static int transaction_activate(Manager *m, JobMode mode) { /* Seventh step: check whether we can actually apply this */ if (mode == JOB_FAIL) - if ((r = transaction_is_destructive(m, mode)) < 0) + if ((r = transaction_is_destructive(m, mode)) < 0) { + log_debug("Requested transaction contradicts existing jobs: %s", strerror(-r)); goto rollback; + } /* Eights step: apply changes */ - if ((r = transaction_apply(m, mode)) < 0) + if ((r = transaction_apply(m, mode)) < 0) { + log_debug("Failed to apply transaction: %s", strerror(-r)); goto rollback; + } assert(hashmap_isempty(m->transaction_jobs)); assert(!m->transaction_anchor); @@ -856,6 +874,8 @@ int manager_add_job(Manager *m, JobType type, Unit *unit, JobMode mode, bool for assert(unit); assert(mode < _JOB_MODE_MAX); + log_debug("Trying to enqueue job %s/%s", unit_id(unit), job_type_to_string(type)); + if ((r = transaction_add_job_and_dependencies(m, type, unit, NULL, true, force, &ret))) { transaction_abort(m); return r; |