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