FreeBSDサーバの4.11から6.2への更新作業もようやく一段落した。portのkrb5をデインストールしてsubversionやGSSAPI関連バイナリを入れ直したり、Apache 2.2をworkerで動かすためにPerlからRubyからすべてスレッド付きでリビルドしたりと、稼働中のサーバで700以上のパッケージを入れ直す。おまけにその作業の真っ最中にgettextが更新されて共有ライブラリバージョンがbumpされてしまい、さらにビルドタスクが大量追加。かなり大掛かりなことになってしまった。

 ああ、portupgradeを作ってよかった。でも重いよな。Rubyで実装しているからとか、いちいちDBを構築・更新しているからというのもあるのだけど、要点はそこではない。たとえばpkg_replaceなどと何が違うのかと言えば、依存関係の検出に関して厳密であることが最大の違い。

 さっき最新のソースを見て改めて確認したが、portmasterとかpkg_replaceは依存関係としてrun-time dependencyしか見ていない。きちんとbuild-time dependencyを見ようと思ったらビルドオプションとともにmake all-depends-listを叩くしかないわけで、これはかなり重い。逆に、それを省けば早いに決まってる。もし気づいていないのならうかつだが、きっと分かっているだろう。ビルドがこけたならそこで気づいて対処すればいいし、おかしなバイナリができるとか、そういうたまにしか起きなさそうな問題よりも普段のパフォーマンスを取るというのは一つの見識で、潔いと思う。

 なお、run-time dependencyだけを見るにしても、/var/db/pkgはそれをビルドした時点の過去の情報であって、ちゃんと今ビルドするにあたっての依存関係、指定したビルドオプションに応じた依存関係を見るには、やはりその場でPortsに訊く(つまりmake(1)を叩く)しかない。Portupgradeは安全のため、完璧とは言えないけどもかなりの程度それをやっている。だから、これだけ遅い。

 そうした言い分はさておき、これだけportsが増え、入れるパッケージも数百個という段階を迎えてはさすがにつらくなってきた。Portsはmake(1)ベースなので柔軟性はものすごい代わりに、まったくスケールしない。本来、並列化はしやすいはずだが、タスク同士の相互依存性が密なことや、情報を得るためだけにプロセスをバンバン起動して深く再帰するという構造的な問題の前には無力だ。依存関係だけでもメタ情報として軽量に扱えるようにしないと先はないね…。


Categories : Tech