3

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
3

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 in systemctl list-units --type=device. You can also add ENV{SYSTEMD_ALIAS}="..." to your udev rule to give your device a more predictable unit name. See man 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:

ACTION=="remove", SUBSYSTEM=="usb", ENV{PRODUCT}=="1a86/7523/*", TAG+="systemd"

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.

2

Though it is suggested in the bugzilla entry, it is not clear that StopWhenUnneeded=true will do anything on removal of the device. man systemd.unit says for this keyword:

systemd will not stop units by default unless they are conflicting with other units, or the user explicitly requested their shut down.

The person creating the bugzilla went on to create a second udev rule instead, which for you might be something like

ACTION=="remove", SUBSYSTEM=="usb", ATTR{idVendor}=="1a86", ATTR{idProduct}=="7523", RUN+="/bin/systemctl --no-block stop klipper.service"

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.