Я видел "Как написать сервис systemd, который зависит от присутствующего устройства?«но это, кажется, не о подключении, а о присутствии.
Это очень похоже, только вам нужна противоположная зависимость: вместо (или, возможно, в дополнение) к вашему сервису в зависимости от устройства вы хотите, чтобы блок виртуального устройства зависел от вашего сервиса.
Фактически, несмотря на то, что заголовок связанного вопроса, по-видимому, задает противоположную вещь, принятый ответ в потоке уже документирует один из точных методов, которые заставили бы устройство запустить службу (метод udev-rule).
Но если у вас есть точное имя устройства .device, проще использовать зависимости systemd напрямую:
Если точный путь sysfs известен:
Например, вы определили, что это устройство sys-subsystem-net-devices-usb0.device. Вы можете использовать различные способы расширения этого модуля (несмотря на то, что он является виртуальным), например, foo.device.d/*.conf
drop-ins или foo.device.wants/
(которые работают так же, как, например, многопользовательские. target.wants/).
Вы можете добавить конфигурацию [Install]
в свой сервис, а затем systemctl включить ее:
[Install]
WantedBy=sys-subsystem-net-devices-%i.device
Или вы можете получить тот же результат напрямую с systemctl add-wants
:
# systemctl add-wants sys-subsystem-net-devices-usb0.device netctl-ifplugd@usb0.service
Оба метода приводят только к символической ссылке, которую можно сделать вручную через ln -s
.
Это обычно работает одинаково для пользовательских единиц.
Если известно только частичное имя (или некоторая комбинация других свойств):
Напишите правило udev, которое соответствует вашему устройству (точный синтаксис правила udev здесь находится вне области действия), и задайте для него свойство udev SYSTEMD_WANTS
(также называемое "переменная среды устройства"), указывающее ваш модуль:
ACTION=="add", SUBSYSTEM=="net", KERNEL=="usb*", ENV{SYSTEMD_WANTS}+="netctl-ifplugd@%k.service"
Поскольку все файлы *.rules
обрабатываются в алфавитном порядке, убедитесь, что ваше правило размещено позже, чем собственные правила systemd "постоянные сетевые интерфейсы".
Это работает с пользовательскими модулями, если вы используете ENV{SYSTEMD_USER_WANTS}
.
У вас может возникнуть желание использовать RUN+="/bin/systemctl start foo"
через udev. Не делай этого. Но если вы это сделаете, то по крайней мере используйте systemctl --no-block
чтобы не создавать возможную тупиковую ситуацию между двумя компонентами.