X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Fcore%2Ftransaction.c;h=36e31c45c9949dc5a5a82b981ff31490242c24cb;hp=4a8d90e6e569692c14f5890eae89ad69033a0cc3;hb=d003f514dab2dbf1a66e11800a50aeaf039d036c;hpb=37d3ab1b7e114f0fb6dfb2e7273569b42794b76a diff --git a/src/core/transaction.c b/src/core/transaction.c index 4a8d90e6e..36e31c45c 100644 --- a/src/core/transaction.c +++ b/src/core/transaction.c @@ -22,8 +22,10 @@ #include #include -#include "transaction.h" #include "bus-errors.h" +#include "bus-util.h" +#include "bus-error.h" +#include "transaction.h" static void transaction_unlink_job(Transaction *tr, Job *j, bool delete_dependencies); @@ -139,7 +141,7 @@ static void transaction_merge_and_delete_job(Transaction *tr, Job *j, Job *other transaction_delete_job(tr, other, true); } -static bool job_is_conflicted_by(Job *j) { +_pure_ static bool job_is_conflicted_by(Job *j) { JobDependency *l; assert(j); @@ -230,7 +232,7 @@ static int delete_one_unmergeable_job(Transaction *tr, Job *j) { return -EINVAL; } -static int transaction_merge_jobs(Transaction *tr, DBusError *e) { +static int transaction_merge_jobs(Transaction *tr, sd_bus_error *e) { Job *j; Iterator i; int r; @@ -260,8 +262,9 @@ static int transaction_merge_jobs(Transaction *tr, DBusError *e) { return -EAGAIN; /* We couldn't merge anything. Failure */ - dbus_set_error(e, BUS_ERROR_TRANSACTION_JOBS_CONFLICTING, "Transaction contains conflicting jobs '%s' and '%s' for %s. Probably contradicting requirement dependencies configured.", - job_type_to_string(t), job_type_to_string(k->type), k->unit->id); + sd_bus_error_setf( + e, BUS_ERROR_TRANSACTION_JOBS_CONFLICTING, "Transaction contains conflicting jobs '%s' and '%s' for %s. Probably contradicting requirement dependencies configured.", + job_type_to_string(t), job_type_to_string(k->type), k->unit->id); return r; } } @@ -319,7 +322,7 @@ rescan: } } -static bool unit_matters_to_anchor(Unit *u, Job *j) { +_pure_ static bool unit_matters_to_anchor(Unit *u, Job *j) { assert(u); assert(!j->transaction_prev); @@ -333,7 +336,7 @@ static bool unit_matters_to_anchor(Unit *u, Job *j) { return false; } -static int transaction_verify_order_one(Transaction *tr, Job *j, Job *from, unsigned generation, DBusError *e) { +static int transaction_verify_order_one(Transaction *tr, Job *j, Job *from, unsigned generation, sd_bus_error *e) { Iterator i; Unit *u; int r; @@ -343,7 +346,7 @@ static int transaction_verify_order_one(Transaction *tr, Job *j, Job *from, unsi assert(!j->transaction_prev); /* Does a recursive sweep through the ordering graph, looking - * for a cycle. If we find cycle we try to break it. */ + * for a cycle. If we find a cycle we try to break it. */ /* Have we seen this before? */ if (j->generation == generation) { @@ -370,7 +373,7 @@ static int transaction_verify_order_one(Transaction *tr, Job *j, Job *from, unsi /* logging for j not k here here to provide consistent narrative */ log_info_unit(j->unit->id, - "Walked on cycle path to %s/%s", + "Found dependency on %s/%s", k->unit->id, job_type_to_string(k->type)); if (!delete && @@ -404,8 +407,8 @@ static int transaction_verify_order_one(Transaction *tr, Job *j, Job *from, unsi log_error("Unable to break cycle"); - dbus_set_error(e, BUS_ERROR_TRANSACTION_ORDER_IS_CYCLIC, - "Transaction order is cyclic. See system logs for details."); + sd_bus_error_setf(e, BUS_ERROR_TRANSACTION_ORDER_IS_CYCLIC, + "Transaction order is cyclic. See system logs for details."); return -ENOEXEC; } @@ -444,7 +447,7 @@ static int transaction_verify_order_one(Transaction *tr, Job *j, Job *from, unsi return 0; } -static int transaction_verify_order(Transaction *tr, unsigned *generation, DBusError *e) { +static int transaction_verify_order(Transaction *tr, unsigned *generation, sd_bus_error *e) { Job *j; int r; Iterator i; @@ -489,7 +492,7 @@ rescan: } } -static int transaction_is_destructive(Transaction *tr, JobMode mode, DBusError *e) { +static int transaction_is_destructive(Transaction *tr, JobMode mode, sd_bus_error *e) { Iterator i; Job *j; @@ -507,7 +510,7 @@ static int transaction_is_destructive(Transaction *tr, JobMode mode, DBusError * if (j->unit->job && (mode == JOB_FAIL || j->unit->job->irreversible) && !job_type_is_superset(j->type, j->unit->job->type)) { - dbus_set_error(e, BUS_ERROR_TRANSACTION_IS_DESTRUCTIVE, "Transaction is destructive."); + sd_bus_error_setf(e, BUS_ERROR_TRANSACTION_IS_DESTRUCTIVE, "Transaction is destructive."); return -EEXIST; } } @@ -575,7 +578,7 @@ static int transaction_apply(Transaction *tr, Manager *m, JobMode mode) { /* Moves the transaction jobs to the set of active jobs */ - if (mode == JOB_ISOLATE) { + if (mode == JOB_ISOLATE || mode == JOB_FLUSH) { /* When isolating first kill all installed jobs which * aren't part of the new transaction */ @@ -634,7 +637,7 @@ rollback: return r; } -int transaction_activate(Transaction *tr, Manager *m, JobMode mode, DBusError *e) { +int transaction_activate(Transaction *tr, Manager *m, JobMode mode, sd_bus_error *e) { Iterator i; Job *j; int r; @@ -676,7 +679,7 @@ int transaction_activate(Transaction *tr, Manager *m, JobMode mode, DBusError *e break; if (r != -EAGAIN) { - log_warning("Requested transaction contains an unfixable cyclic ordering dependency: %s", bus_error(e, r)); + log_warning("Requested transaction contains an unfixable cyclic ordering dependency: %s", bus_error_message(e, r)); return r; } @@ -693,7 +696,7 @@ int transaction_activate(Transaction *tr, Manager *m, JobMode mode, DBusError *e break; if (r != -EAGAIN) { - log_warning("Requested transaction contains unmergeable jobs: %s", bus_error(e, r)); + log_warning("Requested transaction contains unmergeable jobs: %s", bus_error_message(e, r)); return r; } @@ -712,7 +715,7 @@ int transaction_activate(Transaction *tr, Manager *m, JobMode mode, DBusError *e /* Ninth step: check whether we can actually apply this */ r = transaction_is_destructive(tr, mode, e); if (r < 0) { - log_notice("Requested transaction contradicts existing jobs: %s", bus_error(e, r)); + log_notice("Requested transaction contradicts existing jobs: %s", bus_error_message(e, r)); return r; } @@ -732,8 +735,11 @@ int transaction_activate(Transaction *tr, Manager *m, JobMode mode, DBusError *e * feature for cosmetics, not actually useful for * anything beyond that. */ - if (m->idle_pipe[0] < 0 && m->idle_pipe[1] < 0) + if (m->idle_pipe[0] < 0 && m->idle_pipe[1] < 0 && + m->idle_pipe[2] < 0 && m->idle_pipe[3] < 0) { pipe2(m->idle_pipe, O_NONBLOCK|O_CLOEXEC); + pipe2(m->idle_pipe + 2, O_NONBLOCK|O_CLOEXEC); + } } return 0; @@ -771,10 +777,10 @@ static Job* transaction_add_one_job(Transaction *tr, JobType type, Unit *unit, b j->override = override; j->irreversible = tr->irreversible; - LIST_PREPEND(Job, transaction, f, j); + LIST_PREPEND(transaction, f, j); if (hashmap_replace(tr->jobs, unit, f) < 0) { - LIST_REMOVE(Job, transaction, f, j); + LIST_REMOVE(transaction, f, j); job_free(j); return NULL; } @@ -831,7 +837,7 @@ int transaction_add_job_and_dependencies( bool conflicts, bool ignore_requirements, bool ignore_order, - DBusError *e) { + sd_bus_error *e) { Job *ret; Iterator i; Unit *dep; @@ -850,13 +856,14 @@ int transaction_add_job_and_dependencies( if (unit->load_state != UNIT_LOADED && unit->load_state != UNIT_ERROR && + unit->load_state != UNIT_NOT_FOUND && unit->load_state != UNIT_MASKED) { - dbus_set_error(e, BUS_ERROR_LOAD_FAILED, "Unit %s is not loaded properly.", unit->id); + sd_bus_error_setf(e, BUS_ERROR_LOAD_FAILED, "Unit %s is not loaded properly.", unit->id); return -EINVAL; } if (type != JOB_STOP && unit->load_state == UNIT_ERROR) { - dbus_set_error(e, BUS_ERROR_LOAD_FAILED, + sd_bus_error_setf(e, BUS_ERROR_LOAD_FAILED, "Unit %s failed to load: %s. " "See system logs and 'systemctl status %s' for details.", unit->id, @@ -865,13 +872,21 @@ int transaction_add_job_and_dependencies( return -EINVAL; } + if (type != JOB_STOP && unit->load_state == UNIT_NOT_FOUND) { + sd_bus_error_setf(e, BUS_ERROR_LOAD_FAILED, + "Unit %s failed to load: %s.", + unit->id, + strerror(-unit->load_error)); + return -EINVAL; + } + if (type != JOB_STOP && unit->load_state == UNIT_MASKED) { - dbus_set_error(e, BUS_ERROR_MASKED, "Unit %s is masked.", unit->id); + sd_bus_error_setf(e, BUS_ERROR_UNIT_MASKED, "Unit %s is masked.", unit->id); return -EADDRNOTAVAIL; } if (!unit_job_is_applicable(unit, type)) { - dbus_set_error(e, BUS_ERROR_JOB_TYPE_NOT_APPLICABLE, "Job type %s is not applicable for unit %s.", job_type_to_string(type), unit->id); + sd_bus_error_setf(e, BUS_ERROR_JOB_TYPE_NOT_APPLICABLE, "Job type %s is not applicable for unit %s.", job_type_to_string(type), unit->id); return -EBADR; } @@ -903,10 +918,10 @@ int transaction_add_job_and_dependencies( if (r < 0) { log_warning_unit(dep->id, "Cannot add dependency job for unit %s, ignoring: %s", - dep->id, bus_error(e, r)); + dep->id, bus_error_message(e, r)); if (e) - dbus_error_free(e); + sd_bus_error_free(e); } } @@ -922,7 +937,7 @@ int transaction_add_job_and_dependencies( goto fail; if (e) - dbus_error_free(e); + sd_bus_error_free(e); } } @@ -933,7 +948,7 @@ int transaction_add_job_and_dependencies( goto fail; if (e) - dbus_error_free(e); + sd_bus_error_free(e); } } @@ -942,10 +957,10 @@ int transaction_add_job_and_dependencies( if (r < 0) { log_full_unit(r == -EADDRNOTAVAIL ? LOG_DEBUG : LOG_WARNING, dep->id, "Cannot add dependency job for unit %s, ignoring: %s", - dep->id, bus_error(e, r)); + dep->id, bus_error_message(e, r)); if (e) - dbus_error_free(e); + sd_bus_error_free(e); } } @@ -954,10 +969,10 @@ int transaction_add_job_and_dependencies( if (r < 0) { log_full_unit(r == -EADDRNOTAVAIL ? LOG_DEBUG : LOG_WARNING, dep->id, "Cannot add dependency job for unit %s, ignoring: %s", - dep->id, bus_error(e, r)); + dep->id, bus_error_message(e, r)); if (e) - dbus_error_free(e); + sd_bus_error_free(e); } } @@ -968,7 +983,7 @@ int transaction_add_job_and_dependencies( goto fail; if (e) - dbus_error_free(e); + sd_bus_error_free(e); } } @@ -977,10 +992,10 @@ int transaction_add_job_and_dependencies( if (r < 0) { log_full_unit(r == -EADDRNOTAVAIL ? LOG_DEBUG : LOG_WARNING, dep->id, "Cannot add dependency job for unit %s, ignoring: %s", - dep->id, bus_error(e, r)); + dep->id, bus_error_message(e, r)); if (e) - dbus_error_free(e); + sd_bus_error_free(e); } } @@ -991,7 +1006,7 @@ int transaction_add_job_and_dependencies( goto fail; if (e) - dbus_error_free(e); + sd_bus_error_free(e); } } @@ -1000,10 +1015,10 @@ int transaction_add_job_and_dependencies( if (r < 0) { log_warning_unit(dep->id, "Cannot add dependency job for unit %s, ignoring: %s", - dep->id, bus_error(e, r)); + dep->id, bus_error_message(e, r)); if (e) - dbus_error_free(e); + sd_bus_error_free(e); } } @@ -1018,7 +1033,7 @@ int transaction_add_job_and_dependencies( goto fail; if (e) - dbus_error_free(e); + sd_bus_error_free(e); } } @@ -1029,7 +1044,7 @@ int transaction_add_job_and_dependencies( goto fail; if (e) - dbus_error_free(e); + sd_bus_error_free(e); } } @@ -1040,7 +1055,7 @@ int transaction_add_job_and_dependencies( goto fail; if (e) - dbus_error_free(e); + sd_bus_error_free(e); } } @@ -1053,10 +1068,10 @@ int transaction_add_job_and_dependencies( if (r < 0) { log_warning_unit(dep->id, "Cannot add dependency reload job for unit %s, ignoring: %s", - dep->id, bus_error(e, r)); + dep->id, bus_error_message(e, r)); if (e) - dbus_error_free(e); + sd_bus_error_free(e); } } }