Como configurar o systemd para matar e reiniciar um daemon ao recarregar?

9

Eu tenho um daemon antigo que eu quero controlar usando o systemd. Quando seu arquivo de configuração é alterado, ele precisa ser eliminado e reiniciado. Em outras palavras, depois de editar o arquivo de configuração, systemctl reload MYSERVICE deve eliminar o processo e reiniciá-lo.

Tentativa 1: tente os padrões. Isso informa ao systemd como iniciar o daemon, mas não como recarregá-lo.

[Service]
ExecStart=/usr/bin/MYSERVICE
Type=simple

Como resultado, start e restart funcionam, mas reload apresenta este erro:

# systemctl reload MYSERVICE
Failed to reload MYSERVICE.service: Job type reload is not applicable for unit MYSERVICE.service.

Tentativa 2: Diga como matar o processo. Isso mata o processo, mas o systemd não o reinicia para mim.

[Service]
ExecStart=/usr/bin/MYSERVICE
Type=simple
ExecReload=/bin/kill -HUP $MAINPID

... seguido por ...

# systemctl daemon-reload
# systemctl reload MYSERVICE

... mata o processo, mas não é reiniciado automaticamente.

Tentativa 3: use o ExecReload para reiniciar o processo também. Isso falha por alguns motivos:

ExecReload=/bin/kill -HUP $MAINPID ; /usr/bin/MYSERVICE

... a mensagem de erro que recebo ...:

# systemctl daemon-reload
# systemctl reload MYSERVICE
Job for MYSERVICE.service failed because the control process exited with error code. See "systemctl status MYSERVICE.service" and "journalctl -xe" for details.

Eu esperaria que houvesse um ReloadType = kill_and_restart ou algo assim, mas sem essa sorte.

Como dizer ao systemd para matar e reiniciar um daemon ao recarregar?

    
por TomOnTime 31.03.2016 / 17:58

2 respostas

11

A resposta é "você não"! Mas temos boas notícias.

A filosofia do systemd é que o recarregamento é opcional e deve ser deixado indefinido se não houver uma funcionalidade de recarregamento verdadeira. Eu definiria "true reload functionality" como um recarregamento que não elimina e reinicia o serviço, ou faz com que o serviço mude seu PID. Em outras palavras, o systemd só quer refletir quais recursos existem.

Em vez disso, você deve usar systemctl reload-or-restart , que será recarregado se existir e reiniciar, se não existir.

Na página do manual ...

   reload-or-restart PATTERN...
       Reload one or more units if they support it. If not, restart them
       instead. If the units are not running yet, they will be started.

   reload-or-try-restart PATTERN...
       Reload one or more units if they support it. If not, restart them
       instead. This does nothing if the units are not running. Note that,
       for compatibility with SysV init scripts, force-reload is
       equivalent to this command.

Portanto: (1) deixe o ExecReload em branco, (2) use systemctl reload-or-restart MYSERVICE e, (3) esteja tudo pronto.

Se você tentar usar o ExecReload para definir uma maneira de matar e reiniciar o serviço, ele terá um novo PID e o systemd ficará confuso.

    
por 03.04.2016 / 21:30
2

A filosofia do systemd é que reload é opcional e o usuário do systemd deve saber, para cada serviço, se deve chamar reload ou fingir chamando restart .

Portanto, a resposta para sua pergunta é: "Não funciona, e não deveria. Por favor, resolva isso na próxima camada superior."

Em outras palavras, o systemd deseja que você apenas implemente " recarregue " se o serviço subjacente suportar uma funcionalidade de recarregamento verdadeira ... ou seja, um recarregamento que não mate e reinicie o serviço, ou faça o serviço alterar seu PID. Em outras palavras, o systemd só quer refletir quais recursos existem.

Você pode estar se perguntando: Mas não seria mais fácil se eu pudesse implementar uma recarga "falsa" permitindo que ExecReload matasse e reiniciasse o serviço? Então eu poderia usar systemctl reload FOO para todos os meus serviços e eu não teria que lembrar quais suportam e quais não o fizeram?

Sim, isso seria mais fácil, mas isso não seria o caminho do sistema. O Systemd quer que o chamador seja o que sabe se existe reload para o serviço. O Systemd quer ser uma interface comum para os recursos existentes, não quer ser responsável por preencher as lacunas.

Por exemplo, o fantoche presume que um serviço controlado pelo sistema não possui reload e padrão para matar e reiniciar o processo . Se o tipo Service [] adicionar uma maneira de especificar que o recarregamento existe e que ele deve ser usado na notificação, ele precisará saber quais serviços têm ou não um recarregamento nativo. Chef e todos os outros sistemas também teriam que aprender a mesma coisa, porque o systemd quer que ele seja resolvido nessa camada. (MiniRant: para iniciar um sistema de processo, parece ser o sistema de tudo-de-saber-tudo-montagem-personalização de todo o namespace i-do-tudo-na-minha-camada. Portanto, não posso dizer por que não estenda essa filosofia ao recarregamento.Talvez um dos autores possa entrar em contato aqui.)

    
por 03.04.2016 / 18:24

Tags