ZFS の機能を活用すべく、Oracle Solaris の Live アップグレードで使われるブート環境と同じようなものを FreeBSD 9.1-RELEASE に構築したときのメモです。
Boot Environments とは?
ルートファイルシステムが ZFS となっている Oracle Solaris 11 では、システムの Live アップグレードを容易に行うためにブート環境(Boot Environments、以下 BE)と呼ばれる ZFS のクローンとプロモーションを利用する仕組みがあります。
- ブート環境およびデータセットについて - Oracle Solaris 11.1 ブート環境の作成と管理
- イメージと発行元のプロパティーの構成 - Oracle Solaris 11.1 ソフトウェアパッケージの追加および更新
- beadm(1M) - ZFS ブート環境の管理 - マニュアルページセクション 1M: システム管理コマンド
beadm(1M)
コマンド(python2.6 スクリプト)のオープンソース実装(シェルスクリプト)も FreeBSD の Ports Collection に存在します。
- Setting up Solaris-like boot environments on FreeBSD
- HOWTO: FreeBSD ZFS Madness - The FreeBSD Forums
- beadm - FreeBSD utility to manage Boot Environments on ZFS filesystems
Boot Environments への移行手順
基本的に BSDCan 2012 の資料にある手順通りです。
ここでは最初に作成する BE(以下、基礎 BE)となる既存のルートファイルシステムは rpool ではなく rpool/root から作成します。# zpool get bootfs rpool NAME PROPERTY VALUE SOURCE rpool bootfs rpool/root local # zfs list -o name,mountpoint NAME MOUNTPOINT rpool none rpool/root legacy rpool/root/tmp /tmp rpool/root/usr /usr rpool/root/usr/local /usr/local rpool/root/var /var # zfs list -t snapshot no datasets available事前に beadm コマンドをインストールします。
# cd /usr/ports # make quicksearch name=beadm Port: beadm-0.8.5 Path: /usr/ports/sysutils/beadm Info: Solaris-like utility to manage Boot Environments on ZFS Port: beadm-devel-0.8.99.20121205 Path: /usr/ports/sysutils/beadm-devel Info: Solaris-like utility to manage Boot Environments on ZFS # cd /usr/ports/sysutils/beadm # make install clean
基礎 BE の作成
制御構造を使用するため作業はボーンシェルで行います。
# /bin/shBE を配置する ROOT データセットを作成します。必要に応じて重複排除を有効にします。
# zfs create -o dedup=on rpool/ROOT基礎 BE とするルートファイルシステムとその子孫のスナップショットを作成します。
# zfs snapshot -r rpool/root@snap0ルートファイルシステムのスナップショットから基礎 BE を作成します。
# zfs send rpool/root@snap0 | zfs recv rpool/ROOT/base-be基礎 BE を作成したので不要となったルートファイルシステムのスナップショットを削除します。
# zfs destroy rpool/root@snap0基礎 BE に付随するスナップショットは不要なので削除します。
# zfs destroy rpool/ROOT/base-be@snap0ルートファイルシステムの子孫のスナップショットから基礎 BE の子孫ファイルシステムを作成します。
# zfs list -t snapshot -H -o name | grep '^rpool/root/.*@snap0$' | while read s; do zfs send $s | zfs recv -v `echo $s | sed 's/rpool\/root\/\(.*\)@snap0$/rpool\/ROOT\/base-be\/\1/'`; done基礎 BE の作成に使用したすべてのスナップショットを削除します。
# zfs list -t snapshot -H -o name | grep snap0 | xargs -n 1 zfs destroy -vここまでの作業でデータセットは次のようになっています。
# beadm list BE Active Mountpoint Space Created base-be - - 4.5G 2013-03-25 23:09 # zfs list -o name,canmount,mountpoint NAME CANMOUNT MOUNTPOINT rpool on none rpool/ROOT on none rpool/ROOT/base-be on none rpool/ROOT/base-be/tmp on none rpool/ROOT/base-be/usr on none rpool/ROOT/base-be/usr/local on none rpool/ROOT/base-be/var on none rpool/root on legacy rpool/root/tmp on /tmp rpool/root/usr on /usr rpool/root/usr/local on /usr/local rpool/root/var on /var # zfs list -t snapshot no datasets available
基礎 BE でのブート設定
基礎 BE を /mnt にマウントして、ルートファイルシステムとしてマウントするように loader.conf を書き換えます。
→ストレージプールの bootfs プロパティで指定すればよいのでこの設定は不要です。loader.conf でも指定している場合は該当行を削除します。
# zfs set mountpoint=/mnt rpool/ROOT/base-be # sed -i -e 's/^\(vfs.root.mountfrom="zfs:\).*/\1rpool\/ROOT\/base-be"/' /mnt/boot/loader.conf基礎 BE のデータセットにユーザプロパティを設定します。
# zfs set freebsd:boot-environment=1 rpool/ROOT/base-be継承可能な通常の mountpoint プロパティを保持するように基礎 BE 配下のファイルシステムを設定します。
# zfs list -H -o name | grep ROOT/base-be | xargs -n 1 zfs set canmount=off基礎 BE のマウントポイントを設定します。
# zfs set mountpoint=/ rpool/ROOT/base-be基礎 BE の子孫ファイルシステムのマウントポイントをデータセット名の階層に合わせて設定します。
# zfs list -H -o name | grep ROOT/base-be/ | while read f; do zfs set mountpoint=`echo $f | sed 's/.*base-be//'` $f; done基礎 BE 配下のファイルシステムをマウントできるように設定します。
# zfs list -H -o name | grep ROOT/base-be | xargs -n 1 zfs set canmount=on基礎 BE からブートするようにストレージプールのプロパティを設定します。
# zpool set bootfs=rpool/ROOT/base-be rpool現在のルートファイルシステムを自動マウントしないように設定します。
# zfs list -H -o name | grep ^rpool/root | xargs -n 1 zfs set canmount=noautoここまでの作業でデータセットは次のようになっています。
# beadm list BE Active Mountpoint Space Created base-be R - 4.5G 2013-03-25 23:09 # zfs list -o name,canmount,mountpoint NAME CANMOUNT MOUNTPOINT rpool on none rpool/ROOT on none rpool/ROOT/base-be on / rpool/ROOT/base-be/tmp on /tmp rpool/ROOT/base-be/usr on /usr rpool/ROOT/base-be/usr/local on /usr/local rpool/ROOT/base-be/var on /var rpool/root noauto legacy rpool/root/tmp noauto /tmp rpool/root/usr noauto /usr rpool/root/usr/local noauto /usr/local rpool/root/var noauto /var成功を祈って OS を再起動します。
# reboot
旧ルートファイルシステムの削除
基礎 BE からの起動が確認できたら不要となった旧ルートファイルシステムのデータセットを削除します。
# beadm list BE Active Mountpoint Space Created base-be NR / 4.5G 2013-03-25 23:09 # df -t zfs Filesystem 1K-blocks Used Avail Capacity Mounted on rpool/ROOT/base-be 12015618 382379 11633238 3% / rpool/ROOT/base-be/tmp 11633289 51 11633238 0% /tmp rpool/ROOT/base-be/usr 15413918 3780679 11633238 25% /usr rpool/ROOT/base-be/usr/local 12117408 484169 11633238 4% /usr/local rpool/ROOT/base-be/var 11733357 100118 11633238 1% /var # zfs list -o name,mountpoint NAME MOUNTPOINT rpool none rpool/ROOT none rpool/ROOT/base-be / rpool/ROOT/base-be/tmp /tmp rpool/ROOT/base-be/usr /usr rpool/ROOT/base-be/usr/local /usr/local rpool/ROOT/base-be/var /var rpool/root legacy rpool/root/tmp /tmp rpool/root/usr /usr rpool/root/usr/local /usr/local rpool/root/var /var
# zfs list -H -o name | grep rpool/root | sort -r | xargs -n 1 zfs destroy -v
Jail と組み合わせたシステムのアップデート
以下ページに倣って、FreeBSD のコンテナ型仮想化機構 Jail と BE を組み合わせて FreeBSD 9.1-RELEASE-p1 にアップデートしてみます。
- HOWTO: FreeBSD ZFS Madness - The FreeBSD Forums
- 6.2. Perform Upgrade within a Jail
Jail の設定
ここでの設定は、普段 Jail は使用せず今回のアップデートだけで使用する前提です。
- 普段は使用しないので jail_enable は "NO"
- 名前は updatejail
- マウントポイントは /usr/jails/freebsd-update
- IP アドレスはホストと同じセグメントのもの(例では VirtualBox の NAT)
# mkdir /usr/jailsJail の設定を rc.conf に記述します。
# cat << EOF >> /etc/rc.conf jail_enable="NO" jail_set_hostname_allow="NO" jail_list="updatejail" jail_updatejail_rootdir="/usr/jails/freebsd-update" jail_updatejail_hostname="freebsd-update" jail_updatejail_interface="em0" jail_updatejail_ip="10.0.2.100" jail_updatejail_devfs_enable="YES" EOFJail 内で freebsd-update が正常に動作するように chflags を利用できるようにします。
# sysctl security.jail.chflags_allowed=1 security.jail.chflags_allowed: 0 -> 1 # echo !$ >> /etc/sysctl.conf echo security.jail.chflags_allowed=1 >> /etc/sysctl.conf
アップデート用 BE の作成
アップデート用の BE を作成します。(基礎 BE のクローン)
# beadm create freebsd-9.1p1 Created successfullyアップデート用の BE をマウントします。
# beadm mount freebsd-9.1p1 /usr/jails/freebsd-update Mounted successfully on '/usr/jails/freebsd-update'ここまでの作業でデータセットとマウント状態は次のようになっています。
# beadm list BE Active Mountpoint Space Created base-be NR / 4.5G 2013-03-25 23:09 freebsd-9.1p1 - /usr/jails/freebsd-update 221.0K 2013-03-25 23:34 # zfs list -o name,mountpoint,origin NAME MOUNTPOINT ORIGIN rpool none - rpool/ROOT none - rpool/ROOT/base-be / - rpool/ROOT/base-be/tmp /tmp - rpool/ROOT/base-be/usr /usr - rpool/ROOT/base-be/usr/local /usr/local - rpool/ROOT/base-be/var /var - rpool/ROOT/freebsd-9.1p1 / rpool/ROOT/base-be@2013-03-25-23:34:12 rpool/ROOT/freebsd-9.1p1/tmp /tmp rpool/ROOT/base-be/tmp@2013-03-25-23:34:12 rpool/ROOT/freebsd-9.1p1/usr /usr rpool/ROOT/base-be/usr@2013-03-25-23:34:12 rpool/ROOT/freebsd-9.1p1/usr/local /usr/local rpool/ROOT/base-be/usr/local@2013-03-25-23:34:12 rpool/ROOT/freebsd-9.1p1/var /var rpool/ROOT/base-be/var@2013-03-25-23:34:12 # zfs list -t snapshot NAME USED AVAIL REFER MOUNTPOINT rpool/ROOT/base-be@2013-03-25-23:34:12 43K - 373M - rpool/ROOT/base-be/tmp@2013-03-25-23:34:12 0 - 51K - rpool/ROOT/base-be/usr@2013-03-25-23:34:12 47K - 3.61G - rpool/ROOT/base-be/usr/local@2013-03-25-23:34:12 34K - 473M - rpool/ROOT/base-be/var@2013-03-25-23:34:12 43K - 97.8M - # df -t zfs Filesystem 1K-blocks Used Avail Capacity Mounted on rpool/ROOT/base-be 16764769 382379 16382389 2% / rpool/ROOT/base-be/tmp 16382440 51 16382389 0% /tmp rpool/ROOT/base-be/usr 20163076 3780686 16382389 19% /usr rpool/ROOT/base-be/usr/local 16866559 484169 16382389 3% /usr/local rpool/ROOT/base-be/var 16482507 100118 16382389 1% /var rpool/ROOT/freebsd-9.1p1 16764769 382379 16382389 2% /usr/jails/freebsd-update rpool/ROOT/freebsd-9.1p1/tmp 16382425 36 16382389 0% /usr/jails/freebsd-update/tmp rpool/ROOT/freebsd-9.1p1/usr 20163075 3780685 16382389 19% /usr/jails/freebsd-update/usr rpool/ROOT/freebsd-9.1p1/usr/local 16866559 484169 16382389 3% /usr/jails/freebsd-update/usr/local rpool/ROOT/freebsd-9.1p1/var 16482507 100118 16382389 1% /usr/jails/freebsd-update/var
Jail 環境で freebsd-update を実行
Jail 環境を実行します。
# service jail onestart Configuring jails:. set_hostname_allow=NO. Starting jails: freebsd-update.実行した Jail 環境を確認します。
# jls JID IP Address Hostname Path 1 10.0.2.100 freebsd-update /usr/jails/freebsd-updateJail 環境で freebsd-update を実行します。
# jexec 1 freebsd-update fetch installJail 環境を停止します。
# service jail onestop Stopping jails: freebsd-update.アップデート用の BE をアンマウントします。
# beadm unmount freebsd-9.1p1 Unmounted successfully
アップデートした BE での起動
次回リブート時にアップデートした BE がアクティブになるように切り替えます。(アップデート BE のプロモーション)
# beadm activate freebsd-9.1p1 Activated successfullyここまでの作業で BE とデータセットは次のようになっています。
# beadm list BE Active Mountpoint Space Created base-be N / 31.8M 2013-03-25 23:09 freebsd-9.1p1 R - 4.6G 2013-03-25 23:34 # zfs list -o name,mountpoint,origin NAME MOUNTPOINT ORIGIN rpool none - rpool/ROOT none - rpool/ROOT/base-be / rpool/ROOT/freebsd-9.1p1@2013-03-25-23:34:12 rpool/ROOT/base-be/tmp /tmp rpool/ROOT/freebsd-9.1p1/tmp@2013-03-25-23:34:12 rpool/ROOT/base-be/usr /usr rpool/ROOT/freebsd-9.1p1/usr@2013-03-25-23:34:12 rpool/ROOT/base-be/usr/local /usr/local rpool/ROOT/freebsd-9.1p1/usr/local@2013-03-25-23:34:12 rpool/ROOT/base-be/var /var rpool/ROOT/freebsd-9.1p1/var@2013-03-25-23:34:12 rpool/ROOT/freebsd-9.1p1 legacy - rpool/ROOT/freebsd-9.1p1/tmp /tmp - rpool/ROOT/freebsd-9.1p1/usr /usr - rpool/ROOT/freebsd-9.1p1/usr/local /usr/local - rpool/ROOT/freebsd-9.1p1/var /var - # zfs list -t snapshot NAME USED AVAIL REFER MOUNTPOINT rpool/ROOT/freebsd-9.1p1@2013-03-25-23:34:12 6.92M - 373M - rpool/ROOT/freebsd-9.1p1/tmp@2013-03-25-23:34:12 40K - 51K - rpool/ROOT/freebsd-9.1p1/usr@2013-03-25-23:34:12 23.4M - 3.61G - rpool/ROOT/freebsd-9.1p1/usr/local@2013-03-25-23:34:12 143K - 473M - rpool/ROOT/freebsd-9.1p1/var@2013-03-25-23:34:12 212K - 97.8M -再起動します。
# rebootアップデート BE で起動したことを確認します。
# beadm list BE Active Mountpoint Space Created base-be - - 32.1M 2013-03-25 23:09 freebsd-9.1p1 NR / 4.6G 2013-03-25 23:34 # df -t zfs Filesystem 1K-blocks Used Avail Capacity Mounted on rpool/ROOT/freebsd-9.1p1 16713492 382425 16331066 2% / rpool/ROOT/freebsd-9.1p1/tmp 16331101 35 16331066 0% /tmp rpool/ROOT/freebsd-9.1p1/usr 20111756 3780690 16331066 19% /usr rpool/ROOT/freebsd-9.1p1/usr/local 16815235 484168 16331066 3% /usr/local rpool/ROOT/freebsd-9.1p1/var 16451536 120469 16331066 1% /varFreeBSD 初級者なので freebsd-update しても uname の値が変わっていないのが気になりますが、変更ファイルである libc.so.7 が新しくなっているから大丈夫でしょう。
# uname -v FreeBSD 9.1-RELEASE #0 r243825: Tue Dec 4 09:23:10 UTC 2012 root@farrell.cse.buffalo.edu:/usr/obj/usr/src/sys/GENERIC # ll -T /lib/libc.so.7 -r--r--r-- 1 root wheel 1369840 Mar 25 23:50 2013 /lib/libc.so.7(追記)9.1-RELEASE-p1 ではカーネルの変更は無いのでバイナリパッチの freebsd-update で uname の値が変わるはずありませんね。カーネルビルド時に参照されるファイルで確認するのでしょうかね。
# grep -A1 ^REV /usr/src/sys/conf/newvers.sh REVISION="9.1" BRANCH="RELEASE-p1"
おわりに
Oracle Solaris 11 の Boot Environments ではルートファイルシステムのある ZFS データセットの管理のみならず、ブートローダ GNU GRUB のメニューもあわせて編集され、システム起動時に任意の BE を選択できるようになっています。果たして FreeBSD のブートマネージャで同じようなことができるのか分かりませんが、BE を利用することでシステムアップデートに対する敷居は少しは下がったかなと思います。
また BE 前提であれば /home や /var を別階層のデータセットにしておくなどレイアウトも検討すべきですね。やはり Solaris からは学べることが多そうです。
# uname -rsp SunOS 5.11 i386 # zpool get bootfs rpool NAME PROPERTY VALUE SOURCE rpool bootfs rpool/ROOT/solaris local # beadm list BE Active Mountpoint Space Policy Created -- ------ ---------- ----- ------ ------- solaris NR / 2.96G static 2013-03-24 18:06 # zfs list -o name,canmount,mountpoint NAME CANMOUNT MOUNTPOINT rpool on /rpool rpool/ROOT off legacy rpool/ROOT/solaris noauto / rpool/ROOT/solaris/var noauto /var rpool/VARSHARE noauto /var/share rpool/dump - - rpool/export on /export rpool/export/home on /export/home rpool/export/home/yoshikaw on /export/home/yoshikaw rpool/swap - -
0 件のコメント:
コメントを投稿