69 lines
2.6 KiB
Diff
69 lines
2.6 KiB
Diff
|
From 2ce14fcc879b0a24d29dc5f5d36db80c5c1f2653 Mon Sep 17 00:00:00 2001
|
||
|
From: Lennart Poettering <lennart@poettering.net>
|
||
|
Date: Fri, 11 Sep 2020 19:57:09 +0200
|
||
|
Subject: [PATCH] core: propagate unit start limit hit state to triggering path
|
||
|
unit
|
||
|
|
||
|
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)
|
||
|
|
||
|
Related: #2086553
|
||
|
---
|
||
|
src/core/path.c | 15 +++++++++++++++
|
||
|
src/core/path.h | 1 +
|
||
|
2 files changed, 16 insertions(+)
|
||
|
|
||
|
diff --git a/src/core/path.c b/src/core/path.c
|
||
|
index a7c2e0b7c1..c2facf0b16 100644
|
||
|
--- a/src/core/path.c
|
||
|
+++ b/src/core/path.c
|
||
|
@@ -701,6 +701,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.");
|
||
|
@@ -752,6 +766,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);
|
||
|
diff --git a/src/core/path.h b/src/core/path.h
|
||
|
index 4d4b6236c2..8a69f06c13 100644
|
||
|
--- a/src/core/path.h
|
||
|
+++ b/src/core/path.h
|
||
|
@@ -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;
|