長年使っているFreeBSDマシンは、以下のような構成だった。
- OS: FreeBSD 12.3-RELEASE
- ブートデバイス: USBメモリ (BIOSとGPT)
- ルートファイルシステム: 上記USBメモリ上のUFSパーティション
- 他のファイルシステム(/usr, /var等): HDDでRAIDZを組んだzpoolの中
なお、/boot/loader.confに’zfs_load=”YES”‘、/etc/rc.confに’zfs_enable=”YES”‘は記述済みである。
このマシンの構成を、以下のように変更した。
- OS: 変更なし
- ブートデバイス: NVMeのSSD (EFIとGPT)
- ルートファイルシステム: 上記SSD上のUFSパーティション
- 他のファイルシステム: 変更なし
ブートデバイスを適切に(EFIを使用するように)設定し、ルートファイルシステムをdump + restoreでコピーして再起動したのだが、再起動後にブートが止まってしまった。
ブート時の画面表示を確認すると、カーネルは実行されているのだが、以下のようなエラーが出ていた(ブート時の画面表示は、ScrLkキーでスクロールを止めた後、PgUpキーで遡れる)。
mount: /usr: unknown special file or file system
その周辺の挙動を探っていくと、上記エラーログが出てしばらくしてから、HDD(/usrが入っているzpoolを構成するHDD)が認識されている画面表示が出ていた。
また、シングルユーザーモードで起動し、手動で”zfs mount -a”を実行すると、実行する頃にはHDDが認識されているので、正常にマウントできる。
このことから、ブート時にzpool内の/usrをマウントしようとする際に、まだHDDが認識されていないので、/usrがマウントできずにエラーになっているのではないか? と考えた。
いろいろググっていると、MLのアーカイブを発見した。
- https://lists.freebsd.org/pipermail/freebsd-questions/2013-July/252119.html
- https://lists.freebsd.org/pipermail/freebsd-questions/2013-July/252121.html
「mount -p」の結果を/etc/fstabに書き加えれば良いらしい。
試してみると確かに正常にマウントできてブートが進む。画面表示から推測すると、/etc/fstabを処理する際には、書かれているFSがマウントできない場合は、マウントできるまでリトライするらしい。
今回の場合、起動に必須なのは/usrだけなので、/etc/fstabに以下の記述だけを加えることにした。
# to avoid mounting /usr before ada0 attached.
raidtank/usr /usr zfs rw,noatime,nfsv4acls 0 0
再起動したところ、「mount -p」の全結果を書いていたときと同様に、正常にブートが進んだ。ただし1点不明なことがある(後述)。
以下余談。起動時の/etc/rc.d/*の起動順と、「残りのzfsのマウント」の話。
ブート時のzpool内のzfsのマウントは、/etc/rc.d/zfsで行われる。このファイルの中には、「BEFORE: FILESYSTEMS」の記述がある。
また、/etc/rc.d/FILESYSTEMS(何も実行せず、依存関係のみが書いてある)には「REQUIRE: mountcritlocal」の記述がある。
さらに、/etc/rc.d/mountcritlocalの中では「mount -a」が実行される。「mount -a」が失敗した場合、しばらく待ってからリトライする処理もスクリプト内に書かれている。
以上をまとめると、HDDの認識が遅い場合、ブート時のファイルシステムのマウントは以下のようになる。
- /etc/rc.d/zfsを実行する。(“zfs mount -a”を実行する。ただし、まだHDDが認識されていないのでマウントに失敗する)
- /etc/rc.d/mountcritlocalを実行する。(“mount -a”を実行する。HDDが認識されるまでリトライする)
- (タイミングや実行スクリプトは不明だが、zpool内の残りのzfsをマウントする)
上記3.を実行する仕組みが不明なので、引き続き調査していきたい。