[[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