
必要に応じて、ユーザーが起動および停止する一連の相互排他的なシステムサービスがあります。各サービスは一部のハードウェアを排他的に使用する必要があるため、多くのサービスが互いに競合します。 (ただし、すべてのサービスが他のすべてのサービスと競合するわけではありません)
この問題を管理するためにContributes =を使用しましたが、ほぼ完全に機能しますが、サービスを開始するExecStartが実行されているように見え、競合しているサービスのExecStopスクリプトがまだ実行中であるため、ハードウェアリソースがまだ不足しているため、起動サービスが失敗します。利用可能です。
起動スクリプトを安全な時間(30秒など)の間スリープ状態にしておくと、完全に実行されますが、競合するサービスが停止した直後に起動することをお勧めします。
After =は、サービスが任意の順序で繰り返し停止して開始でき、After =が循環依存関係を引き起こすため、機能しないようです。
ExecStartスクリプト内で実行の競合を確認せずにsystemdでこれを行う方法はありますか?
答え1
マニュアルページsystemd.unit(5)
に私が言いたいことはConflicts=
:
Wants=
この設定は、上記の依存関係と同様の依存関係の順序を意味しませんRequires=
。これは、他のデバイスが起動する前に競合するデバイスが停止するようにするか、依存関係をAfter=
宣言する必要があることを意味します。Before=
ジョブの停止は常にジョブの開始前にソートされるため、2 つのソート依存関係のどちらが使用されるかは重要ではありません。Before=
以下/の説明を参照してくださいAfter=
。
つまり、順序依存関係を宣言するだけです。
答え2
私の考えでは、あなたのExecStop=
コマンドがプロセスに終了シグナルを送信し、プロセスの終了が完了する直前に終了するなど、非同期タスクを実行するようです。
ExecStop=
コマンドが同期操作でサービスが完全に終了するまで終了しないことを確認してください。
答え3
プロセスがある場合は、次のようにType=exec
終了を要求してから終了するまで待つことができます。https://github.com/systemd/systemd/issues/13284#issuecomment-784556633
[Service]
# Type must be set correctly for $MAINPID detection to work
Type=exec
ExecStart=/path/to/myservice/start-command
ExecStop=/path/to/myservice/stop-command
ExecStop=/usr/bin/sh -c 'while kill -0 $MAINPID 2>/dev/null; do sleep 1; done'
TimeoutStopSec=15