Я хочу настроить 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