O Debian systemd network-online.target não está funcionando?

24

Estou tentando criar um serviço systemd no Debian Jessie. Eu preciso que ele comece depois que network-online.targetfor alcançado.

O problema é network-online.targetacionado ao mesmo tempo network.targetem que minhas interfaces ainda não estão configuradas, apenas iniciei a consulta DHCP.

Parece que esse problema é específico do Debian porque ele usa a configuração de rede herdada.

Como contornar este problema ou como tornar o network-online.targettrabalho?

10robinho
fonte
Qual é o resultado de systemctl list-dependencies network-online.target? Além disso, observe que isso network-online.targetpode não ser necessário, significa que há acesso à Internet. Veja esta página para mais informações.
saiarcot895
A saída do comando é: network-online.target ● └─systemd-networkd-wait-online.service eu já li essa página, entendo o conceito básico lá, mas ainda é muito estranho não ter um ponto definido em que os serviços críticos de rede possam iniciar. Pelo menos, poderia esperar pela atribuição adequada do DHCP.
10robinho 22/07/2015
Isso significa que network-online.targetdepende apenas do systemd-networkd-wait-online.serviceditado de que está pronto. Não depende do NetworkManager dizer que está pronto, nem verificar se ifuptodos os links foram exibidos com êxito (se você usar esse método para configurar sua rede). O Ubuntu, por outro lado, depende do ifupNetworkManager, mas não para systemd-networkd-wait-online..
saiarcot895
Como você está configurando sua rede /etc/network/interfaces:, .networkarquivos systemd ou NetworkManager?
saiarcot895
Você está certo network-online.targete network.targeté acionado logo depois ifup. Eu uso o padrão debian, então /etc/network/interfacescom o endereço dhcp. Parece que o networkd poderia ser uma solução melhor, mas não é fácil de implementar.
10robinho 23/07/2015

Respostas:

18

Como você está usando /etc/network/interfaces, você precisará de um serviço systemd para monitorar o status de cada interface. Verifique se você possui /lib/systemd/system/ifup-wait-all-auto.service(instalado pelo ifupdownpacote no Ubuntu 15.04). Caso contrário, crie /etc/systemd/system/ifup-wait-all-auto.servicee cole o seguinte:

[Unit]
Description=Wait for all "auto" /etc/network/interfaces to be up for network-online.target
Documentation=man:interfaces(5) man:ifup(8)
DefaultDependencies=no
After=local-fs.target
Before=network-online.target

[Service]
Type=oneshot
RemainAfterExit=yes
TimeoutStartSec=2min
ExecStart=/bin/sh -ec '\
  for i in $(ifquery --list --exclude lo --allow auto); do INTERFACES="$INTERFACES$i "; done; \
  [ -n "$INTERFACES" ] || exit 0; \
  while ! ifquery --state $INTERFACES >/dev/null; do sleep 1; done; \
  for i in $INTERFACES; do while [ -e /run/network/ifup-$i.pid ]; do sleep 0.2; done; done'

[Install]
WantedBy=network-online.target

Este é o arquivo de serviço presente em um sistema Ubuntu 15.04, mas com a [Install]seção adicionada para facilitar as coisas. Espero que o comportamento do ifupUbuntu 15.04 seja o mesmo do ifupDebian Jessie. Caso contrário, algumas modificações serão necessárias (principalmente na última linha).

Então corra sudo systemctl enable ifup-wait-all-auto.service. Depois de reiniciar o computador, você verá que o valor network-online.targeté alcançado após a abertura das interfaces (pelo menos).

saiarcot895
fonte
Obrigado por esforço, deixe-me tentar isso agora e eu vou lhe dar feedback
10robinho
Acabei executando a versão ligeiramente modificada ExecStart = /bin/bash -c 'while [ -z "$(hostname -I)" ]; do sleep 1; done;'. Depende hostnamepara verificar se o endereço IP foi atribuído.
Luka5z 01/05/19
Não tente girar o médico. não é porque ele está usando / etc / network / interfaces. Isso ocorre porque o systemd é muito desleixado e o trabalho é transferido para todos os usuários, em vez de resolver o problema em que foi criado.
Florian Heigl
1
fwiw, ifup-wait-all-auto.serviceele foi descartado na ifupdownversão 0.8.5ubuntu1: ”Solte ifup-wait-all-auto.service. Este foi implementado de forma mais elegante, fazendo Wants network-online.target = networking.service diretamente “. [Changelog ]
myrdd
0

Atenção! Acabei de descobrir isso em uma Jessie Raspbian: remova TODAS as linhas comentadas em / etc / network interfaces e funcionará! Parece ser um bug de análise =) No meu caso específico, deixei o comentário iface eth0 inet dhcpe esqueci-o há eras atrás, mas após a atualização para o Raspbian Jessie e a reconstrução de um kernel, tenho um comportamento muito estranho: ele usava o DHCP e se recusava a faça um ajuste em / etc / network / interfaces. Então, retirei todos os comentários - apenas linhas de trabalho, reinicialização - e funciona! NENHUM PATCHING / EDIÇÃO DE SCRIPT NECESSÁRIO!

Alexey Vesnin
fonte
Interessante, eu preciso tentar isso. Embora não faz muito sentido :)
10robinho
2
Você tem alguma referência sobre isso? Gostaria de ler o (s) relatório (s) de erro e ver o código do buggy.
ʇsәɹoɈ
Não, eu não abri um ticket de bug. Para reproduzi-lo, basta adicionar alguns comentários no seu /etc/network/interfacesarquivo - ele será acionado se ainda estiver lá.
Alexey Vesnin
0

De acordo com https://www.freedesktop.org/wiki/Software/systemd/NetworkTarget/, a maneira recomendada de iniciar um serviço APÓS o nível da rede é usar " network-online.target " no arquivo .service :

 "After=network-online.target"
 "Wants=network-online.target"

No entanto, depois de usar " network-online.target " e meu serviço falhar porque a rede não estava totalmente nivelada, descobri que havia um bug ( https://github.com/coreos/bugs/issues/1966 ): não é garantido que seja 100% infalível.

De fato, onde ferramentas dinâmicas de configuração de rede, como o " NetworkManager ", são usadas como neste caso, o estado da rede nunca pode ser 100% preciso ou previsível. Aparentemente, no link que descreve o bug, " network-online.target " pode se comportar de maneira inconsistente, dependendo dos diferentes aplicativos com os quais é usado.

Solução alternativa :
você precisa analisar a ordem de inicialização dos serviços e usar uma que seja iniciada depois de " network-online.target ":

 systemd-analyze plot > /home/pi/graph.svg

Esse é um processo iterativo que altera os destinos de forma incremental para serviços posteriores e posteriores até encontrar aquele que garante que a rede esteja nivelada e que o serviço inicie sem erros. No meu próprio caso, eu até precisei colocar sleep 10no meu script o serviço SystemD chamado.

F1Linux
fonte
0

Certa vez, encontrei uma resposta no Github que a solucionava tentando continuamente executar ping em um servidor. Somente quando o ping é concluído, o serviço continua:

[Service]
ExecStartPre=/bin/sh -c 'until ping -c1 google.com; do sleep 1; done;'
ExecStart=<your command>

Substituí google.compelo meu próprio servidor porque meu script principal precisava se conectar ao meu servidor.

Sam
fonte