¿Cómo ejecuto un script antes de todo lo demás en el apagado con systemd?


17

Nota: La pregunta formulada brevemente se puede encontrar en la parte inferior.

Tengo un script que hace una copia de seguridad de mis archivos en una unidad USB externa. Ejecutarlo puede llevar un tiempo, dependiendo de la cantidad de datos nuevos que haya creado. Quiero ejecutarlo automáticamente en cada apagado del sistema.

Estoy usando fedora 23 con las últimas actualizaciones (systemd).

Traté de lograr esto de varias maneras, pero no pude hacerlo funcionar.

Proceso de larga ejecución con StopExec

autobackup.service:

[Unit]
Description=Slow backup script
Requires=local-fs.target

[Service]
ExecStart=/bin/true
ExecStop=/etc/systemd/system/do_backup.sh
Type=oneshot
RemainAfterExit=yes

[Install]
WantedBy=multiuser.target

Lo activé con systemctl enable autobackup.servicey comencé con systemctl start autobackup.service.

Parte de mi registro de arranque ( journalctl -b-1):

Dez 22 17:45:27 localhost systemd[1]: Unmounted /mnt/BACKUP.
Dez 22 17:45:27 localhost do_backup.sh[4296]: At subvol /home/BACKUP.2015_12_22-17_45_25
Dez 22 17:45:27 localhost do_backup.sh[4296]: ERROR: parent subvol is not reachable from inside the root subvol.
Dez 22 17:45:27 localhost do_backup.sh[4296]: At snapshot BACKUP.2015_12_22-17_45_25
Dez 22 17:45:27 localhost do_backup.sh[4296]: ERROR: failed to dump stream. Broken pipe
Dez 22 17:45:27 localhost systemd[1]: autobackup.service: Control process exited, code=exited status=1
Dez 22 17:45:27 localhost systemd[1]: Stopped Slow backup script.
Dez 22 17:45:27 localhost systemd[1]: autobackup.service: Unit entered failed state.

Tenga en cuenta que no acorté nada en el medio, realmente desmontó / mnt / BACKUP justo antes de que comenzara el script, una coincidencia graciosa ...

Antes del apagado.

autobackup.service:

[Unit]
Description=Slow backup script
DefaultDependencies=no
Before=shutdown.target

[Service]
ExecStart=/etc/systemd/system/do_backup.sh
Type=oneshot

systemctl edit shutdown.target

[Unit]
Requires=autobackup.service

La salida es básicamente la misma.

El problema

Creo que el problema es que systemd inicia mi secuencia de comandos en paralelo con todas las demás secuencias de comandos de apagado en ambos casos, que desmontan BACKUP y desactivan la infraestructura de tuberías (otro error que recibí a veces, cuando el desmontaje no era lo suficientemente rápido).

La pregunta

¿Cómo puedo enseñarle a systemd a iniciar mi script primero en el apagado, esperar hasta que salga y luego iniciar el resto de los scripts / objetivos / unidades / lo que sea?

Respuestas:


12

No es necesario crear o editar archivos de servicio. Simplemente suelte su script en

/usr/lib/systemd/system-shutdown/

https://www.freedesktop.org/software/systemd/man/systemd-halt.service.html

Inmediatamente antes de ejecutar el sistema actual, detener / apagar / reiniciar / kexec systemd-shutdown ejecutará todos los ejecutables en / usr / lib / systemd / system-shutdown / y les pasará un argumento: "detener", "apagar", "reiniciar" "o" kexec ", dependiendo de la acción elegida. Todos los ejecutables en este directorio se ejecutan en paralelo, y la ejecución de la acción no continúa antes de que finalicen todos los ejecutables.

Lo uso para emitir un pitido simplemente al altavoz de la PC


2
¿Tuviste que hacer este directorio? No lo tengo ni en Ubuntu 16.04 ni en Raspbian (jessie), ambos están basados ​​en systemd.
WoJ

2
Los sistemas Debian usan la ruta diferente /lib/systemd/system-shutdown/. Además, tenga en cuenta que estos scripts se ejecutan muy tarde en el apagado, después de que los sistemas de archivos ya están montados de solo lectura. Por lo tanto, cualquier acceso de escritura al sistema de archivos fallará a menos que se vuelva a montar como lectura-escritura ( mount -oremount,rw /). Consulte ¿Cómo ejecutar scripts en / usr / lib / systemd / system-shutdown / al reiniciar o apagar?
Frank Breitling

99
OP solicitó un script ejecutado "antes que todo lo demás" en el apagado. Los scripts de apagado del sistema se ejecutan después de todo lo demás, inmediatamente antes de matar el núcleo.
Greg Alexander

11

¡Lo tengo!

Tome la solución Proceso de ejecución prolongada con StopExec y modifíquelo así:

autobackup.service:

[Unit]
Description=Slow backup script
RequiresMountsFor=/mnt/BACKUP /home

[Service]
ExecStop=/etc/systemd/system/do_backup.sh
Type=oneshot
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target

Tenga en cuenta la línea:

RequiresMountsFor=/mnt/BACKUP /home

Funciona como se esperaba de esta manera.


2
No deberías necesitar hacer el systemctl edit. systemctl enable autobackuptiene el mismo efecto y es más idiomático, y debería funcionar ya que ya tiene la [Install]sección en su unidad. Sin embargo, tendrá que corregir ese error tipográfico en el nombre del objetivo. ;)
Stefan Majewsky

OMG, estuve buscando durante tanto tiempo una solución para llamar a mi script de respaldo ANTES de desmontar cualquier unidad. ¡Gracias!
deanresin

2
Esto no funciona para mi. No tengo monturas, solo quiero asegurarme de que mi script se ejecute antes de que otras unidades se apaguen.
2rs2ts
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.