How to write a systemd service to reboot a server

My Rpi4 has a problem where podman containers lose proper network connectivity.

A hotfix is to reboot the pi. Until I am able to fix the proper problem I 'd like to schedule a systemd service that reboots the pi every morning.

I tried to do so with the following files
networking_reboot_fix.service:

[Unit]
Description=Restarting Raspberry pi every day to get around networking issues

[Service]
Type=simple
ExecStart=reboot

[Install]
WantedBy=default.target

networking_reboot_fix.timer

[Unit]
Description=Schedule a reboot at specified times in the day
RefuseManualStart=no  # Allow manual starts
RefuseManualStop=no   # Allow manual stops

[Timer]
#Execute job if it missed a run due to machine being off
Persistent=true
#Run 120 seconds after boot for the first time
#OnBootSec=120
#Run every 1 minute thereafter
#OnUnitActiveSec=60
# run on the hour of every hour of every day
OnCalendar=*-*-* *:50:00
#File describing job to execute
Unit=networking_reboot_fix.service

[Install]
WantedBy=timers.target

(Timer was set to every hour at 50m for testing.)
However after I enabled the service, and rebooted the pi for good measure, the pi wouldn’t boot properly. I couldn’t ssh into it. Hopefully I was able to power off the pi, mount the drive from my laptop and remove the offending files so I could ssh back into it after it was booted.

Any ideas what went wrong and how to fix it?

P.S. I was also wondering if instead of creating by own service, I could call the relevant systemd-reboot.service but I m not sure how.

Hi,

Possible stupid question, but did you enable the service or the timer? If it was the service, I suspect it got caught in a boot loop. To enable the timer:

sudo systemctl enable networking_reboot_fix.timer

Thanks Tom.

1 Like

Hm, I probably enabled the service. Let me test again.

I tested that, it likely still bootloops for some reason. I was able to ssh into but as soon I did, I got disconnected, which - I m guessing - means the server re-booted again.

P.S. I haven’t mentioned, but I m using fedora-iot. Don’t know if that 'd make a difference from fedora server.

Hi,

Are you able to attach a screen, to see whats going on?

Thanks Tom.

I’d suggest removing

Persistent=True

As you wouldn’t want it to reboot after being turned off if you just turned it on.

If you want to run every 24 hours after booting I’d suggest using OnBootSec vice calendar.

Every 50 minutes should be: *-*-* *:*/50:00

You can use reboot.target in the unit for the timer vice your service.
see man systemd.special

A special target unit for shutting down and rebooting the
system.
Applications wanting to reboot the system should not start
this unit directly, but should instead execute systemctl
reboot (possibly with the --no-block option) or call
systemd-logind(8)'s org.freedesktop.login1.Manager.Reboot
D-Bus method directly.
runlevel6.target is an alias for this target unit, for
compatibility with SysV.

ref:

https://www.freedesktop.org/software/systemd/man/systemd.timer.html#OnBootSec=

1 Like

Remove this, it makes systemd start this service (and perform a reboot) before reaching default.target (basically when system is ready for user input, e.g. graphical login is displayed) https://www.freedesktop.org/software/systemd/man/systemd.unit.html#WantedBy=

Another mistake was not enabling the timer, like Tom pointed out.

1 Like

I was able to make this work based on suggestions here.
For some reason I needed to move from OnCalendar to OnBootSec in order to not be into a boot loop !

Also for some reason using only the timer unit like this didn’t result in a successfull boot:

[Unit]
Description=Schedule a reboot at specified times in the day
RefuseManualStart=no  # Allow manual starts
RefuseManualStop=no   # Allow manual stops

[Timer]
# Run 120 seconds after boot for the first time
OnBootSec=600
# File describing job to execute
Unit=reboot.target

[Install]
WantedBy=timers.target

The docs say to not use it directly so maybe that’s it.

Here’s the testing setup that worked:

networking_reboot_fix.timer:

[Unit]
Description=Schedule a reboot at specified times in the day
RefuseManualStart=no  # Allow manual starts
RefuseManualStop=no   # Allow manual stops

[Timer]
# Run X seconds after boot for the first time
OnBootSec=600
# File describing job to execute
Unit=networking_reboot_fix.service

[Install]
WantedBy=timers.target

networking_reboot_fix.service:

[Unit]
Description=Restarting Raspberry pi every day to get around networking issues

[Service]
Type=simple
ExecStart=systemctl reboot --no-block

[Install]
WantedBy=default.target

I m mostlikely going to use something like OnBootSec=86401 (=24*60*60+1) to get around the OnCalendar issue.

Thank you for all the suggestions

1 Like