diff --git a/src/core/transaction.c b/src/core/transaction.c index bafbb80b47..982b6cf6dc 100644 --- a/src/core/transaction.c +++ b/src/core/transaction.c @@ -976,11 +976,11 @@ int transaction_add_job_and_dependencies( } if (is_new && !ignore_requirements && type != JOB_NOP) { - Set *following; + _cleanup_set_free_ Set *following = NULL; /* If we are following some other unit, make sure we * add all dependencies of everybody following. */ - if (unit_following_set(ret->unit, &following) > 0) { + if (unit_following_set(ret->unit, &following) > 0) SET_FOREACH(dep, following) { r = transaction_add_job_and_dependencies(tr, type, dep, ret, false, false, false, ignore_order, e); if (r < 0) { @@ -991,16 +991,13 @@ int transaction_add_job_and_dependencies( } } - set_free(following); - } - /* Finally, recursively add in all dependencies. */ if (IN_SET(type, JOB_START, JOB_RESTART)) { UNIT_FOREACH_DEPENDENCY(dep, ret->unit, UNIT_ATOM_PULL_IN_START) { r = transaction_add_job_and_dependencies(tr, JOB_START, dep, ret, true, false, false, ignore_order, e); if (r < 0) { if (r != -EBADR) /* job type not applicable */ - goto fail; + return r; sd_bus_error_free(e); } @@ -1022,7 +1019,7 @@ int transaction_add_job_and_dependencies( r = transaction_add_job_and_dependencies(tr, JOB_VERIFY_ACTIVE, dep, ret, true, false, false, ignore_order, e); if (r < 0) { if (r != -EBADR) /* job type not applicable */ - goto fail; + return r; sd_bus_error_free(e); } @@ -1032,7 +1029,7 @@ int transaction_add_job_and_dependencies( r = transaction_add_job_and_dependencies(tr, JOB_STOP, dep, ret, true, true, false, ignore_order, e); if (r < 0) { if (r != -EBADR) /* job type not applicable */ - goto fail; + return r; sd_bus_error_free(e); } @@ -1050,30 +1047,42 @@ int transaction_add_job_and_dependencies( } if (IN_SET(type, JOB_STOP, JOB_RESTART)) { - UnitDependencyAtom atom; - JobType ptype; - + _cleanup_set_free_ Set *propagated_restart = NULL; /* We propagate STOP as STOP, but RESTART only as TRY_RESTART, in order not to start * dependencies that are not around. */ - if (type == JOB_RESTART) { - atom = UNIT_ATOM_PROPAGATE_RESTART; - ptype = JOB_TRY_RESTART; - } else { - ptype = JOB_STOP; - atom = UNIT_ATOM_PROPAGATE_STOP; - } - UNIT_FOREACH_DEPENDENCY(dep, ret->unit, atom) { - JobType nt; + if (type == JOB_RESTART) + UNIT_FOREACH_DEPENDENCY(dep, ret->unit, UNIT_ATOM_PROPAGATE_RESTART) { + JobType nt; - nt = job_type_collapse(ptype, dep); - if (nt == JOB_NOP) + r = set_ensure_put(&propagated_restart, NULL, dep); + if (r < 0) + return r; + + nt = job_type_collapse(JOB_TRY_RESTART, dep); + if (nt == JOB_NOP) + continue; + + r = transaction_add_job_and_dependencies(tr, nt, dep, ret, true, false, false, ignore_order, e); + if (r < 0) { + if (r != -EBADR) /* job type not applicable */ + return r; + + sd_bus_error_free(e); + } + } + + /* The 'stop' part of a restart job is also propagated to + * units with UNIT_ATOM_PROPAGATE_STOP */ + UNIT_FOREACH_DEPENDENCY(dep, ret->unit, UNIT_ATOM_PROPAGATE_STOP) { + /* Units experienced restart propagation are skipped */ + if (set_contains(propagated_restart, dep)) continue; - r = transaction_add_job_and_dependencies(tr, nt, dep, ret, true, false, false, ignore_order, e); + r = transaction_add_job_and_dependencies(tr, JOB_STOP, dep, ret, true, false, false, ignore_order, e); if (r < 0) { if (r != -EBADR) /* job type not applicable */ - goto fail; + return r; sd_bus_error_free(e); } @@ -1087,9 +1096,6 @@ int transaction_add_job_and_dependencies( } return 0; - -fail: - return r; } int transaction_add_isolate_jobs(Transaction *tr, Manager *m) {