我的理解是,至少在早期的用户空间,init是一个无法退出的shell脚本。它是否正确?
那么当它结束时会发生什么呢?
我知道,在典型的启动顺序中,早期用户空间中的 init shell 脚本会挂载根文件系统,然后将控制权从新的根转移到 init。但假设这没有发生 - 根未安装并且控制未转移到新的根 init - 当 init 脚本结束时会发生什么?
答案1
我的理解是,至少在早期的用户空间,init是一个无法退出的shell脚本。它是否正确?
它不一定是 shell 脚本。您当然可以退出该init
过程。这会导致内核恐慌,但这是可以做到的。
那么当它结束时会发生什么呢?
该脚本通常有一行类似exec switch_root /root "$@"
.因为它使用exec
,所以相同的进程 ID 会被新的二进制文件覆盖以运行。
因此,程序发生init
变化,内核永远看不到exit
来自 init 进程的信息。
反过来,在清理 initramfs 并绑定switch_root
exec
安装到.所以PID 始终保持为 1。/sbin/init
/root
/
init
你可以在这里看到BusyBox的switch_root的源代码,它真的很简单:https://git.busybox.net/busybox/plain/util-linux/switch_root.c最后还有一个很长的评论,解释了幕后发生的一些事情。
答案2
init 进程/sbin/init
不是 shell 脚本,它不会退出(正常情况下)。
从https://en.wikipedia.org/wiki/Init
在基于Unix的计算机操作系统中,init(初始化的缩写)是计算机系统启动过程中启动的第一个进程。 Init 是一个守护进程,它持续运行直到系统关闭。
它是所有其他进程的直接或间接祖先,并自动采用所有孤立进程。
它是内核初始化后内核 fork 和 exec 的第一个用户空间进程。这就是为什么它被称为PID1
(进程ID 1)。
现在 init 进程有不同的实现,例如 upstart 或 systemd,最初的实现是基于 systemV init。
它们基本上所做的就是在启动时读取每个要启动的候选进程的配置文件。传统上,这些配置文件位于/etc/init/
.如果该进程被标记为启动,则该进程将启动,或者 - 如果其配置显示“启动时不要启动我”,则其不会启动,但稍后仍可能手动启动。
如果进程被标记为启动(传统上),它们启动的方式是 init 系统将执行与 中的守护进程相对应的 shell 脚本/etc/init.d/
。
较新的 init 系统和原始系统 V init 之间的一些区别在于,系统 V 使用数字运行级别 0、1、2 等来确定系统状态,而 systemd 或 upstart 使用命名标识符,例如mulit-user.target
.
另外 - 我相信 - 较新的 init 系统会自行启动守护进程并使用自己的所谓“单元”文件来定义配置指令,而不是调用 shell 脚本。
例如,对于 nginx 有一个配置文件/lib/systemd/system/nginx.service
,它定义了启动指令,例如:
[Unit]
Description=A high performance web server and a reverse proxy server
After=network.target
[Service]
Type=forking
PIDFile=/run/nginx.pid
ExecStartPre=/usr/sbin/nginx -t -q -g 'daemon on; master_process on;'
ExecStart=/usr/sbin/nginx -g 'daemon on; master_process on;'
ExecReload=/usr/sbin/nginx -g 'daemon on; master_process on;' -s reload
ExecStop=-/sbin/start-stop-daemon --quiet --stop --retry QUIT/5 --pidfile /run/nginx.pid
TimeoutStopSec=5
KillMode=mixed
[Install]
WantedBy=multi-user.target
您可以使用这样的命令来启用它,sudo systemctl enable nginx.service
这将在中创建一个符号链接
/etc/systemd/system/multi-user.target.wants/nginx.service
指向单元文件:
/lib/systemd/system/nginx.service
sudo systemctl disable nginx.service
将删除符号链接,并且该服务将不会在启动时启动。
较新的 init 系统向后兼容 systemV init 脚本,并将读取其中的配置/etc/init
并启动 shell 脚本/etc/init.d