SystemD 'Requer' falha quando a unidade requerida falha pela primeira vez

0

Eu criei uma unidade de SystemD para iniciar um serviço, e esse serviço requer que outra unidade seja iniciada antecipadamente.

Eu configurei o serviço dependente com Requires=dependant.service , e assim quando depending.service é iniciado automaticamente durante a inicialização, ele primeiro tenta iniciar dependant.service .

O problema é que, se dependant.service começar muito cedo, ele não iniciará (não tenho certeza do que "muito cedo" significa aqui). Para resolver isso, defini dependant.service para Restart=always .

E isso funciona bem - depending.service está habilitado e começa automaticamente, inicia dependant.service , que falha e depois é reiniciado e sempre consegue iniciar na segunda tentativa.

Mas depending.service viu a primeira falha de dependant.service e seu Requires=dependant.service causa falha. O log mostra:

systemd[1]: Dependency failed for depending.
systemd[1]: Job depending.service/start failed with result 'dependency'.

Mesmo que dependant tenha sido bem-sucedido e ambos tenham Restart=always , depending nunca será reiniciado após a falha inicial de dependant .

Eu tentei várias configurações de Requires= , Wants= , BindsTo= e After , mas não consegui encontrar uma combinação que faça com que depending seja reiniciado depois que dependant for reiniciado.

    
por Guss 01.05.2018 / 14:44

1 resposta

1

Parece que a causa raiz é que dependant.service está começando cedo demais às vezes: adicionar Restart diretivas é um pouco invasivo. Isso para mim indica que está faltando um requisito de tempo, para o qual o After serve. Dependendo do tipo de serviço, você precisará determinar quais recursos são necessários antes que o serviço seja iniciado.

Supondo que isso seja relacionado à rede, adicione o seguinte na seção [Unit] de dependant.service :

After=network.target

Ao fazer isso, você está indicando que a rede básica deve estar disponível antes que o systemd tente iniciar o serviço. Caso contrário, o systemd tentará iniciar tantos serviços paralelamente quanto possível, o que significa que, dependendo da ordem de início, você pode estar iniciando basicamente com nada inicializado, que é uma situação que alguns serviços podem tolerar e alguns falharem mal.

Se você quiser ter certeza de que depending.service sempre reinicia com dependant.service , adicione os grupos BindsTo e After a depending.service :

[Unit]
After=dependant.service
BindsTo=dependant.service

Estes comportamentos estão documentados no systemd.unit(7) man página. Eu raramente preciso usar mais de Wants , Requires e After , mas existem opções mais avançadas se você tiver serviços que tenham condições de início particularmente complexas.

Acho útil ao criar um novo serviço (ou grupo de serviços) procurar nos arquivos de unidade fornecidos pela distribuição para ver como eles são feitos e copiar descaradamente as partes boas (tente /usr/lib/systemd/system ou /lib/systemd/system ): eles geralmente têm dicas sobre quais After e Requires são úteis para um determinado tipo de serviço.

    
por 01.05.2018 / 21:48