core: propagate unit start limit hit state to triggering path unit
authorLennart Poettering <lennart@poettering.net>
Fri, 11 Sep 2020 17:57:09 +0000 (19:57 +0200)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Sun, 20 Sep 2020 10:11:25 +0000 (12:11 +0200)
We already do this for socket and automount units, do it for path units
too: if the triggered service keeps hitting the start limit, then fail
the triggering unit too, so that we don#t busy loop forever.

(Note that this leaves only timer units out in the cold for this kind of
protection, but it shouldn't matter there, as they are naturally
protected against busy loops: they are scheduled by time anyway).

Fixes: #16669
(cherry picked from commit 47ab8f73e3468b6e5a48218eacdb830e978d2cfd)
(cherry picked from commit 689d2e061bd7b04f75104067e5ff0046f357f9b8)

src/core/path.c
src/core/path.h

index bd910924d9ee239e0e04655804d036efb0a93601..6c444134368aeb4196c6af9dd13e891def20af27 100644 (file)
@@ -756,6 +756,20 @@ static void path_trigger_notify(Unit *u, Unit *other) {
         /* Filter out invocations with bogus state */
         assert(UNIT_IS_LOAD_COMPLETE(other->load_state));
 
+        /* Don't propagate state changes from the triggered unit if we are already down */
+        if (!IN_SET(p->state, PATH_WAITING, PATH_RUNNING))
+                return;
+
+        /* Propagate start limit hit state */
+        if (other->start_limit_hit) {
+                path_enter_dead(p, PATH_FAILURE_UNIT_START_LIMIT_HIT);
+                return;
+        }
+
+        /* Don't propagate anything if there's still a job queued */
+        if (other->job)
+                return;
+
         if (p->state == PATH_RUNNING &&
             UNIT_IS_INACTIVE_OR_FAILED(unit_active_state(other))) {
                 log_unit_debug(UNIT(p), "Got notified about unit deactivation.");
@@ -792,6 +806,7 @@ static const char* const path_result_table[_PATH_RESULT_MAX] = {
         [PATH_SUCCESS] = "success",
         [PATH_FAILURE_RESOURCES] = "resources",
         [PATH_FAILURE_START_LIMIT_HIT] = "start-limit-hit",
+        [PATH_FAILURE_UNIT_START_LIMIT_HIT] = "unit-start-limit-hit",
 };
 
 DEFINE_STRING_TABLE_LOOKUP(path_result, PathResult);
index 4d4b6236c27f155ce866eef120e1829fdb932ee0..8a69f06c13181b864317ffff8050f241ca350b15 100644 (file)
@@ -45,6 +45,7 @@ typedef enum PathResult {
         PATH_SUCCESS,
         PATH_FAILURE_RESOURCES,
         PATH_FAILURE_START_LIMIT_HIT,
+        PATH_FAILURE_UNIT_START_LIMIT_HIT,
         _PATH_RESULT_MAX,
         _PATH_RESULT_INVALID = -1
 } PathResult;