kdt*_*kdt 18 linux devices proc
在 linux 上,有一个/dev/root
设备节点。这将是与另一个设备节点相同的块设备,例如/dev/sdaX
. /dev/root
在这种情况下,如何解析“真实”设备节点,以便向用户显示合理的设备名称?
比如我在解析/proc/mounts
.
我正在寻找适用于 shell/python 脚本但不适用于 C 的解决方案。
cjm*_*cjm 13
在我看过的系统上,/dev/root
是到真实设备的符号链接,所以readlink /dev/root
(或者readlink -f /dev/root
如果你想要完整路径),就可以了。
Well/dev/root
只是到真实设备的符号链接,因此您可以使用readlink(2)
它从程序中找出它指向的位置,或者readlink(1)
从 shell 脚本中执行相同的操作。
这可能应该更新,因为这里提供的许多信息具有误导性,实际上可能从未完全正确。
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 线程,从这个线程的时代开始,我们可以看到所有变体总是存在,但我相信“大多数”发行版都在使用符号链接方法,但这是一个简单的内核编译开关,如果我正确理解海报,它可以制作一个,也可以不制作一个,即切换一种方式,然后 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
Run Code Online (Sandbox Code Playgroud)
VS 非常干净且易于解析:
mount
/dev/sda1 on / type ext4 (rw,noatime,data=ordered)
Run Code Online (Sandbox Code Playgroud)
在 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 推荐的东西。