1、启动挂载阶段概述
大家好,我是老李。今天咱们聊聊Linux启动过程中一个特别容易翻车的环节——启动挂载阶段。说白了,就是内核启动后,要挂载根文件系统的那段关键时期。我干了这么多年运维,见过太多系统卡在这一步起不来的案例了。
什么是启动挂载阶段
启动挂载阶段,指的是内核启动完成后,init进程开始执行,系统需要挂载各种文件系统的过程。这个阶段通常包括:
- 挂载根文件系统(/)—— 这是最核心的一步
- 挂载虚拟文件系统(如 /proc、/sys、/dev)
- 挂载其他必要分区(如 /boot、/home 等)
- 执行 fsck 检查(文件系统一致性检查)
嗯,这里要注意。这个阶段发生在内核启动之后、用户态服务启动之前。你想想看,如果根文件系统挂不上,后面所有服务都没法跑。我在项目中遇到过一台服务器,就因为 /etc/fstab 里写错了一个UUID,结果系统直接卡在 emergency mode,折腾了我大半天。
依赖错误的概念
依赖错误,简单说就是「A需要B先准备好,但B没准备好」。在启动挂载阶段,这种依赖关系特别明显:
典型的依赖链:
- 挂载 /var 需要 / 先挂载好
- 挂载加密分区需要先加载 cryptsetup 模块
- 挂载网络文件系统(NFS)需要网络先就绪
- 使用 LVM 逻辑卷需要先激活卷组
为什么会这样?因为 systemd 在解析挂载单元时,会按照 After=、Requires=、Wants= 这些指令来排序。一旦某个依赖没满足,整个挂载链就会断掉。
我记得有一次排查一个诡异的问题:系统启动时 /home 分区挂载失败,但手动 mount 却没问题。查了半天才发现,是因为 /home 所在的 LVM 卷组激活太晚,systemd 没等到它准备好就尝试挂载了。说白了,就是时序问题。
为什么依赖错误会导致启动失败
这个问题其实很直接。Linux 启动是一个串行过程,每个步骤都依赖前一步的结果。挂载阶段的依赖错误,会产生连锁反应:
| 依赖错误类型 | 典型表现 | 后果 |
|---|---|---|
| 根文件系统依赖缺失 | 内核 panic,无法进入 init | 系统完全无法启动 |
| 关键分区依赖缺失 | 进入 emergency mode | 系统降级运行,部分功能不可用 |
| 非关键分区依赖缺失 | 挂载失败,跳过该分区 | 服务可能启动异常,数据不可访问 |
| 设备依赖缺失 | 设备节点未创建,挂载超时 | 启动卡住,等待超时后进入 rescue mode |
你想想看,如果 /etc/fstab 里指定了一个不存在的设备,或者设备名写错了,系统会怎么样?它会一直重试,直到超时。我曾经见过一台机器因为磁盘故障导致 /dev/sdb1 消失,结果系统在启动时卡了整整90秒才放弃,然后进入 emergency mode。
避坑指南: 我曾经在 /etc/fstab 里用了设备名(如 /dev/sda1)而不是UUID,结果换了一块硬盘后系统直接起不来。从那以后,我所有生产环境都强制使用UUID或PARTUUID来标识分区。你最好也养成这个习惯。
依赖错误的本质,是 systemd 的挂载单元解析顺序出了问题。每个 .mount 单元文件里都有 Before= 和 After= 声明,systemd 会根据这些声明构建一个依赖图。如果这个图里有环,或者某个节点永远无法满足,那启动就会卡住。
嗯,这里我画了一张图,帮你理解这个依赖关系:
从这张图你能看到,依赖检查是挂载阶段的核心。一旦某个依赖不满足,系统要么重试等待,要么直接宣告失败。我建议你在排查启动问题时,先看看 systemctl list-dependencies 的输出,它能帮你理清挂载单元的依赖关系。
实用技巧: 如果你怀疑是依赖错误导致启动失败,可以在启动时按 Esc 键查看详细日志,或者用 journalctl -b -p err 查看本次启动的错误信息。我个人习惯在排查时先看 systemctl status *.mount,哪个挂载单元是 failed 状态,问题就出在哪。
最后说一句,依赖错误不一定是配置写错了。有时候是硬件问题,比如磁盘没识别;有时候是内核模块没加载,比如需要 dm_crypt 模块但没加载。嗯,这些我们在后面的章节会详细讲。
可可精品资料库