Linux 系统启动流程优化与故障排查

8次阅读

启动卡在“starting switch root…”通常是initramfs找不到根文件系统,需检查root=参数、initramfs是否匹配内核、lvm/加密配置是否正确,并用rd.debug rd.break=pre-mount调试。

Linux 系统启动流程优化与故障排查

systemd 启动卡在 Starting Switch Root... 怎么办

这通常不是真的“卡住”,而是 initramfs 阶段找不到根文件系统,或者 root= 内核参数指定的设备无法识别。常见于更换硬盘、RAID/LVM 重配、或 initramfs 没更新。

实操建议:

  • 启动时按 e 进入 GRUB 编辑模式,检查 linux 行末尾的 root= 参数是否指向正确的设备(如 /dev/nvme0n1p2)或 UUID(推荐用 root=UUID=...
  • 确认 initrd 行加载的是当前内核对应的 initramfs(如 initrd /boot/initramfs-6.6.30-1-lts.img),否则 LVM/加密模块可能缺失
  • 临时加 rd.debug rd.break=pre-mount 参数可中断在 initramfs 内部,用 lsblklvm lvscancryptsetup luksOpen 手动排查设备状态

开机慢?查 systemd-analyze blamecritical-chain

systemd-analyze blame 显示每个 unit 启动耗时,但真正拖慢体验的往往是关键路径上的阻塞点——比如 NetworkManager-wait-online.service 等 DHCP 超时,或某个挂载点依赖未就绪。

实操建议:

  • 先跑 systemd-analyze blame 找出前 5 名耗时 unit;再跑 systemd-analyze critical-chain 看启动链路瓶颈在哪一级(常暴露 remote-fs.targetmulti-user.target 的延迟源头)
  • NetworkManager-wait-online.service 耗时长,且你不需要网络就绪才启动服务,可执行 sudo systemctl disable NetworkManager-wait-online.service(注意:仅适用于无网络依赖的本地服务场景)
  • 自定义挂载(/etc/fstab)中避免使用 _netdev 或未就绪的远程路径,否则会触发默认 90 秒超时

systemd 服务启动失败但日志不显示错误?用 journalctl -u xxx --since "1 hour ago"

很多新手只看 systemctl status xxx,但它的输出常被截断,且不包含 pre-start 阶段的 shell 错误(比如 ExecStartPre 中的命令失败)。真实失败原因往往藏在 journal 里。

实操建议:

  • 务必加时间范围,例如 journalctl -u nginx.service --since "2 minutes ago",否则滚动日志太多容易漏掉关键行
  • 关注 Failed at step XXX spawning 类错误(如 Failed at step EXEC spawning 表示二进制路径错或权限不足;Failed at step CHDIR spawning 表示 WorkingDirectory= 设置的路径不存在
  • 如果服务依赖另一个 unit(如 After=redis-server.service),而该 unit 本身 failed,status 可能只显示 “inactive (dead)”,需单独查那个 unit 的 journal

initramfs 更新漏了?mkinitcpio -Pdracut --force 不是万能的

Arch/Manjaro 用 mkinitcpio -P,RHEL/centos/Fedora 用 dracut --force,但这只是重建镜像——如果内核模块没装、加密密钥没配置、或 LVM 卷组名变了,镜像再新也没用。

实操建议:

  • 更新内核后,必须确认对应版本的 kernel headers、firmware、以及必要模块(如 dm_modext4cryptd)已安装并被 initramfs 捕获
  • 使用 LUKS 时,确保 crypttab 中的 UUID 和 lsblk -f 输出一致;若改过密码或 keyfile 路径,需重新运行 mkinitcpiodracut 并验证 lsinitcpio/dracut -I 是否含所需文件
  • 别信“上次更新过”,每次修改 /etc/mkinitcpio.conf/etc/dracut.conf.d/*.conf 后,都得手动重生成,自动钩子不一定可靠

最麻烦的从来不是哪条命令没敲,而是你以为它生效了,其实 initramfs 根本没读到新配置,或者 root 分区在切换 initramfs 时就被跳过了——这时候连键盘都来不及按,就得靠另一台机器挂载磁盘去修 /boot/etc

text=ZqhQzanResources