0

I have a unit that normally I want running, but sometimes I want to manually shut it off for the day and restart it later automatically. So I have a timer to restart it OnCalendar=daily. This works, but sometimes I need to stop the unit twice because the timer immediately restarts the unit.

Here's a simplified example with minutes instead of days:

[Unit]
Description=foo timer

[Timer]
Persistent=false
OnCalendar=minutely
AccuracySec=1
Unit=foo.service

[Install]
WantedBy=default.target

[Unit]
Description=foo service

[Service]
Type=simple
ExecStart=/bin/sh -c 'while true; do sleep 1; done'

[Install]
WantedBy=default.target

If I systemctl stop foo.service, and the timer had fired more than 1 minute ago (PASSED > 1m in systemdctl list-timers), it immediately refires and starts the unit. The unit always stays stopped until the next minute if I stop it twice. The docs make it sound like Persistent=false should not cause this, but clearly I'm misunderstanding. If it matters, the daily unit I'm actually interested in is a system unit, but the test unit is a user unit; the behavior is the same.

0

1 Answer 1

0

Persistent=false (i.e. default) keeps disabled the function to catch timers missed during system shutdown. In your case the system is on-line and the timer is omitted - if OnCalendar period has passed (likely because foo.service was already running) it still waits for it's moment to be run "a minute/day after last run" - not after last try/check/attempt to be run, which means exactly immediately after stop foo.service.

This is a consequence of, quoting man systemd.timer: Note that in case the unit to activate is already active at the time the timer elapses it is not restarted, but simply left running. Currently I see no direct way to reset the timer if timer has already elapsed but the action was skipped because of service still running.

The indirect method would be to have self-restarting timer, something like foo-try_restart.service invoking systemctl restart foo-try_restart.timer before attempting to systemctl start foo.service. As your foo.service is different from this newly created foo-try_restart.service (with Type=oneshot, without RemainAfterExit) it's foo-try_restart.timer would always fire, so it's timer would be reset after each period.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .