为什么我不能用 UUID 指定我的根文件系统?

cjm*_*cjm 34 linux boot uuid

我的系统在我的 GRUB 2 配置中启动正常:

linux   /bzImage root=/dev/sda2 init=/usr/lib/systemd/systemd ro
Run Code Online (Sandbox Code Playgroud)

但是如果我/dev/sda2用相应的 UUID替换:

linux   /bzImage root=UUID=666c2eee-193d-42db-a490-4c444342bd4e init=/usr/lib/systemd/systemd ro
Run Code Online (Sandbox Code Playgroud)

然后在启动过程中失败:

kernel panic - not syncing: VFS: unable to mount root fs on unknown-block(0,0)
Run Code Online (Sandbox Code Playgroud)

UUID 似乎是正确的:

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

为什么不起作用?是因为我没有使用 initramfs 吗?

这是内核为 3.10.7 的 x86_64 Gentoo Linux。我正在使用 MBR 分区表sda和 GUID 分区表sdb

ine*_*iti 29

只是为了澄清UUIDs 是内核识别硬盘驱动器的唯一可靠方法。有两种类型:UUID,它存储在文件系统中,在启动时内核不可用,以及 PARTUUID,它存储在分区表中,在启动时可用。所以你必须使用

root=PARTUUID=SSSSSSSS-PP
Run Code Online (Sandbox Code Playgroud)

作为/dev/sd??可以与设备改变插入/拔出。

不要忘记将你得到的十六进制数大写SSSSSSSS-PPblkid

越容易使用

root=LABEL=
root=UUID=
Run Code Online (Sandbox Code Playgroud)

仅适用于initramfs获取这些标识符的 。

所以,如果你使用一个非空的initramfs,你可以同时拥有这三个!有了空initramfs,你才有PARTUUID


phe*_*mer 20

从 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) 十六进制的设备号代表自身
 * 2) /dev/nfs 代表Root_NFS (0xff)
 * 3) /dev/<disk_name> 代表磁盘的设备号
 * 4) /dev/<disk_name><decimal> 代表设备号
 * of partition - 磁盘的设备号加上分区号
 * 5) /dev/<disk_name>p<decimal> - 同上,那个形式是
 * 当分区磁盘的磁盘名称以数字结尾时使用。
 * 6) PARTUUID=00112233-4455-6677-8899-AABBCCDDEEFF 代表
 * 如果分区表提供了分区的唯一 ID。
 * UUID 可以是 EFI/GPT UUID,也可以是 MSDOS
 * 使用 SSSSSSSS-PP 格式进行分区,其中 SSSSSSSS 是零-
 * 填充了 32 位“NT 磁盘签名”的十六进制表示,以及 PP
 * 是基于 1 的分区号​​的零填充十六进制表示。
 * 7) PARTUUID=<UUID>/PARTNROFF=<int> 选择一个分区
 * 具有已知唯一 ID 的分区。
 *
 * 如果 name 不属于上述类别,则返回 (0,0)。
 * block_class 用于检查某个东西是否是磁盘名称。如果磁盘
 * 名称包含斜杠,设备名称将它们替换为
 * 刘海。
 */

最后的最后一点表示,如果它无法理解该值,则返回(0,0),因此您的错误。

  • 所以我猜真正的答案是内核不支持`root=UUID`,只支持`root=PARTUUID`。如果你想使用文件系统 UUID,我猜你需要一个可以通过 UUID 处理挂载文件系统的 initramfs。 (7认同)
  • @terdon,我敢打赌你有一个 initramfs 或 initrd。(它可以链接到您的内核而不是一个单独的文件。) (3认同)

Mic*_*idt 5

这是一个 5 年前的帖子。但恕我直言,它仍然没有得到完全回答。缺少一个小例子。这里是:

在这个例子中:

/dev/sda3 = /
/dev/sda2 = swap
Run Code Online (Sandbox Code Playgroud)

...使用 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
Run Code Online (Sandbox Code Playgroud)

/boot/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
}
Run Code Online (Sandbox Code Playgroud)

/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
Run Code Online (Sandbox Code Playgroud)

众所周知,这可以与 lfs8.1(内核 4.12.7)一起使用,但我认为它也应该与大多数其他内核一起使用(较旧的和较新的......)