1

I have systemd unit file, I know it can be restarted on failure by providing parameters, like :

Restart=always
RestartSec=90

It will restart after 90 seconds whenever it fails,

But, I want to restart only if system time is in between given time-frame, say between 08:00 and 17:00, only then restart.

Is there way to do this via systemd ?

3 Answers 3

2

Directly in a service unit file with settings: no.

With a Heath Robinson mechanism: yes, as follows.

  • Create two snippet files somewhere, wibble-in-hours.conf with these settings turned on and wibble-out-of-hours.conf with these settings turned off. Don't forget the section heading.
  • At any given point, /etc/systemd/system/wibble.service.d/restart.conf is one or the other of these files. The systemd manual (q.v.) explains drop-in directories and snippet files.
  • Set up uschedule jobs, cron jobs, or whatever other mechanism you like, to swap the snippet files around at the appropriate times, invoke systemctl daemon-reload, and of course bring the service up if it has terminated during the out of hours period. (Be aware of masking, disabled services, and the fact that some operating systems stop services temporarily during package upgrades, all of which make the test of whether to start the service non-trivial.)
3
  • A slight improvement here is to use systemctl set-property, which will essentially do the management of an override for you in a much simpler way. Using --runtime is also possible, since having the overrides in /run is probably OK (boot needs special handling anyway, since there's no guarantee restart will be in the same state at that point.)
    – filbranden
    Nov 15, 2018 at 4:04
  • In short, at 08:00 run systemctl --runtime set-property wibble.service Restart=yes and at 17:00 run systemctl --runtime set-property wibble.service Restart=no. At boot, need to run a shell script that will check whether the current hour is in [8, 17) and set it to yes, otherwise to no.
    – filbranden
    Nov 15, 2018 at 4:06
  • It's not an improvement for the simple reason that it does not actually work. (-: The manual explains why.
    – JdeBP
    Nov 15, 2018 at 11:50
2

If it's acceptable to you that the interval for the restart is not exactly 90 seconds and not exactly the same every time, then you can implement this in a simple way with a service unit + a corresponding timer unit.

Simply have the timer unit specify your time frame in an OnCalendar= setting.

For example, to run once a minute from 08:00 to 16:59 (usually on second 00, but give systemd a leeway of 5 seconds to schedule it):

[Timer]
OnCalendar=*-*-* 08-16:*:00
AccuracySec=5s

Additionally, have Restart=no (or leave out Restart=, since no is the default) in your service unit.

This configuration will have systemd try to start your unit once a minute within your time frame. However, if the unit is already running, trying to start it will not do anything.

If, on the other hand, the unit is stopped and the timer fires (once a minute within that time frame), it will in effect "restart" the unit.

The net effect is that this timer will cause the unit to restart between 0s and 65s (counting the 5s leeway) after it stops, but only within your time frame (since your timer only fires during those hours.)

If having 0s as a lower bound is unacceptable (let's say, you want at least 30s between the unit stopping and then starting again), you can use a workaround for that by adding an ExecStopPost=/bin/sleep 30 to the service unit. That way, after the main service stops, it will still take 30s for the unit to be effectively "stopped" and therefore will only be eligible for restart from the timer unit after these 30s have elapsed. In effect, this makes it restart within 30s to 95s from when it stopped.

See the man page for systemd.time for more details on how to specify intervals for OnCalendar= so you can tune it to the specific time requirements in your restart policy.

1

Thanks for the suggestions and your time. I achieved this via systemd service with

Restart=always

and two crontab entries as suggested by @JdeBP

  1. one to start at 08:00
  2. other to stop at 17:00

You must log in to answer this question.

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