Tengo un servicio systemd para ejecutar un script bash de monitoreo que se inicia mediante un temporizador systemd. He usado Type=oneshot
el que me parece más apropiado. Sin embargo, a veces el script necesita llamar a otro programa, lo que sucede que se bifurca. Una vez que hace eso, el script finaliza y sale, pero una vez que el script sale, systemd eliminará todos los procesos secundarios restantes.
Podría utilizar KillMode=process
para evitar eso, pero existe el riesgo de que en otras rutas a través del script otros procesos (que no se bifurcan) puedan permanecer ejecutándose después de la salida.
¿Cuál es la mejor manera de lidiar con esto?
Por cierto, el programa de bifurcación es dhcpcd, pero creo que la pregunta se aplica en general. dhcpcd fue iniciado originalmente por ifplugd y este script es a prueba de fallas en caso de que el sistema termine en un estado en el que dhcpcd ya no se esté ejecutando.
Respuesta1
Los procesos se eliminan porque pertenecen a un grupo de control (cgroup) asociado con el servicio, por ejemplo aquí (para el servicio del sistema):
/sys/fs/cgroup/systemd/system.slice/your-service.service
Para sacar un proceso del cgroup,asignarlo a otro cgroup. El "grupo c padre" parece correcto. Para un servicio del sistema es así:
echo <PID> > /sys/fs/cgroup/systemd/system.slice/tasks
# or even to the general systemd cgroup
echo <PID> > /sys/fs/cgroup/systemd/tasks
Para ejecutar algún comando en este cgroup desde el principio, ejecute un shell que se asigne al cgroup y luego exec
al comando real:
sh -c 'echo "$$" > /sys/fs/cgroup/systemd/tasks; exec /the/forking/program'
/the/forking/program
reemplazará el shell, que ya está en el nuevo cgroup. Cuando se bifurca, la instancia bifurcada se encontrará en el nuevo cgroup. Cuando el script principal sale, systemd eliminará los procesos en el cgroup asociado con el servicio, pero el programa en cuestión no estará entre ellos.
Tal vez haya una forma más adecuada de resolver su problema, con archivos unitarios o algo así. Aunque no lo sé.