mirror of
https://github.com/systemd/systemd.git
synced 2025-03-22 06:50:18 +03:00
core/timer: Prevent timer looping when unit cannot start
When a unit job finishes early (e.g. when fork(2) fails) triggered unit goes through states stopped->failed (or failed->failed), in case a ExecStart= command fails unit passes through stopped->starting->failed. The former transition doesn't result in unit active/inactive timestamp being updated and timer (OnUnitActiveSec= or OnUnitInactiveSec=) would use an expired timestamp triggering immediately again (repeatedly). This patch exploits timer's last trigger timestamp to ensure the timer isn't triggered more frequently than OnUnitActiveSec=/OnUnitInactiveSec= period. Steps to reproduce: 0) Create sample units: cat >~/.config/systemd/user/looper.service <<EOD [Service] ExecStart=/usr/bin/sleep 2 EOD cat >~/.config/systemd/user/looper.timer <<EOD [Timer] AccuracySec=5 OnUnitActiveSec=5 EOD 1) systemctl --user daemon-reload 2) systemctl --user start looper.timer # to have first activation timestamp/sentinel systemctl --user start looper.service o Observe the service is being regularly triggered. 3) systemctl set-property user@$UID.service TasksMax=2 o Observe the tight looping as long as the looper.service cannot be started. Ref: #5969
This commit is contained in:
parent
3e52ec4301
commit
204d140c4d
@ -431,6 +431,7 @@ static void timer_enter_waiting(Timer *t, bool initial) {
|
||||
|
||||
if (base <= 0)
|
||||
continue;
|
||||
base = MAX(base, t->last_trigger.monotonic);
|
||||
|
||||
break;
|
||||
|
||||
@ -443,6 +444,7 @@ static void timer_enter_waiting(Timer *t, bool initial) {
|
||||
|
||||
if (base <= 0)
|
||||
continue;
|
||||
base = MAX(base, t->last_trigger.monotonic);
|
||||
|
||||
break;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user