|
|
661545 |
From fe81f6f734ee46a4877df6dda6e31cdc24c00a3c Mon Sep 17 00:00:00 2001
|
|
|
9ab0c5 |
From: =?UTF-8?q?Michal=20Koutn=C3=BD?= <mkoutny@suse.com>
|
|
|
9ab0c5 |
Date: Tue, 16 Jan 2018 19:22:46 +0100
|
|
|
9ab0c5 |
Subject: [PATCH] core/timer: Prevent timer looping when unit cannot start
|
|
|
9ab0c5 |
|
|
|
9ab0c5 |
When a unit job finishes early (e.g. when fork(2) fails) triggered unit goes
|
|
|
9ab0c5 |
through states
|
|
|
9ab0c5 |
stopped->failed (or failed->failed),
|
|
|
9ab0c5 |
in case a ExecStart= command fails unit passes through
|
|
|
9ab0c5 |
stopped->starting->failed.
|
|
|
9ab0c5 |
|
|
|
9ab0c5 |
The former transition doesn't result in unit active/inactive timestamp being
|
|
|
9ab0c5 |
updated and timer (OnUnitActiveSec= or OnUnitInactiveSec=) would use an expired
|
|
|
9ab0c5 |
timestamp triggering immediately again (repeatedly).
|
|
|
9ab0c5 |
|
|
|
9ab0c5 |
This patch exploits timer's last trigger timestamp to ensure the timer isn't
|
|
|
9ab0c5 |
triggered more frequently than OnUnitActiveSec=/OnUnitInactiveSec= period.
|
|
|
9ab0c5 |
|
|
|
9ab0c5 |
Steps to reproduce:
|
|
|
9ab0c5 |
|
|
|
9ab0c5 |
0) Create sample units:
|
|
|
9ab0c5 |
|
|
|
9ab0c5 |
cat >~/.config/systemd/user/looper.service <
|
|
|
9ab0c5 |
[Service]
|
|
|
9ab0c5 |
ExecStart=/usr/bin/sleep 2
|
|
|
9ab0c5 |
EOD
|
|
|
9ab0c5 |
|
|
|
9ab0c5 |
cat >~/.config/systemd/user/looper.timer <
|
|
|
9ab0c5 |
[Timer]
|
|
|
9ab0c5 |
AccuracySec=5
|
|
|
9ab0c5 |
OnUnitActiveSec=5
|
|
|
9ab0c5 |
EOD
|
|
|
9ab0c5 |
|
|
|
9ab0c5 |
1) systemctl --user daemon-reload
|
|
|
9ab0c5 |
|
|
|
9ab0c5 |
2) systemctl --user start looper.timer
|
|
|
9ab0c5 |
# to have first activation timestamp/sentinel
|
|
|
9ab0c5 |
systemctl --user start looper.service
|
|
|
9ab0c5 |
|
|
|
9ab0c5 |
o Observe the service is being regularly triggered.
|
|
|
9ab0c5 |
|
|
|
9ab0c5 |
3) systemctl set-property user@$UID.service TasksMax=2
|
|
|
9ab0c5 |
|
|
|
9ab0c5 |
o Observe the tight looping as long as the looper.service cannot be started.
|
|
|
9ab0c5 |
|
|
|
9ab0c5 |
Ref: #5969
|
|
|
9ab0c5 |
(cherry picked from commit 204d140c4def364c47d36226e4514a7e077fa196)
|
|
|
9ab0c5 |
|
|
|
661545 |
Resolves: #1710302
|
|
|
9ab0c5 |
---
|
|
|
9ab0c5 |
src/core/timer.c | 2 ++
|
|
|
9ab0c5 |
1 file changed, 2 insertions(+)
|
|
|
9ab0c5 |
|
|
|
9ab0c5 |
diff --git a/src/core/timer.c b/src/core/timer.c
|
|
|
9ab0c5 |
index d32b007c7c..1d4868643a 100644
|
|
|
9ab0c5 |
--- a/src/core/timer.c
|
|
|
9ab0c5 |
+++ b/src/core/timer.c
|
|
|
9ab0c5 |
@@ -416,6 +416,7 @@ static void timer_enter_waiting(Timer *t, bool initial) {
|
|
|
9ab0c5 |
|
|
|
9ab0c5 |
if (base <= 0)
|
|
|
9ab0c5 |
continue;
|
|
|
9ab0c5 |
+ base = MAX(base, t->last_trigger.monotonic);
|
|
|
9ab0c5 |
|
|
|
9ab0c5 |
break;
|
|
|
9ab0c5 |
|
|
|
9ab0c5 |
@@ -428,6 +429,7 @@ static void timer_enter_waiting(Timer *t, bool initial) {
|
|
|
9ab0c5 |
|
|
|
9ab0c5 |
if (base <= 0)
|
|
|
9ab0c5 |
continue;
|
|
|
9ab0c5 |
+ base = MAX(base, t->last_trigger.monotonic);
|
|
|
9ab0c5 |
|
|
|
9ab0c5 |
break;
|
|
|
9ab0c5 |
|