Linux 系统启动流程详解与优化方案

16次阅读

systemd 启动卡在 plymouth 是因超时等待而非真卡死,常见于显卡驱动未加载或 grub splash 参数不匹配;可通过 tty 查状态、grub 临时调试或修改 /etc/default/grub 永久解决。

Linux 系统启动流程详解与优化方案

systemd 启动卡在 Starting Wait for Plymouth Boot Screen…… 怎么办

这其实是 Plymouth(图形启动画面)和 systemd 的超时协作问题,不是真卡死,而是等待某个服务超时后才继续。常见于显卡驱动未加载或 /etc/default/grub 中 splash 参数与实际环境不匹配。

  • 先用 Ctrl+Alt+F2 切到 TTY,运行 sudo systemctl status plymouth-start 看是否报 Timeout was reached
  • 临时绕过:重启时在 GRUB 菜单按 e,找到以 linux 开头的行,删掉 splashquiet,加 systemd.log_level=debug,然后 Ctrl+X 启动——能快速定位卡在哪一步
  • 永久修复:编辑 /etc/default/grub,把 GRUB_CMDLINE_LINUX_DEFAULT="splash quiet" 改成 GRUB_CMDLINE_LINUX_DEFAULT="",再运行 sudo update-grub
  • 注意:NVIDIA 闭源驱动下 Plymouth 默认不工作,强行启用反而导致黑屏或无限等待

如何确认 init 进程到底是 systemd 还是 sysvinit

别信 ps -p 1 -o comm= 的表面输出,有些发行版会伪造进程名。真实判断依据只有一个:看 /proc/1/exe 指向哪里。

  • 执行 ls -l /proc/1/exe,如果指向 /lib/systemd/systemd/usr/lib/systemd/systemd,就是 systemd
  • 如果指向 /sbin/initfile /sbin/init 显示“ELF 64-bit LSB pie executable, x86-64”但没提 systemd,大概率是 sysvinit 或 runit
  • Ubuntu 22.04+、CentOS 8+、Arch 默认用 systemd;Debian 10 以前、Alpine 默认不用;RHEL 7 是 systemd 分水岭
  • 混用风险:在 systemd 系统里手动启动 /sbin/init 会导致进程树混乱,systemctl 命令失效

systemctl list-dependencies --reverse 显示一堆 multi-user.target 是啥意思

这不是错误,是 target 依赖关系的正常展开方式。multi-user.target 是大多数非图形系统的“终点目标”,很多服务都声明自己 WantedBy=multi-user.target,所以反查时它会高频出现。

  • 真正该关注的是那些没启动、状态为 inactive (dead)failed 的单元,它们才是拖慢启动的元凶
  • systemd-analyze blame 看耗时最长的前 10 个服务,比依赖图更直接
  • systemd-analyze critical-chain 查从启动到某个 target(如 default.target)的最长路径,能暴露关键阻塞点
  • 注意:--reverse 不显示 socket 或 timer 触发的服务,这类服务可能延迟启动但不计入初始依赖链

禁用 NetworkManager-wait-online.service 安全吗

安全,只要你的服务不依赖网络就绪信号。这个 service 的作用只是让 multi-user.target 等待所有 NetworkManager 管理的连接“上线”,但它本身不提供网络功能。

  • 典型不安全场景:你写了自定义服务,After=network-online.target 且没设 Wants=network-online.target,又依赖 DNS 解析——禁用后可能启动失败
  • 安全做法:运行 sudo systemctl disable NetworkManager-wait-online.service,再检查 systemctl list-dependencies multi-user.target 是否还有其他网络等待项
  • 替代方案:保留它,但缩短超时,在 /etc/systemd/system/NetworkManager-wait-online.service.d/timeout.conf 里写 [Service]nTimeoutStartSec=10
  • 云服务器常见坑:某些镜像把 SSH 启动绑在 network-online.target 上,禁用后 SSH 可能晚几十秒才响应

启动流程里最麻烦的从来不是哪一步慢,而是多个服务之间隐含的启动顺序冲突——比如一个服务等网络,另一个等磁盘,而磁盘挂载又依赖网络存储。这种环状依赖不会报错,只会让 systemd 反复重试直到超时。

text=ZqhQzanResources