Правило udev для запуска службы systemd

Вопрос или проблема

Я модифицирую своё рабочее правило udev (/etc/udev/rules.d/10-local.rules):

SUBSYSTEM=="tty", ATTRS{idVendor}=="1366", ATTRS{idProduct}=="1015", ATTRS{serial}=="000621000000", SYMLINK+="ttymkw"

на это (в конце строки):

SUBSYSTEM=="tty", ATTRS{idVendor}=="1366", ATTRS{idProduct}=="1015", ATTRS{serial}=="000621000000", SYMLINK+="ttymkw", TAG+="systemd", SYSTEMD_WANTS="offnet-uart-log.service"

У меня есть пользовательская служба offnet-uart-log.service в ~/.config/systemd/user, которую я могу вручную запустить, но я пока не дошёл до этого.

С добавленным , TAG+="systemd", SYSTEMD_WANTS="offnet-uart-log.service" в конце моего правила udev, символическая ссылка не создаётся (я перезагружаю с помощью sudo udevadm control --reload-rules && sudo udevadm trigger).

Это говорит мне о том, что правило неправильное, но я не знаю, почему. Может быть, это связано с тем, что udev принадлежит root, а служба – пользователю? Я неправильно понял WANTS?

Я пробовал все четыре комбинации SYSTEM_USER_WANTS или SYSTEM_WANTS, и = или +=. Удаление *_WANTS делает символическую ссылку видимой, так что ошибка в *_WANTS.

Как заставить моё tty-устройство запускать службу логирования?


ИЗМЕНЕНИЕ: как упомянуто в моём собственном ответе ниже, изменение SYSTEM_USER_WANTS на ENV{SYSTEM_USER_WANTS} сработало. Почему это необходимо?

Этот блог-пост делает то, что я хочу, и благодаря ему я заменил SYSTEMD_USER_WANTS на ENV{SYSTEMD_USER_WANTS}, что сделало это рабочим.

Я всё ещё не понимаю, почему конструкция ENV{} необходима и почему я не нашёл её в документации.

Если вы действительно просто хотите запустить службу, вам нужно добавить

RUN{program}="/bin/systemctl --no-block --user start offnet-uart-log.service"

в ваше правило udev. Опция --no-block (предложенная @davolfman) предназначена для того, чтобы обеспечить выполнение команды без ожидания завершения операции, что важно из-за короткого времени, допустимого для udev (см. например, обсуждения здесь и на других страницах, обсуждающих udev и автоматические монтирования).

Ответ или решение

Чтобы корректно настроить правило udev, которое будет триггерить сервис systemd, необходимо учесть несколько моментов. В вашем случае проблема заключается в том, что вы использовали параметр SYSTEMD_USER_WANTS, который не может работать так, как ожидается.

Исправление правила udev

Чтобы ваш сервис offnet-uart-log.service, находящийся в ~/.config/systemd/user/, корректно триггерился, нужно использовать ENV{SYSTEMD_USER_WANTS} вместо SYSTEMD_USER_WANTS. Вот как должно выглядеть ваше новое правило:

SUBSYSTEM=="tty", ATTRS{idVendor}=="1366", ATTRS{idProduct}=="1015", ATTRS{serial}=="000621000000", SYMLINK+="ttymkw", TAG+="systemd", ENV{SYSTEMD_USER_WANTS}="offnet-uart-log.service"

Объяснение использования ENV{}

Контекст ENV{} используется для определения переменных окружения, которые будут доступны в процессе. Это важно, так как переменные окружения udev обычно обрабатываются иначе, чем значения атрибутов, и именно поэтому добавление префикса ENV{} решает вашу проблему. В случае с SYSTEMD_USER_WANTS использование ENV{} указывает udev, что это переменная окружения, которую следует установить для процесса системы, а не системный атрибут.

Альтернативный способ: использование RUN

Если целью является просто запуск сервиса при подключении устройства, можно использовать RUN с командой systemctl. Это более универсальный подход, особенно если возникают проблемы с обработкой переменных окружения. Убедитесь, что у вас установлены необходимые права для выполнения команды. Например:

SUBSYSTEM=="tty", ATTRS{idVendor}=="1366", ATTRS{idProduct}=="1015", ATTRS{serial}=="000621000000", SYMLINK+="ttymkw", RUN+="/bin/systemctl --no-block --user start offnet-uart-log.service"

Опция --no-block позволит избежать ожидания завершения выполнения команды, что важно, так как udev работает в ограниченный промежуток времени при обработке событий.

После внесения изменений

После того как вы внесете указанные выше изменения, не забудьте перезагрузить правила udev и протестировать их:

sudo udevadm control --reload-rules
sudo udevadm trigger

Заключение

Теперь ваше устройство должно правильно триггерить сервис. Убедитесь, что у вас есть необходимые права на выполнение команд и что сервис настроен правильно для работы с systemd. Если возникают дополнительные вопросы, не стесняйтесь обращаться за помощью.

Оцените материал
Добавить комментарий

Капча загружается...