Quero configurar um docked.target
systemd no meu nível de usuário. A ideia é rodar alguns serviços para configurar meus monitores externos.
Atualmente tenho esta como minha regra:
SUBSYSTEM=="usb", ACTION=="add", ENV{ID_VENDOR}=="17ef", ENV{ID_MODEL}=="100a", SYMLINK+="tp_mini_dock", TAG+="systemd", ENV{SYSTEMD_USER_WANTS}="docked.target"
A regra é detectada perfeitamente (posso ver dev-tp_mini_dock.device
quando estou encaixado).
Eu então coloquei isso ~/.config/systemd/user/docked.target
(também tentei /etc/systemd/user
sem sorte):
[Unit]
Description=Docked to ThinkPad Mini Dock
BindTo=dev-tp_mini_dock.device
Mas isso não começa quando eu atraco. No entanto, se eu iniciar manualmente docked.target
enquanto estiver encaixado, ele parará conforme o esperado quando eu desencaixar.
No entanto, se eu usar ENV{SYSTEMD_WANTS}="docked.target"
e colocar o arquivo /etc/systemd/system/docked.target
, o destino será iniciado conforme o esperado quando eu encaixar. O problema então é que minha instância no nível do usuário não conhece os serviços/destinos no nível do sistema.
Alguma ideia? Já vi algumas outras perguntas na rede, e uma quase exatamente igual à minha:https://bbs.archlinux.org/viewtopic.php?pid=1600019
Responder1
Embora ainda não saiba como ENV{SYSTEMD_USER_WANTS}
funciona, consegui resolver meu problema específico depois de lereste blog.
Acontece que posso instalar alvos como uma dependência de dispositivos. Mudei meu arquivo de unidade ~/.config/systemd/user/docked.target
para:
[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
e minha regra do udev para:
SUBSYSTEM=="usb", ACTION=="add", ENV{ID_VENDOR}=="17ef", ENV{ID_MODEL}=="100a", SYMLINK+="tp_mini_dock", TAG+="systemd"
e habilite-o com systemctl --user enable docked.target
.
Agora, quando eu o encaixo, a regra do udev cria o dispositivo systemd, que por sua vez inicia o destino. Então a BindsTo
opção garante que quando o dispositivo desaparecer (for desconectado), o alvo seja interrompido.
Tive que fazer uma mágica absurda para que isso funcionasse quando fiz login com o dock já conectado. Seria de se imaginar que simplesmente adicionar default.target
e WantedBy
seria After
o suficiente... Adicionarei um link para um blog depois de escrevê-lo.
Responder2
Você pode tentar substituir SYSTEMD_USER_WANTS
por MANAGER_USER_WANTS
. Não tenho 100% de certeza sobre essa mudança de nome, mas pelo menos systemd-226
não há SYSTEMD_USER_WANTS
mais menção nas fontes e parece ter sido substituído por MANAGER_USER_WANTS
. Pelo menos funcionou para mim em um caso semelhante.
Responder3
Cara... Esse problema também me deixou doente, que bicho!
No meu caso, eu queria ouvir eventos HDMI (monitor hotplug) e encontrei um truque para contornar esse problema. Pensei comigo mesmo, bem, se udev
de alguma forma ele sabe que iniciou um serviço com este ou aquele nome e se recusa a fazê-lo novamente, então vamos fazê-lo acreditar que inicia um novo serviço a cada vez. Todos os olhos voltados para o udev
evento correspondente:
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
e observe o SEQNUM
. Está mudando a cada novo evento e é exatamente isso que queremos:
ACTION=="change", SUBSYSTEM=="drm", ENV{HOTPLUG}=="1", ENV{SYSTEMD_USER_WANTS}+="monitor-hotplug@$env{SEQNUM}.service", TAG+="systemd"
Funciona perfeitamente até para . Esperançosamente, seus eventos também terão algo semelhante.~/.config/systemd/user/[email protected]
SEQNUM