How to write a systemd service that depends on a device being present?

19,980

You need to combine udev and systemd.

Add a new rule for udev, in /etc/udev/rules.d/95-mywifi.rules, as follows:

 ACTION=="add", ATTRS{idVendor}=="...", ATTRS{idProduct}=="...", SYMLINK=="mywifi", TAG+="systemd", ENV{SYSTEMD_WANTS}="[email protected]"

(You must substitute for the dots the Vendor and Product codes appropriate to your dongle).

The exisiting [email protected] is:

  # cat /lib/systemd/system/netctl-auto\@.service 
  [Unit]
  Description=Automatic wireless network connection using netctl profiles
  Documentation=man:netctl.special(7)
  BindsTo=sys-subsystem-net-devices-%i.device
  After=sys-subsystem-net-devices-%i.device
  Before=network.target
  Wants=network.target

  [Service]
  ExecStart=/usr/bin/netctl-auto start %I
  ExecStop=/usr/bin/netctl-auto stop %I
  RemainAfterExit=yes
  Type=forking

  [Install]
  WantedBy=multi-user.target

For this to work, you will have to setup a netctl profile, see the Arch Linux Wiki to see how to do that.

Share:
19,980

Related videos on Youtube

agtoever
Author by

agtoever

Computer and open source enthousiast. Into astronomy, photography and finance.

Updated on September 18, 2022

Comments

  • agtoever
    agtoever over 1 year

    I would like to write a systemd service that depends on USB WiFi dongle being present. It doesn't need to start when device is plugged in as long as it doesn't start when device is not plugged in. How can I achieve this?

    The systemd configruation file is in [email protected] format. It uses the the %i placeholder. So I tried adding this to the unit file:

    [Path]
    PathExists = /dev/%i
    

    Where %i would be something like wlan0. Unfortunately, this gets completely ignored, so I might not understand the proper use of this section.

    I've also tried:

    [Unit]
    ....
    BindsTo=sys-subsystem-net-devices-%i.device
    After=sys-subsystem-net-devices-%i.device
    

    I it picked up from somewhere (I forgot where), and that doesn't work either.

  • Admin
    Admin over 9 years
    Is there a way to do this for any wifi dongle without having to know vendor and product IDs?
  • MariusMatutiae
    MariusMatutiae over 9 years
    @bvukelic Yes: ACTION=="add", SUBSYSTEM=="net", KERNEL=="wlan[1-9]", SYMLINK=="mywifi", TAG+="systemd", ENV{SYSTEMD_WANTS}="[email protected]". This assumes you hve an onboard wifi called wlan0, in which case nothing is done, plus USB wifi dongles called from wlan1 to wlan9. If you have no onboard wifi card, change [1-9] to [0-9]
  • Admin
    Admin over 9 years
    Thank you for very detailed instructions. I'll test this tomorrow.
  • gdunstone
    gdunstone over 7 years
    I don't have enough rep to comment on the accepted answer, and I know this is a bit of a necro but to expand on answer: I got a working rule based on MariusMatutiaes: ACTION=="add", SUBSYSTEM=="net", KERNEL=="wlan[1-9]", TAG+="systemd", ENV{SYSTEMD_WANTS}="netctl-auto@$name.service" I'm not sure if its better but I would think so because it doesn't use a symlink.