我正在学习Linux。为了测试内核是否会通过启动过程调用 init,我做了:
sudo rm /sbin/init
并重新启动。正如我所料,Ubuntu
由于 /sbin/init 不存在,因此无法成功启动。然后,为了修复它,我使用可启动 USB 来安装、chroot...最后重新符号链接它:
ln -s /lib/systemd/systemd /sbin/init
重新启动...我的Ubuntu
启动再次成功。
但是,它并不Arch
像上面那样工作。这怎么解释呢? (Arch和Ubuntu都使用systemd
as 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/init
or/usr/bin/init
来在真正的根目录中定位其副本,而是简单地使用/lib/systemd/systemd
or /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
。