Правильный способ использования OnFailure в systemd

rsync -a --copy-unsafe-links src/ dest

Со страницы man :

- copy-unsafe-links

Это указывает rsync копировать референт символьных ссылок, указывающих за пределами скопированного дерева. Абсолютные символические ссылки также обрабатываются как обычные файлы , как и любые символические ссылки в самом исходном пути, когда используется - относительный . Эта опция не имеет никакого дополнительного эффекта, если также было указано - copy-links .

[...]

- links --copy-unsafe-links Превратить все небезопасные символические ссылки в файлы и дублировать все безопасные символические ссылки.

4
05.05.2018, 06:01
3 ответа

ПРИМЕЧАНИЕ.:Вы, вероятно, захотите использовать ExecStopPost=вместо OnFailure=здесь (см. мой другой ответ ), но это попытка решить, почему ваша установка OnFailure=не работает.

Проблема с тем, что OnFailure=не запускает модуль, может быть связана с тем, что он находится в неправильном разделе, он должен быть в разделе [Unit], а не [Service].

Вместо этого вы можете попробовать:

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

[Service]
ExecStart=/bin/run_program

И:

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

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

Я могу заставить его работать с этой настройкой.

Но обратите внимание, что использование OnFailure=здесь не идеально, так как вы не можете точно сказать, почему программа не удалась, и цепочка другого запуска в ExecStop=путем прямого вызова /bin/systemctl startдовольно хакерская... решение с использованием ExecStopPost=и просмотром статуса выхода определенно лучше.

Если вы определяете OnFailure=внутри [Service],systemd (по крайней мере версия 234 из Fedora 27 )жалуется на:

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

Не знаю, видите ли вы это в своих журналах или нет... (Может быть, это было добавлено в недавней версии systemd? )Это должно быть намеком на то, что там происходит.

8
27.01.2020, 20:49

Чтобы выполнить некоторую очистку в случае сбоя службы, вы можете использовать ExecStopPost=, которая выполняется независимо от того, успешно служба работает или нет.

В коде, который вы запускаете в ExecStopPost=, вы можете использовать один из $SERVICE_RESULT, $EXIT_CODEили $EXIT_STATUS, чтобы определить состояние отказа и действовать соответствующим образом. См. документацию по этим переменным среды, чтобы проверить, какая из них подходит вам.

Затем вы можете использовать Restart=on-failure, чтобы systemd пытался перезапустить ваше устройство в случае сбоя.

Если сложить все вместе, то это будет выглядеть так. Предполагая, что run_programбудет выходить со статусом 2 всякий раз, когда файлы будут повреждены (, надеюсь, вы сможете адаптировать это к другим сценариям сбоя из документации выше ), это должно работать:

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

(ПРИМЕЧАНИЕ.:Двойной знак доллара -$$предназначен для того, чтобы экранировать это в systemd, поэтому оболочка видит $EXIT_STATUSи обращается к этой переменной. Использование одного знака доллара -также будет работать, но вместо этого systemd выполнит эту замену, и оболочка увидит [ "2" = 2 ], что, возможно, также работает... В любом случае, вы можете обойти большую часть этого, поместив всю эту логику в сценарий оболочки и вызывая его по полному пути в ExecStopPost=, это, вероятно, было бы лучше, и вы также могли бы легко добавить в сценарий больше команд, например, запись в журнал действий, предпринятых для восстановления после состояния ошибки.)

Надеюсь, это даст вам достаточно указаний, чтобы выяснить, как правильно настроить это в вашей конкретной ситуации!

10
27.01.2020, 20:49

Следует опасаться версии systemd. Достоинство $EXIT_STATUSи связанных с ним значений было представлено в systemd версии 232, выпущенной в мае 2017 года

.

Некоторые дистрибутивы (на момент ввода ), такие как RHEL 7.x, все еще используют systemd версии 219, которая не устанавливает такие переменные, как $EXIT_STATUS. Следовательно, вы не можете использовать отличный совет выше :(...

1
27.01.2020, 20:49

Теги

Похожие вопросы