必要なデバイスが最初に失敗すると、SystemDの「必要」が失敗します。

必要なデバイスが最初に失敗すると、SystemDの「必要」が失敗します。

他のデバイスを事前に開始する必要があるサービスを開始するためにSystemDデバイスを作成しました。

起動中に自動的に起動したときに最初に起動しようとするRequires=dependant.service依存サービスを設定しました。depending.servicedependant.service

問題は、dependant.service早すぎると起動しないことです(ここで「早すぎる」が何を意味するのかわかりません)。この問題を解決するためdependant.serviceに設定しましたRestart=always

そしてそれはうまくいきます。depending.service有効、自動起動、起動、クラッシュ、dependant.service再起動、常に2回目の試行で正常に開始されます。

しかし、最初の失敗とその理由が明らかにdepending.serviceなりました。ログには以下が表示されます。dependant.serviceRequires=dependant.service

systemd[1]: Dependency failed for depending.
systemd[1]: Job depending.service/start failed with result 'dependency'.

dependant最終的に成功しましたが、どちらも初期失敗後に再起動されませんRestart=alwaysでした。dependingdependant

Requires=、、、およびWants=のさまざまな設定を試しましたが、再起動後に再起動を引き起こす組み合わせが見つかりませBindsTo=んでした。Afterdependingdependant

答え1

根本原因がdependant.service早すぎる場合があるようです。Restart指示を追加するのは少し面倒だからです。私にとって、これは時間要件が不足していることを示していますAfter。サービスの種類に応じて、サービスを開始する前にどのリソースが必要かを確認する必要があります。

[Unit]これがネットワークに関連していると仮定すると、セクションに次のものを追加する必要がありますdependant.service

After=network.target

これは、systemdがサービスを開始する前にデフォルトのネットワーキングを使用できることを示します。それ以外の場合、systemdはできるだけ多くのサービスを並列に開始しようとします。言い換えれば、開始順序によっては本質的にまったく初期化が行われない場合があり、一部のサービスが許可され、他のサービスがひどく失敗する状況が発生する可能性があります。

depending.service常に再起動するには、次のdependant.service項目にBindsTo追加してください。Afterdepending.service

[Unit]
After=dependant.service
BindsTo=dependant.service

これらの操作は次に記録されます。systemd.unit(7)マンページ。WantsRequiresおよびそれ以上を使用する必要はほとんどありませんが、Afterサービスの開始条件が特に複雑な場合は、より高度なオプションがあります。

私は、新しいサービス(またはサービスグル​​ープ)を作成するときに、ディストリビューションが提供する単位ファイルを見て、どのように実行されるかを確認し、良い部分(try/usr/lib/systemd/systemまたは)を明確にコピーするのが役に立つと思います。リードと要件/lib/systemd/systemについて一般的に見つけるものは次のとおりです。特定の種類のサービスに役立ちます。AfterRequires

答え2

私には役に立ちませんBindsTo。これは(私の考えでは)BindsTo従属デバイスがそれなしでは実行できないことを意味するからです。ただし、この場合、スレーブデバイスが初めて起動に失敗したため、スレーブプロセスはまだ起動していません。

しかし、それによるとシステムユニットに関する文書 PartOfイベントは再起動するたびに伝播されます。だからこれは私にとって効果的です。

[Unit]
After=dependant.service
PartOf=dependant.service

関連情報