FreeBSD GPT+ZFS boot on 9.0-CURRENT

FreeBSDで、GPT+ZFSを使ってブートする環境を構築したんだけど、だいぶ試行錯誤したので自分用メモ。
実はまだ環境構築終わってないんだけど、とりあえず起動して環境準備はほぼ終わっているのでこれでいいかな。
なにせ、ufs+ZFSでブートするとか、GPTの話は探すとあるんだけど、GPT+ZFSで環境を1から仕込み、さらにいろいろとやろうとすると途端に資料がないんだよねー。ってことでメモ書き。

ここでの前提としては、新規のHDDに、USBメモリからFreeBSDを無理やりインストールすることを想定しているので、しくってもいいHDDでやりましょう。現に私も試行錯誤を数日やりましたので。

1. まず、FreeBSD 8か9の環境を準備して、/etc/make.conf に、LOADER_ZFS_SUPPORT=yes とでも書いて、make buildworld & make buildkernel しとく。
2. 適当なUSBメモリを準備してUSBメモリの中に(USBを/dev/da0s1 とでもすると)作った環境を入れる。
なんか適当なツールでブートコードを書いて、

# mount -t ufs /dev/da0s1a /mnt
# make installworld DESTDIR=/mnt
# make installkernel DESTDIR=/mnt
# mergemaster -D /mnt

とりあえずこれでいいかな。必要なZFS関係のモジュールは勝手にロードしてくれるから。

3. USBメモリでブートする。この時点だと、rootでログインできないので、single user modeで立ち上げて、適当にrootのパスワードを付けておけば、うっかりマルチユーザーモードに行っちゃっても大丈夫かな。

4. 外付けのHDDをブートできるようにする。インストールされているHDDがad4で認識されていれば、

# dd if=/dev/zero of=/dev/ad4 bs=1M count=1000
位やっておいて(この辺は超適当)、先頭領域をぶっ潰す。新規のHDDなら必要ないけど、既存のHDDを転用する場合は、先頭のセクタが悪さをすると思うので、忘れないでやっておく。

# /sbin/gpart create -s GPT ad4
ad4 created <- これで、ad4をGPTとして作成してくれる。

# /sbin/gpart add -b 34 -s 128 -t freebsd-boot ad4
ad4p1 added <- これで、HDDの34セクタ目から128セクタ、FreeBSDのブートコード用に確保される。

# /sbin/gpart show ad4
=> 34 125045357 ad4 GPT (60G)
34 128 1 freebsd-boot (64K)
162 125045229 - free - (60G)
こんな感じになる。

# /sbin/gpart add -b 162 -s 125045229 -t freebsd-zfs ad4
ad4p2 added <- これで、HDDの162セクタ目から125045229セクタ(最終セクタ)までが、FreeBSDのZFS領域として確保される。結果、こんな感じになる。

# /sbin/gpart show ad4
=> 34 125045357 ad4 GPT (60G)
34 128 1 freebsd-boot (64K)
162 125045229 2 freebsd-zfs (60G)
# /sbin/gpart bootcode -b /boot/pmbr -p /boot/gptzfsboot -i 1 ad4
ad4に対して、ブートコードをインストールする。いわゆるboot0(最初のセクタのブートコード)に/boot/pmbrを、FreeBSDのブートに、/boot/gptzfsbootをad4p1にインストールすることになる。これでブートコードのインストールと領域確保までは完了。

5. ad4に対してFreeBSDのいわゆるパーティーション設定をする。zpool コマンドとzfs コマンドを使うんだけど、普通は/boot/kernel/zfs.ko と、/boot/kernel/opensolaris.ko があると思うから、勝手にロードしてくれるんだけど、もしなければ入れてください。

# zpool create tank /dev/ad4p2
ad4p2 がFreeBSDのzfs パーティーションで、こいつにtank って名前を付けると思えばいいかな。

# zfs create tank/usr

# zfs create tank/var

# zfs create tank/tmp

# zfs create tank/home
ここまでがいわゆるパーティーションを作る、的な感覚。ufsみたいに実際にパーティーションが分かれるわけじゃないけど、各領域ごとに圧縮の設定とか、いろいろできるので、好きに分ければいい。

# zfs create -V 1gb tank/swap
こいつがswap パーティーション。こっちも適当な大きさで。

# zfs set org.freebsd:swap=on tank/swap
システム起動時にswap領域をmountするためのおまじないだそうで。

6. USBメモリ -> HDDにファイルをコピー
ここまですると、/tankってディレクトリができて、その下にusr,var,tmp,home ができてると思うので、USBメモリの中のファイルを丸ごと/tank にコピー。

7. /tank のブート周りの修正
/tank/boot/loader.conf を、zfs bootできるように書き換える。
zfs_load="YES"
vm.kmem_size="512M"
vm.kmdm_size_max="512M"
vfs.zfs.debug=1
vfs.zfs.prefetch_disable=0
vfs.root.mountfrom="zfs:tank"
を書く。
vfs.zfs.debug=1 は、ZFS デバッグ用なので、トラブった時のために一応入れておく。
vfs.zfs.prefetch_disable=0は、なんかi386はdisableになるって警告が出るので入れた。amd64なら問題ないのかな。
vfs.root.mountfrom="zfs:tank"は、さっき設定したtankからカーネルを読み込むって設定。

次に、/tank/boot/rc.confに、
zfs_enable="YES"
を書く。他にも設定があると思うのでそこは適宜。

# mkdir /boot/zfs
# zpool export tank && zpool import tank
# cp /boot/zfs/zpool.cache /tank/boot/zfs

まぁ、これは6. の時点で済んでいるはずなのでやらなくてもいいんだけど、念のため。もしここで変なエラーが出るようなら、何かしくっているので4. からやり直した方がいいと思う。

8. /tank/etc/fstab の設定
ZFS bootしたときの/etc/fstabを書く。/tankにマウントされているので、実際に編集するのは、/tank/etc/fstab。

# Device Mountpoint FStype Options Dump Pass#
tank / zfs rw 0 0

これだけあれば、他のマウントポイントは、ブート時にzfs mount -a 相当のことをやってくれるんで、特に書く必要はなし。

9. ZFS boot用の設定
# zfs set mountpoint=legacy tank
# zfs set mountpoint=/usr tank/usr
# zfs set mountpoint=/var tank/var
# zfs set mountpoint=/tmp tank/tmp
# zfs set mountpoint=/home tank/home
# zpool set bootfs=tank tank
これで、ZFS bootした時に自動的にmount pointが/usr とか/var になる。なお、このコマンドを発行した時点でmountが自動的にされるようなんで、ちょっと注意がいるかも。

10. ブートの確認
ここまで来たら、リブート -> USBメモリを抜く -> HDDからブートしてみる。これでブートできないとしたら、原因としては、
・インストールされているブートコードが、LOADER_ZFS_SUPPORT 付きでコンパイルされてない
・/boot/pmbr と、/boot/gptzfsboot がちゃんとロードされていない
・/boot/zfs/zpool.cacheの整合性が取れてない
なんかが怪しいかも。

11. TODO
予定では、500GB HDDを2本付けて、1台目のデータを丸々2台目にrsyncでコピーして、疑似RAID1的に使いたいんだけど、zpool.cache が壊れるとなんかtankが見えなくなるし、どうしようかと思案中。この説明もだいぶいい加減なんで、暇になったらちゃんと書きなおします…。

11. 参考URL(だいたいこの辺の情報を複合技で読み解いた(^^; )
Nork's daily how toあたりの、ZFS on GPTネタあたりを中心に。
ZFSメンテナンスの日々 #1
ZFSメンテナンスの日々 #2
ZFSメンテナンスの日々 #3
ZFSメンテナンスの日々 #4
ZFSメンテナンスの日々 #5 ZFS Root 編
ZFSメンテナンスの日々 #6 ZFS なんてオマケです!
ZFSメンテナンスの日々 #7 ZFS Boot 編
ZFS on GPT に挑戦 #1
ZFS on GPT #2

ZFS - FreeBSD Wikiあたりから辿れるところで、
Setting up a ZFS-only system

FreeBSD 7.0のroot ファイルシステムをzfs化

ZFS Tuning Guide
ZFSのチューニングをしようとすると、この辺のページを必読しないと。単純に設定だけいじると、ブート時にkernel panicして大騒ぎになるんだよね。これが9-CURRENTの地雷なのかは不明…。

この記事へのコメント