¿Cómo configurar systemd para matar y reiniciar un demonio en la recarga?


12

Tengo un demonio de la vieja escuela que quiero controlar usando systemd. Cuando su archivo de configuración cambia, debe ser eliminado y reiniciado. En otras palabras, después de editar el archivo de configuración, systemctl reload MYSERVICEdebería eliminar el proceso y reiniciarlo.

Intento 1: pruebe los valores predeterminados. Esto le dice a systemd cómo iniciar el demonio, pero no cómo volver a cargarlo.

[Service]
ExecStart=/usr/bin/MYSERVICE
Type=simple

Como resultado, starty restartfunciona, pero reloadda este error:

# systemctl reload MYSERVICE
Failed to reload MYSERVICE.service: Job type reload is not applicable for unit MYSERVICE.service.

Intento 2: dígale cómo matar el proceso. Esto mata el proceso pero systemd no lo reinicia por mí.

[Service]
ExecStart=/usr/bin/MYSERVICE
Type=simple
ExecReload=/bin/kill -HUP $MAINPID

...seguido por...

# systemctl daemon-reload
# systemctl reload MYSERVICE

... mata el proceso pero no se reinicia automáticamente.

Intento 3: Use ExecReload para reiniciar el proceso también. Esto falla por algunas razones:

ExecReload=/bin/kill -HUP $MAINPID ; /usr/bin/MYSERVICE

... el mensaje de error que recibo ...:

# systemctl daemon-reload
# systemctl reload MYSERVICE
Job for MYSERVICE.service failed because the control process exited with error code. See "systemctl status MYSERVICE.service" and "journalctl -xe" for details.

Esperaría que hubiera un ReloadType = kill_and_restart o algo así, pero no tuve tanta suerte.

¿Cómo decirle a systemd que mate y reinicie un demonio en la recarga?


¿Esto realmente necesita ser calzado para recargar , donde no encaja exactamente? ¿No puedes hacer que el demonio se comporte con sensatez?
Michael Hampton

Gracias @MichaelHampton, pero esta no es una situación en la que pueda reescribir el programa. Agradezco su sugerencia útil. Dicho esto, estoy seguro de que este es un caso de uso común de systemd y una respuesta canónica podría ayudar a mucha gente.
TomOnTime

1
Estoy seguro de que una respuesta podría ayudar a alguien, así que voté la pregunta. No estoy seguro de que este sea un caso de uso común. Después de haber usado systemd durante aproximadamente cinco años, casi desde el día en que se desató en el mundo, esta es la primera vez que recuerdo haber oído hablar de alguien que intentaba este tipo de escenario. Es posible que esté malinterpretando algo debido a la falta de detalles.
Michael Hampton

Respuestas:


16

La respuesta es, "no lo haces"! Pero tenemos buenas noticias.

La filosofía de systemd es que la recarga es opcional y debe dejarse sin definir si no existe una verdadera funcionalidad de recarga. Definiría "verdadera funcionalidad de recarga" como una recarga que no mata y reinicia el servicio, o hace que el servicio cambie su PID. En otras palabras, systemd solo quiere reflejar qué características existen.

En su lugar, debe usar systemctl reload-or-restartque hará una recarga si existe, y un reinicio si no existe.

Desde la página del manual ...

   reload-or-restart PATTERN...
       Reload one or more units if they support it. If not, restart them
       instead. If the units are not running yet, they will be started.

   reload-or-try-restart PATTERN...
       Reload one or more units if they support it. If not, restart them
       instead. This does nothing if the units are not running. Note that,
       for compatibility with SysV init scripts, force-reload is
       equivalent to this command.

Por lo tanto: (1) deje ExecReload en blanco, (2) use systemctl reload-or-restart MYSERVICEy, (3) debería estar listo.

Si intenta utilizar ExecReload para definir una forma de matar y reiniciar el servicio, tendrá un nuevo PID y systemd se confundirá.


3

La filosofía de systemd es que reloades opcional y el usuario de systemd debe saber, para cada servicio, si debe llamar reloado simularlo llamando restart.

Por lo tanto, la respuesta a su pregunta es: "No funciona y no debería. Por favor resuelva esto en la siguiente capa superior".

En otras palabras, systemd quiere que solo implemente " reload " si el servicio subyacente admite una verdadera funcionalidad de recarga ... es decir, una recarga que no mata ni reinicia el servicio, o hace que el servicio cambie su PID. En otras palabras, systemd solo quiere reflejar qué características existen.

Puede que se pregunte: ¿pero no sería más fácil si pudiera implementar una recarga "falsa" al permitir ExecReloadmatar y reiniciar el servicio? Entonces podría usar systemctl reload FOOtodos mis servicios y no tendría que recordar cuáles son compatibles y cuáles no.

Sí, eso sería más fácil, pero esa no sería la forma de systemd. Systemd quiere que la persona que llama sea lo que sabe si reloadexiste para el servicio. Systemd quiere ser una interfaz común a las características que existen, no quiere ser responsable de llenar los vacíos.

Por ejemplo, Puppet asume que un servicio dirigido por systemd no tiene reloady por defecto elimina y reinicia el proceso . Si el tipo de Servicio [] agregó una forma de especificar que existe la recarga, y que debe usarse en la notificación, necesitará saber qué servicios tienen o no una recarga nativa. Chef y todos los demás sistemas también tendrían que aprender lo mismo porque systemd quiere que se resuelva en esa capa. (MiniRant: para iniciar un proceso systemd parece ser el sistema i-do-everything-at-my-layer que todo lo sabe, todo monta y personaliza todo el espacio de nombres. Por lo tanto, no puedo decir por qué no lo hace extienda esta filosofía a la recarga. Tal vez uno de los autores pueda intervenir aquí).


1
Existe systemctl reload-or-restart, que volverá a cargar el servicio si lo admite y lo reiniciará si no lo hace. No tengo idea de por qué Puppet hace esta suposición.
Michael Hampton
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.