システム単位ファイル: 依存関係 "After=/Before=" が機能しません。

システム単位ファイル: 依存関係 "After=/Before=" が機能しません。

systemdユニットファイルに記載されている2つのサービス間の依存関係を作成しようとしています。

  • a.serviceはb.serviceの前に開始する必要があります。
  • a.serviceが失敗した場合、b.serviceを起動できません。

これが私が持っているものです:

% cat a.service
[Unit]
Description=A-Service
Before=b.service

[Service]
ExecStart=/opt/a.sh

[Install]
WantedBy=multi-user.target

% cat b.service
[Unit]
Description=B-Service
After=a.service

[Service]
ExecStart=/opt/b.sh

[Install]
WantedBy=multi-user.target

以下は、サービスAとBに対して実行される単純なスクリプトです。

% cat a.sh
#!/bin/sh
echo "A service started"
exit 0

% cat b.sh
#!/bin/sh
echo "B service started"
while [ true ]; do
   sleep 1
do
exit 0

そこで、次から返してexit 1失敗をシミュレーション/サービスしようとしました。a.shsystemctl status a.service

Active: failed (Result: exit-code) ...
Process: 843 ExecStart=/opt/a.sh (code=exited, status=1/FAILURE)
...

ただし、b.service はまだ起動してアクティブです。

% systemctl status b.service
...
Active: active (running) ...
Process: 844 ExecStart=/opt/b.sh (code=exited, status=0/SUCCESS)
...

さらに、b.serviceの依存関係にはa.service(「失敗」状態)も含まれます。

% systemctl list-dependencies b.service
...

私は何が間違っていましたか?スクリプトに問題があるのでしょうか、それとも[単位]定義が不完全なのでしょうか?

答え1

私は1つを使用しますRequires2番目のデバイスの属性:

このデバイスがアクティブになると、リストされたデバイスもアクティブになります。他のデバイスのいずれかがアクティブではなく、注文の依存関係After =が失敗したデバイスに設定されている場合、そのデバイスは起動しません。

また、分岐する各ユニットの種類を変更しました。デフォルトのタイプ「simple」は、シェルの起動後にそのユニットが起動すると考えられますが、分岐されたユニットはシェルが終了するのを待つからです。このタイプの変更はここでA-Serviceにのみ重要です。

また、Before=b.serviceBからAへのリバース依存関係(Bの「After」ディレクティブを使用)が私にとってより適切であり、両方を持つ必要がないため、A-Serviceからそれを削除しました。

生成されたユニットファイルは次のとおりです。

[Unit]
Description=A-Service

[Service]
Type=forking
ExecStart=/opt/a.sh

[Install]
WantedBy=multi-user.target

そして:

[Unit]
Description=B-Service
Requires=a.service
After=a.service

[Service]
Type=forking
ExecStart=/opt/b.sh

[Install]
WantedBy=multi-user.target

関連情報