Ubuntu Weekly Recipe

第557回 systemdのユニットの関係を読む

この記事を読むのに必要な時間:およそ 4 分

依存関係

次に,ユニットの依存関係を見ています。systemd-resolved.serviceでも,依存関係がいくつか設定されていますので,具体的に説明をしていきます。

なお,ここまで同時にアクティベートされる場合においてと説明をしてきましたが,この同時にアクティベートされるという状況を作るのが,この項で説明する「依存関係」と理解しても,ひとまず問題ないでしょう※4)⁠

※4
systemdのマニュアルには,本稿での「アクティベート順序」を示すディレクティブも「依存関係」を示すディレクティブも一言で"dependency directives"と記載されています。そのため,広義では「アクティベート順序」「依存関係」となるのですが,説明の都合上,このように書き分けています。

Wants=WantedBy=

Wants=を見てください。Wants=では対象としてnss-lookup.targetが設定されています。これはsystemd-resolved.serviceがアクティベートされるときに,指定されたユニットもアクティベートしてほしい(wants)ということを表現しています。

また,[Install]セクションではWantedBy=multi-user.targetと指定されています。これはmulti-user.targetがアクティベートされるときに,systemd-resolved.serviceもアクティベートされてほしいということを表現しています。

ここでほしいと太字で強調しているのは,これらはゆるい依存関係であるためです。

つまり,Wants=だと,指定されたユニット(今回の場合はnss-lookup.targetのアクティベートを試みますが,その結果,何らかの事情でこれが失敗した場合でも,依存関係として指定した側systemd-resolved.serviceには影響はなく,アクティベートを続行します。

WantedBy=でも同じです。当該ユニットsystemd-resolved.serviceのアクティベートが試みられ,結果的に失敗しても,指定したユニットmulti-user.targetのアクティベートには影響しません。

Requires=RequiredBy=

あいにく,systemd-resolved.serviceにはありませんが,Wants=WantedBy=よりも強力な依存関係に,Requires=RequiredBy=があります。Requires=で指定したユニットもアクティベートがトリガーされますが,Wants=とは異なり,こちらはそのユニットを必要(requires)としています。そのため何らかの事情でアクティベートに失敗すると,当該ユニットもアクティベートに失敗します。

RequiredBy=Requires=を受動態としたものです。A.unitの設定でRequiredBy=B.unitとなっている場合にB.unitがアクティベートされると,A.unitもアクティベートされます。この場合もA.unitのアクティベートが失敗すると,RequiredBy=で指定されたB.unitのアクティベートは失敗します。

これらの依存関係を設定するディレクティブと,アクティベート順序を設定するディレクティブとを組み合わせることで,A.unitB.unitを必要としておりRequires=B.unit)⁠かつ,それより後にアクティベートする必要があるAfter=B.unit)⁠という指示を表現できます※5)⁠

※5
反対に言うと,Requires=が指定されていてもAfter=が設定されていなければ,A.unitB.unitを必要としているが,systemdはアクティベート順序は問わず,最終的に両方がアクティブな状態であれば問題はないと判断します(順番は保証されません)⁠つまり,systemdは可能な限りユニットのアクティベートを並列化し,起動・停止を高速化します。

WantedBy=RequiredBy=を指定した場合のシンボリックリンク

A.unitWantedBy=B.unitRequiredBy=B.unitといった形で「受動態」のディレクティブにB.unitが指定されている場合にA.unitsystemctl enableコマンドなどで有効化すると,/etc/systemd/system/以下のB.unit.wantsまたはB.unit.requiresというディレクトリに,ユニット設定ファイルへのシンボリックリンクが張られます。指定したユニットからの見て「能動態」WantsRequiresとして理解されるわけです。

systemd-resolved.serviceではWantedBy=multi-user.targetとなっていますので,/etc/systemd/system/multi-user.target.wants/にシンボリックリンクがあることが確認できます。

$ readlink /etc/systemd/system/multi-user.target.wants/systemd-resolved.service 
/lib/systemd/system/systemd-resolved.service

Conflicts=

systemd-resolved.serviceにはConflicts=の指定があります。これは一風変わった依存関係で,Conflicts=で指定されたユニットか,その指定しているユニットのどちらか一方がアクティブになるというものです。

systemd-resolved.serviceではConflicts=shutdown.targetとなっています。よって,systemd-resolved.serviceがアクティブならshutdown.targetは非アクティブ,その逆もまた然りとなります。

shutdown.targetがアクティブになるときは,システムがシャットダウンへ向かっているということ※6ですので,systemd-resolved.serviceも停止へ向かうと考えればさほど違和感なく理解できるはずです。

※6
「シャットダウンがアクティブになる」という表現はそうとしか言いようがなく,筆者も書いていてわかりづらいです。

著者プロフィール

たなかあきら

Ubuntu Japanese Team Member。ちょっとお高い電子辞書を買ったので,楽しく翻訳をしていたところ,気づいたらメンバーになっていました。