2017/04/01 追記: GPTラベルを利用するように改変。
FreeBSD 10のインストーラから zfs root 対応なので苦もなく zfs 構成にできるが、もっと前からアップグレードを繰り返して運用している FreeBSD サーバなどを zfs に鞍替えするのは腰の重い仕事である。 だが、昔に比べると FreeBSD での zfs ブートの仕組みが整理されていて案外簡単に進む。
ストーリーとして
的な流れを仮定する。
新HDDを接続する。外付けでもOK。あとで古い HDD を外してデバイス名が変わっても平気。新HDDを繋いだデバイスが da0 だとする。
別で使ってたHDDなら既存パーティションをふっとばす。
dd if=/dev/zero of=/dev/da0 count=64
GPTで行くぜい。
gpart create -s gpt da0
gpart add -l bt0 -t freebsd-boot -s 512k da0 gpart add -l sw0 -t freebsd-swap -s 2g da0 gpart add -l z00 -t freebsd-zfs da0
-l オプションでラベルを打っておくことで、デバイス番号がずれても パーティション構成の分かりやすさが保たれるようにする(2017/4/1)。 freebsd-zfs のパーティションは -l z00 としたので、/dev/gpt/z00 でアクセスできるようになる。
gpart bootcode -b /boot/pmbr da0 gpart bootcode -p /boot/gptzfsboot -i 1 da0
FreeBSDインストーラに倣ってブート領域=512KB、 swap=2GB、zfs=残り全部、の3つを切った。
現行の ufs 環境で既にマウントしているファイルシステムとぶつからないよう altroot を指定してプールを作成すると、再起動するまでは altroot を仮のルートディレクトリとしてマウントされる。
altrootを /mnt とする。
zpool create -o altroot=/mnt zpool0 gpt/z00
これでいったん /mnt に全ての領域がマウントされる。
たとえば現行環境が /, /var, /usr のパーティション構成で、 それと1対1対応するように作成するなら以下のようになる。
zfs create -o quota=4g -o mountpoint=/ zpool0/ROOT zfs create -o quota=4g -o mountpoint=/var zpool0/var zfs create -o quota=80g -o mountpoint=/usr zpool0/usr
どのくらい細かく切るかはお好みで。
tar --one-file-system でもなんでもよいが、rsync だと -x と -R オプションを利用してこんな感じか。
rsync -avxHR / /var /usr /mnt
現行環境から新環境にコピーしたい ufs パーティションのマウントポイントをコピー元にして全てコピーする。 その他オプションの意味はman参照。
起動後の /boot/ をどこから探せばよいかを zpool 自身に埋め込んでおく必要がある。今回の場合は zpool0/ROOT としたので以下のように set しておく。
zpool set bootfs=zpool0/ROOT zpool0
コピーしたファイルを zfs 環境に適したものに修正する。
echo zfs_load=YES >> /mnt/boot/loader.conf echo zfs_enable=YES >> /mnt/etc/rc.conf
fstabを修正する。
vi /mnt/etc/fstab
新fstabからufsマウントの行を全部削る。swap は……この流れ、つまり古HDDを全て外して新HDDをSATAに繋ぐ想定だと ada0p2 ということになるが、せっかくzfsにするのだから swap パーティションをzvolにするのもよかろうが、 メモリの少ない状況で ZFS Swap を使うと今一つのようである(※ RootOnZFS #ZFS Swap Volume) ので、普通にGPTパーティションにするのが無難か。
リブートしてブートデバイスを新HDDとして起動してみる。 ちょこちょこ凡ミスが出るだろうが直せばzfs運用に移行できるはず。 確認できたらshutdown後古いHDDを外して新HDDに置き換えてまた起動。
おっと、新HDDでミラーしたい。あとから気づいても簡単。 デバイスプールを構成するディスクに別ディスクを "attach" するだけ。 今回の例で、新HDDを外付けから内蔵SATAに繋ぎ換えたと仮定すると、 以下のようになっているはず。
zpool status zpool0
pool: zpool0
state: ONLINE
scan: none requested
config:
NAME STATE READ WRITE CKSUM
zpool0 ONLINE 0 0 0
ada0p3 ONLINE 0 0 0
errors: No known data errors
構成ディスクは ada0p3 で、このディスクに同じサイズのものを attach すればよい。同サイズのHDDが ada1 に入っていて、同じように GPT を切ったとすると、ada1p3 がミラー相手になるので以下のようにする。
zpool attach zpool0 ada0p3 ada1p3
すぐ resilver が始まり、ミラー化完了。
今回、実例を元に文章化したが、書き漏らしがあるかもしれないので注意されたい。 疑問がある場合は御一報御質問を。good luck!