Versão curta:Como posso fazer com que um serviço controlado pelo sistema acione um desligamento imediato?
Eu tenho um daemon com poderes para fazer coisas arbitrárias em resposta a determinados eventos por meio de um script de shell (fork/exec'd) terminando com
exec halt -p
Ou mais especificamente, exec $@
, mas neste caso $@
é halt -p
. Eu também tentei:
shutdown now
systemctl halt
.
Embora isso funcione, parece haver um problema que faz com que o desligamento, que normalmente levaria apenas alguns segundos, demore vários minutos. Suspeito que seja porque o systemd está aguardando um processo filho de um serviço (o halt
próprio) que não morre educadamente mediante solicitação. Ou seja, é uma espécie de cenário de cobra perseguindo o próprio rabo.
O serviço não tem ExecStop
e é Type=forking
.
Responder1
Lá man systemd.kill
está a seguinte explicação da KillMode
opção:
KillMode=
Especifica como os processos desta unidade devem ser eliminados. Um degrupo controle, processo, misto, nenhum.
Se definido paragrupo de controle,todos os processos restantes no grupo de controle desta unidade serão eliminados na parada da unidade (para serviços: após a execução do comando de parada, conforme configurado com
ExecStop=
).
Isso implica que um personalizado ExecStop
por si só não ajudará, mas:
Se definido paraprocesso, apenas o processo principal em si é eliminado.
Se definido paranenhum, nenhum processo é eliminado. Neste caso, apenas o comando de parada será executado na parada da unidade,
Portanto, ExecStop
pode ser usado em conjunto com KillMode=none
. Isso seria necessário se o daemon iniciasse processos persistentes, para direcioná-los, mas não para o halt
. No meu caso isso não acontece, e o próprio daemon tem um SIGTERM
manipulador e não espera pelos filhos, portanto não precisa de limpeza especial. Portanto, adicionar KillMode=process
ao [Service]
bloco resolveu o problema; o daemon é interrompido, deixando o halt
processo ser concluído e o sistema é encerrado normalmente em alguns segundos.