systemd: остановить зависимую службу при сбое основной службы

(системная версия 229)

У меня есть основная служба A и дополнительная служба B. Основная служба A может работать сама по себе. Но сервис B не может работать правильно сам по себе: ему нужно, чтобы A работал (технически B может работать, но я хочу, чтобы systemd этого не произошло). Моя цель: Если A не работает, B не должен работать. Учитывая, что A и B работают, когда A останавливается или умирает/падает, B следует остановить.

Как мне этого добиться?

Я приближаюсь, добавляя элементы [Unit] в b.service, используя

Requisite=A.service
After=A.service

Результатом вышеизложенного является то, что

  • B не запустится, если A не работает (хорошо).
  • B останавливается, когда A останавливается (хорошо).
  • Однако, если я убью A, служба B продолжит работать (плохо).

Как я могу исправить это последнее поведение? Ни PartOf, ни BindsTo, кажется, не помогают, но, возможно, у меня нет правильного заклинания комбинаций вариантов? Из справочных страниц мне не ясно, какие параметры можно комбинировать.

man-страница systemd.unit: https://www.freedesktop.org/software/systemd/man/systemd.unit.html Связано: Ошибка зависимости Systemctl , остановить зависимые службы


person Uncle Spook    schedule 12.11.2017    source источник
comment
Stack Overflow — это сайт для вопросов по программированию и разработке. Этот вопрос кажется не по теме, потому что он не о программировании или разработке. См. раздел О каких темах я могу задать здесь в Справочном центре. Возможно, Суперпользователь или Unix & Linux Stack Exchange лучше спросить.   -  person jww    schedule 13.11.2017
comment
Действительно? На многие вопросы systemd уже даны ответы здесь, в SO. И это связано с разработкой систем, разрабатываются не только приложения.   -  person Jesús Franco    schedule 14.11.2017
comment
Вместо Реквизита вы пытались использовать BindsTo, поскольку в связанном вопросе предлагается в качестве решения?   -  person Jesús Franco    schedule 14.11.2017
comment
Спасибо, я перенесу вопрос в S/E. @Jesus, BindsTo обрабатывает часть kill B, но у нее есть побочный эффект: когда я запускаю B, A также запускается. Я хочу, чтобы B выдавал ошибку зависимости, как это происходит с Requisite. Но я думаю, что BindsTo — лучший вариант из двух. Спасибо за предложение, чтобы я посмотрел на это снова.   -  person Uncle Spook    schedule 15.11.2017
comment
Перенесено в ServerFault: serverfault.com/questions/884211/   -  person Uncle Spook    schedule 20.11.2017


Ответы (2)


Если вы запускаете Сервис А с Type=notify, вы можете достичь чего-то, если завершите А с SIGINT или SIGTERM, вы действительно можете справиться с этим и отправить сообщение с $NOTIFY_FD на systemd, но этот вариант по-прежнему невозможен с SIGKILL. Это немного сложно, но может достичь того, чего вы хотите.

Вы также должны подумать о том, чтобы сделать A Restart=always. Это, по крайней мере, гарантирует, что A останется доступным, а B не будет продолжать выдавать ошибки. Когда вы kill A (вне systemd), systemd не может узнать, что A был убит, особенно если вы сделаете это с kill -9 (SIGKILL не может быть обработано). . Таким образом, один из лучших способов справиться с этим — сделать Сервис А Restart=always.

person gabhijit    schedule 25.01.2020

Для достижения третьей цели используйте ключевое слово PartOf.

В B.service вам нужно добавить зависимость от A в разделе [Unit], как показано ниже.

[Unit]
..
..
PartOf=A.service

При этом всякий раз, когда A убивают, B также останавливается.

person DarkKnight    schedule 19.11.2017
comment
Спасибо @DarkKnight, но PartOf не совсем подходит; если я обычно останавливаю A, то B останавливается (хорошо), но если A умирает или убит, B продолжает работать (плохо). Использование BindsTo кажется более близким, но у него другая проблема. В любом случае, кстати, я перенес этот вопрос в ServerFault. - person Uncle Spook; 20.11.2017