Вопрос или проблема
Я модифицирую своё рабочее правило 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
. Если возникают дополнительные вопросы, не стесняйтесь обращаться за помощью.