initramfs を再生成した話

結論: エラーメッセージはきちんと確認しましょう、もし出たときは対処しましょう。
こんな基本的なこともできていなかったのか、って自分が嫌になります。

先日、筆者が利用しているArch Linux が起動できなくなりました。その際の原因判別方法と修繕方法を書き残しておきます。これが最善であるとは到底思えませんが。

Arch Linux へなちょこユーザーである筆者は、その日も $ sudo pacman -Syu と入力して最新のパッケージに更新しようとしました。いや、これには語弊があるかもしれません。私の ~/.bashrc には以下の記載があります。

alias update='sudo freshclam && sudo pacman -Syu && rustup update && gem update'

即ち、ClamAV (*nix 環境上にて様々なマルウエアを検出するソフトウエア) の検出パターンファイルや、Rust 言語の開発途上版 (nightly) なども一括で更新してくれる、そのようなスクリプトを書いて日々 $ update などとしていました。ただ、何も考えず実行していたので、先日その実行に失敗しましたときに、気づかずじまいにしていました。時間の経過と共にログは削除されてしまった上に、ログには個人情報も含まれているので、ここにログを貼り付けることはできませんが、結果だけ述べると、inird ファイルの生成に失敗していました。そのファイルを別プロセスが使用しており、書き換えられない状況にしてしまったからだと考えています。そのブロックを解除した状況で、initrd ファイルを

$ mkinitcpio -g /boot/initramfs-linux.img

として生成し直せば終わりでした。update コマンドの実行後は最低限 $? 環境変数を参照することでエラーの有無を確認するべきです。

上に書いたもので問題とその解決策は終わりです。たったこれだけです。

ただ、私の能力では、この解決策を中々行えませんでした。以下では、この結果に至るまで、筆者の行動を時系列にて再現してみようと思います。自分の無能さを積極的に晒していく、ある意味ゲジゲジですね。

以下の対処方法は、自明に劣っているので、参考になりません。優越感に浸りたい方はぜひ先に進んでください。それとも、解決策を探しにこられた方は、先の解決策を検討して、それでこのページを閉じたらよいかと思います。

3月18日

数日インターネットに接続していなかったPC を再び起動させ、F12 でブートメニューに入りArch Linux を選択。そして表示された systemd-boot の画面で 「Arch Linux」を選択。systemd による起動プロセスを眺めた後、相変らず長いパスワードに辟易しながらログイン。ネットワークをnetctl で立ち上げて、問題の $ update を何も考えず実行していた。

その後はいつも通り不調に苦しみつつネットサーフィンをして、AtCoder の過去問を解いたり、BusyBox のソースコードを読んだり。勿論「進捗がない」「情報学科の底辺のくせに生きている馬鹿」「しにたい」と書くことも忘れずに。あ、そういえばロシア語のタイピング練習もしていた気がする。

3月19日

朝から憂鬱さに押しつぶされそうになりつつ Arch Linux を起動させた… つもりが様子がおかしい。まずroot ファイルシステムが認識されない。そんなLabel が存在しないと表示される。あれ、その前を見るとmodule の読み込みに失敗している。そうこうしているとinitramfs 上にあるrescue console に出てしまった。ただ、入力できない。何も打てない。無論マウスも動かない。電源ボタンを何秒か押して強制的に電源を切るしかない、何これ。

LTS 版のLinux Kernelも導入してあるので、 systemd-boot の画面で選択してみる。あれ同じだ。

とりあえず、Solid Stage Drive の障害かと思い、手元にある UEFI Shell から動作するか試した。UEFI Shell はほとんど利用してこなかったし、とりあえず help と打った。ずらずらずらぁぁ、とのんびり出てくるヘルプメッセージを見て少しいらだちつつ、ただこんなのでいらつく私に生存権はない、って思ってたら、とりあえず ls と打てばいいんだな、っていう気持ちになった。

ls

ずらずらずらぁぁ… うん、 cd DISK1: あれ動かない。以下はとても長く、省きますが、結局UEFI Shell ではBtrFS 上に構築されたArch Linux のルートディレクトリを読み込めませんでした。これに小一時間程を浪費しました。

教訓: いきなり新しいものに飛び付くべきでない

結局よく分からなかったので、Universal Serial Bus Memory に入っているArch Linux のiPXE ファイルを用いネットワーク経由での起動を試すことにする。そして、毎回ネットワークからファイルを入手する筆者は一体いかに無駄な存在なのだろうか、としにたみにふけりつつ、起動したArch Linux インストーラ環境で

# fdisk -l

うん、認識されている。そして、

# mount /dev/sda4 /mnt

と打ってみると普通に認識され、内容を書き換えられる。

注: 今から考えると、このmount コマンドの方法は不適切です。正常に稼動しているかどうか分からないディスクをいきなり書き込み可能な状況にてマウントすべきでありません。読み込み専用でマウントして、fsck などを実行し異常の状況を確認すべきです。

そのときはとりあえず

# mount /dev/sda1 /mnt/boot (EFI System Partitionをマウント)

# genfstab -U > /mnt/etc/fstab

として、UUID を正しいものに書き換えて、再起動することとした。

ただ、一向に直らない。どうしようもなく嫌気が差したので、(表向きの理由は、別の用事があったので) このPC に元から入っていた不自由なWindows 10 上で作業をした。そして暫し泳ぎ疲れて眠った。

3月20日

この日は少し精神不安定がましだった。たぶんElixir + Mix + Pheonix で作りたいものがあったからだろう。結局挫折したけど。

ということで、Arch Linux の起動を試みてみると、ふと「module がロードされていない」旨が気になった。あれ、UUID は設定し直したから、なぜroot が認識されないのだろうか。module の場所はLinux kernel のバージョンにより異なることも思い出した。更新した後何も考えず modprobe を実行しようとして失敗し続けていたからだろうか。

あれあれ???

再びArch Linux のiPXE ファイルから起動した。ネットワークから起動するなんて地球温暖化の申し子な私はしぬべきと感じつつ、部屋の窓を眺めていた。そして、いつも通り # mount を打ち、 # arch-chroot /mnt にて入った。

とりあえず、 # pacman -S linux としてLinux kernel を再インストール。そこでmkinitcpio は勝手に動作するので動作してうまくいったのを確認。再起動。

あれ、initramfs の端末。ただ今回はキーボードで入力できる。ただ、exit で抜けるとKernel Panic に陥る。なぜだ。

ここでふと気づく。あれ、UUID 更新忘れてない?

ちなみにこの時にUUID の変更に /boot/loader/entries 以下にある systemd-boot の設定ファイル群を追従させていなかったので、あれ起動しない、などとなったので、直した。ちなみに、これは initramfs 上のBusyBoxがシェルなので、vi なども最低限度の機能しかない。そのときは /etc/fstab に書かれている正しいUUID を tail -n 1 /mnt/etc/fstab >> /mnt/boot/loader/entries/arch.conf などとして書き加えるというバッドノウハウを実行してしまった。

教訓: 何かしら修正する際には、その影響範囲も考慮しよう

さて再起動。動いた!!!

まわりを考慮しよう

何か修正する際に、その影響を考慮するのは大事だということを改めて思い知らされました。この辺に筆者の能力のなさが露呈しています。精進します。

こんな記事の最後まで読んでくださりありがとうございました。無能だとでも笑ってやってください。それでは。

コメント

  1. nininga より:

    正直何を書いているのかよく分からなかったので
    ほぼ読み飛ばしてしまいました、ごめんなさい