![Fondo](https://rvso.com/image/726372/Fondo.png)
Fondo
Me pidieron que creara un systemd
script para un nuevo servicio, foo_daemon
que a veces entra en un "mal estado" y no muere SIGTERM
(probablemente debido al 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 que foo_daemon
estamos en mal estado, tenemos que matarlo a la fuerza mediante:
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
haga lo siguiente?
- Intente cerrar correctamente
foo_daemon
víaSIGTERM
. - Espere hasta 2 segundos para que
foo_daemon
se complete el apagado/terminación. - Intente un cierre forzado de
foo_daemon
víaSIGKILL
si el proceso aún está activo (para que no tengamos el riesgo de que el PID se recicle ysystemd
se produzcan 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 de que el reciclaje de PID cause un problema. - Si, en la práctica, estoy paranoico con respecto al reciclaje de PID, estoy de acuerdo con que el script se emita
SIGKILL
contra el PID del proceso sin preocuparme por matar un PID reciclado.
Respuesta1
systemd ya admite esto desde el primer momento, y eshabilitado por defecto.
Lo único que quizás quieras personalizar es el tiempo de espera, lo cual puedes hacer con TimeoutStopSec=
. Por ejemplo:
[Service]
TimeoutStopSec=2
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 con extensión 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.
Respuesta2
Como nadie mencionó la necesidad Type=oneshot
, aquí hay un ejemplo completo que sale debido a una falla en el tiempo de espera.
[Unit]
Description=timeout test
[Service]
Type=oneshot
TimeoutStartSec=2
ExecStart=/bin/sleep 10