別のブログで書いた記事の転載です。
http://trid-miracle.blogspot.jp/2015/06/qemukernel-panic-vfs.html
環境:QEMU/KVS
・仮想化IO(VirtIO)が有効な場合
Net9P/9Pfsとデバイスのメジャー番号に由来する現象
現象
起動時に
Kernel Panic - not syncing: VFS: Unnable to mount root fs on unknown-block (0, 0)
が表示されます。
※(0, 0)は、設定によって、(253, 0)、(254, 0)などになる場合があります。
原因1
・カーネルのビルド時のconfigで、9Pfs関連の設定がNになっているため発生します。
(例えば、CentOS7では、デフォルトがNになったと、どこかに書いてあったと思います。)
設定はあちこちに分散しています。
関連する設定:
Networking support / Plan 9 Resource Shareing Support (9P2000)
CONFIG_NET_9P
File systems / Network File Systems
CONFIG_9P_FS
など。
対策1
9Pfs関連の設定項目をYにして、カーネルをビルドします。
原因2
設定時と起動時などで、デバイスのメジャー番号が変わるために発生します。
udev、devicemapperがメジャー番号を付け替えるのが原因です。
対策2
LILOの場合
root=
ではなく、addappend=" root="
を使います。
※メジャー番号を認識するタイミングの問題です。
root=/dev/vda1
の場合は、(lilo.confを書き換えた後に)liloを実行した時に決まります。
言い換えると、liloの実行後に、メジャー番号が変わると、Kernel Panicが発生します。
addappend=" root=/dev/vda1"
の場合は、起動時に(文字列で指定する)起動オプションに" root=/dev/vda1"を付け加えるので、正常に起動します。
言い換えると、すでに/dev/vda1メジャー番号は決まった。その/dev/vda1で行ってくれ!という感じです。
appendの設定を間違えると、「メジャー番号は決まった。さあ、どこから起動する?」という状態でLILOの表示が止まるので、挙動がわかりやすいと思います。
appendに相当する設定は、Linuxの起動時に、Tabキーなどを押下すると入力できます。
appendの設定を試したい時などに。
ちなみにliloの設定ファイルの、
append=
は、全てのイメージに共通する設定、
addappend=
は、イメージ毎に設定を追加したい時などに使います。
addが付いている方は、その名の通り、append=
の設定にadd(追加)する設定です。
SlackwareのDocumentなどから。
(LILOを使用する場合) /boot、/(root)をLVMに置くのは非推奨です。
また、/(root)と/usrは同じパーティションに置いた方がよい(そうでないと、起動処理が複雑になる) ともされています。
LVMに/(root)などを配置した場合は、(initrdなどで)LVM用のモジュールなどの読込オプションが必要になります。
(カーネルをビルドして使う場合は、ディスク、ファイルシステム関連のオプションはM(モジュール)でなくY(組み込み)の方がよいと思います。)
LILOは、GPTディスクに非対応です。また、2015年いっぱいで開発終了とのことです。
(ELILOは2014年で開発終了になっています。)
とはいっても、VPS環境で、GPTを使うメリットがあまりないように思います。
(ディスクの容量的にも、障害対応的にも。)
パーティションテーブルのバックアップを戻す機会も無いでしょうし・・
(障害を起こしたセクタに、書き戻しても・・ということで、交換になると思います。)
余談:
起動時に表示される"LILO"は、実は意味があるのです。
"LI"が1st boot loader、"LO"が2nd boot loader。
(開始と終了で、1文字ずつ進んで行きます。)
ハードディスクからの起動では、早すぎてわからないと思いますが・・
覚えておくと役に立つかもしれない、ワンポイント。
参考資料:
LILO "the Linux Loader" の動作について
GRUBの場合も、似たような動作なので、さらっと目を通しておくとよいかも。
(ブートセクターの先頭 438 bytes とか、ね!)
GRUB (+ systemd)の場合
LILOと同じように、/dev/vdaのデバイス番号が決まった後に、どのrootを使うかを指定できれば・・解決するはずなのですが・・・・・
GRUB環境で実験した場合、起動時に手入力でlinux=
~~などを設定すると起動できた・・と思います。
(その時は、grub.confなどでは回避できなかった記憶があります。)
/bootと/(root)を別パーティションに置いている時は、/(root)をLVMに置くと起動できたような気もしますが・・・
一見、起動がある程度すすんだ後に(cdを認識したタイミングなどで)Kernel Panicが発生したように見えるので、原因を知らずに見ると、解析が非常に困難です。
GRUB(のモジュール) -> Linux(のモジュール) -> systemdのどこで出た表示かを正しく推理しましょう。
BIOS環境なのか、UEFI環境なのかも、把握しておきましょう。(システム、Linuxそれぞれの環境を。)
EFIパーティションがあるからといって、UEFI環境とは限りません。
(一旦ハードディスクをまっさらにしてみたら、UEFIシェルが表示されなかった・・なんてことも。)
・・ということで、GRUB環境でこの手の問題にはまると、解決まで相当時間がかかります。
標準でGRUB以外を使用しているDebianなどがデフォルトで用意されている場合は、一旦、それをインストールしてみるのも一手です。
新規のインストール(デフォルトの「動く」環境から乗り換える場合など)の場合は、Linuxが動く状態で十分に情報収集してからOSを差し替えることをお勧めします。
特に、/boot やEFI関連、/etc、/var/log、dmesgやlspciの結果などは、可能であれば手元にコピーしておきましょう。
/sys/firmware/efi
が存在するか も重要です。
(BIOS環境なのかUEFI環境なのかの判定用に)
参考:ArchWiki
Unified Extensible Firmware Interface
(BIOSとUEFIの)ハイブリッド起動ディスクだと起動しない(または、画面が真っ黒のまま) という場合もあります。
その場合は、一旦、BIOS専用の起動ディスクを作って起動してみましょう。
起動ディスクに必要なファイル。
Slackwareの場合
/isolinux/initrd.imgなど
/kernel/huge.s/bzImageなど (カーネルを差し替える場合は、これを入替えます)
他のディストリビューションでも、基本は同じだと思います。
あとは、mkisofsの-bオプション、-cオプションで、起動可能ディスクを作ります。
あと、必要なモジュールもどこかに。
(Linuxのインストール後にコピーするために。)
※カーネルのconfigで、ハードディスクとCD-ROM/DVDにアクセスするための項目は、必ずYにします。M(モジュール)だとだめです。
追記:
RedHat製品マニュアル から、一部抜粋。
付録A デバイスマッパー
A.3. デバイスマッパーによる udev デバイスマネージャーのサポート
表A.1 デバイスマッパーデバイス向けの udev ルール
10-dm.rules
11-dm-lvm.rules
13-dm-disk.rules
以下の変数は、10-dm.rules で設定されています。
DM_UUID: デバイスマッパーデバイスのUUID
以下の変数は、11-dm-lvm.rules で設定されています。
DM_LV_NAME: 論理ボリューム名
10-dm.rules
基本的/一般的なデバイスマッパールールを格納し、/dev/mapper 内に /dev/dm-N をターゲットとするシンボリックリンクを作成します。ここで N は、カーネルによってデバイスに動的に割り当てられる数です。 (/dev/dm-N はノードです)
注意: /dev/dm-N ノードは、デバイスにアクセスするスクリプトには 決して 使用されるべきではありません。N の数は動的に割り当てられ、デバイスがアクティブ化される順序によって変化するためです。
11-dm-lvm.rules
LVM デバイス用に適用されるルールを格納し、ボリュームグループの論理ボリュームのシンボリックリンクを作成します。このシンボリックリンクは、/dev/vgnameディレクトリーに、/dev/dm-N をターゲットとして作成されます。
13-dm-disk.rules
/dev/disk/by-id、/dev/disk/by-uuid、および /dev/disk/by-uuid ディレクトリー内にシンボリックリンクを作成します。
(注:by-uuidが2つ並んでいますが、おそらくby-pathまたはby-labelの誤記です)
まとめると、LVM管理化のディスクと、それ以外で、挙動が変わるということです。
また、LVM管理化にないディスクにUUIDでアクセスするためには、13-dm-disk.rulesの処理が終了している必要があります。
・・・では、これらのディスクに、起動時にどうやったらアクセスできるでしょう?というのが、今回の話題の根底にある問題。
(ブートローダは、基本的には、1番目のディスクの、指定セクタを読み込むという動作なので、/bootなどにアクセスできます。)
どのデバイス名でアクセスしたらよいか についての参考資料。
RedHat製品マニュアル
[4.4.8. 永続的なデバイス番号]
(https://access.redhat.com/documentation/ja-JP/Red_Hat_Enterprise_Linux/6/html/Logical_Volume_Manager_Administration/persistent_numbers.html)
[4. Persistent Naming]
(https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/5/html/Online_Storage_Reconfiguration_Guide/persistent_naming.html)
Archlinux Wiki
[Persistent block device naming]
(https://wiki.archlinux.org/index.php/Persistent_block_device_naming)
※by-idやby-pathで-ide-
などを含むから使えないと書かれていますが、KVMなどの仮想化環境では、(ホスト側の設定で固定で割り振った)-PCI-
などになっているかと思います。
ふぅ。