BMC概率性冷重启失败问题

问题描述: 执行长时间 BMC 重启测试,通过 IPMI 下发的 Chassis Control Cold Reset 命令返回成功(CompletionCode=0x00),但 BMC 未在 1 分钟内实际重启。测试环境为 5290TX V2 服务器,固件版本 ipmcv3 v2.6.2.0,BIOS 版本 BLADE12-2.0.29。

测试环境

  • 机型:openUBMC

  • 固件版本: 26.03

测试步骤

  1. 通过 IPMI 工具向 BMC 下发 Cold Reset 命令(Chassis Control Command)

  2. 记录 IPMI 返回结果

  3. 等待 BMC 在 1 分钟内完成重启

预期结果:IPMI 返回成功(CompletionCode=0x00),BMC 在 1 分钟内重启完成 实际结果:IPMI 返回成功(CompletionCode=0x00),但 BMC 未在 1 分钟内显示重启,实际 BMC 进程未退出,系统继续正常运行。最终 bmc_reset count: 0 确认 BMC 硬件从未重启。


二、根因分析

2.1 完整调用链路追踪

IPMI Chassis Control Cold Reset
  → ipmi_cold_reset() [ipmi_functions.lua:21-37]
    → powerapi:system_reset(ctx, 'ForceRestart', 'ChassisControlCommand') [powerapi.lua:199-278]
      → execute_hardreset() [powerapi.lua:131-141]
        → force_reset:force_restart() [force_reset.lua:48-59]
          设置 ForceRst=1 到对象(Host 侧热复位)
          设置 sys_reset_flag=true(记录是 BMC 主动发起的复位)
    → maca 框架同时发起 GracefulReset(BMC 自身重启流程)

关键发现force_restart() 只是对 Host 系统侧的硬件对象设置 ForceRst=1,这是发给 CPLD 的热复位信号,用于复位 CPU 等主机设备。它不重启 BMC 本身。BMC 自身的重启由 maca 框架层GracefulReset 流程控制。

2.2 日志时间线(framework.log)

td {white-space:nowrap;border:0.5pt solid #dee0e3;font-size:10pt;font-style:normal;font-weight:normal;vertical-align:middle;word-break:normal;word-wrap:normal;}
时间 事件 分析
0:05:08 [ssdp]HealthCheck failed (2 times) ssdp 服务已处于异常状态
05:23.0 GracefulReset begin, BMC reset type: normal system IPMI Cold Reset 命令到达
0:05:24 33个服务完成 prepare 阶段(全部 <200ms) 正常服务快速完成准备
0:05:34 prepare reboot timeout, components: ssdp ssdp 未响应 Prepare 请求,触发超时
0:05:34 33个服务完成 process 阶段(全部 <100ms) 正常服务完成处理
00:05:34~00:06:38 等待 ssdp 64秒 bmc_upgrade 调用 ssdp 的 MicroComponent.Reboot.Process 等待
0:06:38 service[bmc.kepler.bmc_upgrade] request timeout: …method[Process], used time[64s] Process 接口超时
0:06:38 service[bmc.kepler.bmc_upgrade] request timeout: …method[Prepare], used time[74s] Prepare 接口超时(先发起的,后返回)
0:06:38 ssdp 进程因 D-Bus NoReply 异常退出 Message recipient disconnected from message bus without replying
0:06:39 GracefulReset process fail, skip it 框架跳过 process 失败
0:06:42 start to reboot action, stop all scanners 进入 ACTION 阶段
0:06:48 GracefulReset action fail, skip it ACTION 阶段也失败,但标记 “successfully”
最终 BMC 进程未退出,继续正常运行 bmc_reset count: 0 确认 BMC 硬件从未重启

2.3 maca 框架 strings 分析

从 maca 框架的编译后 init.lua(通过 strings 命令分析)提取到关键代码字符串:

  • %s process fail, skip it — process 失败后跳过

  • %s action fail, skip it — action 失败后跳过

  • %s successfully — 无论 process/action 是否失败,最终都打印成功

  • excute_reboot_operation — 实际执行 BMC 重启的函数

  • force_reset / force_reset_with_cause — 强制重启函数(已存在)

  • Force reset BMC successfully! — 强制重启成功消息

  • reboot + /bin/systemctl — 最终执行 systemctl reboot

关键结论:框架中存在 force_resetexcute_reboot_operation 函数,但当 GracefulReset process 失败时,仅仅 skip it 进入 action 阶段,没有 fallback force_reset

2.4 mc_stream.log 确认

BMC 所有服务在 00:06:38(GracefulReset process fail)之后仍然继续初始化,直到 00:09:02 全部完成。这证实了 BMC 进程未退出,而是继续正常运行。

2.5 根因总结

  1. 直接原因:ssdp 服务在 GracefulReset 开始时已处于异常 HealthCheck 状态,导致其 MicroComponent.Reboot.Prepare(74秒超时)和 MicroComponent.Reboot.Process(64秒超时)接口均超时,使 GracefulReset 的 process 阶段失败

  2. 深层原因:maca 框架在 process 失败后走 skip it 分支 → action 也失败 → 仅打印 successfully 就结束流程。框架未在 GracefulReset 失败后触发任何 fallback 重启机制(如调用已有的 force_reset 函数执行 /bin/systemctl reboot

  3. 复现概率 1/47 的原因:ssdp HealthCheck failed 是偶发的,仅在重启命令到达时 ssdp 恰好处于异常状态时触发此问题

dump_SNXXXXXXXXXXXXXY_20260624-0940.tar.gz (9.1 MB)

答案内容由AI生成,仅供参考:

总结

结合知识库信息,您所描述的现象可归因于:

  • 平滑重启过程中组件(如 ssdp)异常导致 Prepare/Process 超时,框架取消或跳过重启
  • 框架在平滑重启失败后未强制调用强制重启机制,导致 BMC 进程继续运行。
  • 知识库中虽有强制重启功能的存在,但未说明其在平滑重启失败后自动触发的逻辑,可能为特定版本的设计限制。

如需进一步定位,可参考知识库中提到的组件健康状态阈值配置最大复位次数以及平滑重启与强制重启的切换条件。更多关于 maca 框架的重启处理细节,建议结合具体版本的框架代码与开发文档进行分析。

点击此处查看详细分析解答

根据知识库中关于BMC 重启机制的相关信息,以下是对所述“BMC 概率性冷重启失败问题”现象的可能解释。需要说明的是,知识库中未直接收录您提供的具体案例(包含 ssdp 超时、GracefulReset 无 fallback 等详细日志),但其中描述的通用机制与问题现象存在对应关系。


1. BMC 冷重启的两种路径

知识库指出,BMC 的重启分为 平滑重启强制重启 两种方式:

  • 平滑重启:先通知各组件准备,若所有组件准备成功,则执行重启;若有组件准备失败,则通知组件取消重启并返回失败。
  • 强制重启:用于异常场景下强行复位,通常通过系统命令(如 systemctl reboot)执行。

在您的场景中,IPMI Cold Reset 命令返回成功(Completion Code = 0x00),但 BMC 未实际重启。知识库中对应的情况是:IPMI 命令可能仅被 BMC 接收并触发重启流程,而实际重启依赖于内部框架(如 maca)的 GracefulReset 流程是否成功完成。如果平滑重启因组件异常而失败,且未自动降级为强制重启,则 BMC 将继续正常运行。


2. 组件异常导致平滑重启失败

知识库中的案例(参见《MACA 问题定位方法 & FAQ》)明确提到:

平滑重启先通知组件重启准备,如果有组件重启准备失败,则通知组件取消重启并返回失败。

并且:

若连续健康检查失败,默认最多复位 3 次,超过 3 次后不再复位。

在您的日志中,存在某个组件(现象中为 ssdp)在重启准备阶段超时,导致 GracefulReset 的 Prepare 和 Process 阶段均超时,最终进入 action 阶段也失败。这与知识库中描述的组件准备失败导致平滑重启被取消的机制一致。


3. GracefulReset 的阶段与失败处理

知识库中定义了 bmc.kepler.MicroComponent.Reboot 接口,包含 PrepareProcessActionCancel 四个阶段。当某个阶段失败时,框架的行为可以是:

  • 跳过失败阶段并继续后续阶段(如您日志中的“skip it”)。
  • 或调用 Cancel 进行回滚。

知识库并未明确说明在 Process 和 Action 均失败后是否会触发强制重启回退。但文档同时指出,强制重启是独立设计的恢复手段,用于异常场景。因此,若平滑重启流程彻底失败但框架未自动调用强制重启,则 BMC 无法完成实际重启。


4. 最大复位次数的影响

知识库中提到,BMC 健康检查机制对组件连续掉线(如 10 分钟内掉线 5 次)会触发 BMC 复位,但复位次数有上限(默认 3 次),超过后不再复位。虽然您的问题中 bmc_reset count:0 表明本次未计入复位次数,但这一机制说明 BMC 复位存在触发条件和次数限制,可能与特定场景下的复位失效有关。


5. 冷复位与 Host 复位的关系

知识库中 ipmitool mc reset cold 命令用于触发 BMC 自身的完全重启,而您描述的调用链路显示 force_restart() 仅向 Host 侧发送复位信号,BMC 自身重启由 maca 框架的 GracefulReset 控制。这在知识库中也有对应:BMC 冷复位是一个独立的系统级操作,但实际执行可能分离为 Host 复位与 BMC 内部重启两个步骤,若后者失败,则 BMC 进程不退出。


总结

结合知识库信息,您所描述的现象可归因于:

  • 平滑重启过程中组件(如 ssdp)异常导致 Prepare/Process 超时,框架取消或跳过重启
  • 框架在平滑重启失败后未强制调用强制重启机制,导致 BMC 进程继续运行。
  • 知识库中虽有强制重启功能的存在,但未说明其在平滑重启失败后自动触发的逻辑,可能为特定版本的设计限制。

如需进一步定位,可参考知识库中提到的组件健康状态阈值配置最大复位次数以及平滑重启与强制重启的切换条件。更多关于 maca 框架的重启处理细节,建议结合具体版本的框架代码与开发文档进行分析。

1 个赞

帮忙确认一下这个问题是不是问题, 或者说线程异常的时候graceful reset就是不应该重启