]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
core: propagate stop too if restart is issued 25977/head
authorMike Yuan <me@yhndnzj.com>
Sun, 8 Jan 2023 15:16:22 +0000 (23:16 +0800)
committerMike Yuan <me@yhndnzj.com>
Thu, 19 Jan 2023 13:56:58 +0000 (21:56 +0800)
The restart of a unit should also be considered as that
a stop job happens, and thus gets propagated to units
specified using PropagatesStopTo=.

Fixes #24068

src/core/transaction.c

index 6beca0e6c476dc4efc72ef5a2f8951569b582856..982b6cf6dc329fef4447e5589a59caad296a975c 100644 (file)
@@ -1047,27 +1047,39 @@ 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;
+
+                                        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);
+                                        }
+                                }
 
-                                nt = job_type_collapse(ptype, dep);
-                                if (nt == JOB_NOP)
+                        /* 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 */
                                                 return r;