次に/varが挙げられます。/varの中にもシステム個有と言えないこともない情報が ありますが、ほとんどが標準値を定めていて後はホストごとに変更されるはずの ものばかりです。だいたい/varという名前からして、常に変更される可能性がある ものが集まっているはずです。ここはディレクトリごとホスト個有だと考えて 良いでしょう。
最後がそれ以外のhome directoryなどです。これは一つのディレクトリにまとめて しまいましょう。私は/local/にしています。
さて整理すると、以下のようになります。
/ ルートパーティション(全ホストで共通) /usr アプリケーションなど(全ホストで共通) /etcの一部 /etcのうちホスト個有の情報 /var ホストごとに異なる。 /local/ homeなど。ホストごとに異なる。
そこでunion file systemを使ってこれを解決します。
最初に/usr/local/etc/を/etc/に下に移動しなければいけません。例えば /etc/usr.local.etc/とかいう名前にしてみましょう。そしてsymbolic linkを作り ます。
# mv /usr/local/etc /etc/usr.local.etc # ln -s /etc/usr.local.etc /usr/local/etc
そして、上記のように分離した情報を、別のパーティションに置きます。 こういう方針の下で作ったdisklabelとfstabが、例えばこんな感じ。
disklabel: 8 partitions: # size offset fstype [fsize bsize bps/cpg] a: 262144 0 4.2BSD 0 0 0 # (Cyl. 0 - 16*) b: 786432 262144 swap # (Cyl. 16*- 65*) c: 12723480 0 unused 0 0 # (Cyl. 0 - 791) e: 4194304 1048576 4.2BSD 0 0 0 # (Cyl. 65*- 326*) f: 8192 5242880 4.2BSD 0 0 0 # (Cyl. 326*- 326*) g: 1048576 5251072 4.2BSD 0 0 0 # (Cyl. 326*- 392*) h: 6423832 6299648 4.2BSD 0 0 0 # (Cyl. 392*- 791*) fstab: # Device Mountpoint FStype Options Dump Pass# /dev/ad0s3b none swap sw 0 0 /dev/ad0s3a / ufs rw 1 1 /dev/ad0s3h /local ufs rw 2 2 /dev/ad0s3f /u ufs rw 2 2 /dev/ad0s3e /usr ufs rw 2 2 /dev/ad0s3g /var ufs rw 2 2 /u/etc /etc union rw 0 0
BSD/OS版PICKLESでは/usrはhパーティション固定だったので、少し気持ち悪いの ですが、FreeBSDのインストーラのdisklabelエディタではディスク内の順番と パーティション番号を好きなように編集することが出来ないので、我慢しましょう。
さて、次にこうして分離した内容をちゃんと機能するようにしなければいけません。
そのためにFreeBSDで必要なのは/etc/rcの編集です。ここで編集するのはunion mount
する前のルートパーティションのファイルなので注意してください。編集する内容は、
mountを実行した後で、再度/etc/rc.confの読みこみを行なうということです。
FreeBSD 4.5-RELEASEの/etc/rcに対するpatchはこんな感じになります。
*** rc~ Mon Jan 28 22:13:17 2002 --- rc Mon Feb 25 13:48:19 2002 *************** *** 213,218 **** --- 213,226 ---- ;; esac + # If there is a global system configuration file, suck it in. + # + if [ -r /etc/defaults/rc.conf ]; then + . /etc/defaults/rc.conf + source_rc_confs + elif [ -r /etc/rc.conf ]; then + . /etc/rc.conf + fi adjkerntz -i
ここまでの内容を、インストール時の手順に照らし合わせておさらいします。
問題になるのは、fstabを参照するプログラムで、これを 調べてみると、dump, dumpfs, fsck, fsdb, mount, quotacheck, rdump, swapon, tunefs, umountなどですが、libcに含まれるgetfsentなどの関数で fstabを参照しているので、根元的にはこれです。
やらないといけないのは、/etc/fstabを見に行こうとしたときに、/etc/fstabと /etc/fstab.userdiskという二つのファイルをマージした内容を参照してくれる ようにすることです。ルートパーティションの/etcには/u/etc/fstab.userdiskへの symbolic linkでfstab.userdiskを作って置きます。こうすることで、/etcの上に union mountされている状態でもされていない状態でもfstab.userdiskを正しく 参照できることになります。
これを実現するために、/usr/src/lib/libc/gen/fstab.cを修正します。
パッチはこれです。FreeBSD 4.6-RELEASE用のパッチ
ですが、このソースは4.3BSDからほとんど変わっていないようなので、すべての
FreeBSDに適用可能でしょう。/sbin/fsckや/sbin/mountなど起動時の処理に関って
くるものはstatic linkされているので、libcのshared libraryを置き換えただけ
では不充分で、必要なプログラムを再compileする必要があります。
(注: とりあえずmountコマンドでだけ動作確認しました)
次に作る必要があるのが checkuserdisk というプログラムで、こいつは
ユーザディスクを探しだして、その中の/uに相当するパーティションを/uに
mountするという処理をします。
BSD/OS版PICKLESでは同じ名前のプログラムがあって、こいつは/etc3を探して
mountして、そのパーティションのデバイス名を返すプログラムでした。/etc3を
/uに置き換えて、あとは同じ仕様で良いのではないかと思います。
ここで、整理しつつcheckuserdiskのやるべき処理を挙げると、以下のように
なります。
BSD/OS版PICKLESでは、systemdiskとuserdiskのfsck, mountを別の処理でやって いたのですが、前述のような改造を加えたfsckとmountであれば、もっと楽に なります。ただし、/uをmountしてから/etcのunion mountを実行しなければならない ため、ここの部分を以下のどちらかの方法で行なう必要があります。
またパーティション構成などをPICKLES的にするために、インストーラの改善が 必要になります。
更にPICKLESにするためには、userdiskのupdate scriptなども作らないといけません。 ここらへんは手間の問題です。