Systemd, похоже, не учитывает зависимость After=?

Systemd, похоже, не учитывает зависимость After=?

У меня есть сервер PostgreSQL ( postgresql.service) и базовый скрипт оболочки ( mobilizon-postgresql.serviceкоторый запускается для предоставления некоторых утверждений о базе данных третьей службе (Mobilizon).

Поэтому, естественно, mobilizon-postgresql.serviceнастроен с After=зависимостью от postgresql.service:

# systemctl show mobilizon-postgresql.service | grep After=
After=basic.target system.slice systemd-journald.socket sysinit.target postgresql.service

Однако после перенастройки системы (которая не затронула эти зависимости) я наблюдаю в журналах следующее поведение:

1677672119.103035 myserver systemd[1]: Starting Mobilizon PostgreSQL setup...
...
1677672119.153192 myserver systemd[1]: Starting PostgreSQL Server...

Итак, mobilizon-postgresql.serviceначалосьдозапуск postgresql.service.

1677672119.279742 myserver mobilizon-postgresql-start[329444]: psql: error: could not connect to server: No such file or directory
1677672119.279742 myserver mobilizon-postgresql-start[329444]:         Is the server running locally and accepting
1677672119.279742 myserver mobilizon-postgresql-start[329444]:         connections on Unix domain socket "/run/postgresql/.s.PGSQL.543>
1677672119.283558 myserver systemd[1]: mobilizon-postgresql.service: Main process exited, code=exited, status=2/INVALIDARGUMENT
1677672119.283707 myserver systemd[1]: mobilizon-postgresql.service: Failed with result 'exit-code'.
1677672119.289678 myserver systemd[1]: Failed to start Mobilizon PostgreSQL setup.

Поэтому, конечно, mobilizon.postgresqlне могу настроить подключение к базе данных.

1677672119.503881 myserver postgres[329458]: [329458] LOG:  starting PostgreSQL 13.10 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 11>
1677672119.512541 myserver postgres[329458]: [329458] LOG:  listening on IPv4 address "0.0.0.0", port 5432
1677672119.512863 myserver postgres[329458]: [329458] LOG:  listening on IPv6 address "::", port 5432
1677672119.519498 myserver postgres[329458]: [329458] LOG:  listening on Unix socket "/run/postgresql/.s.PGSQL.5432"
...
1677672119.871989 myserver systemd[1]: Started PostgreSQL Server.

Лишь позднее postgresql.serviceстало известно, что проект был полностью запущен.

Такое поведение полностью противоречит моему пониманию After=. От systemd.unit(5):

Если модуль foo.service содержит настройку Before=bar.service и оба модуля запускаются, запуск bar.service откладывается до тех пор, пока foo.service не завершит запуск.

Может быть, у меня неверные предположения?

Версия Systemd — 251.12, Distro — NixOS 22.11

решение1

Что systemd подразумевает под «завершением запуска»? man systemd.unitговорит

для сервисных блоков запуск считается завершенным для целей Before=/After=, когда все настроенные команды запуска были вызваны и они либо не были выполнены, либо сообщили об успешном запуске.

Поэтому вам нужно заглянуть в файл службы postgresql, чтобы увидеть, делает ли он что-то вроде разветвления и помещения своего pid в файл, или использует sd_notify()в своем коде для подачи сигнала «готов». Это не очень полезно.

К сожалению, самый простой способ обойти это — заставить mobilizon-postgresql службу ждать, пока не появится сокет домена Unix, используя inotifywaitили подобный, или добавить Restart=on-failureи RestartSec=1повторять попытки до успешного завершения.

Идея Systemd о том, как все должно работать, заключается в том, что вы создаете сокетный модуль, и всякий раз, когда кто-то пытается открыть этот сокет, вы запускаете программу. В этом случае, запуская ваш скрипт, который открывает сокет, он запускает postgresql.

решение2

(Кстати, было бы полезно показать полные единицы)

After=без Wants=или Requires=не имеет эффекта, который вы думаете. Как man systemd.unitописано (на Before=, After=):

Обратите внимание, чтоэти настройки независимы и ортогональны зависимостям требованийкак настроено с помощью Requires=, Wants=, Requisite=, или BindsTo=. Обычно имя блока включается в параметры After=и Wants=, в этом случае указанный блок будет запущен до блока, настроенного с помощью этих параметров.

(Выделено автором постера)

Связанный контент