I've a udev rule:
ACTION=="add", SUBSYSTEM=="usb", ATTR{idVendor}=="1a86", ATTR{idProduct}=="7523", TAG+="systemd", ENV{SYSTEMD_WANTS}+="klipper.service"
Original service is a sysv file:
pi@octopi:/etc/udev/rules.d $ sudo service klipper status
● klipper.service - Modiffied Klipper systemd file
Loaded: loaded (/etc/init.d/klipper; generated; vendor preset: enabled)
Drop-In: /etc/systemd/system/klipper.service.d
└─override.conf
So i override it using sudo systemctl edit klipper.service
then I enter this in the override file:
[Unit]
Description=Modiffied Klipper systemd file
StopWhenUnneeded=yes
Now, when i unplug the device the service still stays "active" and doesn't stop.
This is what they suggest doing:
https://bugzilla.redhat.com/show_bug.cgi?id=871074
I want this service to stop when the device is removed.
Here's the content of sysv init file
#!/bin/sh
# System startup script for Klipper 3d-printer host code
### BEGIN INIT INFO
# Provides: klipper
# Required-Start: $local_fs
# Required-Stop:
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Klipper daemon
# Description: Starts the Klipper daemon.
### END INIT INFO
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
DESC="klipper daemon"
NAME="klipper"
DEFAULTS_FILE=/etc/default/klipper
PIDFILE=/var/run/klipper.pid
. /lib/lsb/init-functions
# Read defaults file
[ -r $DEFAULTS_FILE ] && . $DEFAULTS_FILE
case "$1" in
start) log_daemon_msg "Starting klipper" $NAME
start-stop-daemon --start --quiet --exec $KLIPPY_EXEC \
--background --pidfile $PIDFILE --make-pidfile \
--chuid $KLIPPY_USER --user $KLIPPY_USER \
-- $KLIPPY_ARGS
log_end_msg $?
;;
stop) log_daemon_msg "Stopping klipper" $NAME
killproc -p $PIDFILE $KLIPPY_EXEC
RETVAL=$?
[ $RETVAL -eq 0 ] && [ -e "$PIDFILE" ] && rm -f $PIDFILE
log_end_msg $RETVAL
;;
restart) log_daemon_msg "Restarting klipper" $NAME
$0 stop
$0 start
;;
reload|force-reload)
log_daemon_msg "Reloading configuration not supported" $NAME
log_end_msg 1
;;
status)
status_of_proc -p $PIDFILE $KLIPPY_EXEC $NAME && exit 0 || exit $?
;;
*) log_action_msg "Usage: /etc/init.d/klipper {start|stop|status|restart|reload|force-reload}"
exit 2
;;
esac
exit 0
Best Answer
StopWhenUnneeded=true
does work as desired. What doesn't work is deactivating the device.You can verify this by doing
systemctl status DEVICENAME.device
with the device inserted and removed. I bet what you'll find is the device activates when the device is inserted, and stays activated after it's removed.To find
DEVICENAME
, you can look for it insystemctl list-units --type=device
. You can also addENV{SYSTEMD_ALIAS}="..."
to your udev rule to give your device a more predictable unit name. Seeman systemd.device
.The issue is documented in more detail at https://github.com/systemd/systemd/issues/7587. The problem is apparently the kernel events for the device removal are missing the tags to get them even routed to systemd so it knows to deactivate the device unit.
A workaround is to add a udev rule that adds the
systemd
tag. In your case, probably something like:With that in place, you should then be able to confirm that the device unit reflects the current plugged/unplugged state of the device, and then
StopWhenUnneeded=true
in the service unit will stop the service when the device is unplugged.