「kernel BUG at include/linux/fs.h:3104!」への対応
昨日のLinux kernel upgradeの後、いくつかのサーバーが応答しなくなった。
より正確に書くと「起動直後の僅かな時間を除いて応答しなくなった」。
なんとかコンソール接続してログを見たら、kernel BUG at include/linux/fs.h:3104!
などと出ていた。
ググっても出てこないのでtwitterを「kernel BUG」で検索したら、以下のツイートがヒットした:
↑の記事によれば、GRUBの設定を弄ってupgrade前のkernelで起動させれば良い、らしいのだが。
GRUBに詳しくなく、見比べながらなんてやってるとすぐ操作不能になってしまう。
操作の時間稼ぎにコレ↓が使えそう。
とりあえず、/boot/grub/grub.cfg
からmenuentry
submenu
を見てupgrade前のkernelのmenu名を探す。
↓参考
その後、/etc/default/grub.d/zzz-workaround-5.13.0-kernel-bug.cfg
みたいな感じで最後に読み込まれるようなファイル名でconfigを作る。
※/etc/default/grub
を弄るだけだと/etc/default/grub.d/*
に上書きされてしまう
# GCEの例
GRUB_DEFAULT="Advanced options for Ubuntu>Ubuntu, with Linux 5.13.0-1027-gcp"
GRUB_TIMEOUT_STYLE=hidden
GRUB_TIMEOUT=0
GRUB_DISTRIBUTOR=`lsb_release -i -s 2> /dev/null || echo Debian`
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash"
GRUB_CMDLINE_LINUX=""
保存したらsudo update-grub
してrebootする。
GCEならコレでupgrade前のkernelで起動してくれた
無事upgrade前のkernelで起動できていればsudo systemctl enable docker.service
して復活させてあげよう。一応rebootもしておこう。
厄介なのはOCI Computeの方で、特にシェイプがVM.Standard.A1.Flexで4OCPU/RAM24GBとかだと、スペックが良すぎて起動が速く、docker serviceが起動するまでホントに時間が無い。
コンソールで「login:
」って出るより前にpanic起こすので、「ssh受け付け開始~panic」の数秒間にシェルに入りdocker serviceを止めなければならない。
流石に無理筋なので、別ルートでの解決を試みる。
問題のインスタンスのVolumeを他のインスタンスにアタッチするところまで
まず、問題のcompute instanceを停止してboot volumeをdetachする。
detachが完了したら、他のcompute instanceにblock volumeとしてattachする。ちゃんと選択肢にそのvolumeが出てくる。
(compute instanceが無ければ作ろう、どうせAlways Freeの範囲で作れる)
attachしたcompute instanceにsshで入る。
iSCSIでのログインが必要なので、「アタッチされたブロックボリューム」内の当該ボリュームのメニューから「iSCSIコマンドおよび情報」を表示し、シェルに1行ずつコピペして実行する。
# 例
sudo iscsiadm -m node -o new -T iqn.2015-12.us.oracle.boot:uefi -p 169.254.0.2:3260
sudo iscsiadm -m node -o update -T iqn.2015-12.us.oracle.boot:uefi -n node.startup -v automatic
sudo iscsiadm -m node -T iqn.2015-12.us.oracle.boot:uefi -p 169.254.0.2:3260 -l
ログインできると以下のようなメッセージが表示される:
Logging in to [iface: default, target: iqn.2015-12.us.oracle.com:c6acda73-90b4-4bbb-9a75-faux09015418, portal: 169.254.0.2,3260] (multiple)
Login to [iface: default, target: iqn.2015-12.us.oracle.com:c6acda73-90b4-4bbb-9a75-faux09015418, portal: 169.254.0.2,3260] successful.
そしたら適当なディレクトリにmountする。sudo mount /dev/sdb1 /mnt
とかでも良い。
時間稼ぎをする
時間稼ぎのsudo systemctl disable docker.service
は使えないが、これに相当する操作をしてやれば良い。
systemdのenable/disableはsymlinkで実現されているらしく、相当する操作は容易にできそう。
multi-user.target.wants
は/etc/systemd/system/
の下にあった。symlinkをrm
で消してやれば良い。
sudo rm /mnt/etc/systemd/system/multi-user-target.wants/docker.service
元のインスタンスに戻す
「iSCSIコマンドおよび情報」に注意書きがある。
なので書いてある通り「アンマウント」→「iSCSI切断」→「デタッチ」→「元のインスタンスにブートボリュームとしてアタッチ」の順序で操作する。
アンマウント
sudo umount /mnt
iSCSI切断
# 例
sudo iscsiadm -m node -T iqn.2015-12.us.oracle.boot:uefi -p 169.254.0.2:3260 -u
sudo iscsiadm -m node -o delete -T iqn.2015-12.us.oracle.boot:uefi -p 169.254.0.2:3260
デタッチ
Web上の管理画面からデタッチ操作をする
元のインスタンスにブートボリュームとしてアタッチ
問題のインスタンスの「ブートボリューム」画面に(デタッチ状態の)ブートボリュームが残ってると思うので、それをアタッチする
これで起動できるはず。
もちろんdocker serviceはdisabledの状態なので、 https://zenn.dev/link/comments/c5970f11f3ae19 に従ってGRUBの設定を弄ってkernelを戻してやる必要がある。
2022-06-10T16:00:00+09:00
時点では、GCE側にはkernelの修正アップデート(5.13.0-1031-gcp
)が降ってきているが、OCI Compute側には来てない。
一応aws/azure/gcp/oracleは"Fix Committed"とのことなので、そのうち降ってくることでしょう。
追記 2022-06-11T14:15:00+09:00
時点でOCI Compute側に修正アップデート(5.13.0-1034-oracle
)が降ってきていることを確認。
aws/azureはvmを動かしてないのでわからないっス。
修正が降ってきたら、workaroundのGRUB設定ファイルを消してupdate-grub
してやれば元通り。
もしかしたら勝手に/usr/bin/docker-proxy
がポート443を取ってしまってコンテナが起動できないかもしれないが、docker serviceをrestartしてやれば直る。
sudo systemctl restart docker