FreeBSD 8.1-RELEASEでGPTなHDDにZFSでRootを確保してそこからbootする

3TBのHDDが店頭で売られるようになってきたので、おうちファイルサーバの構成を見直した。方針は以下の通り。

サーバはHP ML115 G1でHDDを4台内蔵可能だから、3台でRAIDZを構成して、残りの1台は空きにする予定。swapをZVolじゃなくてGPTに確保するのは、dumpを意識したから。実際にはあまり使わないんだろうけど。

実際の作業

FreeBSDインストーラは、GPTやZFSに対応してないから、作業はすべてFixitモードを使う。USB memstickまたはDVDを用意すること。ハードウェアがUSBからの起動に対応してるなら、USB memstickがおすすめ。

sysinstallが起動したら、OptionsからRescan Devicesを実行して、その後Fixitを選択する。RescanしないとUSB memstickが見つからない罠。以下はVMware Fusion/Player/Workstationあたりで実行することを前提として、ad0/ad1/ad3の3台でRAIDZを構成する例。
まずはまっさらにする。

# dd if=/dev/zero of=/dev/ad0 count=100
# dd if=/dev/zero of=/dev/ad1 count=100
# dd if=/dev/zero of=/dev/ad3 count=100

GPTを構成する。

# gpart create -s gpt ad0
# gpart create -s gpt ad1
# gpart create -s gpt ad3

boot領域を確保、AFT対策として4k境界を意識する。

# gpart add -b 40 -s 128 -t freebsd-boot ad0
# gpart add -b 40 -s 128 -t freebsd-boot ad1
# gpart add -b 40 -s 128 -t freebsd-boot ad3

swap領域を確保、サイズはとりあえず4GB。

# gpart add -b 168 -s 8388608 -t freebsd-swap ad0
# gpart add -b 168 -s 8388608 -t freebsd-swap ad1
# gpart add -b 168 -s 8388608 -t freebsd-swap ad3

ZFS領域を確保、サイズは残り全部。

# gpart add -t freebsd-zfs ad0
# gpart add -t freebsd-zfs ad1
# gpart add -t freebsd-zfs ad3

bootcodeを書き込む。

# gpart bootcode -b /mnt2/boot/pmbr -p /mnt2/boot/gptzfsboot -i 1 ad0
# gpart bootcode -b /mnt2/boot/pmbr -p /mnt2/boot/gptzfsboot -i 1 ad1
# gpart bootcode -b /mnt2/boot/pmbr -p /mnt2/boot/gptzfsboot -i 1 ad3

ZFSのkernel moduleをloadする。

# kldload /mnt2/boot/kernel/opensolaris.ko
# kldload /mnt2/boot/kernel/zfs.ko

poolを作成する、名前はzroot。

# zpool create zroot raidz ad0p3 ad1p3 ad3p3

bootfsを指定する。

# zpool set bootfs=zroot zroot

ファイルシステムを構成する。以下はすべて圧縮を有効にして、tmp, var, usr, homeを作ってるけど、好みでもっと細かく分けてもいいかも。最低限、snapshotを取りたい単位や、圧縮の設定を変えたい単位で分けておく。

# zfs set checksum=fletcher4 zroot
# zfs set compression=lzjb zroot

# zfs create zroot/tmp
# zfs create zroot/var
# zfs create zroot/var/empty
# zfs create zroot/usr
# zfs create zroot/home

インストールする。baseとkernel以外は後からsysinstallを使ってインストールすればOK。うちでは既存システムからの移行だったので、cpioを使ってまるごとコピーした。

# cd /dist/8.1-RELEASE
# export DESTDIR=/zroot
# ( cd base ; ./install.sh )
# ( cd kernels ; ./install.sh generic )
# cd /zroot/boot
# cp -Rlp GENERIC/* /zroot/boot/kernel/

# zfs set readonly=on zroot/var/empty

起動時にZFSを有効にするための設定をする。prefetchはメモリ量との相談で有効にするか決めよう。

# echo 'zfs_enable="YES"' > /zroot/etc/rc.conf

# echo 'vfs.zfs.prefetch_disable="1"' > /zroot/boot/loader.conf
# echo 'vfs.root.mountfrom="zfs:zroot"' >> /zroot/boot/loader.conf
# echo 'zfs_load="YES"' >> /zroot/boot/loader.conf

zpool.cacheを移植する。これやっておかないと、mountrootで失敗する。

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

swapの設定をする。全部で12GB、すげー容量だな。

# echo '/dev/ad0p2 none swap sw 0 0' > /zroot/etc/fstab
# echo '/dev/ad1p2 none swap sw 0 0' >> /zroot/etc/fstab
# echo '/dev/ad3p2 none swap sw 0 0' >> /zroot/etc/fstab

mountpointの修正。

# export LD_LIBRARY_PATH=/mnt2/lib
# zfs unmount -a
# zfs set mountpoint=legacy zroot
# zfs set mountpoint=/tmp zroot/tmp
# zfs set mountpoint=/usr zroot/usr
# zfs set mountpoint=/var zroot/var
# zfs set mountpoint=/home zroot/home

これで完了。Fixitから抜けて再起動すれば、ZFS Root on GPTなFreeBSD 8.1-RELEASEのできあがり。

# exit

最後にメモリの利用状況を見ながら、kmemとarcの容量を設定する。うちは4GBのメモリで以下の設定にしてる。今のところkernel panicはしてない。

vm_kmem_size="1024M"
vm_kmem_size_max="1024M"
vfs.zfs.arc_min="128M"
vfs.zfs.arc_max="384M"

はまりどころ

exportしたpoolからbootできない

bootcodeがpoolを見つけられずに

No ZFS pools located, can't boot

などとおっしゃるので、慌てずFixitを起動して

# zpool import -f zroot

でimportする。

DEGRADEしたpoolからbootできない

bootcodeがpoolを見つけられずに

No ZFS pools located, can't boot

などとおっしゃるので、慌てずFixitを起動してreplaceするなり対応する。
poolがONLINEになったらbootできるようになる。

zpool addしちゃう

addするといわゆるstripeになっちゃうので冗長性がなくなるうえ、元に戻せない。zpoolはreplaceとscrub以外実行しないのが安全。

まとめ

ZFSはメモリが2GB以上ないと窮屈だけど、snapshotやcloneが使いやすいし、resilverも使用ブロックのみだし、圧縮も簡単だし、使い勝手はいいかんじ。運用に慣れてきたら、send/receiveを使った筐体間のバックアップも試してみたい。
ただし"No ZFS pools located, can't boot"と言われたときの絶望感は異常。Fixitにはお世話になるから、1GBのUSBメモリを用意してFreeBSD Fixit専用に確保しておくのがよさそう。あとHDDがたくさんほしくなる。eSATA + Port Multiplierで外付けHDD大量増設するのもおもしろいかも。