Linux kernel 5.2.1がreleaseされたのでいつも通りにcustom kernelをbuildしてupdateした所、grub2 (bootloader)の設定がどこかの時点でおかしくなっていたらしくunbootableとなった。
色々と調べつつDebian liveからGRUB2を入れ直して復旧できたので手順を記録しておく。
症状と原因
...
symbol `grub_file_filters' not found
grub rescue>
lsすると(hd0,msdos1)みたいなのが表示される。環境依存だが、今回は(hd0,msdos1)が/dev/sda1で/bootに割り当ててあるpartition。
insmod normal.mod
を実行するとsymbol not foundが出る。insmod normal.modできないとnormalになれずbootもできない、と。
どうやらupgradeしたgrub2のpackageそのものか、grub2のinstallation processに問題があったようだ。
rebootのlogとaptitudeによるupgradeのlog
* grub2関連packagesがupgradeされたのは7/10 (2.02+dfsg1-20 → 2.04-1)
* それ以降のrebootは今回 (7/18)が初めてだった (`last reboot`で調べられる)
復旧の用意
正常に稼働するmachineでDebian liveのUSB flash memoryを作製する。今回は別のLinux boxを利用した。
Debian liveのUSB用imageをdownloadする
速度や負荷の面からrikenやjaistなど日本国内のmirror siteを使うと良いだろう。今回はrikenからdebian-live-10.0.0-amd64-standard.isoをdownloadした。GUIは不要との判断からstandardを選択したが、好みでXfceなどのdesktop environmentのflavorsも使える。
standardだとDEがないのでfilesizeが小さい、USB flash memoryへの書き込みが速く終わる、起動が速い、などの利点がある(ように思う)。boot後は自動loginですぐconsoleが使えるようになるので面倒がない点も良い。
USB flash memoryに書き込み
書き込み先のUSB flash memoryは/dev/sdbとして認識したが環境依存。危険なcommandなので必ず書き込み先を確認する。あとblocksize (bs)は適当なので最適値かどうかは不明。
% sudo dd if=debian-live-10.0.0-amd64-standard.iso of=/dev/sdb bs=10M
復旧の手順
ここから復旧対象のmachineでの作業。
BIOS/UEFIのmenuからboot deviceの順序を変更する
USB flash memoryを最優先にする。BIOS/UEFIによって様々だが、一通り眺めればわかるだろう。今時のUEFIだとどんなdevice(s)が接続されているかも表示されることが多いと思う。
Debian liveから起動
USB flash memoryからbootするとmenuが表示される。Install
ではなく、Debian liveを選ぶ。standardだとconsoleに自動loginなので面倒がなくて良い。
なお、Debian liveでは(次回のsessionには保存されないが)必要なDebian packagesを後付けでinstallできる。defaultではLUKSやGRUB2のpackagesが入っていないので、これを導入する。
packageを導入するにはまずnetworkをどうにかする必要がある。ここも環境依存なのだが、今回復旧対象のmachineはstaticにIPv4 addressを割り当てているのでip commandで関連の設定を行う。
IPv4 addressの割り当て
対象のnetwork interfaceはenp0s****として認識された。環境依存。
% ip addr show # どんなnetwork interface(s)があるか、どんなaddressが割り当てられているか
% sudo ip addr del 169.254.13.127/16 dev enp0s**** # 不要なaddress (多分autoで設定されているやつ)を削除しておく。不要だとは思うが念のため
% sudo ip addr add 192.168.11.2/24 dev enp0s**** # 普段machineに割り当てているaddressをassignする
routingの設定
このままだと外に出て行けないのでdefault gatewayを設定する。今回使うrouterのaddressは192.168.11.1。
% ip route show # 現在のrouting tableの確認
% sudo ip route add default via 192.168.11.1 # routerのaddressをdefault gatewayに指定
nameserverの設定
まだdomain nameのresolveができないのでnameserverを指定する。今回はdefault gatewayと同じaddress。
% sudoedit /etc/resolv.conf
> nameserver 192.168.11.1
aptのmirrorを設定
ここまででnetwork installが使えるようになったので、日本国内のmirror serverを設定する。今回はftp.jp.debian.orgを指定した。
% sudoedit /etc/apt/sources.list
> ftp.jp.debian.org
必要なDebian packageのinstallation (#1 LUKS)
前述の通り、Debian liveにはLUKSもGRUB2もdefaultでは入っていないので、別途installする必要がある。networkを設定したので導入可能な状態。
まずはcryptsetupを導入する。grub2は後で別にinstallする。
% sudo apt-get update
% sudo apt-get install cryptsetup
cryptsetupでLUKSの領域をmount
復旧対象machineのSSDは/dev/sdaとして認識されていて、/dev/sda1が/boot、/dev/sda5がroot (LUKSでencrypted)。
% sudo cryptsetup luksOpen /dev/sda5 secured_root # "secured_root"は何でも良いので適当な名前をつける
% sudo mount /dev/mapper/secured_root /mnt # ↑で適当に付けた名前が/dev/mapper/以下に現われるのでそれをmountする
% sudo mount /dev/sda1 /mnt/boot # LUKSで暗号化されたroot partitionに本来の (現在は壊れているので復旧対象の)/bootをmountする
必要なDebian packageのinstallation (#2 GRUB2)
% sudo apt-get install grub2
installationの最中に、grubの設定に関するgraphical menuが出るがcancel。
GRUB2をSSDへinstallし直す
あくまで対象はSSD (/dev/sda)であって、USB flash memoryではないことに注意。
% sudo grub-install --root-directory=/mnt /dev/sda
再起動してUSB flash memoryを引き抜く
% sudo shutdown -r now
reboot後、本来のGRUB menuが出れば復旧完了。
必要に応じて変更したBIOS/UEFIの設定(boot deviceの優先順位)を元に戻す。
参照したwebsites
* [Linux Set Up Routing with ip Command - nixCraft](
https://www.cyberciti.biz/faq/howto-linux-configuring-default-route-with-ipcommand/)
* [grub rescueでnormal.modがnot foundですとか言われた話 - ひびっちぇ どっとこむ](
http://hibitche.hatenablog.jp/entry/2015/07/17/012051)
* [WM×LI: grub rescue が表示されても慌てずに.](
http://nort-wmli.blogspot.com/2013/06/grub-rescue.html)
* [#931896 - grub-efi-amd64: symbol `grub_file_filters` not found - Debian Bug report logs](
https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=931896)