Fondo
Me pidieron que creara un systemdscript para un nuevo servicio, foo_daemonque 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.servicesystemctl stop foo_daemon.servicesystemctl restart foo_daemon.service
Problema
A veces, debido a foo_daemonun 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 systemdscript para foo_daemonque, cada vez que un usuario intente detener / reiniciar el servicio, systemdpueda:
- Intenta un apagado elegante de
foo_daemonviaSIGTERM. - Espere hasta 2 segundos para
foo_daemonque se complete el apagado / finalización . - Intente un apagado forzado de
foo_daemonviaSIGKILLsi el proceso todavía está vivo (por lo que no tenemos el riesgo de que el PID sea reciclado y lossystemdproblemasSIGKILLcon 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
SIGKILLcontra 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-groupy systemd enviará señales a todos los procesos en el cgroup.fuente
Type=simpleen la unidad systemd.Type=forkingtiene 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=notifysystemd 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