All posts by 2510

起動用zpoolでzpool removeしてはいけない

死ぬので。(@FreeBSD 13.0-RELEASE, 2021/07/13時点)

そもそも何故zpool removeしたのか

まずディスクを交換したかった。
大体の場合は、mirrorを作って古いディスクを外せばいい。(zpool attach + zpool remove)
ただ今回はboot領域にうっかりでっかいディスクを使ってしまっていて、SSDに交換しようとしたら容量が足りなかった。

調べたところ、最近のzpoolはzpool addしたあとremoveできて、これを使うと、poolのshrinkができる。
てきとーにやってみたら、簡単にできてしまった。(ぎりぎりに縮小することはできなくて、ものすごく余裕を持たせる必要はあったが)

感心&安心していた。数日後にrebootするまでは。

panicする

停電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がいい。

Raspberry PI 4 Model B + FreeBSD 13 BETA3 + ZFS

試してうまくいったのでメモとして残しておく。
後から手順にしているので、余計な手順や、抜けている手順があるかもしれない。(が、参考くらいにはなるはずと思っている)

なお、初期設定ほかではこちらを参考にさせてもらった。
本稿執筆時点(2021/02/23)では、シリアルコンソールなしで、USB+HDMIディスプレイというごく普通の装備だけで動かせている。

FreeBSD on RaspberryPi 4 Model B 発動篇

必要なもの

  • Raspberry PI 4 Model B+ (以下、RPI。なお、2Gモデルで実験している。)
  • FreeBSD-13.0-BETA3-arm64-aarch64-RPI.img
  • microSDカード (4GB以上)
  • USBメモリ (4GB以上、ZFSを認識させるために使用)
  • 適当な作業用FreeBSDマシン + USB-SDカードアダプタ

手順

  1. 適当な方法でイメージをSDカードに焼く。
    # dd if=/tmp/FreeBSD-13.0-BETA3-arm64-aarch64-RPI.img of=/dev/da0 bs=65536
  2. 念の為、この時点でRPIが起動することを確かめておく。
  3. SDカードを作業用PCに接続する。(以下、SDカードはda0になっているとする)
  4. 現在のUFS内データをバックアップする。
    # mkdir /mnt/raspi
    # mount -t ufs /dev/da0s2a /mnt/raspi
    # cd /mnt/raspi
    # tar -cf /tmp/raspi-rootfs.tar .
    # cd /
    # umount /mnt/raspi
  5. UFSを潰してZFSを作る。バックアップから中身を復元する。
    # 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
  6. /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"
  7. /etc/fstabからrootfsをマウントする記述を取り除く。/dev/ufs/rootfsの部分。忘れると酷い目に遭う。遭った。(おまけ参照)
  8. zpool exportする。
    # zpool export piroot
  9. 作業用PCでもう一仕事。USBメモリに起動用イメージを焼く。もっとも、必要なのはrootfs部分だけだが。 USBメモリを作業PCに挿して、SDカードと全く同じようにして書き込む。例えばこう。
    # dd if=/tmp/FreeBSD-13.0-BETA3-arm64-aarch64-RPI.img of=/dev/da1 bs=65536
  10. SDカードとUSBメモリをRPIに挿して、起動させる。kernelが読まれた後、プロンプトに入るためにEnter以外(SPACEとか)のキーを押す。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
  11. 通常起動する(はず)なので、起動したらzpoolのcacheを作ってコピーして、shutdownする。
    # 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
  12. USBメモリは抜いて起動する。
  13. おつかれさまでした。

おまけ

ある手順を忘れると、起動中に

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 UPgenet0: link state changed to DOWN が出るはず。)

これがまともなエラーを吐かないので調査に手間取った。
途中で作ったUSBメモリを挿していると、これは発生しない。(/dev/ufs/rootfs があるから)
適当なUSBメモリでは代わりにならない。(/dev/ufs/rootfs がないから)
適当に同じようなパーティションを書いたUSBメモリでもダメ。(ラベルを付け忘れたので以下略)

WiFi設定用QRコードの生成

自分用のメモ。
アプリで生成だのなんだの、面倒そうなことばっかり。
Webサイトで生成できる。

pure JS WiFi QR Code Generator

“pure JS”でブラウザ上だけで動く。通信しないので安心。

検索すると上のほうに出てくる mqr.kr (当然リンクしないよ)はSSIDやパスワードをURLに含めて送っちゃうので、とても推奨できない。というかダメだろう、これ。
怪しいなと思って、ダミーのデータを入れつつチェックしていてよかった。

追記:
zxing.appspot.com/generator も同じくGETで送ってるのでダメ。
みんな気にしないのか、堂々と罠をかけてるのか。

寝正月2018

新年明けましておめでとうございます。
寝正月万歳です。

去年はGo Langに手を染め、しかし見た目の汚さが許容できず、LispやらSchemeに逃げました。
長年親しんだC/Perl/Pythonのようには自由にかけませんが、いずれはメイン言語にしていきたいものです。

さて、寝ぼけた頭で、いま頭に詰まっている内容を吐き出します。
Schemeまわりは以下の件でどこかにこぼれ落ちていったので、またそのうち。

Continue reading 寝正月2018