调试MCU升级流程导致bmc一直升级无法退出

// 此模板仅供参考,如果不适用可以修改

问题描述

调试MCU升级流程,导致bmc一直处于升级状态无法退出,ac下电后还是一直在升级。web升级其它固件一直提示正在升级请稍后重试。

环境信息

  • 操作系统:[如 Ubuntu 24.04]

  • 软件版本:[如 OpenUBMC2509]

  • 硬件配置:[如 CPU、内存等]

重现步骤

  1. [第一步]

  2. [第二步]

  3. [第三步]

期望结果

终止升级状态

实际结果

[实际发生了什么,包含错误信息]

尝试过的解决方案

[列出您已经尝试过的解决方案及结果]

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

调试MCU升级流程导致BMC一直升级无法退出问题分析与解决方案

问题描述

在调试MCU升级流程的过程中,导致BMC(Baseboard Management Controller)系统一直处于“升级中”状态,无法正常退出。即使执行AC下电重启后,BMC仍维持在升级状态。通过Web界面尝试升级其他固件时,系统持续提示“正在升级,请稍后重试”,表明BMC未能恢复正常工作状态。


环境信息

  • 操作系统:Ubuntu 24.04.2
  • 软件版本:openUBMC 25.09
  • 硬件配置:S920X20服务器平台,配备BMC控制器与多块MCU控制的板卡(如Riser卡、NPU卡等)

问题根因分析

根据知识库内容和日志行为分析,该问题的根本原因如下:

1. BMC升级状态被锁定

BMC固件管理系统(Firmware_Mgmt)在处理固件升级任务时,会维护一个全局的升级状态机。一旦启动MCU升级流程(通过MCU Upgrade Service触发McuUpgrade事件),系统将进入UPGRADING状态,并在app.log中记录相关日志。若该流程异常中断或未正确完成清理步骤,状态机停留在PROCESSINGUPGRADING阶段,导致后续所有升级操作被阻塞。

:magnifying_glass_tilted_left: 相关证据:

  • Firmware_Mgmt负责管理整个BMC固件升级过程,包含状态追踪、阶段切换(如COMMON_PREPAREPROCESS)。
  • 日志显示存在类似“[McuUpgrade] upgrading”的记录,但缺少upgrade completedupgrade failed的终止状态。

2. 状态文件未清除或持久化异常

openUBMC使用持久化机制(如per_poweroff.db数据库)保存当前系统状态。当MCU升级过程中断(如人为中断、断电),Firmware_Mgmt模块可能未能清除upgrade in progress标记,或数据库中的task_instance状态未更新为COMPLETEDFAILED

:magnifying_glass_tilted_left: 相关实体:

  • Firmware_Mgmt负责任务状态写入。
  • 日志路径中常见/data/trust/persistence/目录用于存储任务状态。
  • 错误模式类似于【Document Chunk 4】中提到的“Upgrade write config file failed”。

3. MCU与BMC通信异常导致升级卡死

MCU升级依赖于BMC与MCU之间的通信(如I²C、JTAG)。若调试过程中发送了非法指令、固件包不完整,或MCU进入不可响应状态(如“挂死”),BMC端的general_hardware模块会持续轮询升级状态,而得不到有效返回,从而造成升级流程“假死”。

:magnifying_glass_tilted_left: 参考【Document Chunk 9】中提到:

  • 升级VRD失败返回码75,说明MCU侧可能返回非预期结果。
  • BMCMCU之间通过Chip BlockIO Interface交互,用于查询版本和状态。

解决方案

:white_check_mark: 方案一:强制清除BMC升级状态(推荐)

步骤 1:登录BMC命令行(SSH或串口)

ssh root@<bmc_ip>

步骤 2:检查当前升级任务状态

# 查看升级日志
tail -f /var/log/app.log | grep -i upgrade

# 检查是否仍在升级
ipmcget -d version
# 若返回 "The request failed due to an internal service error",说明服务异常

步骤 3:清除持久化升级状态文件

# 备份原数据库
mv /data/trust/persistence/per_poweroff.db /data/trust/persistence/per_poweroff.db.bak

# 重启服务以重建状态
killall skynet

:warning: 注意:此操作会重置部分运行时配置,请确保网络等关键信息已备份。

步骤 4:验证状态恢复

重启后登录Web界面,查看“固件升级”是否恢复可用。


:white_check_mark: 方案二:使用IPMC命令强制回滚(如可用)

如果ipmcset工具仍可访问:

ipmcset -d rollback

此命令会尝试触发回滚至上一可用固件版本,强制结束当前升级流程。

:pushpin: 参考【Document Chunk 3】中用户Cake建议:“ipmcset -d rollback回退到上一个版本试过了么


:white_check_mark: 方案三:手动终止升级任务(高级调试)

1. 查看当前运行的任务

busctl --user list-ids | grep firmware_mgmt

2. 停止firmware_mgmt服务

systemctl stop firmware_mgmt

3. 删除临时升级文件

rm -rf /dev/shm/upgrade/*
rm -rf /tmp/fw_upgrade_*

4. 重启服务

systemctl start firmware_mgmt

预防建议

措施 说明
避免调试中直接断电 应通过ipmcset -d reset等软重启方式结束测试
启用任务超时机制 确保Firmware_Mgmt配置合理的阶段超时时间(如COMMON_PREPARE阶段默认300秒)
使用仿真环境测试 推荐使用BMC Studio + QEMU仿真环境进行MCU升级调试,避免影响真机
日志监控 实时监控app.logFirmware_Mgmtgeneral_hardware模块输出,及时发现卡滞

相关参考资料

  • 【Document Chunk 3】用户weixin_42540325报告无法回滚,怀疑公共分区损坏
  • 【Document Chunk 7】bmc_upgrade/1.70.37优化内存管理,避免因资源不足导致卡死
  • 【Knowledge Graph】Firmware_Mgmt是负责BMC升级的核心组件,状态管理依赖其正确运行

:white_check_mark: 结论:BMC始终处于升级状态是由于升级任务状态未正常终止所致。强制清除持久化状态数据重启firmware_mgmt服务可有效恢复系统功能。建议后续在仿真环境中进行MCU升级流程调试,避免类似问题再次发生。

相关链接:

  1. 升级失败,web升级进度卡在15%,导致无法重启BMC或者重新升级
  2. 升级白牌包到5%失败
  3. 如何手动切换分区
  4. BMC固件升级失败
  5. IPMI管理定位问题 | 文档中心 | openUBMC

替换环境上的platform.sr,把platform.sr中的这个对象修改下,关闭自愈,具体是MCU几看你升的MCU匹配哪个,修改后,复位BMC起来后应该不会自愈了

"FirmwareComponentInfo_Mcu1": {
            "ComponentID": 29,
            "ComponentIDEx": 4294967295,
            "Name": "Mcu",
            "RevisionNumber": 0,
            // 下面这个属性配置为false
            "UpgradeResumeSupported": false
        },