![找出Linux中/dev/root代表什么设备?](https://linux22.com/image/16945/%E6%89%BE%E5%87%BALinux%E4%B8%AD%2Fdev%2Froot%E4%BB%A3%E8%A1%A8%E4%BB%80%E4%B9%88%E8%AE%BE%E5%A4%87%EF%BC%9F.png)
在linux上,有一个/dev/root
设备节点。这将是与另一个设备节点相同的块设备,例如/dev/sdaX
.在这种情况下,如何解析/dev/root
“真实”设备节点,以便向用户显示合理的设备名称?
例如,我在解析/proc/mounts
.
我正在寻找可以通过 shell/python 脚本运行但不能通过 C 运行的解决方案。
答案1
解析root=
来自 的参数/proc/cmdline
。
答案2
这可能应该更新,因为这里给出的很多信息都是误导性的,而且实际上可能从来都不是完全正确的。
https://bootlin.com/blog/find-root-device/
对于 / 挂载点,只是告诉您它对应于 /dev/root,这不是您要查找的真正设备。
当然,您可以查看内核命令行并查看指示 Linux 在哪个初始根文件系统上启动(root 参数):
$ cat /proc/cmdline mem=512M console=ttyS2,115200n8 root=/dev/mmcblk0p2 rw rootwait
但是,这并不意味着您看到的是当前的根设备。许多 Linux 系统在中间根文件系统(如 initramdisks 和 initramfs)上启动,这些文件系统仅用于访问最后一个根文件系统。
这里指出的一件事是 /proc/cmdline 中的内容不一定是实际存在的实际最终设备根目录。
这是来自 busybox 的人,我想他们知道在启动情况下他们在说什么。
https://www.linuxquestions.org/questions/slackware-14/slackware-current-dev-root-688189/page2.html
我发现的第二个有用的资源是一个关于 /dev/root 问题的非常古老的 Slackware 线程,从该线程的时代开始,我们可以看到所有变体始终存在,但我相信“大多数”发行版都使用符号link 方法,但那是一个简单的内核编译开关,如果我正确理解了海报,它可以制作一个,也可以不制作一个,也就是说,以一种方式切换它,readlink /dev/root 报告真实的设备名称,切换它另一个,但事实并非如此。
由于该线程的主要主题是如何摆脱 /dev/root,因此他们必须了解它实际上是什么、它的组成部分等,这意味着他们必须了解它才能摆脱它。
咬牙切齿地解释得很好:
/dev/root 是可在 fstab 中使用的通用设备。还可以使用“rootfs”。这样做有一些好处,因为它可以让您不那么具体。我的意思是,如果根分区位于外部驱动器上,它可能并不总是显示为同一设备,并且成功安装它/需要更改 fstab 以匹配正确的设备。通过使用 /dev/root ,它将始终匹配 lilo 或 grub 的内核引导参数中指定的任何设备。
/dev/root 始终作为虚拟挂载点存在,即使您从未见过它。 rootfs 也是如此(将其与 proc 和 tmpfs 等没有前置 /dev 的特殊虚拟设备进行比较)
/dev/root 是一个虚拟设备,如“proc”或“/dev/tcp”。 /dev 中没有用于这些事情的设备节点 - 它已经作为虚拟设备存在于内核中。
这解释了为什么符号链接不一定存在。令我惊讶的是,我以前从未遇到过这个问题,因为我维护着一些需要了解此信息的程序,但迟到总比不到好。
我相信这里提供的一些解决方案“通常”会起作用,并且可能是我会做的,但它们并不是问题的实际解决方案,正如 busybox 作者指出的那样,在非常复杂的情况下实现起来要复杂得多。稳健的方式。
[更新:}在获得一些用户测试数据后,我将使用 mount 方法,至少在某些情况下这似乎没问题。 /proc/cmdline 没有用,因为有太多变体。在第一个示例中,您看到的是旧方法。这种情况越来越少见,因为强烈不鼓励使用它(原始 /dev/sdx[0-9] 类型语法),因为这些路径可以动态更改(交换磁盘顺序、插入新磁盘等,然后突然 /dev/ sda1 变为 /dev/sdb1)。
root=/dev/sda1
root=UUID=5a25cf4a-9772-40cd-b527-62848d4bdfda
root=LABEL=random string
root=PARTUUID=a2079bfb-02
VS 非常干净且易于解析:
mount
/dev/sda1 on / type ext4 (rw,noatime,data=ordered)
在 cmdline 的情况下,您会看到,理论上正确“答案”的唯一变体是第一个,已弃用的变体,因为您不应该将 root 引用到像 /dev/sdxy 这样的移动目标
接下来的两个需要执行进一步的操作,从 /dev/disk/by-uuid 或 /dev/disk/by-label 中的该字符串获取符号链接
最后一个要求我相信使用parted -l 来查找parted id 所指向的内容。
这只是我所知道和见过的变体,很可能还有其他变体,例如 GPTID。
所以我使用的解决方案是这样的:
首先,查看 /dev/root 是否是符号链接。如果是,请验证它不是 /dev/disk/by-uuid 或 by-label,如果是,则必须执行第二步处理才能获取最后的真实路径。取决于您使用的工具。
如果什么都没有,那就去 mount 看看怎么样。作为最后一个后备案例,我没有使用它,因为反对它的论点甚至不一定是有问题的实际分区或设备,足以让我拒绝我的程序的该解决方案。 mount 不是一个完全强大的解决方案,我确信只要有足够的样本,很容易找到根本不正确的情况,但我相信这两种情况涵盖了“大多数”用户,这就是我所需要的。
最好的、最干净的、最可靠的解决方案是内核总是建立符号链接,这不会伤害任何人或任何人,并称其为好的,但这并不是它在现实世界中的运作方式。 。
我不认为这些都是“好的或强大的”解决方案,但挂载选项似乎满足“足够好”的要求,如果需要真正强大的解决方案,请使用 busybox 推荐的东西。
答案3
在我看过的系统上,/dev/root
是一个到真实设备的符号链接,所以readlink /dev/root
(或者readlink -f /dev/root
如果你想要完整路径),会这样做。
答案4
也许我错过了一些东西,但是怎么样:
mount|grep ' / '|cut -d' ' -f 1