From fe81f6f734ee46a4877df6dda6e31cdc24c00a3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20Koutn=C3=BD?= Date: Tue, 16 Jan 2018 19:22:46 +0100 Subject: [PATCH] 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 <~/.config/systemd/user/looper.timer <last_trigger.monotonic); break; @@ -428,6 +429,7 @@ static void timer_enter_waiting(Timer *t, bool initial) { if (base <= 0) continue; + base = MAX(base, t->last_trigger.monotonic); break;