
私はsystemd
現在サービス業に従事しています。たとえば、またはinit 6
実行時にreboot
すべてのサービスの状態変更の順序は何ですか?init 0
この問題が発生するシナリオは次のとおりです。
A
シャットダウンして再起動するとアクティブになるサービスがあります。その目的は、サービスを呼び出して他のサービスから情報を取得することですB
。B
起動時にアクティブで継続的に実行されることを意味します。
reboot
orがinit 0
実行されると、どのような状態で見つけるA
ことができますかB
?
私はこのトピックに関するこの段落が興味深いと思いましたが、詳しくは説明しませんでした。
ActiveState デバイスが現在アクティブであるかどうかを反映するステータス値を含みます。現在定義されている状態は、アクティブ、リロード、非アクティブ、失敗、有効、無効です。 activeは、デバイスがアクティブであることを意味します(明らかに...)。リロードは、デバイスがアクティブであり、現在の設定をリロードしていることを示します。非アクティブとは、非アクティブであり、以前の実行が成功したか、以前の実行がまだ発生していないことを意味します。失敗は非アクティブであり、以前の実行が失敗したことを意味します(この理由の詳細については、結果属性のサービスなど、デバイスタイプ固有のインターフェイスにあります。以下を参照)。アクティブとは、そのデバイスが以前に非アクティブであったが、現在アクティブであることを意味します。これとは対照的に、無効化は、デバイスが現在無効になっているプロセスにあることを示します。
答え1
systemd 設定ではreboot
、poweroff
すべて次のようなさまざまなサブコマンドに変換されhalt
ます。init N
systemctl
。systemctl
これから話します。
もしそうなら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
終了を遅らせる必要があります。存在するB
A
システムユニット(5)私たちは以下を読むことができます:
あるデバイスが別のデバイスに対して逐次依存関係を持ち、後者が起動時に終了した場合、順次依存関係が実際にAfter =またはBefore =タイプであるかどうかにかかわらず、開始前にシャットダウンが発生します。
残念ながら、AをしてもAfter=B.service
Bをしても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)マニュアルページ、「概念」セクション。
- システムユニット(5)マニュアルページの「[Unit]セクションオプション」セクション。
- スタート(7)マンページ。
- systemd.special(5)マンページ。