Ubuntu Weekly Recipe

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

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

systemdではユニット(Unit)という単位でサービスやソケット,あるいは他のユニットをまとめるターゲットなどを管理しています。ユニット設定ファイルはプレーンテキストで書かれていて,これをsystemdが解釈してサービスやシステムの起動・停止を管理しています。

ところで,サービス同士やサービスとその関連するソケットの間では,⁠あるサービスは別のサービスが先に起動していないと使えない」⁠このサービスはあるソケットを必要としており,これよりあとに起動する必要がある」など,アクティベート順序(起動順序)や依存関係があります※1)⁠これらのアクティベート順序や依存関係もユニット設定ファイルに記載されていて,systemdが解釈し,適切に実行していきます。

※1
System V系initのようにサービスだけをsystemdが扱うのであれば「起動順序」が適切なのですが,systemdのユニットには.mount(マウントポイントのユニット).targetといった「起動」という用語がふさわしくないユニットがあります。そのため,やや変わった言い回しではありますが,⁠アクティベート順序」という言葉を使うことにしました。

今回は,このアクティベート順序や依存関係について,systemdのユニットの設定ファイルで使われる基本的なディレクティブとその設定を調べるsystemdのコマンドを紹介し,systemdユニットの世界へ皆様をご招待します。

ユニットの設定ファイルを特定する

それでは実際のユニット設定ファイルを眺めていきましょう。今回,中身を見ていくユニットは,名前解決のサービスであるsystemd-resolved.serviceです※2)⁠

※2
Ubuntu 18.04 LTS デスクトップ版に入っていて,今回紹介したい設定を比較的取り揃えていることの2点がsystemd-resolved.serviceを選んだ理由です。

systemct catコマンドを使用すると,ユニットの設定ファイルを表示させることができます。

$ systemctl cat systemd-resolved.service

すると,設定ファイルのパス/lib/systemd/system/systemd-resolved.serviceとその中身が表示されます。すべてを載せると量が多いため,今回のテーマであるアクティベート順序と依存関係に関する部分だけを抜粋したのが以下になります。

# /lib/systemd/system/systemd-resolved.service
(中略)
[Unit]
Description=Network Name Resolution
(中略)
DefaultDependencies=no
After=systemd-sysusers.service systemd-networkd.service
Before=network.target nss-lookup.target shutdown.target
Conflicts=shutdown.target
Wants=nss-lookup.target

(中略)
[Install]
WantedBy=multi-user.target
(後略)

アクティベート順序

ユニットのアクティベート順序は,After=Before=で設定されます。これらのディレクティブはスペース区切りをすることで,複数のユニットを指定できます。

systemd-resolved.serviceでのアクティベート順序を見ていきます。After=の設定に従い,systemd-sysusers.serviceまたはsystemd-networkd.serviceもしくはその両方が同時にアクティベートされる場合においてsystemd-resolved.serviceは,これらのユニットがアクティブになるのを待って,アクティベートを開始します。Before=では同様に,同時にアクティベートされる場合においてnetwork.targetnss-lookup.targetshutdown.targetの3つは,systemd-resolved.serviceがアクティブになるのを待ってアクティベートを開始します。複数のユニットが同時に非アクティブ化される際は、逆の順序で実施されます。つまり,After=で指定されたユニット,当該ユニット,Before=で指定されたユニットの順に非アクティブ化されます。

ここでAfter=Before=もユニットのアクティベートの順序を示すだけで,⁠このサービスには別のこのサービスが必要」というユニット同士の依存関係を示すわけではない点に注意してください。この点で,System V系のinitでは基本的には起動順序でサービス同士の依存関係をコントロールしていたのと大きく異なります※3)⁠

※3
もっとも,System V系initでも,LSB(Linux Standard Base)に則って,サービスのrcスクリプト上で依存関係を表現し,insservがそれを使って依存関係が満たされるようにサービスの起動順序をコントロールするといった仕組みがありました。

同時にアクティベートされる場合においてと太字で強調したのは,同時でなければ,当該ユニットはAfter=Before=の設定に関係なく,アクティベートされるためです。

著者プロフィール

たなかあきら

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