Перезапуск служби Systemd Unit, якщо інша служба запускається або перезавантажується


16

Мені хотілося б знати, чи є спосіб Systemdперезапустити A.service( After) під час B.serviceзапуску чи перезавантаження (лише для конфігурації перезавантаження), якщо можливо, без редагування, B.serviceяке встановлюється та модернізується системою.

A.serviceмає запускатися, навіть якщо B.serviceйого не встановлено, вимкнено або зупинено.

A.service:

[Unit]
After = B.service network-online.target
Wants = B.service

[Service]
Type=oneshot
ExecStart = /script.sh start
ExecStop = /script.sh stop
RemainAfterExit=yes

[Install]
WantedBy = network-online.target

B.service:

[Unit]
After=syslog.target network.target

[Service]
Type=forking
ExecStart=/cmd start
ExecStop=/cmd stop
ExecReload=/cmd reload
PIDFile=/var/run/cmd.pid

[Install]
WantedBy=multi-user.target

Відповіді:


12

Ви можете використовувати PartOfв [Unit]розділі.

Приклад: PartOf=B.service

На сторінці людини,

PartOf =

Налаштовує залежності, схожі на Requires =, але обмежується зупинкою та перезапуском одиниць. Коли systemd зупиняє або перезапускає перелічені тут одиниці, дія поширюється на цей блок. Зауважте, що це одностороння залежність - зміни цього блоку не впливають на перелічені одиниці.


Дякую, я розглядав, Overriding vendor settingsале це виглядає ще легше і перспективніше, тільки хвилювання - це я не хочу Aзупинятися, якщо Bзупиняюсь, просто, A.restartякщо B.startвсе-таки я скоро пройду тест і побачу, чи є якийсь спосіб цим керувати, повідомляю вас
Алекс

@Alex: Що робити , якщо ви використовуєте PartOfі Restart=alwaysразом?
Сухі

Я переглядаю Restart=документацію, я не впевнений, яка поведінка з oneshotсервісами, але незалежно від того: When the death of the process is a result of systemd operation (e.g. service stop or restart), the service will not be restartedякщо я правильно зрозумію, вручну зупинка B зупиниться A
Alex

Ну а тепер, баунті автоматично призначив себе на закінчення терміну дії, @Thushi Я ціную ваші зусилля та пропозиції, але PartOfце не є вирішенням питання.
Олексій

@ Алекс: Ну, очки для мене не важливі. Є так багато інших способів заробити очки. Мені просто хочеться знати, чи вирішує надане рішення ваше питання. Якщо ні, ми будемо працювати над цим далі. Як щодо використання PartOfз Restart=always? Ви пробували це?
Сухі

3

Я не мав ніякого контролю над stopз PartOf=, і Aне повинні зупинятися B, так що я в кінцевому підсумку з допомогою Перевизначення параметрів постачальника , здається, працює.

/etc/systemd/system/B.service.d/override.conf

[Service]
ExecStart=
ExecStart=/bin/sh -c '/cmd start || exit $?; sleep 5; [ -x /script.sh ] && /script.sh start; exit 0'
ExecReload=
ExecReload=/bin/sh -c '/cmd reload || exit $?; sleep 5; [ -x /script.sh ] && /script.sh start; exit 0'

/cmdреалізація асинхронна, і для доступу до ресурсу, до якого також /script.shпотрібно отримати доступ, я не знайшов нічого кращого (поки що) спати кілька секунд.

Я намагався використовувати systemctl [--no-block] try-restartперед використанням /script.shбезпосередньо, але не вийшло.


Я також шукаю рішення для цього сценарію. Не могли б ви пояснити це рішення трохи більше? або дайте посилання на деякі документи, щоб прочитати та зрозуміти, що ви зробили.
zappy

Привіт @zappy, знайдіть посібник man systemd.unit(або шукайте його в Інтернеті, якщо він не встановлений) і шукайте розділ "Переопределення налаштувань постачальника".
Олексій

Дякую за ваш внесок Я розумію, що ви обираєте вищевказаний метод лише тому, що служба B - конкретний постачальник, і ви не хочете редагувати файл служби. Але в моєму випадку і послуги A, і B не постачаються. Я відчуваю, що це переважає, це може ускладнити систему. Чи є у нас інші варіанти?
zappy

Питання - пару років, ви перевірили документацію? Можливо, цей сценарій був висвітлений з тих пір. У той час я поспішав, але встигаючи шукати системний офіційний список розсилки і запитати там, врешті-решт, відкрию питання
Алекс

1

На даний момент systemd не покриває цей сенаріо. Цю функціональність неможливо досягти лише за допомогою службових файлів. Однією з можливостей є викрадення systemctl через скрипт оболонки з тим самим іменем, і в цьому перевірте, чи не збирається B.service перезапустити або перезавантажити, також зробіть відповідні дії з A.service і, якщо потрібно, оновіть rc.local, щоб перейти до належного стану під час завантаження. У мене є ця проблема з docker.service та networking.service, але я завжди завжди перезапускаю їх разом:

systemctl перезапустити docker.service networking.service

Очевидно, це не було б ефективно, якщо система сам маніпулює B.service внутрішньо (наприклад, за допомогою інших службових файлів.).

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.