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

Было бы гораздо проще просто отредактировать скрипт, но если это невозможно, вы можете сделать:

BACKUP_FILE=$(create_backup.sh | grep -oP 'Backup file is:\s*\K\S+') && 
ln -s $BACKUP_FILE /folder/here
8
13.04.2017, 15:36
2 ответа

Это необязательно.

Если службам C необходимо дождаться готовности S , чтобы они могли открыть к нему сокетное соединение, то это совсем не обязательно. . Вместо этого можно воспользоваться преимуществом раннего открытия прослушивающего сокета менеджерами служб.

В нескольких системах, в том числе s6 Лорана Беркота , my nosh toolset и systemd, есть способы, с помощью которых прослушивающий сокет можно открыть на ранней стадии, самое первое при настройке сервиса. Все они включают в себя нечто иное, чем служебная программа, открывающая прослушивающий сокет (-ы), и служебная программа, когда вызывается, принимает прослушивающие (-ые) сокеты (-ы) как уже открытые файловые дескрипторы.

В частности, с помощью systemd создается блок сокета , который определяет прослушивающий сокет. systemd открывает модуль сокета и настраивает его так, чтобы сетевая подсистема ядра прослушивала соединения; и передает его фактической службе в качестве дескриптора открытого файла, когда дело доходит до порождения процесса (ов), который обрабатывает соединения с сокетом. (Это можно сделать двумя способами, как и inetd , но обсуждение деталей служб Accept = true и Accept = false выходит за рамки объем этого ответа.)

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

Когда это происходит, важны протоколы готовности.

systemd имеет набор протоколов готовности , которые он понимает, определенную службу за службой с настройкой Type = в служебном модуле. Особый интерес представляет протокол готовности уведомить о готовности. С его помощью systemd сообщает, что следует ожидать сообщений от службы, и когда служба готова, он отправляет сообщение, которое отмечает готовность. systemd откладывает активацию других служб до тех пор, пока не будет отмечена готовность.

Использование этого требует двух вещей:

  • Изменение кода S так, чтобы он вызывал что-то вроде функции Пьера-Ива Ритчарда notify_systemd () или функции Кэмерона Т. Нормана функция notify_socket () .
  • Настройка сервисного подразделения для сервиса с помощью Type = notify и NotifyAccess = main .

Ограничение NotifyAccess = main (по умолчанию) связано с тем, что systemd нужно знать, чтобы игнорировать сообщения от вредоносных (или просто неисправных) программ, потому что любой процесс в системе может отправлять сообщения в systemd сокет уведомлений.

Один использует Пьера-Код Ива Ритчарда или Кэмерона Т. Нормана является предпочтительным, поскольку он не исключает возможности наличия этого механизма в UbuntuBSD, Debian FreeBSD, реальной FreeBSD, TrueOS, OpenBSD и т. Д .; что исключает код, предоставленный авторами systemd.

Одной из ловушек, которую следует избегать, является программа systemd-notify . У него есть несколько серьезных проблем, не последняя из которых заключается в том, что отправленные с ним сообщения могут быть выброшены необработанными systemd. Самая большая проблема в этом случае заключается в том, что он не работает как «главный» процесс службы, поэтому необходимо открыть уведомления о готовности для службы S для каждого процесса в системе с помощью NotifyAccess = все .

Еще одна ловушка, которую следует избегать, - это думать, что протокол разветвления проще. Нет. Чтобы выполнить это правильно , необходимо не выполнять разветвление и не выходить из родительского объекта до тех пор, пока (с одной стороны) не будут запущены все рабочие потоки программы. Это не соответствует тому, как подавляющее большинство демонов, которые форкуются, фактически разветвляются.

Дополнительная литература

9
27.01.2020, 20:11

así:

S.servicio

[Unit]
Description=My main Service

[Service]
Type=notify
ExecStart=/usr/bin/myBinary

Servicio C0

[Unit]
Description=Dependent service number 0
PartOf=S.service

Servicio C1

[Unit]
Description=Dependent service number 1
PartOf=S.service

Servicio C9

[Unit]
Description=Dependent service number 9
PartOf=S.service

Donde /usr/bin/myBinary realiza una llamada sd _para notificar a READY=1 cuando se completa la inicialización.

Dependiendo de cómo desee que se comporte la dependencia, puede usar PartOf, Requires o BindsTo u otros .

1
27.01.2020, 20:11

Теги

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