首页 / 资讯中心 / 文章详情

Dell服务器启动卡在initramfs的根因分析与修复实践

Dell服务器启动卡在initramfs的根因分析与修复实践 ★ FEATURED ARTICLE
1. 故障初现服务器从正常到翻车的全过程先说一下现场情况。某公司机房一台 Dell R430双路 E5-2600 v4 平台32GB 内存PERC H730 阵列卡三块盘组的 RAID5系统装在虚拟盘 VD0 上日常跑着内部业务系统。设备已经稳定运行了挺长时间没有动过硬件阵列状态之前也一直正常。问题出在一次例行重启之后。机器本身能加电BIOS 自检正常阵列卡自检也过了但系统引导阶段卡在一个非常眼熟又非常让人头疼的画面一堆内核日志刷完之后停在了initramfs的 shell 提示符屏幕上就一行孤零零的提示告诉你switch_root失败根文件系统没挂上。这里先把概念理清楚initramfs是 Linux 引导过程里的临时根文件系统内核把它加载到内存里做硬件初始化、加载驱动、识别根分区最后把控制权交给真正的系统根目录。如果它没能正确找到并挂载实际的根文件系统就会把用户丢到一个小型的救援 shell 里让你手动处理。这玩意儿说白了是系统启动的“最后一公里”一旦这一步断了你的服务器就进不了正常的单用户或多用户模式所有依赖系统启动的服务全部趴窝。当时我的第一反应其实不是慌而是“哦又是这套”。因为这类问题在物理服务器上并不少见尤其是 Dell 这类插了阵列卡的机器根因往往集中在几个固定环节磁盘阵列状态、根分区识别方式、内核参数里的 root 指定、还有 initramfs 本身有没有包含对应驱动。接下来要做的就是一步步把这个链路排查清楚。2. 排障路径从 initramfs shell 开始逐层排除2.1 第一步先看根文件系统到底为什么没挂上进入 initramfs shell 之后首先不要瞎敲命令先做一件事观察屏幕上方遗留的引导日志。这些日志一般会直接告诉你是“无法找到设备”、“设备超时”还是“文件系统超级块错误”信息量很大。在我这个案例里日志里出现了类似下面这样的关键行[ 4.183797] sd 2:0:0:0: [sda] read capacity failed [ 4.183899] sd 2:0:0:0: [sda] Sense Key : Not Ready [ 4.184102] sd 2:0:0:0: [sda] CDB: opcode0x28 [ 4.184279] sd 2:0:0:0: [sda] No Caching mode page found看到read capacity failed和Not Ready基本可以判定阵列虚拟磁盘在系统层面没有正常暴露。但我没有立刻下结论因为这种情况有两种可能一是阵列卡里的虚拟盘真的掉了需要进 BIOS 配置界面检查二是系统内核缺少或没有正确加载阵列卡驱动导致磁盘设备根本没出现。顺便说一句很多人一看到 initramfs 就急着去修文件系统其实这是误区。你得先确认设备在不在如果设备都不在后面的修复全是空谈。就好比你家水管漏水你首先得确认水表井里有没有水而不是直接撬地板。2.2 第二步确认磁盘设备与阵列卡状态在 initramfs shell 里先敲一条最基础的命令看看系统能不能识别到块设备ls /dev/sd*没有输出或者只输出了/dev/sda但 lsblk 看不到分区。接着再检查设备映射器是否有阵列设备ls /dev/mapper/*我这个案例里/dev/mapper下面只有一个control没有任何vg-*或阵列虚拟盘设备说明 LVM 卷组没有激活底层块设备也没出现。这时候就该怀疑驱动或阵列卡固件层面了。Dell R430 的 PERC H730 使用的是megaraid_sas驱动正常来讲市面主流发行版的内核都自带这个模块。但我没有直接排除驱动问题而是先试着手动加载一遍modprobe megaraid_sas执行后没有报错再查一次设备ls /dev/sd*设备依然没有出现。这说明在内核层面已经加载了控制器驱动但是控制器可能报错或者虚拟盘状态异常。到这一步初步结论偏向阵列卡虚拟盘掉线或 RAID 状态异常。这里还要补一个细节如果你在 BIOS 开机自检阶段看到 PERC 卡自检时跳出了“Foreign State”或者“Virtual Disk Degraded”之类的红色告警那就更加印证问题出在阵列层。我这次重启时特意留意了自检画面虽然没看到明显的红色报错但不排除日志滚屏太快错过提示所以下一步干脆直接进阵列卡管理界面确认。2.3 第三步通过阵列卡配置界面确认虚拟盘状态重启服务器在开机自检阶段等 PERC 卡提示出现时按Ctrl R进入 RAID 配置界面。进去之后能看到物理磁盘和虚拟磁盘列表。我这次的界面显示三块物理盘都在线没有掉盘、没有报 Foreign虚拟盘 VD0 的状态也显示正常没有 Degraded。这个结果其实很有意思。阵列层面看起来什么都正常但系统就是看不到设备。那问题就进一步收窄了要么是阵列卡固件和驱动之间有兼容性问题要么是系统引导阶段加载驱动时机不对要么是根分区设备路径发生了变化比如从原来的/dev/sda1变成了别的名字而 initramfs 里的配置还在用老路径去查找。Dell 平台还有一个常见特征如果阵列卡检测到“安全模式”或者开机自检流程异常可能会暂时把虚拟盘设为只读或不可见这种情况下必须重启让阵列卡重新初始化。我当时在配置界面里做了一个操作把 VD0 设置为 Bootable然后保存退出重启。虽然它本来就是启动盘但重新写一遍引导标志有时候能强制阵列卡重新暴露设备。重启之后依然进入 initramfs shell。到此阶段硬件层面的基本排查做完没发现明显的阵列故障问题焦点转向引导配置和根分区识别链路。3. 根因定位与实际修复重建 initramfs 是核心操作3.1 手动挂载根分区验证文件系统是否完好既然设备层没暴露我起初想当然地觉得继续在 shell 里折腾下去意义不大但转念一想还是要确认一下万一内核重启后设备出现了只是没激活 LVM 卷组呢。所以我在 initramfs shell 里又手动激活了一次 LVMlvm vgscan lvm vgchange -ayvgscan没有任何输出vgchange -ay也没有激活任何卷组。设备映射器里依然空空如也。这时候我已经比较确定设备没有出现在内核的设备树里LVM 自然也无从谈起。再想想——Dell R430 这块机器出问题时有没有可能是系统更新导致的驱动模块变化比如某个内核小版本升级之后initramfs 里没有包含对应内核模块或者模块加载顺序出了问题。于是我在 shell 里查看 initramfs 内是否有 megaraid_sas 驱动ls /lib/modules/$(uname -r)/kernel/drivers/scsi/megaraid/如果有输出说明驱动在 initramfs 里是存在的。但存在不表示加载成功还有可能因为 udev 规则或模块依赖问题导致没被自动装载。既然手动modprobe没报错也没产生设备那更可能是控制器本身在该引导阶段未就绪。这里我做了个决定不继续反复重启硬试而是先用现有的 initramfs shell 尝试把所有根分区相关步骤走一遍看看能不能直接切到真正的系统环境。因为只要切进去后面可以做完整的日志分析、驱动检查、initramfs 重建。说到这顺便科普下 initramfs 的完整作用链路很多人对它只有模糊概念。内核引导时bootloader一般是 GRUB2加载内核和 initramfs 镜像到内存initramfs 里包含必需的驱动包括磁盘控制器驱动、udev 规则、lvm 工具等。内核查到root参数后会尝试按指定方式找到根设备并挂载。如果找不到就进入 initramfs 的 emergency shell。所以排障的核心就是围绕三个问题驱动装没装、设备在不在、根参数对不对。3.2 紧急救援模式下查看真实日志既然 initramfs shell 里的信息有限我最想做的事情是拿到内核日志和系统日志。在 initramfs shell 里执行dmesg | tail -n 50看了一遍发现关键信息其实还是和最开始观察到的类似sd 2:0:0:0访问失败控制器设备出现Not Ready状态。但后面还有一条值得注意的记录是关于megaraid_sas探测超时的。这说明控制器初始化期间驱动等待固件响应超时最终放弃了设备。这个报错模式在 Dell 老平台上偶有出现尤其涉及 H730 这类卡时和电源管理、PCIe 链路协商、以及阵列卡缓存策略都有关系。但我不太想在这种场景下去做硬件级深度调优因为结合经验这类问题通过清理重建引导配置往往就能恢复。为了进一步确认我决定进入救援模式。由于 initramfs shell 里没有完整的 systemd我用最传统的办法在 GRUB 启动项里附加rd.break参数这样内核会在 initramfs 阶段暂停并给出一个类似救援的 shell。但实际操作时发现系统已经进不了正常的 GRUB 交互界面因为每次启动都快速落入 initramfs。好在我可以在 initramfs 提示符下直接手动走完整套挂载流程# 1. 手动扫描并激活卷组 lvm vgscan --mdevices 16 lvm vgchange -ay # 2. 如果卷组激活根逻辑卷出现在 /dev/mapper/ ls /dev/mapper/ # 3. 挂载根文件系统到临时目录 mkdir /sysroot mount /dev/mapper/vg-root /sysroot # 4. 挂载必要虚拟文件系统切换到真实根环境 mount -t proc /proc /sysroot/proc mount -t sysfs /sys /sysroot/sys mount --rbind /dev /sysroot/dev chroot /sysroot /bin/bash当然前提是你的根分区用 LVM。如果直接是传统分区mount /dev/sda1 /sysroot即可。在我这次案例中执行lvm vgscan时依旧发现不了卷组说明底层设备根本没出现。这让我重新把怀疑重心放回阵列卡与内核之间的通信问题上。但既然阵列卡本身管理界面显示正常更可能是系统 think 的内存中残留了旧的设备状态或者控制器没有完全复位。最终决定彻底断电重启让阵列卡完全重新初始化。这一步很关键Dell 服务器在异常关机或控制器异常后有时必须完全断电再上电而不是简单地重启。因为重启时主板可能没有给阵列卡一个完整的复位周期PCIe 设备状态残留在半初始化状态。像这种“看着硬件全都正常但系统就是认不到盘”的场景先断电放置十几秒再开机成本最低收益却很大。实际操作远程没法断电只能让机房人员协助或者用 iDRAC 的电源控制执行reset远端重启如果是戴尔的 iDRAC还可以直接执行power cycle。我这次是通过 iDRAC 做了一次完整的power cycle然后再次开机。果然这一次启动直接过了 initramfs进了正常的系统登录界面。看到登录提示那一刻长舒一口气。但故事没完——这种“断电重启就好了”的情况必须深挖否则下次再犯只会更复杂。3.3 进入系统后修复根因重建 initramfs进系统后的第一时间我做了三件事看日志、看阵列状态、看引导配置。# 查看阵列卡相关日志 dmesg | grep -i megaraid journalctl -k | grep -i megaraid journalctl | grep -i -E sd 2:0|read capacity|Not Ready日志里确实能看到开机时还有一些Not Ready的瞬时记录但驱动后续重试成功最终设备正常挂载。这说明问题根源是控制器初始化慢于内核的驱动探测超时阈值导致驱动在早期放弃了一次尝试。而这次的 power cycle 给了控制器充足的时间完成固件初始化。这种问题在旧版本固件上比较常见Dell 后来出的固件更新也专门修复过类似的“控制器响应延迟”问题。但我不打算只靠固件解决因为硬件层面的偶发问题很多时候靠软件兜底更稳妥。于是开始做软件层面的加固第一确认当前系统和内核版本。这一步很重要因为后续要重建 initramfs版本不匹配会带来新的坑。uname -r cat /etc/os-release市面上主流 Linux 发行版重建 initramfs 的工具链不一样Red Hat 系用dracutDebian/Ubuntu 系用update-initramfs。Dell 官方对 R430 的主流支持系统里两种都常见。我的修复命令# Red Hat 系 dracut -f /boot/initramfs-$(uname -r).img $(uname -r) # Debian/Ubuntu 系 update-initramfs -u -k $(uname -r)重建 initramfs 的意义在于把当前内核所需的所有驱动模块和 udev 规则重新打包进去避免旧 initramfs 里的驱动清单过时或不完整。比如这次如果驱动加载时序调整过或内核模块发生了变动旧的 initramfs 可能仍然保留旧配置。第二步检查/etc/fstab和 GRUB 配置里的根设备指定方式。我在这个案例里重点看了系统使用的是什么方式定位根设备。cat /etc/fstab grep -E root|rd.lvm /boot/grub2/grub.cfg现在的主流系统都推荐用 UUID 而不是直接写设备名。我检查了一下fstab 里挂载项是 UUIDGRUB 配置里root用的也是UUID形式。这是好习惯意味着即使设备名变化系统也能找到根分区。但这同时也意味着如果initramfs 本身损坏或不完整即使 UUID 正确内核也无法完成挂载因为它根本没有可用的驱动或 udev 规则去发现设备。所以重建 initramfs 在这里可以说是釜底抽薪。重建后我还做了一步更新 GRUB。grub2-mkconfig -o /boot/grub2/grub.cfg如果你用的是 UEFI 启动路径可能略有差别需要确认grub.cfg的实际位置别改错了地方。之后重启验证这次启动流程非常干净直接从 GRUB 进内核initramfs 阶段没有任何报错顺利到达登录界面。验证无误后我又特意再重启了一次确认这个问题不是“碰运气”恢复的连续两次正常启动后才算真正闭环。4. 常见误判与避坑提醒这些弯路我替你走过4.1 容易误导判断的几个经典场景这里集中梳理一下是我这次排障过程中踩过和见过的典型误判专门写出来帮大家避坑。第一看到 initramfs 就以为系统坏了。实际很多情况只是根设备发现失败内核兜底才进 shell。不要慌按顺序排查设备、驱动、配置三个层面80% 的问题都能定位。第二阵列卡界面正常不代表内核一定能认盘。我这次就是典型PERC 界面里 VD0 状态正常、物理盘全在线但驱动一直无法获得设备响应。原因是控制器固件初始化未完成内核探测超时。这种时候优先考虑完整断电重启而不是反复重启。第三过度依赖 fsck 修复文件系统。fsck 确实能修复很多文件系统元数据问题但它对“设备不存在”的情况毫无办法。在设备没有出现前先检查ls /dev/sd*、dmesg、lvm vgchange -ay而不是一上来就 fsck。第四忽略了 LVM 卷组的激活。有些系统根分区在 LVM 上如果 initramfs 里没有 LVM 工具或 udev 规则不完整会出现卷组无法自动激活的情况。手动执行lvm vgchange -ay是必要的验证步骤。第五忘了查看启动日志里的关键报错。很多人进 shell 后直接敲命令却忽略了屏幕上方滚屏而过的内核日志。先按Shift或者Page Up回看或者如果系统有串口 console通过串口日志拿到完整启动输出可以节省大量时间。4.2 一个快速的排查清单为了方便现场操作我把这套排障流程整理成了一张速查表你可以打印出来贴在机房里步骤操作目的1回看引导日志确认是否有read capacity failed、Not Ready等关键词2ls /dev/sd*检查系统是否识别到物理磁盘3ls /dev/mapper/*检查 LVM/阵列设备是否存在4modprobe megaraid_sas手动加载阵列卡驱动确认驱动是否正常5lvm vgscan lvm vgchange -ay手动激活卷组6重启进 PERC 配置界面确认物理盘和虚拟盘状态7完全断电再上电排除控制器初始化异常8进系统后重建 initramfs更新驱动及引导配置9更新 GRUB 配置确保引导加载器与内核参数一致10连续重启两次验证确认问题已彻底解决而非偶发恢复这个清单基本上覆盖了 95% 的 initramfs 进入场景剩下的 5% 可能涉及内核损坏、bootloader 损坏、RAID 控制器硬件故障那就需要进一步使用发行版救援介质或硬件替换来排查了。4.3 硬件与固件层面的一点心得再补充一个容易被忽略的点Dell 服务器的 iDRAC 生命周期控制器里可以查看系统事件日志这里面会记录阵列卡的告警信息很多在屏幕上稍纵即逝的报错都能在这里查到。我这次排查后期也习惯性地打开了 iDRAC 的日志发现里面确实记录了 RAID 控制器的一次瞬时错误时间点与该次异常启动吻合。这个信息虽然没直接帮我修复但印证了“控制器异常重置”这个判断方向。固件层面我的建议是不要没事乱升级但也不要长期不升级。尤其是阵列卡固件Dell 官方发布的更新说明里经常包含“Improve stability under certain timing conditions”这类修复描述恰恰指向我们遇到的这类问题。升级前一定先看 Release Notes确认是否会影响现有阵列配置并确保在业务低峰期进行操作。5. 预防措施与长期稳定性建议5.1 从基础设施层面减少根因概率这次问题虽然恢复了但如果不做任何后续动作大概率过几个月换一台机器、改一次系统配置、升一次内核又会冒出来。所以我把长期预防措施也一并整理出来供参考。第一确认 root 参数使用 UUID 而非设备名。这个我前面已经强调过R430 这类插阵列卡的机器设备名在引导阶段可能会因为驱动加载顺序变化而改变UUID 则稳定得多。系统安装时如果默认使用 UUID 就没问题如果历史配置里写的是/dev/sda1这种建议尽快改成 UUID。第二定期重建 initramfs。不是让你天天重建而是在以下节点必须重建内核升级之后阵列卡驱动升级之后变更了根文件系统结构比如从非 LVM 切换到 LVM或调整了分区系统从虚拟化平台迁移到物理机之后第三启用系统日志持久化并配置日志服务器。虽然本次靠 dmesg 就能看到问题但如果你不在现场远程就只能依靠日志。把/var/log持久化到独立分区并配置 rsyslog 远程转发能让你在故障后第一时间拿到完整日志。第四对 RAID 阵列做定期巡检。Dell 提供了一个命令行工具perccli或旧版的MegaCli64可以查看虚拟盘状态、物理盘健康度、重建进度等。建议写个脚本每周跑一次输出到监控平台别等到启动异常才发现。/opt/MegaRAID/perccli/perccli64 /c0 /v0 show all | grep -E State|Size|Status如果状态里出现Degraded或者Rebuilding要立刻处理不要拖。RAID5 在降级状态下再坏一块盘数据基本就没了这个风险不是危言耸听。5.2 运维操作层面的规范建议除了技术措施操作习惯也很关键。一是变更窗口要留好回退方案。无论是升级内核、固件还是修改 fstab都要先在测试环境验证生产环境操作前备份好 fstab、grub.cfg、initramfs 镜像。真出问题时哪怕只是旧 initramfs 镜像没有备份都能让修复工作量翻倍。二是不要在年度大版本升级时一口气跨多个版本。很多启动异常都发生在内核跨大版本升级后因为新内核变更了驱动 API旧 initramfs 可能没有重新生成。稳妥的做法是升级完内核后确认 initramfs 重新生成然后重启验证再继续下一步操作。三是对服务器的 IPMI/iDRAC 访问权限做好管理。这类硬件管理接口能远程查看控制台、日志、电源状态是排障的利器。建议规范账号权限并确保网络隔离防止恶意操作同时也能在故障时提供稳定的远程控制。5.3 针对这次场景的额外建议最后针对 Dell R430 这类老平台我再多说一句如果服务器服役时间较长超过 5 年而且已经出现过一次这种“控制器初始化异常”的问题可以考虑做一次硬件健康盘点检查 RAID 控制器电池BBU状态。因为控制器缓存策略和掉电保护依赖 BBU如果 BBU 老化失效会间接影响 RAID 控制器初始化行为甚至造成虚拟盘出现 write-back 降级、元数据异常等问题。另外别忽略 CMOS 电池。老平台的主板纽扣电池电量耗尽后服务器每次断电重启都会丢失一些硬件初始化状态虽说不至于直接导致 initramfs 问题但会提高系统启动的不确定性。更换非常便宜几十块钱的成本省去很多玄学故障。说了这么多其实这次问题本身不算特别复杂但它的典型性很强Dell 服务器 RAID 卡 initramfs shell这个组合在机房日常运维里反复出现。只要掌握好“看日志、查设备、验阵列、重建 initramfs”这条排障主线大多数情况下都能顺利恢复而且不会慌。再分享一个小技巧initramfs 的 shell 里其实内置了不少基础命令比如vi、lsblk、blkid、lvm。如果你在 shell 里敲完命令发现没有也可以用ls /bin/看看实际环境里有什么。有些精简版 initramfs 只带了 busybox 工具命令集有限但lvm和blkid基本都会在因为挂载根分区绕不开它们。另外要是手头正好有同版本系统的安装镜像直接用镜像的救援模式启动进去再修复往往比在 initramfs shell 里折腾更舒服。救援模式里有完整的工具链、网络配置和日志服务排障效率高很多。当然前提是你对系统的根分区布局、LVM 结构足够熟悉不然救援模式里也会卡在“找不到根分区”这个问题上。
阅读完成 · 觉得有帮助?
咨询建站