跳转到内容

启动故障

系统无法正常启动是最令人紧张的故障之一。本文覆盖 GRUB 引导修复、救援模式使用、fstab 错误排查、dracut 问题等常见启动故障的排查与修复方法。

EL 系统的启动流程:

  1. 固件(BIOS/UEFI) — 硬件自检,加载引导程序
  2. GRUB2 — 读取配置,加载内核和 initramfs
  3. 内核 — 初始化硬件,挂载 initramfs
  4. dracut/initramfs — 加载驱动,挂载根文件系统
  5. systemd — 启动目标(target)和服务

在不同阶段出现的故障,表现和解决方法各不相同。

当 GRUB 无法找到配置文件或模块时,会进入 grub rescue> 提示符。

屏幕显示:

error: no such partition.
Entering rescue mode...
grub rescue>
列出可用磁盘和分区
grub rescue> ls

这会显示类似 (hd0) (hd0,msdos1) (hd0,msdos2) 的输出。

逐个分区查找 grub 目录
grub rescue> ls (hd0,msdos1)/boot/grub2/
grub rescue> ls (hd0,msdos2)/boot/grub2/

找到包含 GRUB 文件的分区后:

设置前缀和根分区
grub rescue> set prefix=(hd0,msdos1)/boot/grub2
grub rescue> set root=(hd0,msdos1)
加载 normal 模块并引导
grub rescue> insmod normal
grub rescue> normal

系统启动后,立即修复 GRUB 配置:

重新安装 GRUB(BIOS 系统)
$ sudo grub2-install /dev/sda
$ sudo grub2-mkconfig -o /boot/grub2/grub.cfg
重新安装 GRUB(EFI 系统)
$ sudo dnf reinstall grub2-efi-x64 shim-x64
$ sudo grub2-mkconfig -o /boot/efi/EFI/$(. /etc/os-release && echo $ID)/grub.cfg

紧急模式在 systemd 无法完成基本初始化时触发,例如 /etc/fstab 中有无法挂载的文件系统。

屏幕显示:

Welcome to emergency mode! After logging in, type "journalctl -xb" to view
system logs, "systemctl reboot" to reboot, "systemctl default" to try again
to boot into default mode.
Give root password for maintenance
(or press Control-D to continue):

输入 root 密码登录后:

查看启动日志中的错误
$ journalctl -xb --priority=err
检查 fstab 中是否有问题的挂载项
$ cat /etc/fstab
尝试手动挂载所有文件系统
$ mount -a 2>&1

如果是某个分区导致的问题:

检查磁盘和分区状态
$ lsblk -f
$ blkid

修复问题后:

重启系统
$ systemctl reboot

救援模式从安装介质启动,用于修复无法启动的系统。

  1. 从 AlmaLinux / Rocky Linux 安装 ISO 启动
  2. 在启动菜单选择 Troubleshooting
  3. 选择 Rescue a system

系统会检测已安装的系统并挂载到 /mnt/sysimage

切换到已安装的系统环境
$ chroot /mnt/sysimage

现在你可以像在正常系统中一样执行修复命令。

手动挂载(如果自动检测失败)

Section titled “手动挂载(如果自动检测失败)”
查看可用分区
$ lsblk -f
手动挂载根分区
$ mount /dev/sda2 /mnt/sysimage
挂载 boot 分区
$ mount /dev/sda1 /mnt/sysimage/boot
挂载必要的虚拟文件系统
$ mount --bind /dev /mnt/sysimage/dev
$ mount --bind /proc /mnt/sysimage/proc
$ mount --bind /sys /mnt/sysimage/sys
$ mount --bind /run /mnt/sysimage/run
chroot 进入系统
$ chroot /mnt/sysimage

单用户模式用于在最小环境下排查问题,例如重置 root 密码。

  1. 在 GRUB 启动菜单按 e 编辑引导条目
  2. 找到以 linux 开头的行(包含 vmlinuz
  3. 在该行末尾添加:rd.breakinit=/bin/bash
  4. Ctrl+X 启动
重新挂载根文件系统为读写
switch_root:/# mount -o remount,rw /sysroot
切换到系统根目录
switch_root:/# chroot /sysroot
重置 root 密码
sh-4.4# passwd root
如果 SELinux 处于 enforcing 模式,需要重新标记
sh-4.4# touch /.autorelabel
退出并重启
sh-4.4# exit
switch_root:/# exit

注意: touch /.autorelabel 会在下次启动时重新标记整个文件系统的 SELinux 标签,这个过程可能需要几分钟到几十分钟,取决于文件数量。不要在此过程中强制关机。

查看当前启动的日志
$ journalctl -b
查看上一次启动的日志
$ journalctl -b -1
仅查看错误级别的启动日志
$ journalctl -b -p err
列出所有可用的启动记录
$ journalctl --list-boots
查看内核环形缓冲区消息
$ dmesg | less
只查看错误和警告
$ dmesg --level=err,warn
查看与存储相关的消息
$ dmesg | grep -i -E '(sd[a-z]|nvme|ata|scsi)'

默认情况下,EL 系统的 journald 日志可能不会持久保存。启用持久化后可以查看之前的启动日志:

创建持久化日志目录
$ sudo mkdir -p /var/log/journal
$ sudo systemd-tmpfiles --create --prefix /var/log/journal
$ sudo systemctl restart systemd-journald

/etc/fstab 中的错误是导致启动失败的常见原因。

  • UUID 与实际分区不匹配(更换磁盘后)
  • 引用了不存在的分区
  • 挂载选项错误
  • NFS/CIFS 远程挂载在网络就绪前执行
查看当前磁盘的 UUID
$ blkid
对比 fstab 中的 UUID
$ cat /etc/fstab
验证 fstab 是否有语法错误
$ sudo findmnt --verify --tab-file /etc/fstab

如果某个分区的 UUID 已变更:

用 blkid 获取新的 UUID 并更新 fstab
$ sudo blkid /dev/sda2

输出例如:/dev/sda2: UUID="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"

编辑 fstab,替换旧的 UUID
$ sudo vi /etc/fstab

对于网络文件系统挂载,添加 _netdevnofail 选项:

server:/export /mnt/nfs nfs defaults,_netdev,nofail 0 0

nofail 确保即使挂载失败系统也能正常启动。_netdev 确保等待网络就绪后再尝试挂载。

重新安装 GRUB 到 MBR
$ sudo grub2-install /dev/sda
重新生成 GRUB 配置文件
$ sudo grub2-mkconfig -o /boot/grub2/grub.cfg
重新安装 EFI 引导文件
$ sudo dnf reinstall grub2-efi-x64 shim-x64
重新生成 GRUB 配置
$ sudo grub2-mkconfig -o /boot/efi/EFI/$(. /etc/os-release && echo $ID)/grub.cfg
验证 EFI 启动项
$ efibootmgr -v

如果系统完全无法启动,从安装介质进入救援模式后:

chroot 到系统(假设已挂载到 /mnt/sysimage)
$ chroot /mnt/sysimage
重新安装内核和 GRUB(BIOS)
$ dnf reinstall kernel-core
$ grub2-install /dev/sda
$ grub2-mkconfig -o /boot/grub2/grub.cfg
重新安装内核和 GRUB(EFI)
$ dnf reinstall kernel-core grub2-efi-x64 shim-x64
$ grub2-mkconfig -o /boot/efi/EFI/$(. /etc/os-release && echo $ID)/grub.cfg

dracut 负责生成 initramfs(初始内存文件系统),其中包含启动阶段所需的驱动和工具。

  • 启动时报 dracut-initqueue 超时
  • 提示找不到根文件系统
  • 进入 dracut emergency shell
dracut-initqueue[xxx]: Warning: dracut-initqueue timeout
dracut-initqueue[xxx]: Warning: Could not boot.
在 dracut shell 中查看可用磁盘
dracut:/# ls /dev/sd* /dev/nvme*
查看 dracut 日志
dracut:/# journalctl
为当前内核重新生成 initramfs
$ sudo dracut --force
为指定内核版本重新生成
$ sudo dracut --force /boot/initramfs-$(uname -r).img $(uname -r)
包含额外驱动模块
$ sudo dracut --force --add-drivers "megaraid_sas mpt3sas" /boot/initramfs-$(uname -r).img $(uname -r)

缺少存储驱动: 如果更换了存储控制器或迁移了虚拟机平台:

列出 initramfs 中包含的模块
$ lsinitrd /boot/initramfs-$(uname -r).img | grep -i driver
添加 virtio 驱动(适用于 KVM/QEMU 虚拟机)
$ sudo dracut --force --add-drivers "virtio_blk virtio_scsi virtio_net virtio_pci"

initramfs 文件损坏:

检查 initramfs 文件大小(正常应至少几十 MB)
$ ls -lh /boot/initramfs-*.img

如果文件大小异常(如只有几 KB),说明文件已损坏,需要重新生成。

  1. 在 GRUB 启动菜单选择旧内核版本启动
  2. 如果 GRUB 菜单不显示(倒计时太短),在启动时反复按 Esc 或按住 Shift
启动旧内核后,查看已安装的内核
$ rpm -qa kernel-core | sort -V
将默认内核设回旧版本
$ sudo grubby --set-default /boot/vmlinuz-<旧内核版本>
移除有问题的新内核
$ sudo dnf remove kernel-core-<有问题的版本>