fundo
Me pediram para criar um systemd
script para um novo serviço, foo_daemon
que às vezes entra em "estado ruim" e não morre SIGTERM
(provavelmente devido ao manipulador de sinal personalizado). Isso é problemático para os desenvolvedores, pois eles são instruídos a iniciar / parar / reiniciar o serviço via:
systemctl start foo_daemon.service
systemctl stop foo_daemon.service
systemctl restart foo_daemon.service
Problema
Às vezes, devido a foo_daemon
entrar em um estado ruim, temos que matá-lo à força via:
systemctl kill -s KILL foo_daemon.service
Questão
Como posso configurar meu systemd
script para foo_daemon
que, sempre que um usuário tentar parar / reiniciar o serviço systemd
,:
- Tente desligar normalmente a
foo_daemon
viaSIGTERM
. - Dê até 2 segundos para que o desligamento / término
foo_daemon
seja concluído. - Tente desligar a
foo_daemon
viaSIGKILL
se o processo ainda estiver ativo (portanto, não corremos o risco de o PID ser reciclado esystemd
problemasSIGKILL
com o PID errado). O dispositivo que estamos testando gera / bifurca-se rapidamente em vários processos, portanto , existe uma preocupação rara, mas muito real, com a reciclagem de PID, causando um problema. - Se, na prática, estou apenas paranóico com a reciclagem de PID, estou bem com o script emitido
SIGKILL
contra o PID do processo sem me preocupar em matar um PID reciclado.
Respostas:
O systemd já suporta isso imediatamente e é ativado por padrão .
A única coisa que você pode querer personalizar é o tempo limite, com o qual você pode fazer
TimeoutStopSec=
. Por exemplo:Agora, o systemd enviará um SIGTERM, aguarde dois segundos para o serviço sair e, se não o fizer, enviará um SIGKILL.
Se o seu serviço não estiver ciente do sistema, talvez seja necessário fornecer o caminho para o arquivo PID
PIDFile=
.Por fim, você mencionou que seu daemon gera muitos processos. Nesse caso, você pode querer configurar
KillMode=control-group
e o systemd enviará sinais para todos os processos no cgroup.fonte
Type=simple
na unidade systemd.Type=forking
tem a vantagem de (se o serviço foi escrito corretamente) informar o systemd quando estiver totalmente 'pronto', o que Type = simple não pode fazer. Daemonizing não é um problema, mesmo sem um arquivo PID - o systemd rastreará o processo principal de qualquer maneira.Type=notify
é o melhor para o systemd, e muitos serviços comuns já fazem isso. Mas provavelmente não esse serviço legado. No caso do OP, ele possui um serviço que gera muitos processos. Os documentos do systemd alertam sobre esse caso .Como ninguém mencionou a necessidade
Type=oneshot
, aqui está um exemplo completo que sai devido a uma falha de tempo limite.fonte