つれづれなる日記 @ maoo.jp

退屈な日々をより退屈な文章でだらだらと

「カスタマイズ」vs.「安全第一」

補足
http://d.hatena.ne.jp/maoo/20090912/1252806106

(前書き)

 最初のところでリンクしてあるが、"MacBook Pro"さんでのLeopardな"Mac OS X"環境における"dynamic_pager"とスワップファイルに関するカスタマイズのことについて、ちょっと前に書いたことがある。だが、それを行うことによる問題点が本日になって発見されたので、まずは補足情報その他としてここに新たに書いておくことにしたわけである。例によって自分のためのメモみたいなものなので、公開したところでどうということでもないかもしれないが。

カスタマイズで発生する問題

 "/System/Library/LaunchDaemons/com.apple.dynamic_pager.plist"を改変し、"/sbin/dynamic_pager"のオプションとして"-H","-L","-S"を明示的に指定することが可能であり、これにより、システム標準では可変であるスワップファイルのサイズを固定にすることができる。しかしその結果として、「システム起動時(もしかしたらシステム終了時)には古いスワップファイルを自動的に消去・削除する」という行われるべき処理が実行されなくなってしまう現象が発生することに気づいた。
 ちょっと昔のバージョンのOS環境においては、その処理は"/private/etc/rc"(シェルスクリプト)が担当しており、スワップファイルである"/private/var/vm/swap*"を消去した後に"dynamic_pager"を起動していた。現在の環境であるとlaunchdが"dynamic_pager"を起動しているわけだが、それを定義しているファイル"com.apple.dynamic_pager.plist"では、すでにあった古いスワップファイル"/private/var/vm/swapfile*"に関する処理についての指示・指定が特になされていないようだ。
 いったいどこでどなたがこの処理を担当することになっているのか、いろいろと調べてみてもけっきょくはわからなかった。ただ、カスタマイズ前にはこのような現象はなかったように思えたため、まずは変更前の環境に戻した上で動作を確認してみたところ、きちんと清く正しい処理が行われるようになった。つまり、「古いスワップファイルを削除する処理は"dynamic_pager"が(起動直後に)実行するが"-H","-L","-S"のオプションを指定するとそれが行われなくなる」と考えるのが妥当であろう。
 ところで、古いスワップファイルが残っていたからどうなのか…というと、それでシステムが誤作動するようなことはたぶんないはずだが*1、とりあえず気持ちがよくないということで。過去にいっぱいスワップファイルが誕生してしまっていたことが一度でもあると、同じファイル名がまた使用されるまでHDDの中にずっと残留するということになるからね。しかも存在している意味はなにもないわけだし、容量的にはかなりの無駄が生じることにもなる。嬉しくない。

解決策の模索

launchdにて対応させる

 "com.apple.dynamic_pager.plist"中の記述でスワップファイル削除の処理もさせる。

  • 可能であれば楽だし清く正しいとは思うが、仕様的に*2無理そう。このファイルはシェルスクリプトでもないし、許される記述の範囲でそのような処理は実現できそうもないように思える。
独自のシェルスクリプトにて対応させる

 "com.apple.dynamic_pager.plist"での指定により独自のシェルスクリプトを実行させ、その中でスワップファイルの削除と"dynamic_pager"の実行を行う。

  • スワップファイルに関する一連の処理を一つの場所に記述できるため、情報が分散せず処理が集中しわかりやすい。
  • 独立した独自のファイルが発生してしまう。個人的な環境だから強行してもいいだろうが、OSのバージョンアップの時などにまた面倒なことが発生する危険性は高くなる。
他のシェルスクリプトにて対応させる

 システム起動時に実行される"/etc/rc.local"やシステム終了時に実行される"/etc/rc.shutdown.local"なりで、古いスワップファイルの削除を担当させる。

  • スワップファイルがあるディレクトリーのPATH情報などが複数の場所に分散してしまう。それでは間違いが発生しやすくなるし美しくない。
  • launchdの機構から考えて、「"rc.local"と"dynamic_pager"の実行はどちらが先か」「"rc.shutdown.local"の実行と"dynamic_pager"のkillはどちらが先か」などについては、状態により順番が前後することすらあるかもしれないし*3、厳密に支配もできないだろうし*4、故意にタイミングをずらすような行為は危険だと考えられる。よって、これらの状況を考慮した上でなんとか"dynamic_pager"の起動前にスワップファイルを消去しておくか、あるいはfindコマンドを利用してタイムスタンプから判定し「新しいスワップファイル以外を消去」*5などとやらなければならなくなる。どうあれあまり好ましいやり方でもない。
"dynamic_pager"をソースコードから改変して運用する

 オプションに関わらずスワップファイルがきちんと削除されるように改変する。

  • 面倒だし危険もある。やりたくない。
"dynamic_pager"そのものをDisabledにする

 Daemonそのものを起動しないようにして、新たなスワップファイルが生成されることから阻止する。

  • 搭載メモリーがせめて4GB以上になってから考えたい。
  • そもそもそういう環境はたぶんOSにいやがられそうに思えるし、ならばやらないほうが総合的に正解であると思う。
その他いろいろ

 とりあえず欠点がないプランは一つも思いつかなかった…。

結論:あきらめる

 次のバージョンのOSを導入する日がそれほど遠くないかもしれないのだし、ここで苦労して時間をかけて満足できる解決策をひたすら考えるのもわりと無駄かもしれない。また、OS移行の時に苦労する可能性があるような改変は、本当に必要な最低限のものだけにしておきたい。よって、"dynamic_pager"に関する前回のカスタマイズについてはやめることにした。ちょっと残念ではあったのだが、もともと「それほど面倒でもないなら好みの状態にしたい」程度の考えだったのだし、大きな問題ではあるまい。
 カスタマイズについては改変前後のデータをすべて保存することにしているので、そこからのファイルのコピーだけで作業はとっとと完了し、きれいさっぱりシステム標準の状態に戻っていった。こういう作業を行う時には、とにかく用心して安全第一の主義を徹底しておいたほうが身のためだと思う。いやまあ、本当に安全第一ということであれば、システム標準の状態からとにかくなにも変更しないのが一番ではあると思うのだが、ええとその、それじゃつまらないし。

新しいOSでは進化しているのか?

 さて、"Snow Leopard"ではこのあたりの環境はどんなことになっているんだろう。そういえば、別パーティションスワップファイルを運用することくらい、いいかげん楽にできるようにしてくれたっていいような気がするのだが。けっこうニーズもあるようだし。それから、スワップファイルのサイズを固定化できるとかファイル数の上限を設定できるとか、そういうこともやってくれないかなあ。仮想メモリーまわりの仕様については、もうちょっとエレガントにしてほしいものだとずっと思っているんだが。

*1:新たなスワップファイルの生成をしようとして、しかしその名称のファイルがすでにあった場合となれば、そこでunlink()くらいはしてくれるだろう。いくらなんでも。

*2:参考 `man 5 launchd.plist`

*3:そもそもlaunchdの目標の一つは、それぞれのタスクをできるだけ非同期そして並列で実行させて効率を上げることにあるはず。これがブート(boot)の高速化にかなり貢献しているのだろう。

*4:参考 `man 5 launchd.plist`

*5:参考 `man 1 find`