Tornar o serviço do usuário systemd dependente do destino do sistema

4

Eu tenho um serviço de usuário em ~/.config/systemd/user/example.service da seguinte forma:

[Unit]
Description=Example service
After=network.target

[Service]
ExecStart=/bin/bash -c 'host google.com > /var/tmp/example'

[Install]
WantedBy=default.target

O serviço real que estou tentando controlar realmente faz algo útil e acessa a rede, é claro; este é apenas um exemplo simplificado.

O serviço está ativado via systemctl --user enable example.service , o que cria o link simbólico ~/.config/systemd/user/default.target.wants/example.service , apontando para ~/.config/systemd/user/example.service .

Com essa configuração, e com systemd sessões de usuário ativadas, conforme descrito no Arch Wiki , o serviço é iniciado como meu usuário na inicialização. No entanto, não é realmente iniciado após a configuração da rede; em vez disso, parece começar imediatamente, pois /var/tmp/example contém:

;; connection timed out; no servers could be reached

(E o serviço real que estou tentando controlar também não alcança a rede e falha com erros semelhantes de pesquisa de nome)

Isso significa que o serviço não é executado após network.target . Como faço para esperar por network.target antes de executar?

    
por dflemstr 01.01.2013 / 22:21

2 respostas

1

Esqueça o network.target . man systemd.special diz:

network.target
       systemd automatically adds dependencies of type After for
       this target unit to all SysV init script service units
       with an LSB header referring to the $network facility.

Portanto, esse alvo é basicamente um hack de compatibilidade para scripts init do SysV.

Supondo que a sua conexão de rede seja gerenciada pelo NetworkManager, você obviamente está certo em depender desse destino, porque NetworkManager.service define Before=network.target . Mas isso significa apenas que o NetworkManager foi iniciado, e não que a conexão de rede está realmente estabelecida. Isso pode demorar um pouco (dhcp roundtrips, handshake de Wi-Fi, etc.) e é inteiramente responsabilidade do NetworkManager. Pelo menos no meu sistema (F18) existe um serviço chamado NetworkManager-wait-online . Ele usa o programa utilitário nm-online para bloquear até que haja uma conexão ativa estabelecida. Tente Require, Before na sua definição de unidade ou use essa ferramenta por conta própria.

    
por 01.02.2013 / 04:35
1

Eu estava tendo o mesmo problema, com um script de backup do usuário que precisa de acesso à Internet. Eu resolvi isso adicionando ~/.config/systemd/user/wait-for-network.service que apenas pinga google.com até que seja alcançável:

[Unit]
Description=Ping a server on the internet until it becomes reachable

[Service]
Type=oneshot
ExecStart=/bin/bash -c 'while ! ping -c1 google.com; do sleep 1; done'
TimeoutStartSec=60s

Depois, fiz o meu script de backup depender disso:

[Unit]
Description=...
Requires=wait-for-network.service
After=wait-for-network.service

Isso funciona independentemente de você usar NetworkManager ou algum outro meio para estabelecer a conexão.

    
por 15.03.2016 / 08:52