From 9727f2427ff6b2e1f4ab927cc57ad8e888f04e95 Mon Sep 17 00:00:00 2001 From: Daan De Meyer Date: Tue, 24 Aug 2021 16:46:47 +0100 Subject: core: Check unit start rate limiting earlier Fixes #17433. Currently, if any of the validations we do before we check start rate limiting fail, we can still enter a busy loop as no rate limiting gets applied. A common occurence of this scenario is path units triggering a service that fails a condition check. To fix the issue, we simply move up start rate limiting checks to be the first thing we do when starting a unit. To achieve this, we add a new method to the unit vtable and implement it for the relevant unit types so that we can do the start rate limit checks earlier on. --- src/core/socket.c | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) (limited to 'src/core/socket.c') diff --git a/src/core/socket.c b/src/core/socket.c index ceaf39bdd3..177068eed4 100644 --- a/src/core/socket.c +++ b/src/core/socket.c @@ -2513,12 +2513,6 @@ static int socket_start(Unit *u) { assert(IN_SET(s->state, SOCKET_DEAD, SOCKET_FAILED)); - r = unit_test_start_limit(u); - if (r < 0) { - socket_enter_dead(s, SOCKET_FAILURE_START_LIMIT_HIT); - return r; - } - r = unit_acquire_invocation_id(u); if (r < 0) return r; @@ -3425,6 +3419,21 @@ static int socket_can_clean(Unit *u, ExecCleanMask *ret) { return exec_context_get_clean_mask(&s->exec_context, ret); } +static int socket_test_start_limit(Unit *u) { + Socket *s = SOCKET(u); + int r; + + assert(s); + + r = unit_test_start_limit(u); + if (r < 0) { + socket_enter_dead(s, SOCKET_FAILURE_START_LIMIT_HIT); + return r; + } + + return 0; +} + static const char* const socket_exec_command_table[_SOCKET_EXEC_COMMAND_MAX] = { [SOCKET_EXEC_START_PRE] = "ExecStartPre", [SOCKET_EXEC_START_CHOWN] = "ExecStartChown", @@ -3551,4 +3560,6 @@ const UnitVTable socket_vtable = { [JOB_TIMEOUT] = "Timed out stopping %s.", }, }, + + .test_start_limit = socket_test_start_limit, }; -- cgit v1.2.1