Fondo
Me pidieron que creara un systemd
script para un nuevo servicio, foo_daemon
que a veces entra en un "mal estado" y no morirá SIGTERM
(probablemente debido a un controlador de señal personalizado). Esto es problemático para los desarrolladores, ya que se les indica que inicien / detengan / reinicien el servicio a través de:
systemctl start foo_daemon.service
systemctl stop foo_daemon.service
systemctl restart foo_daemon.service
Problema
A veces, debido a foo_daemon
un mal estado, tenemos que matarlo por la fuerza a través de:
systemctl kill -s KILL foo_daemon.service
Pregunta
¿Cómo puedo configurar mi systemd
script para foo_daemon
que, cada vez que un usuario intente detener / reiniciar el servicio, systemd
pueda:
- Intenta un apagado elegante de
foo_daemon
viaSIGTERM
. - Espere hasta 2 segundos para
foo_daemon
que se complete el apagado / finalización . - Intente un apagado forzado de
foo_daemon
viaSIGKILL
si el proceso todavía está vivo (por lo que no tenemos el riesgo de que el PID sea reciclado y lossystemd
problemasSIGKILL
con el PID incorrecto). El dispositivo que estamos probando genera / bifurca numerosos procesos rápidamente, por lo que existe una preocupación rara pero muy real sobre el reciclaje de PID que causa un problema. - Si, en la práctica, estoy siendo paranoico sobre el reciclaje de PID, estoy de acuerdo con que el script solo emita
SIGKILL
contra el proceso 'PID sin preocuparme por matar un PID reciclado.
Respuestas:
systemd ya admite esto de forma inmediata, y está habilitado de forma predeterminada .
Lo único que puede personalizar es el tiempo de espera, que puede hacer con
TimeoutStopSec=
. Por ejemplo:Ahora, systemd enviará un SIGTERM, esperará dos segundos para que salga el servicio, y si no lo hace, enviará un SIGKILL.
Si su servicio no es compatible con systemd, es posible que deba proporcionar la ruta a su archivo PID
PIDFile=
.Finalmente, mencionaste que tu demonio genera muchos procesos. En este caso, es posible que desee configurar
KillMode=control-group
y systemd enviará señales a todos los procesos en el cgroup.fuente
Type=simple
en la unidad systemd.Type=forking
tiene la ventaja de (si el servicio se escribió correctamente) informar a systemd cuando está completamente 'listo', lo que Type = simple no puede hacer. Daemonizing no es un problema, incluso sin un archivo PID: systemd rastreará el proceso principal de todos modos.Type=notify
systemd es lo mejor para systemd, y muchos servicios comunes ya lo hacen. Pero probablemente no este servicio heredado. En el caso del OP, tiene un servicio que genera muchos procesos. Los documentos del sistema advierten sobre este caso .Como nadie mencionó la necesidad
Type=oneshot
, aquí hay un ejemplo completo que sale debido a una falla de tiempo de espera.fuente