なぜ UUID でルート ファイル システムを指定できないのですか?

なぜ UUID でルート ファイル システムを指定できないのですか?

私のシステムは、GRUB 2 設定で次のようにすると正常に起動します。

linux   /bzImage root=/dev/sda2 init=/usr/lib/systemd/systemd ro

/dev/sda2しかし、対応する UUID に置き換えると:

linux   /bzImage root=UUID=666c2eee-193d-42db-a490-4c444342bd4e init=/usr/lib/systemd/systemd ro

起動中に失敗します:

kernel panic - not syncing: VFS: unable to mount root fs on unknown-block(0,0)

UUID は正しいようです:

# blkid
/dev/sda1: UUID="97ac3744-39de-4d6d-9a81-e3a3ea08a8bb" TYPE="ext2" 
/dev/sda2: UUID="666c2eee-193d-42db-a490-4c444342bd4e" TYPE="ext4" 

なぜ動作しないのでしょうか? initramfs を使用していないからでしょうか?

これはカーネル 3.10.7 を搭載した x86_64 Gentoo Linux です。 では MBR パーティション テーブルsda、 では GUID パーティション テーブルを使用していますsdb

答え1

念のため明確にしておくとUUID、UUIDはカーネルがハードドライブを識別する唯一の信頼できる方法です。UUIDには2つの種類があります。UUIDはファイルシステムに保存され、起動時にはカーネルから利用できません。PARTUUIDはパーティションテーブルに保存され、起動時に利用できます。したがって、

root=PARTUUID=SSSSSSSS-PP

/dev/sd??デバイスのプラグの接続/切断によって変化する可能性があります。

忘れないでください大文字にするSSSSSSSS-PPから得られる16 進数blkid!

より使いやすく

root=LABEL=
root=UUID=

これらの識別子を取得するでのみ機能しますinitramfs

したがって、空でない を使用するとinitramfs、3 つすべてを持つことができます。 が空の場合はinitramfs、 のみになりますPARTUUID

答え2

UUID から起動するために渡す必要があるパラメータは ですPARTUUID。したがって、 である必要がありますroot=PARTUUID=666c2eee-193d-42db-a490-4c444342bd4e

ドキュメントでは、なぜそれが戻ってくるのかを次のように説明していますunknown-block(0,0)

カーネルパラメータ.txt:

    root= [KNL] ルートファイルシステム
            init/do_mounts.c の name_to_dev_t コメントを参照してください。

初期化/do_mounts.c:

/*
 * 名前をデバイス番号に変換します。次の形式が使用できます。
 *
 * 1) 16進数のデバイス番号はそれ自身を表します
 * 2) /dev/nfsはRoot_NFS(0xff)を表します
 * 3) /dev/<disk_name>はディスクのデバイス番号を表します
 * 4) /dev/<disk_name><decimal>はデバイス番号を表します
 * パーティション - ディスクのデバイス番号とパーティション番号
 * 5) /dev/<disk_name>p<decimal> - 上記と同じで、形式は
 * パーティション化されたディスクのディスク名が数字で終わる場合に使用されます。
 * 6) PARTUUID=00112233-4455-6677-8899-AABBCCDDEEFFは、
 * パーティション テーブルが提供する場合のパーティションの一意の ID。
 * UUIDはEFI/GPT UUID、またはMSDOSを参照します。
 * SSSSSSSS-PP形式を使用したパーティション。SSSSSSSSはゼロから始まる
 * 32ビットの「NTディスク署名」の16進数表現、およびPP
 * は、1 から始まるパーティション番号の 0 で埋められた 16 進表現です。
 * 7) PARTUUID=<UUID>/PARTNROFF=<int> でパーティションを選択する
 * 既知の一意の ID を持つパーティション。
 *
 * 名前が上記のカテゴリに該当しない場合は、(0,0) を返します。
 * block_classは、何かがディスク名であるかどうかを確認するために使用されます。ディスクが
 * 名前にスラッシュが含まれている場合、デバイス名ではスラッシュが次のように置き換えられます。
 * 前髪。
 */

最後の部分では、値を理解できない場合は を返すと書かれており(0,0)、これがエラーの原因です。

答え3

これは 5 年前のスレッドです。しかし、私の意見では、まだ完全には答えられていません。少し例が欠けています。これがそれです:

この例では、

/dev/sda3 = /
/dev/sda2 = swap

...GPT パーティションを使用します。MBR (DOS パーティション) では PARTUUID は短くなりますが、手順は同じです...

blkid を使用して PARTUUID を取得します。

blkid -s PARTUUID -o value /dev/sda3 # root
77fd7830-faa2-4e99-a48b-337ad9eded28
blkid -s PARTUUID -o value /dev/sda2 # swap
5b63167a-6fd2-4e72-948c-90832372956c

: : ブートローダの grub ディレクトリに grub.cfg を作成します。

search --no-floppy --part-uuid --set=root 77fd7830-faa2-4e99-a48b-337ad9eded28

menuentry "GNU/Linux, KERNEL 4.12.7-lfs-8.1" {
  linux /boot/vmlinuz-4.12.7-lfs-8.1 root=PARTUUID=77fd7830-faa2-4e99-a48b-337ad9eded28 net.ifnames=0 ipv6.disable=1 ro rootwait rootfstype=ext4
}

/etc/fstab/:

PARTUUID=77fd7830-faa2-4e99-a48b-337ad9eded28 / ext4 noatime,nodiratime,errors=remount-ro 0 1
PARTUUID=5b63167a-6fd2-4e72-948c-90832372956c swap swap pri=1 0 0

これは lfs8.1 (カーネル 4.12.7) で動作することがわかっていますが、他のほとんどのカーネル (古いものや新しいものなど) でも動作するはずです。

関連情報