サービスの初期化が完了し、完全に実行され、他のサービスを使用する準備ができた後にのみ開始できる複数のサービス(例C0
:C1
...)があります。 systemdを使ってどのように予約しますか?C9
S
存在するsystemdでのパスの有効化と宛先順序付けサービスの使用サービスにS
一種のフラグファイルを作成するメカニズムがあるとします。代わりに、S
サービスが実行されるプログラムを完全に制御でき、必要に応じてシステムメカニズムを追加できるとします。
答え1
必ずしも必要ではありません。
C
サービスがソケット接続を開く準備ができるまで待つ必要がある場合は、S
これをまったく実行する必要はありません。代わりに、次のものを使用できます。早期リスニングソケットを開くサービス管理者別。
以下を含む複数のシステムローラン・ベルコテのS6、私のスナックツールセットsystemdにはいくつかの方法がありますリスニングソケットサービスを設定するときに最初にすべきことだけできるだけ早くオープンすることが可能です。これらはすべて、リスニングソケットを開くサービスプログラムと、呼び出し時に開かれたファイル記述子でリスニングソケットを受け取るサービスプログラム以外のものを含みます。
特にsystemdを使用してソケットユニットリスニングソケットを定義します。 systemdは、ソケットデバイスを開き、カーネルネットワーキングサブシステムが接続を受信するように設定し、ソケット接続を処理するプロセスを作成すると、それを開いたファイル記述子として実際のサービスに渡します。 (これは2つの方法で行うことができますが、inetd
サービスとサービスの詳細についての議論はこの回答の範囲外です。)Accept=true
Accept=false
重要なことは、人々が必ずしもこれ以上注文する必要はないということです。カーネルは、サービスプログラムが初期化され、クライアント接続を受け入れ、クライアントと通信する準備ができるまでクライアント接続をキューにバッチします。
これを行うには、プロトコルを準備することが重要です。
systemdには次のセットがあります。契約の準備Type=
サービスはサービスユニットの設定で指定されていることを理解しています。ここで関心のある特定の準備プロトコルはnotify
準備プロトコルです。これにより、systemd はサービスのメッセージを待つように指示され、サービスが準備されたら準備完了というメッセージが送信されます。 systemdは、準備が完了するまで他のサービスのアクティブ化を遅らせます。
これを悪用するには、次の2つが必要です。
S
Pierre-Yves Ritschardnotify_systemd()
関数や Cameron T Norman 関数notify_socket()
などの関数を呼び出すようにコードを変更します。Type=notify
サービスのサービスユニットを有効にして設定しますNotifyAccess=main
。
このNotifyAccess=main
制限(デフォルト)は、システム内のすべてのプロセスがsystemdの通知ソケットにメッセージを送信できるため、systemdがいたずらな(または単純なバグのある)プログラムからのメッセージを無視する必要があることに注意する必要があるためです。
人々はPierre-Yves RitchardまたはCameron T Normanのコードを好む。これは、UbuntuBSD、Debian FreeBSD、実際のFreeBSD、TrueOS、OpenBSDなどでこのメカニズムを使用する可能性を排除しないからです。 systemd作成者が提供したコードはこれを除外します。
避けるべきトラップの1つはsystemd-notify
プログラミングです。これにはいくつかの主な問題があり、その中で最も重要なのは、一緒に送信されたメッセージがsystemdで処理されずに破棄されることです。この場合のS
最大の問題は、サービスの「メイン」プロセスとして実行されないため、それを使用する必要があることですNotifyAccess=all
。
避けるべきもう一つのトラップは、合意がforking
より簡単であると考えることです。そうではありません。行為正しくプログラムのすべてのワーカースレッドが実行されるまで、親スレッドを分岐または終了しないことに関連しています。これは、ほとんどのフォークデーモンが実際にフォークする方法と一致しません。
追加読書
- ジョナサンデボインポラード(2015)。Unixデーモンの準備プロトコルの問題。よく与えられる答えです。
- レナルト・ペトリング(2010)。
sd_notify()
。システムのマニュアルページ。 freedesktop.org. - レナルト・ペトリング(2010)。
systemd-notify
。システムのマニュアルページ。 freedesktop.org. - 特定のインターフェイスが起動する前に起動するのを待つようにシステムサービスユニットファイルを作成するにはどうすればよいですか?
- systemdのステータス出力にステータス情報を追加する
答え2
このように:
提供する
[Unit]
Description=My main Service
[Service]
Type=notify
ExecStart=/usr/bin/myBinary
C0サービス
[Unit]
Description=Dependent service number 0
PartOf=S.service
C1.サービス
[Unit]
Description=Dependent service number 1
PartOf=S.service
C9.サービス
[Unit]
Description=Dependent service number 9
PartOf=S.service
/usr/bin/myBinaryが使用する場所sd_notify準備=1初期化が完了した後に呼び出されます。
依存関係の動作方法に応じて、PartOf、Requires、またはBindsToを使用できます。他の人。
答え3
systemd.service(5)
マニュアルページへの具体的な参照タイプに関する部分について =各サービスタイプは、Systemdが他のサービスに機能を提供する準備ができていることを確認する方法が異なります。
その
Type=simple
場合は、デーモンが起動する前に、対応する通信チャネルをインストールする必要があります(たとえば、ソケットのアクティブ化によってsystemdによって設定されたソケットなど)。この場合、
Type=forking
開始が完了し、すべての通信チャネルが確立された後、親プロセスが終了することが予想されます。その
Type=dbus
場合、デーモンはD-Busバスから名前を取得すると予想され、この時点でsystemdは後続のデバイスを起動します。この場合、
Type=notify
デーモンはsd_notify(3)
開始が完了したとき、または同等の呼び出しを介して通知メッセージを送信すると予想されます。この通知メッセージを送信した後、systemd は後続のデバイスを起動します。
最後のオプション(メッセージ転送sd_notify
)の場合は、ユーティリティを使用でき、systemd-notify
を使用してアクセス権を付与することを忘れないでくださいNotifyAccess=all
。
あなたがサービスを制御できるならば、S
あなたのユースケースに最適なオプションを選択するか、実装するのが最も簡単なオプションを自由に選択できます。