2015年6月2日

QEMU環境で、Kernel Panic VFS が発生する場合の対処法 (確定)

Translation -> Kernel Panic VFS under QEMU - Reason and HowTo

[現象]

VirtIOが有効な環境のQEMUゲストで、Linuxの起動時に、Kernel Panicが発生します。

表示例:
Kernel Panic - not syncing: VFS: Unnable to mount root fs on unknown-block (0, 0)
が表示されます。
※設定(lilo.conf)によって、(0, 0)の中の数字が(253, ?)、(254, ?)などに変わるようです。

※トレースに、intel_pmu_init あるいは intel_raplなどが表示される場合は、別の問題です。
QEMU環境で、Kernel Panic not syncing が発生する場合の対処法


[対応策]


----
注意:
カーネルのビルド時の設定(.config)で、
CONFIG_9P_FS
などを有効にしておく必要があります。(無効の場合は、/dev/vdaなどを認識しないようです。)
CONFIG_9P_FS は、(File systems / Network File Systems)にあります。
※CONFIG_9P_FS は、CONFIG_NET_9Pに依存しています。
CONFIG_NET_9P は、(Networking support / Plan 9 Resource Shareing Support (9P2000))にあります。

----
LILOの場合:
root=ではなく、 addappend=" root="を利用します。

lilo.confの例 (該当部分のみ抜粋):
# root = /dev/vda1
addappend=" root=/dev/vda1"
注意:addappend=の中の root=/dev/vda1に、スペースを含めるのはNGです。
間にスペースがあると、(分解されて) 別のオプションとして処理されます。

補足:なぜ、addappend= を使うと動くのか?
addappend= (または append=) は、boot: プロンプトなどに渡すオプションを指定するものです。

言い換えると、boot: プロンプトで、root=/dev/vda1を指定したら立ち上がるので、
addappend= で、root=/dev/vda1を指定すれば、立ち上がるということです。
(/dev/vda1を、どのタイミングで取得するかが鍵なのだと思います。)

なお、/dev/vda*のメジャー番号を確認した所、
セットアップ時(254)とセットアップ後(253)で異なっていました。


addappend=" root=/dev/vda1"とした場合は、
/dev/vda1のメジャー番号が変わっても立ち上がります。

root=/dev/vda1とした場合は、
最後に"lilo"コマンドを実行した時と、/dev/vda1のメジャー番号が
変わっていない場合のみ、立ち上がります。

メジャー番号が変わっている場合は、
Kernel Panic ・・・ unknown-block (254, 1) が発生します。
(表示されるメジャー番号は、liloを実行した時のもの。)


GRUBの場合も、似たような方法で解決する可能性があります。
(試していないので、未確定です。)

[原因]

udev(あるいはデバイスマッパ)によって、デバイス(/dev/vdaなど)のメジャー番号が
変化するために発生すると現象だと思われます。



参考:
[dm-devel] Weird discrepancy between /dev/mapper/* and /dev/dm-* devices breaks lilo
This is a problem hitting lilo relatively hard as it has logic to
 ignore devices with the same major/minor
訳(一部):「LILOにはメジャー/マイナー番号が被ると、 そのデバイスを無視するメカニズムがある。」

これが、Kernel Panic VFSの、問題の本質の部分だと思います。


関連のありそうな資料:

付録A デバイスマッパー
A.3. デバイスマッパーによる udev デバイスマネージャーのサポート
10-dm.rules:
以下の変数は、10-dm.rules で設定されています。
(略) DM_UUID: デバイスマッパーデバイスのUUID

11-dm-lvm.rules:
LVM デバイス用に適用されるルールを格納し、ボリュームグループの論理ボリュームのシンボリックリンクを作成します。

13-dm-disk.rules:
/dev/disk/by-id、/dev/disk/by-uuid、および /dev/disk/by-uuid ディレクトリー内にシンボリックリンクを作成します。

処理の順番は、10, 11, (12), 13・・・なので、
UUIDを付ける -> LVM関連 -> その他のディスク の順に処理されると思います。
この辺りで何かが起きている予感がします。

[現象の詳細]

・ Slackware のセットアップ時 (セットアップ用DVDで起動)

ls -l /dev/vda*
(略) 254, 0 /dev/vda
(略) 254, 1 /dev/vda1
・・・

注:MBRディスクです。(GPTではありません)
※parted等でmsdosのラベルを付けただけでは、既存のGRUBの1stステージが生き残りますが、
以降の作業でMBRをLILOで上書きしています。 (起動時のGRUB表示はありません。)

環境補足:
/(root), /boot : /dev/vda1 (ext4、パーティションのタイプは83 (Linux))

他に、LVMのパーティションが存在します。


セットアップで、パッケージのインストールまで終了した後の作業
※セットアップ中に表示されるliloconfigは、
MBR(またはルートパーティション)へのインストールでエラーが発生するので、
そこで終了します。

mount /dev/vda1 /mnt
chroot /mnt
mknod /dev/vda b 254 0
mknod /dev/vda1 b 254 1
chmod 660 /dev/vda
chmod 660 /dev/vda1
chown root:disk /dev/vda
chown root:disk /dev/vda1


lilo.conf (抜粋):

boot=/dev/vda
disk=/dev/vda bios=0x80 max-partitions=7
(略)

image = ・・・
# addappend=" root=UUID=・・・"
root = /dev/vda1
label = Linux
(略)

# lilo
Added Linux *


参考: UUIDを使う場合(GPTディスクの場合)
ArchWiki - Persistent block device naming - "Boot managers"
If you are using LILO, then do not try this with the root=... configuration option; it will not work. Use append="root=..." or addappend="root=..." instead.
と書いてあるので、LILOの場合は、root="UUID=・・・"ではなく、
addappend=" root=UUID=・・・"を使います。

append= を使うと、グローバル(共通設定)にあるappend= の「かわりに」.、
imageセクション内のappend= で指定した内容が使われます。

addappend= の場合は、共通設定のappend= に「加えて」、
imageセクション内のaddappend= で指定した内容が使われます。

※append= などの内容は、LILOがチェックしないので注意しましょう。

追記:
ArchWikiの記述は、"UUIDの場合はaddappend=・・・"を使う と書いてあるように見えますが、
UUID以外の指定方法 (/dev/vda1などでの指定)でも、addappend=で問題が解決するようです。

ちなみに、root="LABEL=・・・"や、root="UUID=・・・"という指定自体は有効です。
(起動できるかどうかは、環境次第です。)
参考:
man lilo.conf ("root="のあたりを参照して下さい)


追記2:
ArchWiki - Persistent block device naming
UUID以外の指定方法についての考察などが書かれています。

この中で、
Both contain strings to indicate which subsystem they belong to (i.e. -ide- for by-path, and -ata- for by-id) and thus are not suitable (略)
訳:-ide-や-ata-を含むから、by-pathや、by-idは、
デバイス名の代わりに使う固定の名前としては使えない

と書かれていますが、QEMU(仮想)環境では少し状況が異なります。

tape device pass-through with virtio-scsi
この例に出てくるような、address type='pci'の場合は、-pci-が文字列に現われるかと思います。
例:
ls /dev/disk/py-path
pci-(略)-virtio-pci-(略)

とは言っても、LILOでは使えないようなので、GRUBで試す時用の知識ですが・・
参考程度に。


・ Slackware のセットアップ後 (HDDから起動)

LILOの場合は、起動直後に、次の表示で止まります。
Please append a correct "root=" boot option; here are the available partitions:
fd00 (略) vda driverL virtio_blk
fd01 (略) vda1 (vda1のPARTUUID)
(略) sr0 driver: sr
Kernel Panic - not syncing: VFS: Unnable to mount root fs on unknown-block (0, 0)
CPU: 0 PID: 1 Comm: swapper/0 Not tainted (カーネルバージョン)

"Kernel Panic" "VFS""Unnable to mount root fs"が、この問題を見分けるポイント。
lilo.confの内容により、(0, 0) 以外の数字が表示される場合もあります。

例: (253, ?)、(254, ?)など。

この、 254以外の数字(253)を見かけた というのが、大きなポイント。


PID: 1 (= init)・・・の表示は、/(root)がマウントできないことが原因と推測します。


※GRUBの場合は、起動プロセスがある程度進んだ後で、
Kernel Panic - not syncing: VFSで止まります。
(その分、原因の切り分けが困難になります。)

→ sr0 (CD/DVD)の後に、Kernel Panic VFSの表示が出るので、
HDD側か、DVD側か、仮想化(virtio、9P)関連か、
(GRUB自体も独立したモジュールを持っているので)GRUB関連か、
それとも他の問題(QEMU、Bochs関連など)か、切り分けが困難になります。

systemdも利用している環境では、さらに、initrdの問題も検討対象となります。

GRUBを利用している場合は、pagerなどのオプションを利用して、
起動画面を一時停止しながら見るとよいと思います。

参考:
ArchWiki - GRUB 「デバッグメッセージを有効にする」
以下を grub.cfg に追加してください:
set pager=1
set debug=all
追加する場合は、menuentryの中に書きます。
※あまり・・・かなり・・・お勧めしませんが。
(余計な表示が9割以上あって、本来の表示を探すのに苦労します。)

「systemd debug」などで検索してみるとよいかと思います。


・ Slackware のセットアップ後
(セットアップ用DVDのboot:プロンプトで、root=/dev/vda1 などを指定して起動)

セットアップ後のLinuxが立ち上がります。
/dev/vda  : (254, 0)
/dev/vda1: (254, 1)
になっています。

LVM管理下のディスク:
/dev/mapper/(略)  -> /dev/dm-0
/dev/dm-0 : (253, 0)
になっています。

0 件のコメント:

コメントを投稿