知見でもなんでもないが、記録のために。
TL;DR
- 寝ている間にストレージサーバがpanicした。
- 自動再起動したが、zpoolがFAULTEDとなっていた。
- 5秒分のデータを失ってもいいならimportできるよ、という親切なメッセージが出た。
- zpool import -Fだけで無事直った。
知見でもなんでもないが、記録のために。
TL;DR
簡単だった。
言うまでもないけど、ff:ff:ff:ff:ff:ff
は好きなMACアドレスに書き換えてほしい。ほかのパラメータも、ね。
# pkg install bhyve-firmware # bhyve -AHP -s 0:0,hostbridge -s 1:0,lpc -s 2:0,virtio-net,tap0,mac=ff:ff:ff:ff:ff:ff -c 1 -m 256M -l bootrom,/usr/local/share/uefi-firmware/BHYVE_UEFI.fd -l com1,stdio guest
参考はこちら。
ポイントは BHYVE_UEFI.fd
は放っておけば IPv4 PXE Boot してくれるということ。
なので、PXE Bootしたいからオプションを探して……と悩む必要はない。起動可能なドライブを接続しなければいいのだ。
ArduinoでI2Cをいじって遊んでいたところ、そもそも最初のトリガーをEthernetかなにかで送らねばならず。
結局Raspberry Piにするか、もしくはArduino Yunにするのかと思っていたところ、いいものが見つかった。
サンハヤト: USB・I2C(SMBus)変換モジュール MM-CP2112B
CP2112というチップが載ったちんまいボードで、USBからI2C 1本とGPIO 8本が使える素敵な子。
しかもFreeBSDはCP2112のドライバを標準で積んでいて、kldloadするだけ。
買おうと思ったら、なぜか押し入れから発掘されたので、早速試してみた。(いつ買ったんだろうね??)
注意: ng_bridgeを使った場合の話です。ngctlする人向けです。ifconfigでbridgeする人には関係ない(はず)の内容です。
CARPを設定したら60秒おきに切れたり繋ったりする。
対策としては、CARPをGRE/VXLANなどに通すか、ng_bridgeのループ判定を無効化する。
なんで「かも」かというと、これを書いた前日に散々発生したくせに、調査を始めたら全然起きなくなったから。
でも起きると60秒間通信不能になるので、危険ではあるはず。
ng_bridgeは簡易ループ判定を持っている。
この判定はパケット受信時に「記憶しているMACアドレスとポートの対が異なる」現象がminStableAge(デフォルト1秒)より短い間隔で発生すると、ループありと判定するもの。
参考: ng_bridgeの判定部分
carp(ucarp)は、送信元MACアドレスを 00:00:5E:00:00:<vhid>
にして送るため、ng_bridgeからすると同じMACアドレスからのパケットがいろんなポートから出入りすることになって、上記ループ判定に引っかかることがある。
ng_bridgeにバレなければいいので、encapsuleすればいい。GREとかVXLANとか。
GREだとpeer-to-peerしかできないので、3台以上でcarpしたい場合には向かないが、multicast(=ethernetからすればbroadcast)を減らせるというメリットがある。
encapsuleすると障害の原因が増えかねない。ループは自己責任で、というならこちら。
setconfigでloopTimeout=0
にする。set後にgetconfigするとloopTimeoutがいなくなるが、効いている模様。
# ngctl msg br0: getconfig Rec'd response "getconfig" (2) from "[5]:": │ performing TSO on the inner frames in hardware: cxgbe(4). Args: { debugLevel=1 loopTimeout=60 maxStaleness=900 minStableAge=1 } # ngctl msg br0: setconfig '{ debugLevel=1 loopTimeout=0 maxStaleness=900 minStableAge=1 }' # ngctl msg br0: getconfig Rec'd response "getconfig" (2) from "[5]:": Args: { debugLevel=1 maxStaleness=900 minStableAge=1 }
CARPはMASTERがadvertise中にBACKUPはadvertiseしないため、この事象はあまり発生しないように思える。
しかし、CARPが動作するような状況、つまり中間にある機器(switch, netif)の一時障害が発生すると、両者がMASTERになり、この一時障害の解消時に問題を引き起こす可能性がある。
ちなみに、CARPのパスワードを間違えると相互にadvertiseする状態になるので、すぐにこの現象を引き起こすことになる。
死ぬので。(@FreeBSD 13.0-RELEASE, 2021/07/13時点)
まずディスクを交換したかった。
大体の場合は、mirrorを作って古いディスクを外せばいい。(zpool attach + zpool remove)
ただ今回はboot領域にうっかりでっかいディスクを使ってしまっていて、SSDに交換しようとしたら容量が足りなかった。
調べたところ、最近のzpoolはzpool addしたあとremoveできて、これを使うと、poolのshrinkができる。
てきとーにやってみたら、簡単にできてしまった。(ぎりぎりに縮小することはできなくて、ものすごく余裕を持たせる必要はあったが)
感心&安心していた。数日後にrebootするまでは。
停電etc.でrebootすることもあるが、そのときに(今回みたいな)障害に遭いたくない。というわけで時間があるときにやる。
rebootしたら、こんなpanicが出てrebootループに入ってしまった。
余談1: その前にbootcodeの書き替え忘れもあった。
余談2: rebootが早すぎて読めなかったので、iPhoneで動画撮影して見る羽目になった。
Root mount waiting for: usbus0 uhub2: 4 ports with 4 removable, self powered panic: VERIFY(nvlist_lookup_uint64(configs[i], ZPOOL_CONFIG_POOL_TXG, &txg) == 0) failed
ZFS絡みなのが分かったので、すぐに別のマシンに繋いでテストしたりしたが、まったく問題が見つからない。
zpool import
は正常だし、zpool scrub
しても何も出ない。
実は大分前に、ZIL(log)を取り外したときに同じ現象だったことを(奇跡的に)思い出した。
このときにどうしたかは思い出せなかったが、つまりpoolが悪い。
どうするかは簡単で、zfs send
してzfs receive
すればいい。
boot用なので5GB程度しかなく、すぐに復旧できた。
余談3: cat ... | zfs receive
は遅い。dd if=... bs=262144 | zfs receive
がいい。
試してうまくいったのでメモとして残しておく。
後から手順にしているので、余計な手順や、抜けている手順があるかもしれない。(が、参考くらいにはなるはずと思っている)
なお、初期設定ほかではこちらを参考にさせてもらった。
本稿執筆時点(2021/02/23)では、シリアルコンソールなしで、USB+HDMIディスプレイというごく普通の装備だけで動かせている。
FreeBSD on RaspberryPi 4 Model B 発動篇
# dd if=/tmp/FreeBSD-13.0-BETA3-arm64-aarch64-RPI.img of=/dev/da0 bs=65536
# mkdir /mnt/raspi # mount -t ufs /dev/da0s2a /mnt/raspi # cd /mnt/raspi # tar -cf /tmp/raspi-rootfs.tar . # cd / # umount /mnt/raspi
# gpart delete -i 2 da0 # gpart add -t freebsd -a 1M da0 # gpart create -s BSD da0s2 # gpart add -t freebsd-zfs -s 4G da0s2 # zpool create -t piroot -m none zroot /dev/da0s2a # zfs create piroot/ROOT # zfs create -o mountpoint=/ -u piroot/ROOT/default # zpool set bootfs=piroot/ROOT/default piroot # mount -t zfs piroot/ROOT/default /mnt/raspi # cd /mnt/raspi # tar -xf /tmp/raspi-rootfs.tar
/boot/loader.conf
(もちろん /mnt/raspi/boot/loader.conf
のことだよ!) を書き変える。hw.usb.template, umodem_load, boot_multicons, boot_serialは無効化した。どれが犯人か分からないが、bcm_dmaでエラーが起きたので無効化して逃げている。
#hw.usb.template=3 #umodel_load="YES" #boot_multicons="YES" #boot_serial="YES" beastie_disable="YES" loader_color="NO" zfs_load="YES" vfs.root.mountfrom="zfs:zroot/ROOT/default"
/etc/fstab
からrootfsをマウントする記述を取り除く。/dev/ufs/rootfs
の部分。忘れると酷い目に遭う。遭った。(おまけ参照)# zpool export piroot
# dd if=/tmp/FreeBSD-13.0-BETA3-arm64-aarch64-RPI.img of=/dev/da1 bs=65536
vfs.root.mountfrom
を書き変えて、一時的にUSBメモリから起動させる。
Hit [Enter] to boot immediately, or any other key for command prompt. Booting [/boot/kernel/kernel] in 10 seconds... Type '?' for a list of commands, 'help' for more detailed help. OK set vfs.root.mountfrom=ufs:/dev/da0s2a OK boot
# kldload /boot/kernel/zfs.ko # zpool import -f -o cachefile=/tmp/zpool.cache -R /mnt/raspi zroot # cp /tmp/zpool.cache /mnt/raspi/boot/zfs/zpool.cache # shutdown -p now
ある手順を忘れると、起動中に
Warning: no time-of-day clock registered, system time will not be set accurately
が出て止まる。
このとき、loaderで boot -v
すると、start_init: trying /sbin/init
で止まる。
(正常起動時は lo0: link state changed to UP
や genet0: link state changed to DOWN
が出るはず。)
これがまともなエラーを吐かないので調査に手間取った。
途中で作ったUSBメモリを挿していると、これは発生しない。(/dev/ufs/rootfs
があるから)
適当なUSBメモリでは代わりにならない。(/dev/ufs/rootfs
がないから)
適当に同じようなパーティションを書いたUSBメモリでもダメ。(ラベルを付け忘れたので以下略)
そんなものはfreebsd-version
コマンドで取れるのは分かってる。
でも、どうしてもコマンドを叩けない、叩きたくない、というときのためのメモ。
主にjailの管理用で、User Land側のバージョン取得が目的。
気がつけば2週間。
decentralizedなコミュニケーションツール “matrix” の実装である “synapse” をFreeBSDで動かした。
メモを見ながら書くので抜けている可能性大。
前回インストールしたPandora FMSで遊んでみた感想。
Zabbixもいい加減古い。
UIも古臭いから、なにか試そうと思って見つけたPandora FMSをFreeBSD環境に入れてみた。
今回はインストールの話だけ。