[[FreeBSD/ZFS]]

* ZFS boot の設定方法 [#b22f8080]

- 参考 http://wiki.freebsd.org/RootOnZFS
-- 以下に書いてあることはほとんど同じなので、こっち見たほうが早いかもしれない。

- ここでは GPT ディスクを使う。
-- GPT では OS のデュアルブート不可。どうしてもやりたい場合は GPT 対応のブートローダが必要。(Grub2 とか)
- Swap は GPT パーティションとする。
-- ZFS では Swap 領域をカーネルダンプに使うことができない。
- zfs set mountpoint は原則使わない。/etc/fstab を使用する。
-- 自動マウントにしていると、いつマウントされるのか制御できず余計な時にマウントされて非常に厄介なため。
-- ただし、ファイルシステム階層で自動マウントしたい場合は zfs set mountpoint を使う。(/usr/home/* 配下とか。)
- telnetd を一時的に動かして、外部の端末からコマンドを投入するのが得策かと思う。
-- Fixit 環境で sshd を動かす手順は検討中。ホスト鍵作成あたりが厄介。

* 下準備 [#na5a4827]
- CDROM/DVD か USB にて起動。
- 以下、自分の環境に合わせて変更する。
-- Country Selection
--- 110 Japan を選択する。
-- System Console Keymap
--- Japanese 106 を選択する。

- sysinstall Main Menu
-- Fixit を選択する。
- Plese choose a fixit option
-- 起動したメディアに合わせて CDROM/DVD か USB を選択。
- dmesg から接続したディスクを検索する。
 # dmesg | grep "MB <"
 ad0: 20480MB <VBOX HARDDISK 1.0> at ata0-master UDMA33

* パーティションを作成し、ZFS プールを作成する。 [#h11628e6]
** シングルディスク構成の場合 [#w3643386]
- パーティションテーブルを初期化する。(これは必要に応じて。メディアの認識の都合で zfs.ko の読み込み前であるべき。)
 # dd if=/dev/zero of=/dev/ad0 bs=1m count=1
- GPT パーティションテーブルを作成する
 # gpart create -s gpt ad0
- ブートパーティションを作成する。
 # gpart add -s 64K -t freebsd-boot ad0
- Swap パーティションを作成する。(容量はRAMの2~4倍程度取っておく。後から拡張困難なので注意。)
 # gpart add -s 4G -t freebsd-swap -l swap0 ad0
- 残りを ZFS パーティションとして作成する。
 # gpart add -t freebsd-zfs -l disk0 ad0
- Protected MBR(pmbr) と gptzfsboot ローダを入れる。
 # gpart bootcode -b /mnt2/boot/pmbr -p /mnt2/boot/gptzfsboot -i 1 ad0
 ad0 has bootcode
-- -i 1 は 1番目のパーティション(freebsd-boot)を指す。

- ZFS カーネルモジュールを読み込む
 # kldload /mnt2/boot/kernel/opensolaris.ko
 # kldload /mnt2/boot/kernel/zfs.ko

- /boot/zfs/zfs.cache を残すために、/boot/zfs ディレクトリを作る。
 # mkdir /boot/zfs
- ZFS プールを作成する。
 # zpool create zroot /dev/gpt/disk0
-- zroot という名前は好きなように。
-- パーティションを切り直した時に、前のプール情報が残っていてエラーになってしまう場合がある。その時は破棄して作り直す。
 # zpool list
 # zpool destroy zroot

** ミラー構成の場合 [#yba6fb8f]

- 2つのディスクでまったく同じことをやる。(ad0 で実行した後、ad1 で置き換えて実行する)
-- GPT パーティションテーブルを作成する
 # gpart create -s gpt ad0
 # gpart create -s gpt ad1
-- パーティションテーブルを初期化する。(これは必要に応じて。メディアの認識の都合で zfs.ko の読み込み前であるべき。)
 # dd if=/dev/zero of=/dev/ad0 bs=1m count=1
 # dd if=/dev/zero of=/dev/ad1 bs=1m count=1
-- ブートパーティションを作成する。
 # gpart add -s 64K -t freebsd-boot ad0
 # gpart add -s 64K -t freebsd-boot ad1
-- Swap パーティションを作成する。(容量はRAMの2~4倍程度取っておく。後から拡張困難なので注意。)
 # gpart add -s 4G -t freebsd-swap -l swap0 ad0
 # gpart add -s 4G -t freebsd-swap -l swap1 ad1
-- 残りを ZFS パーティションとして作成する。
 # gpart add -t freebsd-zfs -l disk0 ad0
 # gpart add -t freebsd-zfs -l disk1 ad1
-- Protected MBR(pmbr) と gptzfsboot ローダを入れる。
 # 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
--- -i 1 は 1番目のパーティション(freebsd-boot)を指す。

- ZFS カーネルモジュールを読み込む
 # kldload /mnt2/boot/kernel/opensolaris.ko
 # kldload /mnt2/boot/kernel/zfs.ko

- /boot/zfs/zfs.cache を残すために、/boot/zfs ディレクトリを作る。
 # mkdir /boot/zfs
- ZFS プールを作成する。
 # zpool create zroot mirror /dev/gpt/disk0 /dev/gpt/disk1
-- zroot という名前は好きなように。
-- パーティションを切り直した時に、前のプール情報が残っていてエラーになってしまう場合がある。その時は破棄して作り直す。
 # zpool list
 # zpool destroy zroot

* ZFS でファイルシステムを作成する。 [#h6f325c5]
** 方針 [#gb06f6df]
- /tmp は tmpfs を使う。
- %%/var/run は tmpfs を使う。%% 一部のアプリが永続的なディレクトリ構成をここに置くため、tmpfs はダメ。
- ZFS はスナップショットをまとめて取りたい集合で切っていく。
- zroot/system 配下に OS のファイルシステム /, /usr, /var を配置する。
- / は zroot/system/sysroot, /usr は zroot/system/usr で割り当てる。こう分離しないと / の差し替えが非常に困難になる。
- zroot/home としてユーザーのホームディレクトリを作成する。

** 手順 [#t7f08187]
- チェックサムは fletcher4 を使う。(デフォルトは fletcher2。スピードより安全を取るなら sha256。)
 # zfs set checksum=fletcher4 zroot
- スナップショットにごみがたまるだけなので atime は設定しない。(ごく稀にこれがダメなアプリがある模様なので要注意)
 # zfs set atime=off zroot
- zroot のマウントポイントを legacy にする。(ZFS の自動マウントでひどい目に遭ったので ZFS のマウントは当てにしない。)
 # zfs set mountpoint=legacy zroot

- 各ファイルシステムを切る。
 # zfs create                                               zroot/system
 # zfs create                                               zroot/system/sysroot
 # zfs create                                               zroot/system/usr
 # zfs create                                               zroot/system/var
 # zfs create -o compression=lzjb -o exec=off -o setuid=off zroot/system/var/crash
 # zfs create                     -o exec=off -o setuid=off zroot/system/var/db
 # zfs create -o compression=lzjb -o exec=on  -o setuid=off zroot/system/var/db/pkg
 # zfs create                     -o exec=off -o setuid=off zroot/system/var/empty
 # zfs create -o compression=lzjb -o exec=off -o setuid=off zroot/system/var/log
 # zfs create -o compression=lzjb -o exec=off -o setuid=off zroot/system/var/mail
 # zfs create                                               zroot/system/var/run
 # zfs create -o compression=lzjb -o exec=on  -o setuid=off zroot/system/var/tmp
 # zfs create -o compression=lzjb -o exec=on  -o setuid=off zroot/ports
 # zfs create                     -o exec=off -o setuid=off zroot/ports/distfiles
 # zfs create                     -o exec=off -o setuid=off zroot/ports/packages
 # zfs create -o compression=lzjb -o exec=off -o setuid=off zroot/src
 # zfs create                                               zroot/home

- ブートするファイルシステムを設定する。(/boot のありか)
 # zpool set bootfs=zroot/system/sysroot zroot

- /tmproot 配下に仮のファイルシステムを作成する。
 # mkdir /tmproot
 # mount -t zfs zroot/system/sysroot /tmproot
 # mkdir /tmproot/tmp
 # chmod 1777 /tmp
 # mkdir /tmproot/usr
 # mount -t zfs zroot/system/usr /tmproot/usr
 # mkdir /tmproot/usr/home
 # mount -t zfs zroot/home /tmproot/usr/home
 # ln -s /usr/home /tmproot/home
 # mkdir /tmproot/usr/ports
 # mount -t zfs zroot/ports /tmproot/usr/ports
 # mkdir /tmproot/usr/ports/distfiles
 # mount -t zfs zroot/ports/distfiles /tmproot/usr/ports/distfiles
 # mkdir /tmproot/usr/ports/packages
 # mount -t zfs zroot/ports/packages /tmproot/usr/ports/packages
 # mkdir /tmproot/usr/src
 # mount -t zfs zroot/src /tmproot/usr/src
 # mkdir /tmproot/var
 # mount -t zfs zroot/system/var /tmproot/var
 # mkdir /tmproot/var/crash
 # mount -t zfs zroot/system/var/crash /tmproot/var/crash
 # mkdir /tmproot/var/db
 # mount -t zfs zroot/system/var/db /tmproot/var/db
 # mkdir /tmproot/var/db/pkg
 # mount -t zfs zroot/system/var/db/pkg /tmproot/var/db/pkg
 # mkdir /tmproot/var/empty
 # mount -t zfs zroot/system/var/empty /tmproot/var/empty
 # mkdir /tmproot/var/log
 # mount -t zfs zroot/system/var/log /tmproot/var/log
 # mkdir /tmproot/var/mail
 # mount -t zfs zroot/system/var/mail /tmproot/var/mail
 # mkdir /tmproot/var/run
 # mount -t zfs zroot/system/var/run /tmproot/var/run
 # mkdir /tmproot/var/tmp
 # mount -t zfs zroot/system/var/tmp /tmproot/var/tmp
 # chmod 1777 /tmproot/var/tmp

- FreeBSD の各種ファイルを入れる
 # cd /dist/8.0-*
 # export DESTDIR=/tmproot
 # for dir in base catpages dict doc games info lib32 manpages ports
 # do
 #     (cd $dir ; ./install.sh) ;
 # done
 # cd src ; ./install.sh all
 # cd ../kernels ; ./install.sh generic
 # cd /tmproot/boot ; cp -Rlp GENERIC/* /tmproot/boot/kernel/

- /var/empty を read only にする。
 # zfs set readonly=on zroot/system/var/empty

- chroot する。
 # chroot /tmproot

- /etc/fstab に以下を入れる
 # Device                Mountpoint      FStype  Options         Dump    Pass#
 /dev/gpt/swap0          none            swap    sw              0       0
 zroot/system/usr        /usr            zfs     rw              0       0
 zroot/system/var        /var            zfs     rw              0       0
 zroot/system/var/crash  /var/crash      zfs     rw              0       0
 zroot/system/var/db     /var/db         zfs     rw              0       0
 zroot/system/var/db/pkg /var/db/pkg     zfs     rw              0       0
 zroot/system/var/empty  /var/empty      zfs     ro              0       0
 zroot/system/var/log    /var/log        zfs     rw              0       0
 zroot/system/var/mail   /var/mail       zfs     rw              0       0
 tmpfs                   /var/run        tmpfs   rw,size=10000000 0 0
 zroot/system/var/run    /var/run        zfs     rw              0       0
 zroot/system/var/tmp    /var/tmp        zfs     rw              0       0
 tmpfs                   /tmp            tmpfs   rw,mode=1777,size=1073741824 0 0
 tmpfs                   /ports/tmp      tmpfs   rw,size=1073741824 0 0
 zroot/ports             /usr/ports      zfs     rw              0       0
 zroot/ports/distfiles   /usr/ports/distfiles    zfs     rw              0      0
 zroot/ports/packages    /usr/ports/packages     zfs     rw              0      0
 zroot/src               /usr/src        zfs     rw              0       0
 zroot/mydata            /usr/mydata     zfs     rw              0       0

- /etc/rc.conf を設定する。(hostname とか ifconfig はシステムに応じて変更を。)
 echo 'zfs_enable="YES"' >> /etc/rc.conf
 echo 'hostname="zfsroot.localdomain"' >> /etc/rc.conf
 echo 'ifconfig_re0="DHCP"' >> /etc/rc.conf

- /boot/loader.conf を設定する。 
 echo 'zfs_load="YES"' >> /boot/loader.conf
 echo 'vfs.root.mountfrom="zfs:zroot/system/sysroot"' >> /boot/loader.conf

- 7.0~7.2R,8.0R では以下の手順でブートローダの再構築が必要
 # echo 'LOADER_ZFS_SUPPORT=YES' >> /etc/src.conf
 # mount -t devfs devfs /dev
 # export DESTDIR=""
 # cd /usr/src/sys/boot
 # make obj
 # make depend
 # make
 # cd i386/loader
 # make install

- aliases を再作成。(必要?)
 # cd /etc/mail
 # make aliases

- /dev はもう不要なのでアンマウント
 # umount /dev

- chroot 環境を脱出
 # exit

- ZFS の情報をブートローダ用にコピー
 # cp /boot/zfs/zpool.cache /zroot/boot/zfs/zpool.cache
 # cp /boot/zfs/zpool.cache /tmproot/boot/zfs/zpool.cache
-- mkdir /boot/zfs を忘れているとできない。その場合は以下で作り直し。
 # mkdir /boot/zfs; zfs export zroot; zfs import zroot

- Fixit 環境を出る。
 # exit

- 再起動する。
- シングルユーザーでログインする。
- /usr/home を自動マウントにする。
 # zfs set mountpoint=/usr/home zroot/home

- ユーザーを追加するときには、先にファイルシステムを切り、ユーザー単位でのスナップショット権限を与える。
 # zfs create zroot/home/alice
 # adduser
 ...
 # zfs allow alice mount,create,snapshot,rename,destroy,clone,promote,send,receive zroot/home/alice

* 謎のスクリプト [#c8adcb36]

動作保証なし。
Use at your own risk.

 #!/bin/sh
 
 if [ $# -ne 4 ]; then
     echo "usage: create_ZFS_root_single.sh DISK0 SWAP_SIZE GPT_DISK0_NAME POOL_NAME"
     echo "ex. ./create_ZFS_root_single.sh ad0 2g disk0 zroot"
     exit 1
 fi
 
 DISK0=$1
 SWAP_SIZE=$2
 GPT_DISK0_NAME=$3
 POOL_NAME=$4
 
 echo "ERASE ALL DATA ON $DISK0. OK? enter 'yes'"
 read ANSWER
 if [ "$ANSWER" != "yes" ]; then
     echo "bye!"
     exit 2
 fi
 
 echo Delete partition info.
 dd if=/dev/zero of=/dev/$DISK0 bs=1m count=1
 
 echo Create partition.
 gpart create -s gpt $DISK0
 gpart add -s 64K -t freebsd-boot $DISK0
 gpart add -s $SWAP_SIZE -t freebsd-boot $DISK0
 gpart add -t freebsd-zfs -l $GPT_DISK0_NAME $DISK0
 gpart bootcode -b /mnt2/boot/pmbr -p /mnt2/boot/gptzfsboot -i 1 $DISK0
 
 echo Load ZFS module
 kldload /mnt2/boot/kernel/opensolaris.ko
 kldload /mnt2/boot/kernel/zfs.ko
 
 echo ZFS check
 zpool import
 echo "NO POOL CHECK OK? enter 'yes'"
 read ANSWER
 if [ "$ANSWER" != "yes" ]; then
     echo "bye!"
     exit 2
 fi
 
 echo create ZFS pool
 mkdir /boot/zfs
 zpool create $POOL_NAME /dev/gpt/$GPT_DISK0_NAME
 
 echo create ZFS filesystem
 mkdir /tmproot
 zfs set checksum=fletcher4 $POOL_NAME
 zfs set atime=off $POOL_NAME
 zfs set mountpoint=legacy $POOL_NAME
 
 zfs create                                               ${POOL_NAME}/system
 zfs create                                               ${POOL_NAME}/system/sysroot
 zfs create                                               ${POOL_NAME}/system/usr
 zfs create                                               ${POOL_NAME}/system/var
 zfs create -o compression=lzjb -o exec=off -o setuid=off ${POOL_NAME}/system/var/crash
 zfs create                     -o exec=off -o setuid=off ${POOL_NAME}/system/var/db
 zfs create -o compression=lzjb -o exec=on  -o setuid=off ${POOL_NAME}/system/var/db/pkg
 zfs create                     -o exec=off -o setuid=off ${POOL_NAME}/system/var/empty
 zfs create -o compression=lzjb -o exec=off -o setuid=off ${POOL_NAME}/system/var/log
 zfs create -o compression=lzjb -o exec=off -o setuid=off ${POOL_NAME}/system/var/mail
 zfs create -o compression=lzjb -o exec=on  -o setuid=off ${POOL_NAME}/system/var/tmp
 zfs create -o compression=lzjb -o exec=on  -o setuid=off ${POOL_NAME}/ports
 zfs create                     -o exec=off -o setuid=off ${POOL_NAME}/ports/distfiles
 zfs create                     -o exec=off -o setuid=off ${POOL_NAME}/ports/packages
 zfs create -o compression=lzjb -o exec=off -o setuid=off ${POOL_NAME}/src
 zfs create                                               ${POOL_NAME}/home
 
 zpool set bootfs=${POOL_NAME}/system/sysroot ${POOL_NAME}
 
 echo mount ZFS filesystem
 mount -t zfs ${POOL_NAME}/system/sysroot /tmproot
 mkdir /tmproot/tmp
 chmod 1777 /tmp
 mkdir /tmproot/usr
 mount -t zfs ${POOL_NAME}/system/usr /tmproot/usr
 mkdir /tmproot/usr/home
 mount -t zfs ${POOL_NAME}/home /tmproot/usr/home
 ln -s /usr/home /tmproot/home
 mkdir /tmproot/usr/ports
 mount -t zfs ${POOL_NAME}/ports /tmproot/usr/ports
 mkdir /tmproot/usr/ports/distfiles
 mount -t zfs ${POOL_NAME}/ports/distfiles /tmproot/usr/ports/distfiles
 mkdir /tmproot/usr/ports/packages
 mount -t zfs ${POOL_NAME}/ports/packages /tmproot/usr/ports/packages
 
 mkdir /tmproot/usr/src
 mount -t zfs ${POOL_NAME}/src /tmproot/usr/src
 
 mkdir /tmproot/var
 mount -t zfs ${POOL_NAME}/system/var /tmproot/var
 mkdir /tmproot/var/crash
 mount -t zfs ${POOL_NAME}/system/var/crash /tmproot/var/crash
 mkdir /tmproot/var/db
 mount -t zfs ${POOL_NAME}/system/var/db /tmproot/var/db
 mkdir /tmproot/var/db/pkg
 mount -t zfs ${POOL_NAME}/system/var/db/pkg /tmproot/var/db/pkg
 mkdir /tmproot/var/empty
 mount -t zfs ${POOL_NAME}/system/var/empty /tmproot/var/empty
 mkdir /tmproot/var/log
 mount -t zfs ${POOL_NAME}/system/var/log /tmproot/var/log
 mkdir /tmproot/var/mail
 mount -t zfs ${POOL_NAME}/system/var/mail /tmproot/var/mail
 mkdir /tmproot/var/tmp
 mount -t zfs ${POOL_NAME}/system/var/tmp /tmproot/var/tmp
 chmod 1777 /tmproot/var/tmp
 
 echo "Extract FreeBSD distribution. OK? enter 'yes'"
 read ANSWER
 if [ "$ANSWER" != "yes" ]; then
     echo "bye!"
     exit 2
 fi
 
 echo extract FreeBSD distribution
 cd /dist/8.0-*
 export DESTDIR=/tmproot
 for dir in base catpages dict doc games info lib32 manpages ports
 do
     (cd $dir ; ./install.sh) ;
 done
 
 cd src ; ./install.sh all
 
 cd ../kernels ; ./install.sh generic
 
 cd /tmproot/boot ; cp -Rlp GENERIC/* /tmproot/boot/kernel/
 
 echo set configuration
 
 zfs set readonly=on ${POOL_NAME}/system/var/empty
 #exit 1
 
 cat <<CHROOTSCRIPT_EOT >/tmproot/zfssinglechroot.sh
 #!/bin/sh
 cat <<EOT >> /etc/fstab
 # Device                Mountpoint      FStype  Options         Dump    Pass#
 /dev/gpt/swap0          none            swap    sw              0       0
 zroot/system/sysroot    /               zfs     rw              0       0
 zroot/system/usr        /usr            zfs     rw              0       0
 zroot/ports             /usr/ports      zfs     rw              0       0
 zroot/ports/distfiles   /usr/ports/distfiles    zfs     rw              0      0
 zroot/ports/packages    /usr/ports/packages     zfs     rw              0      0
 zroot/src               /usr/src        zfs     rw              0       0
 zroot/system/var        /var            zfs     rw              0       0
 zroot/system/var/crash  /var/crash      zfs     rw              0       0
 zroot/system/var/db     /var/db         zfs     rw              0       0
 zroot/system/var/db/pkg /var/db/pkg     zfs     rw              0       0
 zroot/system/var/empty  /var/empty      zfs     rw              0       0
 zroot/system/var/log    /var/log        zfs     rw              0       0
 zroot/system/var/mail   /var/mail       zfs     rw              0       0
 tmpfs                   /var/run        tmpfs   rw,size=10000000 0 0
 zroot/system/var/tmp    /var/tmp        zfs     rw              0       0
 tmpfs                   /tmp            tmpfs   rw,mode=1777,size=1073741824 0 0
 tmpfs                   /ports/tmp      tmpfs   rw,size=1073741824 0 0
 EOT
 
 echo 'zfs_enable="YES"' >> /etc/rc.conf
 echo 'hostname="zfsroot.localdomain"' >> /etc/rc.conf
 echo 'ifconfig_re0="DHCP"' >> /etc/rc.conf
 
 echo 'zfs_load="YES"' >> /boot/loader.conf
 echo 'vfs.root.mountfrom="zfs:zroot/system/sysroot"' >> /boot/loader.conf
 
 echo reinstall boot loader
 
 echo 'LOADER_ZFS_SUPPORT=YES' >> /etc/src.conf
 
 mount -t devfs devfs /dev
 export DESTDIR=""
 cd /usr/src/sys/boot
 make obj
 make depend
 make
 cd i386/loader
 make install
 
 cd /etc/mail
 make aliases
 
 umount /dev
 exit
 CHROOTSCRIPT_EOT
 
 chmod +x /tmproot/zfssinglechroot.sh
 
 chroot /tmproot /zfssinglechroot.sh
 rm /tmproot/zfssinglechroot.sh
 
 cp /boot/zfs/zpool.cache /zroot/boot/zfs/zpool.cache
 
 echo Exit Fixit and reboot, then enter single mode.
 echo and then enter follow command.
 echo # zfs set mountpoint=/usr/home zroot/home
 echo # exit

トップ   編集 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS