Issue
I'm setting up Debian so that it works in kiosk mode. To do this, I created a service that performs the watchdog function:
[Unit]
Description=Watchdog for myapp
[email protected]
After=polkit.service
After=udisks2.service
[Service]
ExecStartPre=systemctl stop dm
ExecStart=su user -c "startx /opt/myapp-watchdog.sh -- :0 vt7"
ExecStop=systemctl start dm
Type=simple
Restart=on-failure
StartLimitInterval=60s
StartLimitBurst=5
RuntimeMaxSec=infinity
Environment="DISPLAY=:0"
Environment="XAUTHORITY=/home/user/.Xauthority"
Environment="XDG_VTNR=7"
[Install]
WantedBy=graphical.target
The problem is that ExecStart gets the exit code not from myapp, but from startx. I have tried many options, but I have not been able to come up with a way that would work as it should...
I tried trying to pass exit code through pipe, exit &? and writing the exit code to a file. But, apparently, my skills in bash are not enough to make the right command.
Googling also didn't help because to find a case in which people call starts directly from the root, and not from the user, which is why the transfer of exit code is much easier than in my case
Solution
Figured it out. It is impossible to solve this problem by means of startx (proof: Link to the xserver error on gitlab). I had to invent bicycles and use crutches.
The solution is for the service to run a script in which the software is run in a loop. After that, the software exit code is checked. If the code is 0, then the script completes its work. Otherwise, the next iteration of the loop is started. The code below implements a mechanism for exiting this cycle if the software was completed incorrectly 5 or more times in the last minute after the first emergency exit.
Service code:
[Unit]
Description=Watchdog for myapp
[email protected]
After=polkit.service
After=udisks2.service
[Service]
ExecStartPre=systemctl stop dm
ExecStart=su user -c "startx /opt/myapp-watchdog.sh -- :0 vt7"
ExecStop=systemctl start dm
Type=simple
Restart=on-failure
StartLimitInterval=60s
StartLimitBurst=5
RuntimeMaxSec=infinity
Environment="DISPLAY=:0"
Environment="XAUTHORITY=/home/user/.Xauthority"
Environment="XDG_VTNR=7"
[Install]
WantedBy=graphical.target
Service script code:
#!/bin/bash
RETURN_VALUE="1"
RESET_COUNTER=0
RESET_COUNTER_TIME=0
TIME_NOW=0
echo "myapp-watchdog: myapp-watchdog started"
while [ $RETURN_VALUE != "0" ]
do
echo "myapp-watchdog: myapp started"
/opt/myapp
RETURN_VALUE=$?
TIME_NOW=$(date +"%s")
if [ $RETURN_VALUE == "0" ]
then
echo "myapp-watchdog: myapp exited with code 0"
echo "myapp-watchdog: myapp-watchdog finished"
exit 0
else
if [[ $TIME_NOW -gt $RESET_COUNTER_TIME ]]
then
RESET_COUNTER=0
fi
if [ $RESET_COUNTER == 0 ]
then
RESET_COUNTER_TIME=$TIME_NOW+60
fi
RESET_COUNTER=$((RESET_COUNTER + 1))
echo "myapp-watchdog: abnormal exit code detected. Current number of errors in the last minute: $RESET_COUNTER"
if [ $RESET_COUNTER == 5 ]
then
echo "myapp-watchdog: myapp exited with code 1"
echo "myapp-watchdog: myapp-watchdog finished"
exit 1
fi
fi
done
Answered By - George Tuzikov Answer Checked By - Mary Flores (WPSolving Volunteer)