追加読書

追加読書

私はsystemd現在サービス業に従事しています。たとえば、またはinit 6実行時にrebootすべてのサービスの状態変更の順序は何ですか?init 0

この問題が発生するシナリオは次のとおりです。

Aシャットダウンして再起動するとアクティブになるサービスがあります。その目的は、サービスを呼び出して他のサービスから情報を取得することですBB起動時にアクティブで継続的に実行されることを意味します。

rebootorがinit 0実行されると、どのような状態で見つけるAことができますかB

私はこのトピックに関するこの段落が興味深いと思いましたが、詳しくは説明しませんでした。

ActiveState デバイスが現在アクティブであるかどうかを反映するステータス値を含みます。現在定義されている状態は、アクティブ、リロード、非アクティブ、失敗、有効、無効です。 activeは、デバイスがアクティブであることを意味します(明らかに...)。リロードは、デバイスがアクティブであり、現在の設定をリロードしていることを示します。非アクティブとは、非アクティブであり、以前の実行が成功したか、以前の実行がまだ発生していないことを意味します。失敗は非アクティブであり、以前の実行が失敗したことを意味します(この理由の詳細については、結果属性のサービスなど、デバイスタイプ固有のインターフェイスにあります。以下を参照)。アクティブとは、そのデバイスが以前に非アクティブであったが、現在アクティブであることを意味します。これとは対照的に、無効化は、デバイスが現在無効になっているプロセスにあることを示します。

http://www.freedesktop.org/wiki/Software/systemd/dbus/

答え1

systemd 設定ではrebootpoweroffすべて次のようなさまざまなサブコマンドに変換されhaltます。init Nsystemctlsystemctlこれから話します。

もしそうならsystemctl reboot(例えば)コマンドを実行するとどうなりますか? 〜しない限りpolkit/logind 抽象化レイヤー(root権限が利用可能な場合は使用されません)このコマンドはに変換され、systemctl isolate reboot.targetこれと同じですsystemctl start --job-mode=isolate reboot.target

システム用語で単位(対象、サービスなど)を「分離」することは、次のことを意味します。IgnoreOnIsolate=yes指定されたデバイスとすべての依存関係を開始(アクティブ化)し、指定されていない他のすべてのデバイスを停止(非アクティブ化)します。。したがって、再起動コマンドを実行すると、デバイスreboot.target(およびその依存関係)が開始キューに追加され、他のすべてのデバイスがストップキューに追加されます。

これらのターゲットの依存関係を手動で確認することはできません(systemctl list-dependenciesコマンドを使用できます)。私たちに見せてくださいスタート(7)、システム制御システムの起動/終了時に何が起こるかを説明するマニュアルページです。

対応するASCII図はここにコピーして貼り付けます(FTR、systemd 221を反映しています)。

                              (conflicts with  (conflicts with
                                all system     all file system
                                 services)     mounts, swaps,
                                     |           cryptsetup
                                     |          devices, ...)
                                     |                |
                                     v                v
                              shutdown.target    umount.target
                                     |                |
                                     \_______   ______/
                                             \ /
                                              v
                                     (various low-level
                                          services)
                                              |
                                              v
                                        final.target
                                              |
        _____________________________________/ \_________________________________
       /                         |                        |                      \
       |                         |                        |                      |
       v                         v                        v                      v
systemd-reboot.service   systemd-poweroff.service   systemd-halt.service   systemd-kexec.service
       |                         |                        |                      |
       v                         v                        v                      v
reboot.target             poweroff.target            halt.target           kexec.target

このプログラムはかなり自明です。デフォルトでは、特殊shutdown.targetターゲットはすべてのサービスユニットと競合します(設定されていない場合DefaultDependencies=no)。

したがって、最初のアプローチは、サービスが終了するたびにアクティブになるようにAサービスを依存関係にすることです。shutdown.target(作成にもこのプロセスが必要であることに注意してくださいDefaultDependencies=no。)

ただし、systemdのすべての操作はデフォルトで並列に実行されるため、Aサービスも並べ替える必要があります。つまり、サービスが開始されデータ検索が完了するまでB終了を遅らせる必要があります。存在するBAシステムユニット(5)私たちは以下を読むことができます:

あるデバイスが別のデバイスに対して逐次依存関係を持ち、後者が起動時に終了した場合、順次依存関係が実際にAfter =またはBefore =タイプであるかどうかにかかわらず、開始前にシャットダウンが発生します。

残念ながら、AをしてもAfter=B.serviceBをしてもBefore=B.serviceブロックされます。今後Aが始まりました。

だから私たちは別の道に行かなければなりません。Type=oneshot有効にすると何もしませ/bin/trueんが()無効にすると、必要な操作を実行する一般的なサービスを作成できます。 (これも設定する必要がありますRemainsAfterExit=yes。そうしないと、サービスが/bin/true終了した後に自動的に非アクティブになります。)B.serviceこれらのサービスは必要に応じて注文できます。

順次依存関係を持つ2つのデバイスがシャットダウンすると、開始順序は逆になります。つまり、あるデバイスが別のデバイスにAfter =を設定した場合、両方のデバイスがシャットダウンすると、前者は後者の前に停止します。

これらすべてをまとめると、ユニットファイルはA.service次のようになります。

[Unit]
Description=Collect information about B

# we want to deactivate together with B
Requisite=B.service

# we want to deactivate before B deactivates
After=B.service

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/bin/true
ExecStop=/path/to/B

[Install]
# replace with whatever is needed
WantedBy=B.service

また、最新(≥217)バージョンのsystemdを使用している場合ExecStart=/bin/true 完全に除外できます

追加読書

  1. システム(1)マニュアルページ、「概念」セクション。
  2. システムユニット(5)マニュアルページの「[Unit]セクションオプション」セクション。
  3. スタート(7)マンページ。
  4. systemd.special(5)マンページ。

関連情報