diff options
author | Daan De Meyer <daan.j.demeyer@gmail.com> | 2021-12-17 20:01:31 +0100 |
---|---|---|
committer | Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> | 2022-01-11 20:27:28 +0100 |
commit | 4c63c3b00aac56390a44e4c0a9d056426d6ff81d (patch) | |
tree | 490ccaf0edff3ee8e6ba01dc2aa8447a28f634a9 | |
parent | 6a28f8b55904c818b25e4db2e1511faac79fd471 (diff) | |
download | systemd-4c63c3b00aac56390a44e4c0a9d056426d6ff81d.tar.gz |
core: Add trigger limit for path units
When conditions fail on a service unit, a path unit can cause
PID 1 to busy loop as it keeps trying to activate the service unit.
To avoid this from happening, add a trigger limit to the path unit,
identical to the trigger limit we have for socket units.
Initially, let's start with a high limit and not make it configurable.
If needed, we can add properties to configure the rate limit similar
to the ones we have for socket units.
(cherry picked from commit aaae822b37aa3ca39aebb516fdc6bef36d730c25)
-rw-r--r-- | src/core/path.c | 10 | ||||
-rw-r--r-- | src/core/path.h | 3 |
2 files changed, 13 insertions, 0 deletions
diff --git a/src/core/path.c b/src/core/path.c index 684e17f433..6ef8238948 100644 --- a/src/core/path.c +++ b/src/core/path.c @@ -265,6 +265,9 @@ static void path_init(Unit *u) { assert(u->load_state == UNIT_STUB); p->directory_mode = 0755; + + p->trigger_limit.interval = 2 * USEC_PER_SEC; + p->trigger_limit.burst = 200; } void path_free_specs(Path *p) { @@ -494,6 +497,12 @@ static void path_enter_running(Path *p) { if (unit_stop_pending(UNIT(p))) return; + if (!ratelimit_below(&p->trigger_limit)) { + log_unit_warning(UNIT(p), "Trigger limit hit, refusing further activation."); + path_enter_dead(p, PATH_FAILURE_TRIGGER_LIMIT_HIT); + return; + } + trigger = UNIT_TRIGGER(UNIT(p)); if (!trigger) { log_unit_error(UNIT(p), "Unit to trigger vanished."); @@ -826,6 +835,7 @@ static const char* const path_result_table[_PATH_RESULT_MAX] = { [PATH_FAILURE_RESOURCES] = "resources", [PATH_FAILURE_START_LIMIT_HIT] = "start-limit-hit", [PATH_FAILURE_UNIT_START_LIMIT_HIT] = "unit-start-limit-hit", + [PATH_FAILURE_TRIGGER_LIMIT_HIT] = "trigger-limit-hit", }; DEFINE_STRING_TABLE_LOOKUP(path_result, PathResult); diff --git a/src/core/path.h b/src/core/path.h index 66ae857dc4..d835c24166 100644 --- a/src/core/path.h +++ b/src/core/path.h @@ -46,6 +46,7 @@ typedef enum PathResult { PATH_FAILURE_RESOURCES, PATH_FAILURE_START_LIMIT_HIT, PATH_FAILURE_UNIT_START_LIMIT_HIT, + PATH_FAILURE_TRIGGER_LIMIT_HIT, _PATH_RESULT_MAX, _PATH_RESULT_INVALID = -EINVAL, } PathResult; @@ -61,6 +62,8 @@ struct Path { mode_t directory_mode; PathResult result; + + RateLimit trigger_limit; }; void path_free_specs(Path *p); |