summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaan De Meyer <daan.j.demeyer@gmail.com>2021-12-17 20:01:31 +0100
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2022-01-11 20:27:28 +0100
commit4c63c3b00aac56390a44e4c0a9d056426d6ff81d (patch)
tree490ccaf0edff3ee8e6ba01dc2aa8447a28f634a9
parent6a28f8b55904c818b25e4db2e1511faac79fd471 (diff)
downloadsystemd-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.c10
-rw-r--r--src/core/path.h3
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);