#おことわり
自己満足のために技術的に可能かどうかを検証したものであり、本記事のような構成が実用的意義を持つかどうかは考慮していません。
#動機
SSDは高速で嬉しいけれど、どうしても心情的に信頼しきれない。システムはSSDにインストールするとして、大事なデータはHDDでミラリングしておき、さらにSSDが壊れたときのためHDDからも起動できるようにしておきたい。1
#構成
- システム: DELL Precision 5820 Tower
- SSD: Intel SSDPEMKF256B8 (NVMe 256MB) 2
- HDD: Seagate BarraCuda ST1000DM010 (SATA 1TB) x2
- OS: FreeBSD 12.2-RELEASE-p13
SSDは単独でZFS pool (zroot)とし、HDDは2台でmirroring pool (tank)とする。tankには自前のデータを格納するほか、zrootに構築したシステムを逐次tankにバックアップしておき、SSDにトラブルが起きた場合にはtankだけで起動し可用性を確保するものとする。
#インストール
- まずSSD (nvd0)にインストールする。Guided Root-on-ZFSで
GPT(BIOS+UEFI)
を選択。 - 再起動し、mirroring poolを構成することだけを目的として、もう1回インストールする。ada0とada1を使い、Guided Root-on-ZFSで
GPT(BIOS+UEFI)
を選択、プール名をtank
とし、素のswapパーティションを32GB確保する。 - SSDから起動するようにUEFIを設定して起動
# gpart show
=> 40 500118112 nvd0 GPT (238G)
40 409600 1 efi (200M)
409640 1024 2 freebsd-boot (512K)
410664 984 - free - (492K)
411648 4194304 3 freebsd-swap (2.0G)
4605952 495511552 4 freebsd-zfs (236G)
500117504 648 - free - (324K)
=> 40 1953525088 ada0 GPT (932G)
40 409600 1 efi (200M)
409640 1024 2 freebsd-boot (512K)
410664 984 - free - (492K)
411648 67108864 3 freebsd-swap (32G)
67520512 1886003200 4 freebsd-zfs (899G)
1953523712 1416 - free - (708K)
=> 40 1953525088 ada1 GPT (932G)
40 409600 1 efi (200M)
409640 1024 2 freebsd-boot (512K)
410664 984 - free - (492K)
411648 67108864 3 freebsd-swap (32G)
67520512 1886003200 4 freebsd-zfs (899G)
1953523712 1416 - free - (708K)
うっかりルートレベルのデータセットを使うと後々厄介なのでマウントポイントを消しておく。
# zfs set mountpoint=none zroot
# rmdir /zroot
tankをインポートして中身を消し、さらにマウントポイントを無効化する。
# zpool import -f tank
# zfs destroy -r tank
# zfs set canmount=off tank
以下のように2つのZFS poolが構成されている。
>zpool status
pool: tank
state: ONLINE
scan: none requested
config:
NAME STATE READ WRITE CKSUM
tank ONLINE 0 0 0
mirror-0 ONLINE 0 0 0
ada0p4 ONLINE 0 0 0
ada1p4 ONLINE 0 0 0
errors: No known data errors
pool: zroot
state: ONLINE
scan: none requested
config:
NAME STATE READ WRITE CKSUM
zroot ONLINE 0 0 0
nvd0p4 ONLINE 0 0 0
errors: No known data errors
swapの設定を/etc/fstabに書いておく。
# sed -i '' -e '/nvd0/{h;s/nvd0/ada0/;H;s/ada0/ada1/;H;g;}' /etc/fstab
# cat /etc/fstab
# Device Mountpoint FStype Options Dump Pass#
/dev/nvd0p3 none swap sw 0 0
/dev/ada0p3 none swap sw 0 0
/dev/ada1p3 none swap sw 0 0
# swapon -a
あとは好きなようにシステムをセットアップする。動機で述べたように zroot はあくまでシステムだけに用い、自前のデータは tank プールを使うようにしておく。
#起動切り替え
tank上のバックアップは日常的にはマウントされては困るためcanmount=noauto
としておくが、tankから起動した場合は自動的にマウントされることが必要。FreeBSD 12ではルートファイルシステムの子はcanmount=noauto
でも自動的にマウントするようになっている(cf. /etc/rc.d/zfsbe)4ので、これを利用できるようにバックアップを取れば良い。
バックアップの手順は、
- zrootのスナップショットを作成
- ルートファイルシステム(zroot/ROOT/default)をtank/altrootとしてバックアップ
- その他zroot上のファイルシステムをtank/altroot/*としてバックアップ
- tank/altroot以下で
canmount=on
のものをcanmount=noauto
にしておく。 - tankの
bootfs
プロパティを設定する。
# zfs snapshot -r zroot@replicate
# zfs send -Rc zroot/ROOT/default@replicate |zfs receive -uv tank/altroot
# for fs in `zfs list -H -o name -r zroot |sed 1d |cut -d/ -f 2 |uniq |grep -v ROOT`; do zfs send -Rc zroot/${fs}@replicate |zfs receive -uvd tank/altroot; done
# zfs list -H -o name,canmount -r tank/altroot |grep 'on$' |cut -f 1 |xargs -n1 zfs set canmount=noauto
# zpool set bootfs=tank/altroot tank
# zfs list -o name,canmount,mountpoint,mounted -r tank/altroot
NAME CANMOUNT MOUNTPOINT MOUNTED
tank/altroot noauto / no
tank/altroot/tmp noauto /tmp no
tank/altroot/usr off /usr no
tank/altroot/usr/home noauto /usr/home no
tank/altroot/usr/ports noauto /usr/ports no
tank/altroot/usr/src noauto /usr/src no
tank/altroot/var off /var no
tank/altroot/var/audit noauto /var/audit no
tank/altroot/var/crash noauto /var/crash no
tank/altroot/var/log noauto /var/log no
tank/altroot/var/mail noauto /var/mail no
tank/altroot/var/tmp noauto /var/tmp no
この状態でSSDから起動する限りはtank/altroot以下はマウントされないが、SSDを抜いてHDDから起動するとtank/altroot以下がマウントされる。5
以下のように差分バックアップができるので、適切なタイミングで実施されるように設定すればよい。
# zfs rename -r zroot@replicate @previous
# zfs rename -r tank/altroot@replicate @previous
# zfs snapshot -r zroot@replicate
# zfs send -Rc -i previous zroot/ROOT/default@replicate |zfs receive -uv tank/altroot
# for fs in `zfs list -H -o name -r zroot |sed 1d |cut -d/ -f 2 |uniq |grep -v ROOT`; do zfs send -Rc -i previous zroot/${fs}@replicate |zfs receive -uvd tank/altroot; done
# zfs destroy -r zroot@previous
# zfs destroy -r tank/altroot@previous
-
この構成、実は1度だけ役に立ちました。あるとき突然SSDが認識されなくなり、勝手にHDDから再起動してサービスは継続したことがあります。後日のメンテでSSDを触ってから再起動したらSSDから起動したのですが、さて…。 ↩
-
おそらくDELL用専用品番で、Intel Pro 7600p/760p/E 6100p シリーズと同世代の64層3DTLC(2018年Q1)。デフォルトではIntel Volume Management Deviceに繋がっていてFreeBSD 12では認識されない。BIOSでIntel VMD Technologyを無効化することで認識可能になる。 ↩
-
FreeBSD 11以前でも/etc/rc.d/zfsbeを持ち込めばうまく行くのかもしれない。 ↩
-
もともとZFS Boot Environment用の仕掛け。 ↩
-
SSDが有効なままHDDから起動すると、ルートファイルシステム以外のtank/altroot以下とzroot以下のファイルシステムが二重にマウントされる。 ↩