
Estoy en el proceso de convertir un servicio /etc/init.d existente a systemd. Parecía estar funcionando pero encontré un problema extraño. El servicio systemd comenzará felizmente con el comando "systemctl start service_name" y se detendrá con "systemctl stop service_name", pero no parece detenerse limpiamente. La aplicación subyacente comprueba si ya se está ejecutando y finaliza inmediatamente si este es el caso. Esto es lo que está pasando.
Aquí hay un fragmento equivalente del antiguo script /etc/init.d:
kill_process() {
pkill -SIGINT service_name
sleep 1
if [ -n "$(pgrep service_name)" ]; then
pkill -SIGTERM service_name
sleep 1
fi
if [ -n "$(pgrep service_name)" ]; then
pkill -SIGKILL service_name
sleep 1
fi
if [ -z "$(pgrep service_name)" ]; then
rm -f /var/lock/subsys/service_name
fi
}
start() {
action $"Starting Service: " /sbin/service_name
}
stop() {
action $"Stopping Service: " kill_process
}
restart() {
stop
start
}
Y este es mi intento inicial del equivalente a systemd:
[Unit]
Description=Service Name
[Service]
ExecStart=/sbin/service_name
[Install]
WantedBy=multi-user.target
Tenía entendido que el servicio systemd se encargaría de la terminación del proceso utilizando SIGTERM, pero he experimentado con otros valores para KillSignal y ExecStop. Sin embargo, todavía tengo que entender esta diferencia en el comportamiento de terminación. Además, si cierro la aplicación manualmente usando SIGINT, tampoco cierro el servicio limpiamente. Me pregunto si /etc/init.d está haciendo algo más entre bastidores.
Se agradece cualquier sugerencia.
Respuesta1
Sólo quería trazar una línea debajo de esta publicación en caso de que sea de interés para alguien más.
La aplicación C que se ejecuta como parte del servicio usaba previamente fork() si getppid() aún no era 1 (es decir, no estaba ya bifurcado). Parece que cuando systemd ejecuta la aplicación, ya tiene un PID principal de 1. Nuestra aplicación no tenía manejo explícito de SIGTERM antes, pero se cerró correctamente al reaccionar a SIGINT en el contexto de /etc/init.d. Agregué un controlador SIGTERM específico y el servicio ahora se comporta como se esperaba.