GNU/Linux >> Tutoriales Linux >  >> Linux

Forma correcta de usar OnFailure en systemd

Para realizar una limpieza si el servicio falla, puede usar ExecStopPost= , que se ejecuta ya sea que el servicio tenga éxito o no.

En el código que ejecutas en ExecStopPost= , puedes usar uno de $SERVICE_RESULT , $EXIT_CODE o $EXIT_STATUS para determinar la condición de falla y actuar en consecuencia. Consulte la documentación sobre esas variables de entorno para comprobar cuál es la adecuada para usted.

Entonces puedes usar Restart=on-failure para que systemd intente reiniciar su unidad cuando falle.

Poniéndolo todo junto, así es como se vería. Suponiendo que run_program saldrá con el estado 2 cada vez que los archivos estén dañados (con suerte, puede adaptar esto a otros escenarios de falla de la documentación anterior), esto debería funcionar:

[Service]
ExecStart=/bin/run_program
ExecStopPost=/bin/sh -c 'if [ "$$EXIT_STATUS" = 2 ]; then rm /file/to/delete; fi'
Restart=on-failure

(NOTA :El doble signo de dólar $$ es escapar de esto a systemd, por lo que el shell ve $EXIT_STATUS y accede a esa variable. Usar un solo signo de dólar también funcionaría, pero luego systemd haría ese reemplazo y el shell vería [ "2" = 2 ] , que podría decirse que también funciona... De todos modos, puede omitir la mayor parte de eso colocando toda esta lógica en un script de shell y llamándolo por su ruta completa en ExecStopPost= , probablemente sería mejor y también podría agregar fácilmente más comandos a la secuencia de comandos, como registrar la acción realizada para recuperarse de la condición de error).

¡Esperemos que esto le brinde suficientes consejos para descubrir cómo configurar esto correctamente dada su situación particular!


NOTA :Probablemente quieras usar ExecStopPost= en lugar de OnFailure= aquí (ver mi otra respuesta), pero esto está tratando de abordar por qué su OnFailure= la configuración no funciona.

El problema con OnFailure= no iniciar la unidad puede deberse a que está en la sección incorrecta, debe estar en el [Unit] sección y no [Service] .

Puedes probar esto en su lugar:

# software.service
[Unit]
Description=Software
OnFailure=software-fail.service

[Service]
ExecStart=/bin/run_program

Y:

# software-fail.service
[Unit]
Description=Delete corrupt files

[Service]
ExecStart=/bin/rm /file/to/delete
ExecStop=/bin/systemctl --user start software.service

Puedo hacer que funcione con esta configuración.

Pero tenga en cuenta que usar OnFailure= no es lo ideal aquí, ya que realmente no se puede saber por qué falló el programa y encadenar otro inicio en ExecStop= llamando al /bin/systemctl start directamente es bastante raro... La solución usando ExecStopPost= y mirar el estado de salida es definitivamente superior.

Si define OnFailure= dentro de [Service] , systemd (al menos la versión 234 de Fedora 27) se queja con:

software.service:6: Unknown lvalue 'OnFailure' in section 'Service'

No estoy seguro de si está viendo eso en sus registros o no... (¿Quizás esto se agregó en systemd reciente?) Eso debería ser una pista de lo que está sucediendo allí.


Linux
  1. Cómo usar el comando Systemctl para administrar los servicios de Systemd

  2. Cómo crear un servicio Systemd en Linux

  3. ¿Alguna forma de usar Xargs a través de una tubería?

  4. Debian:¿la forma correcta de usar Onfailure en Systemd?

  5. ¿Cómo usar Systemd para reiniciar un servicio cuando está inactivo?

Comandos Systemctl para administrar el servicio Systemd

Administrar cgroups con systemd

Forma correcta de usar Ubuntu systemctl para controlar Systemd

systemd - Dando a mi servicio múltiples argumentos

activación de socket systemd frente a xinetd

Uso de CPUQuota en systemd