Fondo

Fondo

Fondo

Me pidieron que creara un systemdscript para un nuevo servicio, foo_daemonque 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_daemonestamos en mal estado, tenemos que matarlo a la fuerza mediante:

  • 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, systemdhaga lo siguiente?

  • Intente cerrar correctamente foo_daemonvía SIGTERM.
  • Espere hasta 2 segundos para que foo_daemonse complete el apagado/terminación.
  • Intente un cierre forzado de foo_daemonvía SIGKILLsi el proceso aún está activo (para que no tengamos el riesgo de que el PID se recicle y systemdse produzcan problemas SIGKILLcon 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 SIGKILLcontra 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-groupy 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

información relacionada