Re: Running VDR from systemd on Raspberry Pi OS

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Tue, Dec 27, 2022 at 11:15:29PM +0100, Martin Dummer wrote:

Am 27.12.22 um 21:49 schrieb Marko Mäkelä:

First, I removed the custom /etc/fstab entry. Everything will be
controlled by systemd as follows:


On systemd-systems, each line  in /etc/fstab is automatically converted
by a binary "systemd-fstab-generator" into "xxx.mount" units.

That is correct. I converted the fstab-generated video.mount file to a custom one.

So what you do here
[...]
is more or less the same as one line in /etc/fstab.

It is, except for the [Unit] keys BindsTo and After, and the [Install] key WantedBy, which causes the file system to be mounted automatically and the dependent service started once a matching storage device is plugged in.

Years ago, executing commands when USB storage was plugged in could be achieved by writing udev rules. In fact, I first attempted that, but I did not come up with a solution that would work both on system startup and when the storage is plugged into an already running system. The systemd mount unit and the service unit, with declared dependencies on /dev/disk/by-label/VDR do exactly what I need, without being tied to a specific USB ID.

When it comes to the power button, I found a Python 2.7 script https://github.com/ryran/reboot-guard that can disable or enable shutdown, reboot, halt, by creating or removing simple configuration files. Because this script is not packaged in Debian, and Python 2 is kind of obsolete, I wrote a shell script to achieve the same:

sudo tee /etc/systemd/system/vdr-keep-alive.sh << "EOF"
#!/bin/sh

TARGETS="
/lib/systemd/system/poweroff.target.d
/lib/systemd/system/reboot.target.d
/lib/systemd/system/halt.target.d
"
CONF=vdr-keep-alive.conf

case "$1" in
start)
  for t in $TARGETS
  do
    if [ ! -f "$t/$CONF" ]
    then
      if [ ! -d "$t/" ]
      then
	mkdir "$t"
      fi
      echo "[Unit]\nRefuseManualStart=yes" > "$t/$CONF"
    fi
  done
  ;;
stop)
  for t in $TARGETS
  do
    rm -f "$t/$CONF"
  done
  ;;
esac

exec systemctl daemon-reload
EOF

Whether the override is in place can be checked with commands like "systemctl cat shutdown.target". On my system, "sudo reboot" would be silently ignored, while "sudo systemctl reboot" would display verbose messages, suggesting to check "systemctl status reboot.target" for details.

Furthermore, I learned about ExecStartPre and ExecStop. The former can be used for preparatory steps, such as blocking the shutdown and reboot commands with the above script. ExecStop seems to be unusable for this type of a service. I moved those steps to be part of the shutdown script that will be invoked by VDR:

tee /var/lib/vdr/vdr-shutdown.sh << "EOF"
#!/bin/sh
set -eu
if [ "$5" = 1 ]
then
  sudo systemd-mount -u /dev/disk/by-label/VDR
  sudo /etc/systemd/system/vdr-keep-alive.sh stop
  sudo udisksctl power-off -b /dev/disk/by-label/VDR
fi
EOF

Thanks to the declared dependencies, the udisksctl command will actually stop VDR.

The "set -e" at the start of the script ensures that if the file system cannot be unmounted (due to VDR playing back a recording, or any other process accessing the file system), the script will be aborted at the first step, and VDR will keep running.

Finally, here is the revised service file. It now includes Conflicts=shutdown.target to ensure an orderly shutdown of VDR in case the logic to disable shutdown is disabled:

sudo tee /etc/systemd/system/vdr.service << "EOF"
[Unit]
Description=Video Disk Recorder
After=systemd-user-sessions.service plymouth-quit-wait.service
After=rc-local.service
After=getty@tty1.service
BindsTo=dev-disk-by\x2dlabel-VDR.device
After=dev-disk-by\x2dlabel-VDR.device
After=video.mount
Conflicts=getty@tty1.service
Conflicts=shutdown.target
ConditionPathExists=/video/video

[Service]
User=pi
ExecStartPre=+/etc/systemd/system/vdr-keep-alive.sh start
ExecStart=/usr/local/bin/vdr --no-kbd --lirc=/dev/lirc0 -Prpihddevice -v /video/video -s /var/lib/vdr/vdr-shutdown.sh
TimeoutStartSec=infinity
Type=idle
Restart=on-failure
RestartSec=1s
TTYVTDisallocate=yes

[Install]
WantedBy=dev-disk-by\x2dlabel-VDR.device
EOF

With this setup, any USB based storage that contains a partition that contains a file system labeled VDR that contains the subdirectory "video" becomes special as follows:

1. The first virtual console (/dev/tty1) is always reserved for VDR.
2. If the storage is not available on startup, there will be no timeout or waiting (like with /etc/fstab there would be). 3. If the storage is available on startup or plugged in at any later time, it will be mounted in /video. If /video/video exists, VDR will be started and the shutdown, reboot, halt actions disabled. 4. If VDR is shut down from its user interface, the file system will be unmounted, the storage powered off, and the shutdown, reboot, halt actions re-enabled.

The drive LED becomes a proxy indicator for "VDR is running"; there is no need to turn on the screen to check that.

To restart VDR, just unplug the USB cable (after the USB drive LED has turned off) and plug the cable back in, optionally using a different drive.

To shut down the entire system, simply press the Power button once more while the USB drive LED is off (or the drive is disconnected).

In my old PC based system, I had an ATtiny microcontroller board that would run on standby power, listen to the IR receiver, and start up the system via WoL or PCI PME when the power button was pressed. While something similar would be possible with the Raspberry Pi (using GPIO 3, or pin 5 on the connector), I think that the current setup is good enough for me, with the IR receiver mounted on the TV HAT with 3 loose wires and poking out of the Pi TV HAT case. With a daughter board for the IR receiver and an SMD microcontroller using 4 loose wires, it should be doable.

	Marko

_______________________________________________
vdr mailing list
vdr@xxxxxxxxxxx
https://www.linuxtv.org/cgi-bin/mailman/listinfo/vdr




[Index of Archives]     [Linux Media]     [Asterisk]     [DCCP]     [Netdev]     [Xorg]     [Util Linux NG]     [Xfree86]     [Big List of Linux Books]     [Fedora Users]     [Fedora Women]     [ALSA Devel]     [Linux USB]

  Powered by Linux