Systemd は After= 依存関係を尊重していないようです。

Systemd は After= 依存関係を尊重していないようです。

PostgreSQL サーバー ( ) と、データベースに関するいくつかのアサーションをサード パーティのサービス (Mobilizon) に提供するために実行されるpostgresql.service基本的なシェル スクリプト ( ) があります。mobilizon-postgresql.service

したがって、当然ながら、は の依存関係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.postgresqlDB への接続を設定することはできません。

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

man systemd.unitsystemdの「起動完了」とはどういう意味ですか?

サービス ユニットの場合、構成されたすべての起動コマンドが呼び出され、失敗したか起動の成功が報告されたときに、Before=/After= の目的で起動が完了したと見なされます。

したがって、postgresql サービス ファイルを調べて、フォークしてファイルに pid を入れる、またはsd_notify()コード内で「準備完了」を通知するなどの操作を行っているかどうかを確認する必要があります。これはあまり役に立ちません。

残念ながら、この問題を回避する簡単な方法は、または同様のものmobilizon-postgresql を使用して、サービスが Unix ドメイン ソケットが存在するまで待機するようにするinotifywaitか、または追加してRestart=on-failureRestartSec=1成功するまで再試行することです。

Systemd の動作の考え方は、ソケット ユニットを作成し、誰かがそのソケットを開こうとするとプログラムを起動するというものです。この場合、ソケットを開くスクリプトを起動すると、postgresql が起動します。

答え2

(ちなみに、完全なユニットを表示すると便利です)

After=Wants=または がなければRequires=、あなたが考えるような効果はありません。man systemd.unitについて説明されているようにBefore=, After=:

ご了承くださいこれらの設定は要件の依存関係とは独立しており、直交している。Requires=、、、またはによって構成されている場合。とオプションの両方にユニット名を含めるのが一般的なパターンであり、その場合Wants=、 リストされているユニットは、これらのオプションで構成されているユニットの前に起動されます。Requisite=BindsTo=After=Wants=

(ポスターによる強調)

関連情報