]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
core: set Result=start-limit-hit when a unit is rate limited
authorLuca Boccassi <luca.boccassi@gmail.com>
Wed, 3 Dec 2025 18:59:34 +0000 (18:59 +0000)
committerMike Yuan <me@yhndnzj.com>
Wed, 17 Dec 2025 23:19:09 +0000 (00:19 +0100)
There is currently no way to figure out a rate limit was hit on a unit,
as the last result is stripped in order to keep reporting the first
result, which is useful in case of a watchdog failure, which is the
reason why it was changed as such.

But rate limiting is also an important information to provide to
users, so allow the Result property to reflect it when it
happens.

src/core/automount.c
src/core/mount.c
src/core/path.c
src/core/service.c
src/core/socket.c
src/core/swap.c
src/core/timer.c
test/units/TEST-07-PID1.issue-3166.sh

index 05b35d06a4c7713c7c40c7185b4447475803b9ea..6543204400149fbc33f29b71d4f9ea3c8fe84385 100644 (file)
@@ -324,7 +324,7 @@ static void automount_dump(Unit *u, FILE *f, const char *prefix) {
 static void automount_enter_dead(Automount *a, AutomountResult f) {
         assert(a);
 
-        if (a->result == AUTOMOUNT_SUCCESS)
+        if (a->result == AUTOMOUNT_SUCCESS || IN_SET(f, AUTOMOUNT_FAILURE_MOUNT_START_LIMIT_HIT, AUTOMOUNT_FAILURE_START_LIMIT_HIT))
                 a->result = f;
 
         unit_log_result(UNIT(a), a->result == AUTOMOUNT_SUCCESS, automount_result_to_string(a->result));
index 833ab762cb5319c6dd4e2265b69ea740de478bc1..680e376febfc9c5252508fd146a43697bb836343 100644 (file)
@@ -893,7 +893,7 @@ static int mount_spawn(Mount *m, ExecCommand *c, ExecFlags flags, PidRef *ret_pi
 static void mount_enter_dead(Mount *m, MountResult f, bool flush_result) {
         assert(m);
 
-        if (m->result == MOUNT_SUCCESS || flush_result)
+        if (m->result == MOUNT_SUCCESS || f == MOUNT_FAILURE_START_LIMIT_HIT || flush_result)
                 m->result = f;
 
         unit_log_result(UNIT(m), m->result == MOUNT_SUCCESS, mount_result_to_string(m->result));
index 74218dd6be5ad7d91351474a25c342fd97563739..764dea03dc46e1c245a8c1da03f3351873ad758b 100644 (file)
@@ -502,7 +502,7 @@ static int path_coldplug(Unit *u) {
 static void path_enter_dead(Path *p, PathResult f) {
         assert(p);
 
-        if (p->result == PATH_SUCCESS)
+        if (p->result == PATH_SUCCESS || IN_SET(f, PATH_FAILURE_START_LIMIT_HIT, PATH_FAILURE_UNIT_START_LIMIT_HIT))
                 p->result = f;
 
         unit_log_result(UNIT(p), p->result == PATH_SUCCESS, path_result_to_string(p->result));
index dcc4a992ccf4ace78d618d4ecd270132f6d4a3f4..9f7ccaaa4126491cf9b50838b1a056e6831e70c3 100644 (file)
@@ -2115,7 +2115,7 @@ static void service_enter_dead(Service *s, ServiceResult f, bool allow_restart)
         if (unit_stop_pending(UNIT(s)))
                 allow_restart = false;
 
-        if (s->result == SERVICE_SUCCESS)
+        if (s->result == SERVICE_SUCCESS || f == SERVICE_FAILURE_START_LIMIT_HIT)
                 s->result = f;
 
         if (s->result == SERVICE_SUCCESS) {
index cb79c590aa70225f7d0794574861525b1438c222..848cb3137200bb8ef6068feadbe6028fdbe728a5 100644 (file)
@@ -2116,7 +2116,7 @@ static int socket_chown(Socket *s, PidRef *ret_pid) {
 static void socket_enter_dead(Socket *s, SocketResult f) {
         assert(s);
 
-        if (s->result == SOCKET_SUCCESS)
+        if (s->result == SOCKET_SUCCESS || IN_SET(f, SOCKET_FAILURE_SERVICE_START_LIMIT_HIT, SOCKET_FAILURE_START_LIMIT_HIT))
                 s->result = f;
 
         if (s->result == SOCKET_SUCCESS)
index 3ab4b134f2a413a0dff583160be0d39c2dd34b83..5de1dccf42779159912e38fae85cddda3bc51e8d 100644 (file)
@@ -668,7 +668,7 @@ static int swap_spawn(Swap *s, ExecCommand *c, PidRef *ret_pid) {
 static void swap_enter_dead(Swap *s, SwapResult f) {
         assert(s);
 
-        if (s->result == SWAP_SUCCESS)
+        if (s->result == SWAP_SUCCESS || f == SWAP_FAILURE_START_LIMIT_HIT)
                 s->result = f;
 
         unit_log_result(UNIT(s), s->result == SWAP_SUCCESS, swap_result_to_string(s->result));
index d95514462d3f110bd6fa0bbb12bd3e1909478ea1..f2d4b5cc3dff9d7bcf46874fc16fccccb65095be 100644 (file)
@@ -324,7 +324,7 @@ static int timer_coldplug(Unit *u) {
 static void timer_enter_dead(Timer *t, TimerResult f) {
         assert(t);
 
-        if (t->result == TIMER_SUCCESS)
+        if (t->result == TIMER_SUCCESS || f == TIMER_FAILURE_START_LIMIT_HIT)
                 t->result = f;
 
         unit_log_result(UNIT(t), t->result == TIMER_SUCCESS, timer_result_to_string(t->result));
index 6677901358f8822fb89bd0e9c0b091f858f99c87..07c211debec513022ee9f75f8bb42cf926e3fcc9 100755 (executable)
@@ -14,3 +14,4 @@ while [[ "$active_state" == "activating" || "$active_state" =~ ^(in)?active$ ]];
 done
 systemctl is-failed issue3166-fail-on-restart.service || exit 1
 [[ "$(systemctl show --value --property NRestarts issue3166-fail-on-restart.service)" -le 3 ]] || exit 1
+[[ "$(systemctl show --value --property Result issue3166-fail-on-restart.service)" = "start-limit-hit" ]] || exit 1