はじめに
昨今、大抵のLinuxディストリビューションにおいては、Systemdが標準採用されています。 ディストリビューションによって提供されているパッケージを使うだけなら、(通常はすでに適切に設定済みのため)普段それほどサービスの依存関係を意識することはありません。 しかし、独自に開発したソフトウェアをサービスとして動かしたりするときには、サービスの依存関係を正しく指定しないと意図したように動作しないという問題に遭遇することがあります。
今回はそんなときに便利なサービスの依存関係を調べる方法を紹介します。
実際のサービスの起動順序を確認するには
まず、意図した順序でサービスが起動しているか調べるには、systemd-analyzeコマンドを使います。
systemd-analyzeにオプションを何も指定しないと、次のように起動にどれだけかかったかを表示します。1
% systemd-analyze
Startup finished in 14.348s (kernel) + 7.952s (userspace) = 22.300s
これにplotオプションをつけて実行すると、SVG形式の結果を得られます。
適当なファイルにリダイレクトしてブラウザで表示すると良いでしょう。
% systemd-analyze plot > something.svg
% firefox something.svg
実際に描画してみた結果は次のようになりました。

凡例については次の通りになっています。

このように、どの順序でサービスが起動されたのか、またどれくらい時間がかかっているのかがわかりやすく表示されます。 サービスのunitファイルの記述に漏れがあり、意図しないタイミングで起動されてしまっていたケースなどではこれがヒントになります。
サービスの依存関係を調べるには
今度は、unitファイルの記述をもとにサービスの依存関係を調べてみましょう。
systemctlにはlist-dependenciesというオプションがあり、依存関係を調べてツリー表示できます。
ここでいう依存関係はRequires=やWants=といった、必要となるunitに着目した依存関係です。
起動順に着目して調べるには、list-dependenciesに--beforeや--afterを併せて指定します。
--beforeを指定するとunitファイルのBefore=ディレクティブをたどって依存関係を表示します。
同様に--afterを指定するとunitファイルのAfter=ディレクティブをたどって依存関係を表示します。
例えば、getty@tty1がどのサービスの前に起動していないといけないことになっているかを調べるには次のようにします。
% systemctl list-dependencies --before getty@tty1
getty@tty1.service
● ├─getty.target
● │ └─multi-user.target
● │ ├─systemd-update-utmp-runlevel.service
● │ └─graphical.target
● │ └─systemd-update-utmp-runlevel.service
● └─shutdown.target
これは、実際にgetty@tty1.serviceに以下の記述があることと一致しています。
# If additional gettys are spawned during boot then we should make
# sure that this is synchronized before getty.target, even though
# getty.target didn't actually pull it in.
Before=getty.target
IgnoreOnIsolate=yes
まとめ
Systemdのサービスの依存関係を調べる方法として、systemd-analyzeとsystemctlの使い方を紹介しました。
Systemdで依存関係にまつわるトラブルに遭遇したら、使ってみると便利かも知れません。
-
デフォルトでtimeオプションを指定したのと同じ挙動になるため。 ↩