为什么在 Arch linux 中使用 /bin/init -> ../lib/systemd/systemd 而不是 /bin/init -> /lib/systemd/systemd ?

为什么在 Arch linux 中使用 /bin/init -> ../lib/systemd/systemd 而不是 /bin/init -> /lib/systemd/systemd ?

我正在学习Linux。为了测试内核是否会通过启动过程调用 init,我做了:

sudo rm /sbin/init

并重新启动。正如我所料,Ubuntu由于 /sbin/init 不存在,因此无法成功启动。然后,为了修复它,我使用可启动 USB 来安装、chroot...最后重新符号链接它:

ln -s /lib/systemd/systemd /sbin/init

重新启动...我的Ubuntu启动再次成功。

但是,它并不Arch像上面那样工作。这怎么解释呢? (Arch和Ubuntu都使用systemdas init,我将它们分别安装在一个分区中。)

(在 Arch 中删除 /sbin/init 后,它显示 ERROR: Root device mounted successfully, but /sbin/init does not exist.I did it as root)

解决:Arch

ln -s ../lib/systemd/systemd /sbin/init

(感谢 terdon )

答案1

我想到了:

$ ls -l /tmp/sbin
lrwxrwxrwx 1 tom tom 7 Jul 29 23:32 /tmp/sbin -> usr/bin
$ ls -l /tmp/lib
ls: cannot access '/tmp/lib': No such file or directory
$ ls -l /tmp/usr/
total 0
drwxr-xr-x 2 tom tom 80 Jul 29 23:34 bin
drwxr-xr-x 3 tom tom 60 Jul 29 23:34 lib
$ ls -l /tmp/usr/bin/
total 0
lrwxrwxrwx 1 tom tom 20 Jul 29 23:33 inita -> /lib/systemd/systemd
lrwxrwxrwx 1 tom tom 22 Jul 29 23:33 initb -> ../lib/systemd/systemd
$ ls -l /tmp/usr/lib/
total 0
drwxr-xr-x 2 tom tom 60 Jul 29 23:34 systemd
$ ls -l /tmp/usr/lib/systemd/
total 0
-rwxr-xr-x 1 tom tom 0 Jul 29 23:34 systemd
$ realpath /tmp/sbin/init{a,b}
/usr/lib/systemd/systemd
/tmp/usr/lib/systemd/systemd

然后看一下 Arch 默认使用的“早期”init(脚本)中的这些行:

https://github.com/archlinux/mkinitcpio/blob/v30/init#L5

https://github.com/archlinux/mkinitcpio/blob/v30/init#L57

考虑/tmp上面的是/new_root。然后你应该明白为什么使用是错误的init(a) -> /lib/systemd/systemd

/(root)在切换root之前和之后指的是完全不同的东西。

在它只是一个 ramfs(或者实际上是 tmpfs?)之前,initramfs / initcpio 的内容被提取到其中。之后是用于“真正根”的文件系统(即安装在其上的文件系统/new_root)。

由于检查是在切换 root 之前完成的:

https://github.com/archlinux/mkinitcpio/blob/v30/init#L76

它不会找到/usr/lib/systemd/systemd

我不知道Ubuntu中的early init到底是用什么做的。它有可能是 systemd(mkinitcpio 也允许您在 Arch 中这样做。您只需要包含 systemd 挂钩。)systemd 可能不会使用/sbin/initor/usr/bin/init来在真正的根目录中定位其副本,而是简单地使用/lib/systemd/systemdor /usr/lib/systemd/systemd

PS 因为当您使用 systemd 挂钩时,(在真实根目录中)的副本usr/lib/systemd/systemd将被添加到 initramfs / initcpio.conf 中。如果它还包含(我懒得检查)lib -> usr/lib符号链接,则sbin/init( usr/bin/init) 最终将导致usr/lib/systemd/systemd(在前面提到的 ramfs / tmpfs 中),即使它指向/lib/systemd/systemd. (我删除/所有路径中的所有前导是有原因的,但是/lib/systemd/systemd。看看您是否能理解原因。)

PS 你可能想知道为什么realpath /tmp/sbin/inita在我的测试中/usr/lib/systemd/systemd即使我没有/tmp/lib指向usr/lib.原因是/tmp/sbin/inita解析到/tmp/usr/bin/inita哪个指向/lib/systemd/systemd哪个解析到/usr/lib/systemd/systemd

相关内容