Fundo

Fundo

Fundo

Pediram-me para criar um systemdscript para um novo serviço, foo_daemonque à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_daemonum estado ruim, temos que matá-lo à força por meio de:

  • systemctl kill -s KILL foo_daemon.service

Pergunta

Como posso configurar meu systemdscript para foo_daemonque, sempre que um usuário tentar parar/reiniciar o serviço systemd,:

  • Tente um desligamento normal de foo_daemonvia SIGTERM.
  • Aguarde até 2 segundos para que o desligamento/encerramento foo_daemonseja concluído.
  • Tente um desligamento forçado de foo_daemonvia SIGKILLse o processo ainda estiver ativo (para não corrermos o risco de o PID ser reciclado e systemdgerar problemas SIGKILLcontra 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 SIGKILLo 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-groupe 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

informação relacionada