984f77
From afb5e76925f7f4992252cc392dac4dda6c4faf69 Mon Sep 17 00:00:00 2001
984f77
From: Lennart Poettering <lennart@poettering.net>
984f77
Date: Fri, 11 Sep 2020 19:57:09 +0200
984f77
Subject: [PATCH] core: propagate unit start limit hit state to triggering path
984f77
 unit
984f77
984f77
We already do this for socket and automount units, do it for path units
984f77
too: if the triggered service keeps hitting the start limit, then fail
984f77
the triggering unit too, so that we don#t busy loop forever.
984f77
984f77
(Note that this leaves only timer units out in the cold for this kind of
984f77
protection, but it shouldn't matter there, as they are naturally
984f77
protected against busy loops: they are scheduled by time anyway).
984f77
984f77
Fixes: #16669
984f77
(cherry picked from commit 47ab8f73e3468b6e5a48218eacdb830e978d2cfd)
984f77
984f77
Related: #2065322
984f77
---
984f77
 src/core/path.c | 15 +++++++++++++++
984f77
 src/core/path.h |  1 +
984f77
 2 files changed, 16 insertions(+)
984f77
984f77
diff --git a/src/core/path.c b/src/core/path.c
984f77
index a7c2e0b7c1..c2facf0b16 100644
984f77
--- a/src/core/path.c
984f77
+++ b/src/core/path.c
984f77
@@ -701,6 +701,20 @@ static void path_trigger_notify(Unit *u, Unit *other) {
984f77
         /* Filter out invocations with bogus state */
984f77
         assert(UNIT_IS_LOAD_COMPLETE(other->load_state));
984f77
 
984f77
+        /* Don't propagate state changes from the triggered unit if we are already down */
984f77
+        if (!IN_SET(p->state, PATH_WAITING, PATH_RUNNING))
984f77
+                return;
984f77
+
984f77
+        /* Propagate start limit hit state */
984f77
+        if (other->start_limit_hit) {
984f77
+                path_enter_dead(p, PATH_FAILURE_UNIT_START_LIMIT_HIT);
984f77
+                return;
984f77
+        }
984f77
+
984f77
+        /* Don't propagate anything if there's still a job queued */
984f77
+        if (other->job)
984f77
+                return;
984f77
+
984f77
         if (p->state == PATH_RUNNING &&
984f77
             UNIT_IS_INACTIVE_OR_FAILED(unit_active_state(other))) {
984f77
                 log_unit_debug(UNIT(p), "Got notified about unit deactivation.");
984f77
@@ -752,6 +766,7 @@ static const char* const path_result_table[_PATH_RESULT_MAX] = {
984f77
         [PATH_SUCCESS] = "success",
984f77
         [PATH_FAILURE_RESOURCES] = "resources",
984f77
         [PATH_FAILURE_START_LIMIT_HIT] = "start-limit-hit",
984f77
+        [PATH_FAILURE_UNIT_START_LIMIT_HIT] = "unit-start-limit-hit",
984f77
 };
984f77
 
984f77
 DEFINE_STRING_TABLE_LOOKUP(path_result, PathResult);
984f77
diff --git a/src/core/path.h b/src/core/path.h
984f77
index 4d4b6236c2..8a69f06c13 100644
984f77
--- a/src/core/path.h
984f77
+++ b/src/core/path.h
984f77
@@ -45,6 +45,7 @@ typedef enum PathResult {
984f77
         PATH_SUCCESS,
984f77
         PATH_FAILURE_RESOURCES,
984f77
         PATH_FAILURE_START_LIMIT_HIT,
984f77
+        PATH_FAILURE_UNIT_START_LIMIT_HIT,
984f77
         _PATH_RESULT_MAX,
984f77
         _PATH_RESULT_INVALID = -1
984f77
 } PathResult;