深入解析 Linux init 机制
init 进程是 Linux 启动后的第一个用户态进程(PID=1),init进程的二进制代码是由根文件系统负责提供,负责:
- 系统初始化(挂载文件系统、启动服务)
- 进程管理(孤儿进程回收、守护进程启动)
- 系统关机与重启
- 等等
init 进程的启动流程
1. 内核启动 init
- 内核启动完成后,会执行:
execve("/sbin/init", ...)
- 依次尝试查找:
/sbin/init
/etc/init
/bin/init
/bin/sh # 如果 `init` 失败,进入紧急 shell
- init 进程从 /proc/cmdline 读取 启动参数:
cat /proc/cmdline
- init=/bin/sh 进入单用户模式
- systemd.unit=rescue.target 进入救援模式
2. 初始化系统环境
- 挂载必要的文件系统
mount -t proc proc /proc
mount -t sysfs sysfs /sys
mount -t devtmpfs devtmpfs /dev
- 初始化 udev(设备管理)
udevd --daemon
3. 加载 init 配置
不同 Linux 版本使用不同的 init 机制:
init 类型 | 配置文件 | 示例系统 |
---|---|---|
Systemd | /etc/systemd/system/ | Ubuntu 16+、CentOS 7+ |
SysVinit | /etc/inittab | CentOS 6、Debian 7 |
Upstart | /etc/init/ | Ubuntu 9.10~14.04 |
- 查看当前 init 类型:
ps -p 1
# systemd: /sbin/init -> /lib/systemd/systemd
# sysvinit: /sbin/init (init [5] or similar)
4. 进入目标运行级别
- Systemd 运行 default.target
- SysVinit 读取 /etc/inittab,进入 runlevel
init 在不同 init 系统中的作用
1. Systemd
- 并行启动,基于 target 依赖管理
- 配置文件目录:
/etc/systemd/system/
/usr/lib/systemd/system/
- 查看已启动的服务
systemctl list-units --type=service
- 进入单用户模式
systemctl isolate rescue.target
2. SysVinit
- 基于 runlevel 启动
- 运行级别(runlevel)
- 实测在systemd中也可以用
0 - 关机
1 - 单用户模式
2 - 多用户(无网络)
3 - 多用户(含网络)
5 - 图形界面
6 - 重启
- 切换运行级别
init 0 # 关机
init 3 # 切换到多用户模式
init 6 # 重启
init 进程的进程管理
1. 孤儿进程回收
- init 进程负责回收 孤儿进程
- 如果一个进程的父进程退出,它会被 init 接管
- 例如:
if (fork() == 0) {
// 子进程
setsid(); // 创建新会话
while(1) sleep(1); // 守护进程
}
// 父进程退出
- 孤儿进程的 PPID 会变成 1:
ps -ef | grep my_process
2. init 信号处理
信号 | 作用 |
---|---|
SIGTERM+4(Real-Time Signal) | 关闭系统 |
SIGINT | 进入紧急模式 |
SIGUSR1 | 重新加载配置 |
检查 init 是否运行
cat /proc/1/cmdline
# 输出
# root@rk3562:~# cat /proc/1/cmdline
# /lib/systemd/systemd--system--deserialize33
如果为空,说明 init 没有正常运行。