dshimizu/blog/alpha

とりとめのないITブログ

FreeBSD 9.1-RELEASE で ZFS Root FileSystem 環境を構築する

はじめに

昨年末(2012/12/31)に正式アナウンスされたFreeBSD 9.1-RELEASEですが、早々にインストールする機会がありましたので、ZFS Root FileSystem環境となるように構築しました。

FreeBSDはさくらのVPSZFS環境を作って使ってはいましたが、自身でインストールメディアからインストールするのははじめてというレベルの初心者です。ただ、FreeBSDでのZFSはもう十分にプロダクションレベルに達しているとのことで、いろいろと情報もあり、単純にZFS Root FileSystemとして構築するだけであれば、それほど苦労せず出来ました。
今回は、昨年参加させていただいた "第13回 FreeBSD 勉強会" の資料に記されている手順をもとに構築を行いました。

参考資料

以下に実施した手順をまとめましたので記載致します。
なお、インストールはVMware ESXi上に作成したゲストOSへ行いました。

※2013/5/19追記

記載していた手順に不備がありましたので修正しました。

  • "OS起動時に読み込まれる各コンフィグファイルを修正する"の項目でrc.conf作成先PATHの誤りを修正しました。
    (rc.confのPATH:/mnt/root/etc/rc.conf/media/root/etc/rc.confへ修正)

手順

勉強会の資料を基に、大まかに以下の順序で作成を行いました。
現状のFreeBSDインストーラZFSでのインストールに対応していないので、CUIで設定を行っていきます。

  1. FreeBSD 9.1-RELEASEのインストールメディアからブートする
  2. GTPパーティションを作成する
  3. ZFSストレージプールとデータセットを作成する
  4. FreeBSD 9.1-RELEASEカーネル類を展開する
  5. OS起動時に読み込まれる各コンフィグファイルを修正する
  6. zpool.cacheを明示的に作成する
  7. ストレージプール/データセットにプロパティを指定する
  8. ZFSでブート可能かチェックを行う
  9. システムを再起動し、設定を確認する

ゲストOS環境

インストールする仮想マシンのスペックは以下です。
ZFSを利用するにはメモリリソースやディスクの本数など構成に不足があると思いますが、ここではZFS環境構築を優先しています。

仮想プロセッサ数 1コア
メモリサイズ 2GB
NIC アダプタ タイプ E1000
SCSI コントローラ LSI Logic SAS
ディスクサイズ 200GB HDD*1個

※SCSコントローラに準仮想化を選択したいところでしたが、非推奨となっており認識されませんでした。
※仮想NICバイスについてはVMXNET2も選択してみましたが、FreeBSD 9.1では認識されませんでした。

FreeBSD 9.1-RELEASEでZFS Root FileSystem環境を構築する

FreeBSD 9.1-RELEASEのインストールメディアからブートする

作成したゲストOSで、インストール用のメディア( FreeBSD-9.1-RELEASE-amd64-dvd1.iso )からブートさせます。 [Enter]を押下して、通常ブートさせます(シングルユーザモードでも構いません)。

[Install]を選択します


[YES]を押下して、キーボードの設定を行います。

使っているキーボードのタイプに合わせて指定します。 ここではJapanese 106を指定しました。

ホスト名を設定します。


インストールするコンポーネントを指定します。

パーティションの設定を行います。ここで[Shell]を選択します。

ここから以下のようにCUIに切り替わりますので、先に記載した資料をもとにZFSの設定を行います。

GPTパーティションを作成する

新規にGPTパーティションを作成します。
VMware ESXiから認識されるLSI Logic SASのデバイス名は/dev/da0でしたが、ここは環境に合わせて読み替えてください。

# gpart create -s gpt /dev/da0
da0 created

最初のパーティションにブートパーティションfreebsd-bootを作成します。 ここには/boot/pmbr(約512B)と/boot/gptzfsboot(約40KB)が読み込まれることになるため、その分だけ確保しておけば良いのですが、念のため64KB確保しています。 なお、LBA(論理ブロック・アドレシング)34がディスク上の最初に使用可能なセクタですので、-b 34としています(省略可)。


# gpart add -s 64K -b 34 -t freebsd-boot -l /boot/boot0 /dev/da0
da0p1 added

2番目のパーティションスワップパーティションfreebsd-swapを作成します。 スワップサイズは1GBとしておきます。


# gpart add -s 1G -t freebsd-swap -l swap0 /dev/da0
da0p2 added

3番目のパーティションZFSファイルシステムパーティションfreebsd-zfsとして作成します。


# gpart add -t freebsd-zfs -l disk0 /dev/da0
da0p3 added

ブートローダーへの書き込みを行います。
GPTでは、FreeBSDのブートシーケンスはBIOS→pmbr→gptzfsboot(ZFSの場合)/gptufsboot(UFSの場合)→/boot/loader→kernelとなっているようなので、-bオプションでブートストラップコードを含むファイル/boot/pmbrを指定し、-pオプションでパーティションに書き込まれるブートストラップコード/boot/gptzfsbootを指定し、-iオプションの引数で最初のパーティションに書き込むように指定します。


# gpart bootcode -b /boot/pmbr -p /boot/gptzfsboot -i 1 /dev/da0
bootcode written to da0
パーティション作成失敗時の対応
パーティション作成の手順に失敗した場合は、以下の手順でディスクパーティション情報を削除できます。

# gpart delete -i 1 /dev/da0
da0p1 deleted
# gpart delete -i 2 /dev/da0
da0p2 deleted
# gpart delete -i 3 /dev/da0
da0p3 deleted
# gpart destroy /dev/da0
da0 destroyed
ZFSストレージプールとデータセットを作成する

ZFSストレージプールを作成します。
メディアからブートしているため/には書き込めないので、代替ルートディレクトリとして/mediaを指定します。 これにより、プール内のすべてのマウントポイントの先頭にこのディレクトリが付加されます。


# zpool create -f -o altroot=/media rpool /dev/gpt/disk0

メモリ搭載量が4GB以下の場合はZFSのプリフェッチ機能がデフォルトで無効になっている旨のメッセージと、ZFSファイルシステム、ストレージプールのバージョンが表示されます。
ZFSのプリフェッチ機能とは、ファイル読み取りパターンから一部のファイル読み取りを予測することでIO待ち時間を削減する機能です。
有効にしたい場合はメッセージのとおり、 /boot/loader.conf 内に vfs.zfs.prefetch_disable=0を追加してください。


ZFS NOTICE: Prefetch is disabled by default if less than 4GB of RAM is present to enable,
add "vfs.zfs.prefetch_disable=0" to /boot/loader.conf.
ZFS filesystem version 5
ZFS storage pool version 25

データセットを作成します。ここではSolaris10のようなデータセット構成にするため、以下のようなデータセットにしています。 他にも必要なデータセットがあれば、作成します。


# zfs create rpool/ROOT
# zfs create rpool/ROOT/FreeBSD

ブートに利用するデータセット(ZFSファイルシステム)を設定します。ここではrpool/ROOT/FreeBSDを設定します。 ここで設定したデータセットZFSルートファイルシステムとなります。


# zpool set bootfs=rpool/ROOT/FreeBSD rpool

現時点での各データセットとそのマウントポイントは以下のようになっております。 /mediaを代替ルートディレクトリとしていますので、すべてのマウントポイントの先頭に/mediaが付与されています。


# zfs list
NAME USED AVAIL REFER MOUNTPOINT
rpool 178K 198G 31K /media
rpool/ROOT 62K 198G 31K /media/ROOT
rpool/ROOT/FreeBSD 31K 198G 31K /media/ROOT/FreeBSD
FreeBSD 9.1-RELEASEカーネル類を展開する

ベースシステム、カーネルソースコードを、ZFS ルートファイルシステムのマウントポイントである/media/ROOT/FreeBSD配下へ展開します。


# tar xzpf /usr/freebsd-dist/base.txz -C /media/ROOT/FreeBSD

# tar xzpf /usr/freebsd-dist/kernel.txz -C /media/ROOT/FreeBSD

# tar xzpf /usr/freebsd-dist/src.txz -C /media/ROOT/FreeBSD
OS起動時に読み込まれる各コンフィグファイルを設定する

カーネルバイナリを展開後、/media/ROOT/FreeBSD配下にFreeBSDの各ディレクトリが作成されますので、ZFS用にコンフィグファイルを設定していきます。 まず、システム起動時にZFS関連モジュールを読み込むように、loader.confzfs_load="YES"を設定します。 vfs.root.mountfromにはZFSルートファイルシステムとなるデータセットを指定します。


# echo 'zfs_load="YES"' >> /media/ROOT/FreeBSD/boot/loader.conf

# echo 'vfs.root.mountfrom="zfs:rpool/ROOT/FreeBSD"' >> /media/ROOT/FreeBSD/boot/loader.conf

システム起動時にZFSが有効になるようにrc.confを設定します。


# echo 'zfs_enable="YES"' >> /media/ROOT/FreeBSD/etc/rc.conf

ZFS管理ではないswapデバイスの設定を/etc/fstabに記載します。


# echo "/dev/da0p2 none swap sw 0 0" > /media/ROOT/FreeBSD/etc/fstab
zpool.cacheを明示的に作成する

ZFSファイルシステムを一度アンマウントします。


# zfs umount -a

作成したpoolをexportし、再度importします。
zpool.cacheはOS起動時に読み込まれ、ストレージプールを認識するために利用されるファイルで、import時にはzpool.cacheファイルを/tmp上に作成するように指定します。これは、本来/boot/zfs配下へ作成されるこのファイルが、この時点では該当ディレクトリに書き込めないため、暫定的に/tmpへ作成するようにしています。


# mount -t tmpfs tmpfs /tmp

# zpool export rpool

# zpool import -o cachefile=/tmp/zpool.cache -o altroot=/media rpool

/tmp/zpool.cacheファイルをコピーします。


# cp -p /tmp/zpool.cache /media/ROOT/FreeBSD/boot/zfs/
ストレージプール/データセットにプロパティを指定する

ストレージプールと同名のデータセットrpoolはマウントしないようにし、その配下のデータセットrpool/ROOTlegacyへ、rpool/ROOT/FreeBSD/へマウントするようにマウントポイントを指定します。
※他にもデータセットを作成している場合は、ここで全てマウントポイントを指定します。


# zfs set mountpoint=none rpool

# zfs set mountpoint=legacy rpool/ROOT

# zfs set mountpoint=/ rpool/ROOT/FreeBSD

指定したマウントポイントを確認します。


# zfs get -r mountpoint rpool
NAME PROPERTY VALUE SOURCE
rpool mountpoint none default
rpool/ROOT mountpoint legacy local
rpool/ROOT/FreeBSD mountpoint /media local
ZFSでブート可能かチェックを行う。※これは飛ばしても構いません。

FreeBSD 9.1より、ZFSでブートが可能かをチェックするスクリプトが導入されたようですので、それをビルドしてチェックを行います。 下記のコマンドでビルドします。


# cd /media/usr/src/tools/tools/zfsboottest

# make && make DESTDIR=/media install

以下のような出力があります。


Warning: Object directory not changed from original /usr/src/tools/tools/zfsboottest
ln -sf /usr/src/tools/tools/zfsboottest/../../../sys/i386/include machine
cc -O1 -I/usr/src/tools/tools/zfsboottest/../../../sys/boot/zfs -I/usr/src/tools/tools/zfsboottest/../../../sys/cddl/boot/zfs -I. -fdiagnostics-show-option -W -Wextra -Wno-sign-compare -Wno-unused-parameter -Werror -std=gnu99 -fstack-protector -c zfsboottest.c
cc -O1 -I/usr/src/tools/tools/zfsboottest/../../../sys/boot/zfs -I/usr/src/tools/tools/zfsboottest/../../../sys/cddl/boot/zfs -I. -fdiagnostics-show-option -W -Wextra -Wno-sign-compare -Wno-unused-parameter -Werror -std=gnu99 -fstack-protector -lmd -o zfsboottest zfsboottest.o
install -s -o root -g wheel -m 555 zfsboottest /usr/bin
install -o root -g wheel -m 555 zfsboottest.sh /usr/bin/zfsboottest.sh

チェックスクリプトを実行します。


# env PATH=$PATH:/media/usr/bin sh ./zfsboottest.sh rpool

以下のような、ZFSルートファイルシステムに指定しているデータセットrpool/ROOT/FreeBSDlegacyにマウントするようにメッセージが出ます。


The "mountpoint" property of dataset "rpool/ROOT/FreeBSD" should be set to "legacy".

legacyは従来通り/etc/fstabで管理を行う設定で、FreeBSDZFSを使う場合、ZFSの自動マウントが制御できないなどの問題回避のためにルートファイルシステムlegacyでマウントすることが推奨されているようです。
今回はSolaris10のようなデータセット構成としてルートファイルシステム/にするため、この作業は飛ばします。実施しなくても手順に誤りがなければ問題なく起動します。

実施する場合

# zfs set mountpoint=legacy rpool/ROOT/FreeBSD (チェックスクリプト実行時の出力メッセージの通りにrpool/ROOT/FreeBSDのマウントポイントをlegacyへ変更)
システムを再起動し、設定を確認する

リブートし、OSが正常に起動することを確認します。


# sync;sync;sync

# shutdown -r now

ログインし、パーティションやストレージプール、データセットを見ると以下のようになっております。

パーティション構成

# gpart show
=> 34 419430333 da0 GPT (200G)
34 128 1 freebsd-boot (64k)
162 2097152 2 freebsd-swap (1.0G)
2097314 411041597 3 freebsd-zfs (199G)
ZFSストレージプール構成

# zpool status
pool: rpool
state: ONLINE
scan: none requested
config:

NAME STATE READ WRITE CKSUM
rpool ONLINE 0 0 0
gpt/disk0 ONLINE 0 0 0

errors: No known data errors
ZFSデータセット構成

# zfs list
NAME USED AVAIL REFER MOUNTPOINT
rpool 1.31G 197G 31K none
rpool/ROOT 1.31G 197G 32K legacy
rpool/ROOT/FreeBSD 1.31G 197G 1.31G /

以上で、FreeBSDでのZFS Root FileSystem環境が構築できました。
※続いて、OSの設定を行う必要がありますが、ここでは割愛します。

おわりに

以上でFreeBSD 9.1-RELEASEでのZFS Root環境の構築は完了です。
ARCやZIL、ミラー、RAID-ZといったZFSの機能を生かす設定などは全然出来ておらず、FreeBSDもまだまだ初心者ですが、これからいろいろ触れていきたいと思います。