![Fundo](https://rvso.com/image/726372/Fundo.png)
Fundo
Pediram-me para criar um systemd
script para um novo serviço, foo_daemon
que às vezes entra em um "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 por meio de:
systemctl start foo_daemon.service
systemctl stop foo_daemon.service
systemctl restart foo_daemon.service
Problema
Às vezes, devido a foo_daemon
um estado ruim, temos que matá-lo à força por meio de:
systemctl kill -s KILL foo_daemon.service
Pergunta
Como posso configurar meu systemd
script para foo_daemon
que, sempre que um usuário tentar parar/reiniciar o serviço systemd
,:
- Tente um desligamento normal de
foo_daemon
viaSIGTERM
. - Aguarde até 2 segundos para que o desligamento/encerramento
foo_daemon
seja concluído. - Tente um desligamento forçado de
foo_daemon
viaSIGKILL
se o processo ainda estiver ativo (para não corrermos o risco de o PID ser reciclado esystemd
gerar problemasSIGKILL
contra o PID errado). O dispositivo que estamos testando gera/bifurca vários processos rapidamente,portanto, há uma preocupação rara, mas muito real, de que a reciclagem do PID esteja causando um problema. - Se, na prática, estou apenas sendo paranóico com a reciclagem do PID, estou bem com o script apenas emitindo
SIGKILL
o PID do processo sem me preocupar em matar um PID reciclado.
Responder1
O systemd já suporta isso imediatamente, e éativado por padrão.
A única coisa que você pode querer personalizar é o tempo limite, que você pode fazer com TimeoutStopSec=
. Por exemplo:
[Service]
TimeoutStopSec=2
Agora, o systemd enviará um SIGTERM, aguardará dois segundos para o serviço sair e, caso contrário, enviará um SIGKILL.
Se o seu serviço não for compatível com o systemd, pode ser necessário fornecer o caminho para o arquivo PID com a extensão PIDFile=
.
Finalmente, você mencionou que seu daemon gera muitos processos. Neste caso, você pode querer configurar KillMode=control-group
e o systemd enviará sinais para todos os processos no cgroup.
Responder2
Como ninguém mencionou a necessidade de Type=oneshot
, aqui está um exemplo completo que sai devido a uma falha de tempo limite.
[Unit]
Description=timeout test
[Service]
Type=oneshot
TimeoutStartSec=2
ExecStart=/bin/sleep 10