Oneshot Service in Linux Systemd

My trusty old VDR box started behaving erratically: sometimes the IR remote didn’t do anything. Rebooting the whole box usually helped, but not always. Eventually I was able to narrow the problem down: for some reason the LIRC serial driver did not correctly detect the IR receiver in the serial port at the boot. I don’t have any idea why that happened and why it started only recently. But, I was able to figure out a workaround where the lirc_serial module was reloaded later in the Linux boot process. This is my documentation about the implementation.

First, /usr/local/bin/lirc_serial_reload.sh is the script that does the actual work:

#!/bin/bash
systemctl stop lircd.socket
systemctl stop lircd.service
rmmod lirc_serial
modprobe lirc_serial
systemctl start lircd.socket
systemctl start lircd.service

The interesting part was to figure out how to run that once during the boot process. On this Debian 9 Stretch system systemd is responsible for running all the startup scripts, so I found out the oneshot service type and created the configuration in /etc/systemd/system/lircserialrestart.service:

[Unit]
Description=lirc_serial restart, by Markku
After=lircd.service
Before=vdr.service

[Service]
Type=oneshot
ExecStart=/usr/local/bin/lirc_serial_reload.sh

[Install]
WantedBy=multi-user.target

Basically, it defines that the service is only run once (Type=oneshot), it is to be run after LIRC daemon (because it stops and later starts the daemon again) but before VDR.

And finally the service was enabled with systemctl daemon-reload and systemctl enable lircserialrestart.service commands.

Leave a Reply