2016年11月1日火曜日

ZFS root+mirror構成でのディスク障害からからの回復

FreeBSD 11でbsd-installを使って以下のような構成でインストールしている場合の、ディスク障害からからの回復方法のメモです。
  • パーティションはGPT
  • 起動はEFI
  • rootはZFS(ZFS root)
  • 起動パーティションをZFSでミラー 
  • swapもミラー(ただしgmirrorを利用)

 

ディスクを交換する


ディスクada0とada1でZFSを使いミラー構成にしており、ada1が壊れ、これを入れ替えたとします。

 

パーティションを回復する 

backup a partition table with gpart(8)
https://lists.freebsd.org/pipermail/freebsd-geom/2010-November/004489.html 
gpart backup/restoreを使います。
動作しているディスクada0のパーティション情報を、交換したディスクada1に書き込むには以下のようにします。
# gpart backup ada0 | gpart restore -F ada1
#
このあと、gpart show -lでada0のラベルを参照しながら、gpart modifyでada1にラベルを書き込みます。たとえば以下のようにします。
# gpart modify -i 2 -l zfs0 ada0
#

bootコードを回復する

EFI ZFS loader success story
https://lists.freebsd.org/pipermail/freebsd-hackers/2015-August/048141.html
ブートコードを以下のようにして書き込ます。
# gpart bootcode -b /boot/pmbr -p /boot/gptzfsboot -i 2 ada1
#
-iで指定するインデックスに注意します。freebsd-bootパーティションを指定しなければなりません。

 

EFIブートコードを回復する

UEFI
https://wiki.freebsd.org/UEFI
EFIから起動するためのブートコードも書き込まなくてはなりません。
# dd if=/boot/boot1.efifat of=/dev/ada0p1
ada0p1はefiタイプになっているパーティションです。このパーティションは実はFATになっていてマウントすることができます。
Disk Setup On FreeBSD
http://www.wonkity.com/~wblock/docs/html/disksetup.html
そのため、上記のWWWページでも書かれているようにFATイメージ(boot1.efifat)を書き込むのではなく、手動でEFI用のブートコードを設定することもできます。
Create and format a partition to hold the the small MS-DOS filesystem for UEFI bootcode.
# gpart add -t efi -l gpefiboot -a4k -s492k da0
da0p2 added
# newfs_msdos /dev/da0p2


Copy the FreeBSD /boot/boot1.efi bootcode file into the efi filesystem.
# mount -t msdosfs /dev/da0p2 /mnt
# mkdir -p /mnt/EFI/BOOT
# cp /boot/boot1.efi /mnt/EFI/BOOT/
# umount /mnt
こちらでは実際のブートコードであるboot1.efiをコピーしています。ただ.efifatをみると、ブートコードのファイル名はBOOTx64.efiになっているので、もう少し情報を集める必要があります。

 

swapの回復


swapもgmirrorなのでこれからも回復する必要があります。
FreeBSDのgmirrorでのHDD故障対応
http://uls.self.jp/wordpress/freebsd/?p=64
# gmirror forget swap
Name Status Components gmirror/swap COMPLETE ada0
# gmirror insert swap ada1
swap:rebuilding provider ada1.
#

追記: ZFSに使うパーティションをラベルで参照する

bsd-installだとzfsに使うパーティションの参照が物理デバイス名になっています。
物理デバイス名は、接続されているディスク数によって変わってしまうので、故障のときにうまくありません。
zpoolをdisk labelで組み直す
https://blog.bixr.com/2014/03/734/
交換後再起動したら問題発生。
実はda4に割り当てられていたHDDが故障したのでHDDを抜き取り、送付、交換用HDDが届くまで1週間位かかっているのだが、その間、故障してからずっとPCは動作させっぱなしだったので新しくHDDを挿した時にも空いていたda4が再度割り当てられていた。ここで再起動すると認識の順番が変わりda4->da6, da5->da4, da6->da5にずれてしまった。
このため、ラベルを参照するように変更したいのですが、上記のWWWページの手法はルートファイルシステムには適用できません。というのは、zfs exportとするとファイルシステムはアンマウントされますが、ルートファイルシステムはアンマウントできないので、うまくいきません。

このシステムでは、ルートファイルシステムはミラーになっているのでこれをうまく使います。
  1. 片側のディスクを外す(detach)
  2. ラベル参照で追加(attach)して同期
  3. 同期後、残りのディスクを外して、またラベル参照で追加、同期
このとき、事前に/boo/loader.confで
kern.geom.label.gptid.enable=1
としてから起動し直しておく必要があります。