Как мне запустить скрипт, прежде чем все остальное при завершении работы с systemd?

17

Примечание: кратко сформулированный вопрос можно найти внизу.

У меня есть скрипт, который делает резервную копию моих файлов на внешний USB-накопитель. Выполнение этого может занять некоторое время, в зависимости от количества новых данных, которые я создал. Я хочу запускать его автоматически при каждом выключении системы.

Я использую Fedora 23 с последними обновлениями (systemd).

Я пытался достичь этого несколькими способами, но я не мог заставить его работать.

Длительный процесс с 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

Я активировал это с systemctl enable autobackup.serviceи начал это с systemctl start autobackup.service.

Часть моего журнала загрузки ( 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.

Обратите внимание, что я ничего не сокращал между ними, он действительно размонтировал / mnt / BACKUP непосредственно перед запуском скрипта, забавное совпадение ..

Перед выключением. Цель

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

Вывод в основном одинаковый.

Проблема

Я думаю, проблема в том, что systemd запускает мой сценарий параллельно со всеми другими сценариями завершения работы в обоих случаях, которые размонтируют BACKUP и деактивируют инфраструктуру канала (еще одна ошибка, которую я иногда получал, когда размонтирование было недостаточно быстрым).

Вопрос

Как я могу научить systemd сначала запускать мой скрипт при завершении работы, ждать, пока он не выйдет, а затем запустить остальные сценарии завершения работы / цели / модули / что угодно?

le_me
источник

Ответы:

12

Нет необходимости создавать или редактировать служебные файлы. Просто оставьте свой скрипт в

/usr/lib/systemd/system-shutdown/

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

Непосредственно перед выполнением фактической остановки системы / poweroff / reboot / kexec systemd-shutdown запустит все исполняемые файлы в / usr / lib / systemd / system-shutdown / и передаст им один аргумент: либо «halt», «poweroff», «reboot» "или" kexec ", в зависимости от выбранного действия. Все исполняемые файлы в этом каталоге выполняются параллельно, и выполнение действия не продолжается до завершения всех исполняемых файлов.

Я использую его, чтобы просто подать звуковой сигнал на динамик ПК.

Joost
источник
2
Вы должны были сделать этот каталог? У меня его нет ни на Ubuntu 16.04, ни на Raspbian (jessie) - оба на системной основе.
WoJ
2
Системы Debian используют другой путь /lib/systemd/system-shutdown/. Кроме того, имейте в виду, что эти сценарии выполняются очень поздно при завершении работы, после того как файловые системы уже смонтированы только для чтения. Таким образом, любой доступ на запись в файловую систему завершится ошибкой, если не будет перемонтирован как read-write ( mount -oremount,rw /). См. Как выполнить сценарии в / usr / lib / systemd / system-shutdown / при перезагрузке или завершении работы?
Фрэнк
9
ОП запросил сценарий, выполняемый "перед всем остальным" при завершении работы. Скрипты выключения системы выполняются после всего остального, непосредственно перед уничтожением ядра.
Грег Александр
11

Я понял!

Возьмите решение Долгосрочный процесс с StopExec и измените его следующим образом:

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

Обратите внимание на строку:

RequiresMountsFor=/mnt/BACKUP /home

Это работает так, как ожидалось.

le_me
источник
2
Вам не нужно делать это systemctl edit. systemctl enable autobackupимеет тот же эффект и более идиоматичен, и должен работать, так как у вас уже есть [Install]раздел в вашем устройстве. Вы должны будете исправить эту опечатку в названии цели. ;)
Стефан Маевский
О, Боже, я так долго искал решение для вызова скрипта резервного копирования, ДО того как все диски будут размонтированы. Спасибо!
деканрезин
2
Это не работает для меня. У меня нет никаких монтирований, я просто хочу убедиться, что мой скрипт запускается до того, как другие модули будут закрыты.
2rs2ts