Как запустить службу systemd, если подключено указанное USB-устройство (сетевой адаптер)?

523
SoniEx2

У меня есть USB-адаптер Ethernet, который я использую для доступа к Ethernet, но я хотел бы автоматически запускать его netctl-ifplugd@...при подключении. (Не путать с подключением кабеля Ethernet - это обрабатывается netctl-ifplugd.) Как я могу это сделать?

Я видел, как написать сервис systemd, который зависит от присутствующего устройства? но дело не в подключении, а в присутствии.

0

2 ответа на вопрос

1
blihp

Удев это то, что вы хотите посмотреть. Это позволит вам выполнять такие вещи, как выполнение команд, когда оборудование подключено, отключено, происходят изменения состояния и т. Д. Вы также можете указать широкий спектр критериев для управления запуском (например, когда подключено какое-либо устройство хранения или только определенная модель из конкретный производитель и т. д.) Вы должны увидеть все существующие правила в вашей системе в /etc/udev/rules.d/

1
grawity

Я видел "Как написать сервис systemd, который зависит от присутствующего устройства?" но дело не в подключении, а в присутствии.

Это очень похоже, только вам нужна противоположная зависимость: вместо (или, возможно, в дополнение) к вашему сервису в зависимости от устройства вы хотите, чтобы блок виртуального устройства зависел от вашего сервиса.

Фактически, несмотря на то, что заголовок связанного вопроса, по- видимому, задает противоположную вещь, принятый ответ в потоке уже документирует один из точных методов, которые заставили бы устройство запустить службу (метод udev-rule).

Но если у вас есть точное имя устройства .device, проще использовать зависимости systemd напрямую:

Если точный путь sysfs известен:

Например, вы определили, что это устройство sys-subsystem-net-devices-usb0.device . Вы можете использовать различные способы расширения этого модуля (несмотря на то, что он виртуальный), например, вставкиfoo.device.d/*.conf или foo.device.wants/символические ссылки (которые работают так же, как, например, multi-user.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 здесь выходит за рамки), и задайте для него SYSTEMD_WANTSсвойство udev (также называемое «переменная среды устройства»), указывающее ваш модуль:

ACTION=="add", SUBSYSTEM=="net", KERNEL=="usb*", ENV+="netctl-ifplugd@%k.service" 

Поскольку все *.rulesфайлы обрабатываются в алфавитном порядке, убедитесь, что ваше правило размещено позже, чем собственные правила systemd «постоянные сетевые интерфейсы».

Это работает с пользовательскими модулями, если вы используете ENV.


Вы можете испытать желание использовать RUN+="/bin/systemctl start foo"через udev. Не делай этого. Но если вы это сделаете, то, по крайней мере, используйте эту systemctl --no-blockопцию, чтобы не создавать возможную тупиковую ситуацию между двумя компонентами.