SystemDで指定された時間後にサービスを開始するには?

SystemDで指定された時間後にサービスを開始するには?

SysV initスクリプトをsystemdに変換しようとしています。 SysV 構成は、次のようにさまざまなプロセスを作成します。

su -l $USER_A -c "$CMD_A &"
usleep 600000
su -l $USER_B -c "$CMD_B &"
usleep 100000
su -l $USER_C -c "$CMD_C &"
usleep 300000

すべてのビルドプロセスは異なるユーザーを使用するため、常に各プロセスに対してシステムサービスユニットを作成しました。このサービスユニットは依存関係を指定します(Requires + Afterを使用)。たとえば、サービスユニットの1つは次のとおりです。

[Unit]
Description=CMD_B
Requires=CMD_A
After=CMD_A

[Service]
User=USER_B
Type=simple
ExecStart=/FULLPATH/CMD_B

[Install]
WantedBy=multi-user.target

問題は、さまざまなプロセスがPOSIXキューを介して通信し、これらのキューがすぐには生成されないため、POSIXキューが作成されるのを待つほど強力ではないため、各起動間に時間がかかり失敗することです。

これらのプロセスは変更できないため、各サービスの開始間の経過時間だけを追加できます。

各サービスのアクティブ化の間に特定の期間を考慮する必要があることをsystemdに「明確に」通知する方法は何ですか?

注:systemdは「以降」の依存関係を尊重しますが、これらのコマンドはすぐにアクティブになると見なされるため、ほぼ同時に(数ミリ秒以内に)生成されます。 1つを追加しようとすると、ExecStartPost=/usr/bin/usleep 600000数ミリ秒以内に生成されるように見え、サービスの種類が単純なため、これはExecStartPost決してトリガーされないようです。だから私は試しましたがExecStartPre=/usr/bin/usleep 600000(CMD_Cの場合はCMD_Cを100000に変更しました)、今度は順序が尊重されていないようです。 CMD_A が最初に開始され、次に 100ms 後に CMD_C、最後に 600ms 後に CMD_B が開始されます。したがって、CMD_C は CMD_B の前に開始されるので失敗します。今はこのトリックを使用していますが、ExecStartPre=CMD_Bには600ミリ秒、CMD_Cには700ミリ秒などを選択しました。うまくいきますが、とても悪いと思います。

ベストアンサー1

タイムアウトを使わずに代わりに依存する方法を思いつきたいです。ファイルを待つsystemdのメカニズムプログラムを開始する前に存在します。

ご存知のように、Linuxはposixメッセージキューをファイルとして公開できます。私のFedoraシステムでは、デフォルトでこれを行いますが、そのディレクトリが/dev/mqueue/ない場合は作成できます。mount -t mqueue none /dev/mqueue

man systemd.pathその後、次の簡単な単位を使用できます(参照)myqueueb.path

[Path]
PathExists=/dev/mqueue/queueb
[Install]
WantedBy=multi-user.target

そして別のmyqueueb.service 同じ名前(またはUnit=上記で設定)

[Unit]
Description=CMD_B
[Service]
User=USER_B
Type=simple
ExecStart=/FULLPATH/CMD_B

あなたが欲しいものをしてください。する2番目のデバイスをアクティブにしないでください。、しかしそれをやっsystemctl enable myqueueb.pathsystemctl start myqueueb.path。これにより、ファイルにinotifywaitが設定されます/dev/mqueue/queueb

このファイルは、最初のプログラムがメッセージキューを作成するとqueueb表示され、systemdは自動的にmyqueueb.serviceプログラムを起動して実行しますCMD_B。もちろん、キュー名とCMD_Cの関係に一致するようにこれらの名前も変更する必要があります。

おすすめ記事