#きょうのsystemd : 受動態の target units は何のためにある?

勉強になったので翻訳

(私家訳。誤訳や誤解があれば指摘歓迎。)

[systemd-devel] Why do passive target units have to exist?

やぁ

systemdのドキュメントを読んでいるところなんだけど、受動態(passive)のunitがちょっとこんがらがった。

"network.target"を例に取ると、

"systemd-networkd.service" には "Wants=network.target" と "Before=network.target" が書かれている。これで、"systemd-networkd.service"は事実上、"systemd-networkd.service" と "network.target" との両方を起動させることができるし、 "network.target" を "systemd-networkd.service" がアクティブになろうとする後にアクティブにすることができる。シャットダウンの順序も正しいと思う。つまり、 "network.target" は"systemd-networkd.service" より先に停止させられる。ここまでは全部わかる。

もし、能動態(active)のtarget unitでこれを実現しようとしたらどうなるのだろう? "systemd-network.target" で "WantedBy=network.target" を指定することはできるのだろうか? そうすれば、 "systemd-network.service" を有効にすれば("network.target.wants" ディレクトリにシンボリックリンクがつくられて)、"network.target" を起動させれば、 "systemd-networkd.service" も起動させることができる。これでも、target unit デフォルトの依存関係で "network.target" は "systemd-networkd.service" の後にアクティブになる。シャットダウンの順序の正しいだろう。

自分にわかる唯一の違いは起動させる units の違いだ。つまり、受動態の "network.target" で "systemd-networkd.service" を起動させるか、能動態の "network.target" で "network.target" を起動させるかの違いかなんだ。

能動態の target units に対して、受動態の target units を使うメリットってあるんだろうか?

John

これに対する、Andrei Borzenkovの反応

[systemd-devel] Why do passive target units have to exist?

思うに、systemdがinitスクリプトに頼らざるを得なかった最初期の歴史的アーティファクトなんじゃないかな。networkingを実装しているinitスクリプトは network.target としても知られている $network を提供していた。だけど、もちろん、これはこれ自身をネイティブなsystemd unitに引っ掛けるものじゃなかった。ネイティブな units だけを使っている限りは、実用上の差はないよ。

[systemd-devel] Why do passive target units have to exist?

Johnがいろんな受動態のtargetをリストアップして、これら全部そうなん?と聞き始める。

ここで、Lennart参戦。

[systemd-devel] Why do passive target units have to exist?

違うよ。これら(訳注: Johnの挙げた受動態のtargetたち)はそれ(訳注: 初期のinitスクリプト)とはまったく関係ない。 これらは全部、同期のポイントなんだ。この同期のポイントはブートの遷移の中ではできればない方がいい。でも必要なら制御しないといけないんだ。

もともとの質問である「能動態の target units に対して、受動態の target units を使うメリットってあるんだろうか?」について Lennart。

[systemd-devel] Why do passive target units have to exist?

我々は基本的に同期ポイントは最小限にしようとしているんだ。 "network.target" もその一つで、そうする理由がなければ、そいつには活躍してほしくない。 同期ポイントが多ければ多いほど、ブートがよりシリアルなものになってしまうんだ。

ロジックはこうだ。もし networking スタックがなければ、サービスがこれの前後で同期する理由がなくなる。必要に応じて、 network.target を制御するのはまさに networking スタックであって、その利用者じゃないんだ。

納得できるかな?

Johnの追加の質問

[systemd-devel] Why do passive target units have to exist?

腑に落ちたよ。説明ありがとう。

だけど、まだ疑問がある。もし、基本的なゴールが同期ポイントの最小化にあるんなら、どうして、より多くの能動態の target を受動態のそれに変えないんだ? 例えばこうだ。全部のマシンにスワップがあるわけじゃない。それなら、swap.targetは受動態のtargetに変えて、不必要な同期ポイントを避けることができるんじゃないか? 何か理由があるに違いないと思うんだけど、それが何だかはわからなかった。

Lennartの回答

[systemd-devel] Why do passive target units have to exist?

あぁ、targetsはただの同期ポイントってわけじゃないんだ。こいつらは物事をグループ化するための方法でもあるんだ。 swap.targetはすべてのスワップバイスを制御する方法であり、local-fs.targetはすべてのローカルファイルシステムを制御するなどなど。

読んでたらごっちゃになってきたが、理屈としてはおそらく、次の通り:

  • network.target を必要としているのは systemd-networkd.service であって、その逆では決してない
  • 理屈上、Johnの書くとおり、systemd-networkd.service に WantedBy=network.target と書いても動きはするだろう
  • ただし、この場合、network.targetがsystemd-networkd.serviceを起動させようとしてしまう
  • サービス起動をパラレルにすることを考えると、target unitの依存関係は少ないほうがいい

ふむ