Как использовать ENV{SYSTEMD_USER_WANTS}= в правиле udev?

Как использовать ENV{SYSTEMD_USER_WANTS}= в правиле udev?

Я хочу настроить docked.targetна уровне пользователя systemd. Идея заключается в запуске некоторых служб для настройки моих внешних дисплеев.

В настоящее время у меня есть такое правило:

SUBSYSTEM=="usb", ACTION=="add", ENV{ID_VENDOR}=="17ef", ENV{ID_MODEL}=="100a", SYMLINK+="tp_mini_dock", TAG+="systemd", ENV{SYSTEMD_USER_WANTS}="docked.target"

Правило отлично обнаруживается (я вижу, dev-tp_mini_dock.deviceкогда я подключен).

Затем у меня есть это ~/.config/systemd/user/docked.target(тоже /etc/systemd/userбезуспешно пробовал):

[Unit]
Description=Docked to ThinkPad Mini Dock
BindTo=dev-tp_mini_dock.device

Но это не запускается, когда я пристыковываюсь. Однако, если я вручную запускаю, docked.targetкогда пристыкован, это останавливается, как и ожидалось, когда я отстыковываюсь.

Однако, если я использую ENV{SYSTEMD_WANTS}="docked.target"и помещаю файл в /etc/systemd/system/docked.target, цель запускается как и ожидалось, когда я пристыковываюсь. Проблема тогда в том, что мой экземпляр уровня пользователя не знает о службах/целях уровня системы.

Есть мысли? Я видел еще несколько вопросов в сети, и один почти такой же, как мой:https://bbs.archlinux.org/viewtopic.php?pid=1600019

решение1

Хотя я до сих пор не знаю, как это ENV{SYSTEMD_USER_WANTS}работает, мне удалось решить свою конкретную проблему после прочтенияэтот блог.

Оказывается, я могу устанавливать цели как зависимость от устройств. Я изменил свой файл юнита ~/.config/systemd/user/docked.targetна:

[Unit]
Description=Docked to ThinkPad Mini Dock
BindsTo=dev-tp_mini_dock.device
After=dev-tp_mini_dock.device

[Install]
WantedBy=dev-tp_mini_dock.device

и мое правило udev:

SUBSYSTEM=="usb", ACTION=="add", ENV{ID_VENDOR}=="17ef", ENV{ID_MODEL}=="100a", SYMLINK+="tp_mini_dock", TAG+="systemd"

а затем включите его с помощью systemctl --user enable docked.target.

Теперь, когда я его пристыковываю, правило udev создает устройство systemd, которое в свою очередь запускает цель. Затем опция BindsToгарантирует, что когда устройство исчезает (отключается), цель останавливается.

Мне пришлось проделать какую-то бессмысленную магию, чтобы это заработало, когда я вхожу в систему с уже подключенной док-станцией. Можно было бы подумать, что простого добавления default.targetк WantedByи Afterбудет достаточно... Я добавлю ссылку на блог после того, как напишу его.

решение2

Вы можете попробовать заменить SYSTEMD_USER_WANTSна MANAGER_USER_WANTS. Я не уверен на 100% насчет этого изменения имени, но, по крайней мере, в источниках больше systemd-226нет упоминаний о , SYSTEMD_USER_WANTSи, похоже, его заменили на MANAGER_USER_WANTS. По крайней мере, это сработало для меня в похожем случае.

решение3

Господи... Меня эта проблема тоже бесила, что за фигня!

В моем случае я хотел слушать события HDMI (монитор hotplug), и я нашел трюк, как обойти эту проблему. Я подумал: ну, если это udevкаким-то образом знает, что оно запустило службу с тем или иным именем и отказывается делать это снова, то давайте заставим его поверить, что оно запускает новую службу каждый раз. Все глаза на соответствующее udevсобытие:

UDEV  [19214.534185] change   /devices/pci0000:00/0000:00:01.0/0000:01:00.0/drm/card0 (drm)
ACTION=change
DEVLINKS=/dev/dri/by-path/pci-0000:01:00.0-card
DEVNAME=/dev/dri/card0
DEVPATH=/devices/pci0000:00/0000:00:01.0/0000:01:00.0/drm/card0
DEVTYPE=drm_minor
HOTPLUG=1
ID_FOR_SEAT=drm-pci-0000_01_00_0
ID_PATH=pci-0000:01:00.0
ID_PATH_TAG=pci-0000_01_00_0
MAJOR=226
MINOR=0
SEQNUM=3364
SUBSYSTEM=drm
USEC_INITIALIZED=3280572

и обратите внимание на SEQNUM. Он меняется при каждом новом событии, и это именно то, что нам нужно:

ACTION=="change", SUBSYSTEM=="drm", ENV{HOTPLUG}=="1", ENV{SYSTEMD_USER_WANTS}+="monitor-hotplug@$env{SEQNUM}.service", TAG+="systemd"

Работает как по волшебству даже для . Надеюсь, ваши мероприятия также имеют или что-то подобное.~/.config/systemd/user/[email protected]SEQNUM

Связанный контент