Qual é a maneira correta de escrever uma regra do udev para interromper um serviço no systemd

12

Estou executando o Arch Linux e tenho uma regra do udev que inicia um serviço quando um dispositivo é inserido. Nesse caso, ele disca uma conexão quando um modem 3G é conectado.

KERNEL=="ttyUSB*", SYMLINK=="gsmmodem", TAG+="systemd", ENV{SYSTEMD_WANTS}="[email protected]"

No entanto, se o dispositivo for removido, o systemd não interromperá o serviço e, portanto, quando for conectado novamente, não iniciará o serviço, pois já está em execução.

O que eu preciso é de uma regra udev correspondente que seja executada quando o dispositivo for removido para interromper o serviço.

Atualizar

Usando a resposta abaixo, o que tenho agora é a seguinte regra do udev

KERNEL=="ttyUSB*", SYMLINK=="gsmmodem", TAG+="systemd", ENV{SYSTEMD_WANTS}="vodafone.service"

com o seguinte arquivo de serviço (que foi basicamente copiado e colado no arquivo de serviço netcfg:

[Unit]
Description=Netcfg networking service for Vodafone Dongle
Before=network.target
Wants=network.target
BindsTo=dev-gsmmodem.device
After=dev-gsmmodem.device

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/bin/netcfg check-iface wvdial
ExecStop=-/usr/bin/netcfg down wvdial
KillMode=none

[Install]
WantedBy=multi-user.target

Estou usando netcfg-wvdialdo AUR para fazer a discagem.

crazystick
fonte

Respostas:

11

Seu problema pode ser resolvido usando o systemd apenas, simplesmente especificando que seu serviço requer ou, ainda melhor, vincula-se ao dispositivo fornecido.

Citação:

"Se uma das outras unidades [necessárias / vinculadas a] for desativada ou sua ativação falhar, esta unidade [serviço] será desativada"

Você só precisa editar seu arquivo de serviço da seguinte maneira.

[Unit]
<...>
BindsTo=<DEVICE UNIT HERE>.device
<...>
After=<DEVICE UNIT HERE>.device

Nota: para obter uma lista de todos os arquivos de unidades de dispositivos disponíveis, use systemctl list-units --all --full | grep ".device"

brunocodutra
fonte
Isso significa que não preciso da regra udev? Tentei fazer o que você sugeriu, criando um novo arquivo de serviço para substituir o netcfg @ wvdial.service e incluindo essas duas linhas. Parece parar o serviço agora, mas não o inicia quando o dispositivo é conectado novamente.
crazystick
@crazystick você ainda precisa da regra do udev para iniciar o serviço, o que eu quis dizer é que você não precisará usar o udev para interrompê-lo.
Brunocodutra
Entendi. Funciona muito bem com a regra do udev e o arquivo de serviço modificado.
crazystick
2
Você pode usar StopWhenUnneeded=trueem vez BindsToeAfter
SERGA
A @SergA, quando respondi, havia um erro que impedia o StopWhenUnneeded=truetrabalho, mas acredito que já foi corrigido há um bom tempo.
Brunocodutra 19/05/19