Re: [vdr] Running VDR from systemd on Raspberry Pi OS

2022-12-29 Thread Marko Mäkelä

Sat, Dec 24, 2022 at 11:33:19AM +0200, Marko Mäkelä wrote:
Yesterday, I finally bought external storage for my Raspberry Pi based 
VDR setup, a Samsung Portable SSD T7.


I have now documented my setup in the following wiki pages:
https://www.linuxtv.org/vdrwiki/index.php/Systemd
https://www.linuxtv.org/vdrwiki/index.php/LIRC
https://www.linuxtv.org/vdrwiki/index.php/Raspberry_Pi

Most of it is not specific to the Raspberry Pi. I made the systemd 
article modular. Adding the pluggable video storage to the vdr.service 
file is only 2 lines (the [Install] section).


Marko

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


Re: [vdr] Running VDR from systemd on Raspberry Pi OS

2022-12-28 Thread Marko Mäkelä

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 

Re: [vdr] Running VDR from systemd on Raspberry Pi OS

2022-12-27 Thread Martin Dummer


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. So what
you do here



sudo tee /etc/systemd/system/video.mount << "EOF"
[Unit]
BindsTo=dev-disk-by\x2dlabel-VDR.device
After=dev-disk-by\x2dlabel-VDR.device
Requires=systemd-fsck@dev-disk-by\x2dlabel-VDR.service
After=systemd-fsck@dev-disk-by\x2dlabel-VDR.service
[Mount]
Where=/video
What=/dev/disk/by-label/VDR
Type=ext4
Options=defaults,noatime,nofail
[Install]
WantedBy=dev-disk-by\x2dlabel-VDR.device
EOF


is more or less the same as one line in /etc/fstab.

see "man systemd.mount" and "man systemd-fstab-generator"

Just a hint

Martin


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


Re: [vdr] Running VDR from systemd on Raspberry Pi OS

2022-12-27 Thread Marko Mäkelä

Tue, Dec 27, 2022 at 12:04:00PM +0200, Marko Mäkelä wrote:

I might configure some more, such as:

* Write some udev rule so that when the USB storage is unplugged and 
replugged, the file system will be auto-mounted and VDR service will 
be started.
* Restore /etc/systemd/logind.conf to HandlePowerKey=poweroff so that 
the system can be easily shut down by pressing the Power button again.


I finally figured it out mostly. What is missing is a nice way of 
overriding the power button. When VDR is running, the button should be 
handled by VDR; otherwise, pressing the power button should trigger 
system shutdown, like it does by default.


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


sudo mkdir -m 000 /video
sudo tee /etc/systemd/system/video.mount << "EOF"
[Unit]
BindsTo=dev-disk-by\x2dlabel-VDR.device
After=dev-disk-by\x2dlabel-VDR.device
Requires=systemd-fsck@dev-disk-by\x2dlabel-VDR.service
After=systemd-fsck@dev-disk-by\x2dlabel-VDR.service
[Mount]
Where=/video
What=/dev/disk/by-label/VDR
Type=ext4
Options=defaults,noatime,nofail
[Install]
WantedBy=dev-disk-by\x2dlabel-VDR.device
EOF
sudo tee /etc/systemd/system/vdr.service << "EOF"
[Unit]
Description=Runs VDR when storage is plugged in
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
ConditionPathExists=/video/video
[Service]
User=pi
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
sudo systemctl enable video.mount
sudo systemctl enable vdr
sudo udevadm control --reload
cat > /var/lib/vdr/vdr-shutdown.sh << "EOF"
#!/bin/sh
set -eu
if [ "$5" = 1 ]
then
  sudo udisksctl unmount -b /dev/disk/by-label/VDR
  sudo udisksctl power-off -b /dev/disk/by-label/VDR
  PK=/etc/systemd/logind.conf.d/00-powerkey.conf
  sudo mv -f "$PK".disabled "$PK" || :
  sudo systemctl restart systemd-logind
  sudo mv -f "$PK" "$PK".disabled
  sudo systemctl stop vdr
fi
EOF
chmod +x /var/lib/vdr/vdr-shutdown.sh
sudo mkdir /etc/systemd/logind.conf.d
sudo tee /etc/systemd/login.conf.d/00-powerkey.conf.disabled << "EOF"
[Login]
HandlePowerKey=poweroff
EOF
sudo systemctl restart systemd-logind

In addition to these, /etc/systemd/login.conf needs to be edited so that 
its [Login] section says HandlePowerKey=ignore.


I also had a udev rule that would execute "systemctl restart 
systemd-logind" when the storage is plugged in. Without that, if I 
plugged in the storage (and got VDR auto-started), then pressed the 
power button, and then repeated the same (unplug, replug, press the 
power button again), the system would shut down abruptly.


If there is a better way to make systemd-logind ignore the power button 
as long as VDR is running, please let me know. I tried adding 
Conflicts=exit.target to the vdr.service, but that did not prevent the 
shutdown. A rule Conflicts=shutdown.target means that the service shall 
be terminated on shutdown, according to "man 7 systemd.special".


Marko

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


Re: [vdr] Running VDR from systemd on Raspberry Pi OS

2022-12-27 Thread Marko Mäkelä

Mon, Dec 26, 2022 at 01:34:48AM +0100, Udo Richter wrote:

No, just replace the call to vdr in the service with a call to a runvdr
script (any of the ones floating around, or just a three-liner), and in
that script, after vdr ends, do whatever cleanup you need to do.


I see. That could certainly work.

I could execute "udisksctl unmount -f /dev/disk/by-label/VDR" to have 
the file system lazily unmounted as soon as all files are closed. But 
there is no such lazy option for power-off, and power-off itself will 
not unmount the file system.


Because I store the VDR configuration outside of this file system, it 
should be safe to attempt to unmount the video directory while VDR is 
running:


#!/bin/sh
set -e
if [ "$5" = 1 ]
then
  sudo udisksctl unmount -b /dev/disk/by-label/VDR
  sudo udisksctl power-off -b /dev/disk/by-label/VDR
  sudo service vdr stop
fi

I tested that the above script works when I press the Power button while 
watching live TV. If I am watching a recording that resides on this file 
system, the first command will fail, and thanks to "set -e", the rest of 
the script (in particular, shutting down the VDR service) will be 
skipped, that is, VDR will keep running.


In addition to having this script, I might configure some more, such as:

* Write some udev rule so that when the USB storage is unplugged and 
replugged, the file system will be auto-mounted and VDR service will be 
started.
* Restore /etc/systemd/logind.conf to HandlePowerKey=poweroff so that 
the system can be easily shut down by pressing the Power button again.


That would make it easy to do things like moving the disk to another 
computer for backing up or managing recordings. (Yes, I would rather use 
the native speed of the drive via USB 3, rather than have it throttled 
by 100 Mb/s Ethernet or the single USB 2.0 bus of the Raspberry Pi 2.)


In fact, this type of setup would also allow easy swapping of USB drives 
(one at a time) for making or watching recordings, a little like it was 
in the VCR times. The downtime for swapping drives would be a few 
seconds. The VDR configuration would be stored in the root file system, 
outside these detachable drives. The user interface to the entire setup 
would remain "living room compliant": remote control, display, and the 
USB cable of the drive.


The system could keep powering other tasks (such as home automation) 
while no storage is attached. If I didn't care about downtime, I might 
also use the following crude script to simply shut down the entire 
system:


#!/bin/sh
if [ "$5" = 1 ]
then
  sudo shutdown -h now
fi

In either case, the user would be responsible for starting VDR in time 
for the next scheduled recording.


Marko

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


Re: [vdr] Running VDR from systemd on Raspberry Pi OS

2022-12-25 Thread Udo Richter

On 25.12.22 20:47, Marko Mäkelä wrote:

However, I'd say the most clean way is to include the unmount and
udiskctrl into the vdr shutdown itself, so these commands run within
the vdr service after the vdr process stops. That way you just have to
fire the service stop and are done.


Do you mean implementing that as part of VDR plugin?


No, just replace the call to vdr in the service with a call to a runvdr
script (any of the ones floating around, or just a three-liner), and in
that script, after vdr ends, do whatever cleanup you need to do.

Cheers,

Udo


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


Re: [vdr] Running VDR from systemd on Raspberry Pi OS

2022-12-25 Thread Marko Mäkelä

Sun, Dec 25, 2022 at 01:10:51PM +0100, Udo Richter wrote:

On 24.12.22 10:33, Marko Mäkelä wrote:

then
  sudo service vdr stop
  sudo umount /video
  sudo udisksctl power-off -b /dev/sda
fi

The first step appears to terminate the shell script, because the shell
is a subprocess of VDR. So, the storage will remain mounted and powered
on. I guess that we need to launch a separate "vdr-shutdown" service
that would take care of the remaining steps. Has someone already
implemented something like this?


Maybe you can prevent that by backgrounding and setting some bash trap's
on SIGINT or SIGKILL.


All these steps depend on each other: VDR must be stopped before the 
video directory can be unmounted, and actually any pending writes should 
be durably submitted before the device is powered off. That would make 
any asynchronous invocation a little more challenging.


I did not test it carefully yet, but I understood from the systemd 
documentation that the following might work as intended (umount as soon 
as all file handles are closed by VDR):


sudo systemd-umount /video
sudo service vdr stop

I just learned about "man systemd.mount" via this question on automating 
backups to USB storage: https://unix.stackexchange.com/questions/89881/


However, I'd say the most clean way is to include the unmount and 
udiskctrl into the vdr shutdown itself, so these commands run within 
the vdr service after the vdr process stops. That way you just have to 
fire the service stop and are done.


Do you mean implementing that as part of VDR plugin?

Or if you want to go full systemd, you can probably do a service that 
does the mount/unmount/poweroff on start/stop, and then add that as 
requirement to the vdr service.


A simple change to the shutdown script would be to have it execute 
something like "sudo shutdown -h now" (or whatever invocation systemd 
prefers). That will umount and power off the USB storage just fine.


I think that I might actually go down that route, because currently the 
Raspberry Pi runs no other services than VDR. Except for the -s script, 
the vdr.service file that I posted yesterday already works for me.


I did not find any systemd integration with udisksctl, other than as 
part of an implicit poweroff service.


I could also avoid defining a shutdown script at all, and instead define 
a command script for invoking shutdown. That could be invoked when there 
are no timed recordings coming up for a while. I would have to remember 
to power up the system manually for the next timed recording. This would 
allow the power button on the remote control to be mapped to a "suspend" 
function that would make VDR stop the video output and stop polling the 
tuner. The USB SSD could remain powered on; I do not think it will 
consume much power when not being accessed.


Marko

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


Re: [vdr] Running VDR from systemd on Raspberry Pi OS

2022-12-25 Thread Udo Richter

On 24.12.22 10:33, Marko Mäkelä wrote:

then
   sudo service vdr stop
   sudo umount /video
   sudo udisksctl power-off -b /dev/sda
fi

The first step appears to terminate the shell script, because the shell
is a subprocess of VDR. So, the storage will remain mounted and powered
on. I guess that we need to launch a separate "vdr-shutdown" service
that would take care of the remaining steps. Has someone already
implemented something like this?


Maybe you can prevent that by backgrounding and setting some bash trap's
on SIGINT or SIGKILL.

Other methods to decouple a process so it runs separated, would be
'nohup' or the old 'at now' trick.

However, I'd say the most clean way is to include the unmount and
udiskctrl into the vdr shutdown itself, so these commands run within the
vdr service after the vdr process stops. That way you just have to fire
the service stop and are done.

From a quick look into documentation, you can just not wait for the
stop to complete:

systemctl stop vdr.service --no-block


Or if you want to go full systemd, you can probably do a service that
does the mount/unmount/poweroff on start/stop, and then add that as
requirement to the vdr service.


Cheers,

Udo


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


[vdr] Running VDR from systemd on Raspberry Pi OS

2022-12-24 Thread Marko Mäkelä
Yesterday, I finally bought external storage for my Raspberry Pi based 
VDR setup, a Samsung Portable SSD T7. It supports USB 3, but it also 
works on the Raspberry Pi 2's USB 2.0 and does not consume too much 
power. My old tower PC case based system that I had set up in 2004 has 
now been replaced with something that is better in every thinkable 
respect: power consumption, noise (passive cooling, no HDDs), speed, and 
size (not much larger than the remote control unit).


Hardware:
* Raspberry Pi 2
* Pi TV hat
* TV hat case
* an IR receiver attached via soldered wires to the TV hat, at GPIO pin 18
* a remote control unit (from an old Hauppauge Nova-T PCI card)
* Samsung Portable SSD T7 (1 TB)

Software:
* Raspberry OS Legacy installed on a MicroSD card, with no GUI
* sudo apt install ir-keytable
* VDR 2.6.3 (or 2.6.2) compiled from source
* https://github.com/reufer/rpihddevice/ compiled from source
* "make install" to /usr/local

My /boot/config.txt includes the following lines:
dtoverlay=gpio-ir,gpio_pin=18
dtparam=audio=on
gpu_mem=256

In /etc/rc_maps.cfg (the configuration file of ir-keytable), ensure that 
there is a line like the following that will match the remote control 
unit that you are using:

* * hauppauge.toml
The above works for several RC5 based Hauppauge remote control units.

To prevent the Power button on the remote control unit from shutting 
down the entire system, add the following to the [Login] section of 
/etc/systemd/logind.conf:


HandlePowerKey=ignore

The default is HandlePowerKey=poweroff.

Use mkfs.ext4 to replace the FAT file system of the only partition of 
the T7. There is no need to change the partitioning or specify a block 
size or alignment, because the physical block size is reported as 512 
bytes. Optionally, you may set a label by executing something like this: 
tune2fs -L VDR /dev/sda1


You may create a mount point:

sudo mkdir -m 000 /video

Then, add a line like this to /etc/fstab to have the storage mounted 
automatically:


LABEL=VDR /video ext4 defaults,noatime,nofail 0 1

You may replace the LABEL=VDR with whatever symbolic link you have in 
/dev/disk/by-label (see also tune2fs above). On my system, I actually 
wrote PARTUUID=33d32895-01 because there is a symbolic link 
/dev/disk/by-partuuid/33d32895-01 that identifies the partition.


Once the storage is mounted, execute the following:
sudo mkdir /video/video
sudo chown pi:pi /video/video

The next step is to configure VDR to start up correctly. I have some 
configuration files in /var/lib/vdr. For testing, I used to start VDR 
manually from the command line, and shut it down by choosing "restart" 
from the OSD menu. Now I want it to restart automatically, but only if 
suitable USB storage has been plugged in:


sudo tee /etc/systemd/system/vdr.service << EOF
[Unit]
After=systemd-user-sessions.service plymouth-quit-wait.service
After=rc-local.service
After=getty@tty1.service
After=video.mount
Conflicts=getty@tty1.service

ConditionPathExists=/video/video

[Service]
User=pi
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]
Alias=display-manager.service
EOF

This will replace the getty process on virtual terminal 1 (tty1). If the 
storage is not plugged within 90 seconds from startup (I do not know how 
to configure that timeout), then an error message will appear on the 
console. No getty will be started on tty1 in any case; you can always 
log in from tty2 by pressing Alt+F2.


The shutdown script /var/lib/vdr/vdr-shutdown.sh does not work as 
intended yet:


#!/bin/sh

if [ "$5" = 1 ]
then
  sudo service vdr stop
  sudo umount /video
  sudo udisksctl power-off -b /dev/sda
fi

The first step appears to terminate the shell script, because the shell 
is a subprocess of VDR. So, the storage will remain mounted and powered 
on. I guess that we need to launch a separate "vdr-shutdown" service 
that would take care of the remaining steps. Has someone already 
implemented something like this?


After the "umount" and "udisksctl" commands are executed, it is safe to 
unplug the storage. The LED of the SSD will shortly change color and 
then turn off during the execution of the "udisksctl" command.


What I am also missing is a udev rule that would automatically mount the 
storage and attempt to start up VDR as soon as the storage is plugged 
in. Currently, I have to manually execute the following if I plug in the 
drive to an already running system:


sudo mount /video
sudo service vdr start

This configuration provides a rather simple user interface for VDR. No 
keyboard or mouse is needed, just the remote control unit, a display, 
and optionally the USB cable, if the system has other uses that are 
independent of VDR.


For timed recordings, I think that on the Raspberry Pi, it is easiest to 
let the VDR process run all the time. Starting up