BMC升级后总回滚问题

问题描述

客户现场个别机器,非全部机器出现:BMC执行升级操作后,应用层报告升级成功(Progress=100%, State=Completed),但BMC重启后新版本未能生效,系统自动回滚到升级前的旧版本。该现象在连续三次升级尝试中反复出现。请问该如何恢复确保新版本 rootfs 镜像大小与分区表定义一致,或更新分区表以适配更大的 rootfs 镜像?

升级路径:25.12.01.02 → 25.12.01.09

最终结果:始终回滚到 25.12.01.02

环境信息

  • 软件版本:2512 LTS SP1

事件时间线

实际结果

Flash 存储区域 rootfs 镜像尺寸不匹配(size mismatch)
M3 底层固件升级的关键错误链:

  1. [NVOPS] size:0x17847000 rd size:0x17859000 offset:0x0
    → 预期 rootfs 大小 = 0x17847000 (约 377MB)
    → 实际读取大小 = 0x17859000 (约 377MB+72KB)
    → 尺寸偏差 = 0x12000 (72KB)

  2. [SA] nv 1 code failed
    → NVRAM/SPI NAND 读取校验失败

  3. [FWUPD] read temp region rootfs error

  4. [FWUPD] verify tmp region rootfs error

  5. [FWUPD] rootfs tmp verify fail, ret:-22 (-EINVAL)

  6. [FWUPD] fw_upgrade_rootfs_process error, ret:-22


每次应用层都报告"升级成功",但 M3 底层始终因为 rootfs 镜像尺寸校验失败而无法完成固件同步。

分析结论

BMC升级后回滚的根本原因是 M3 固件层在将 tmp 区 rootfs 同步到 active/gold 区时,检测到 rootfs 镜像尺寸不匹配(size=0x17847000 vs rd size=0x17859000),导致 rootfs 校验失败(ret:-22),active 区域 rootfs 未被正确更新。重启后双分区均无法加载 rootfs,触发回滚机制,系统从旧的可用固件恢复启动。

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

总结

项目 内容
问题本质 rootfs 镜像大小(377MB+72KB)超出分区定义(377MB),导致 M3 固件校验失败
根本原因 构建系统生成的 rootfs_BMC.img 超出原始分区容量
错误码 ret:-22 (-EINVAL),源于 verify tmp region rootfs error
解决方案 1. 缩减镜像至 ≤394272768 字节
2. 或更新 M3 分区表以支持更大尺寸
预防措施 在 CI/CD 流程中加入镜像大小断言检查

:white_check_mark: 最终结论请立即检查构建产物 rootfs_BMC.img 的实际大小,确保其等于 394272768 字节(0x17847000);若不一致,则需精简内容或调整分区表,否则所有升级都将因底层校验失败而触发回滚。

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

BMC升级后反复回滚问题分析与解决方案

问题概述

在BMC固件升级过程中,尽管应用层报告升级成功(Progress=100%,State=Completed),但系统重启后仍回滚至旧版本(25.12.01.02),新版本(25.12.01.09)未能生效。该问题在连续三次升级尝试中重复出现,表明存在M3底层固件校验失败导致的系统级回滚机制触发


故障现象详情

  • 升级路径25.12.01.02 → 25.12.01.09
  • 软件版本:2512 LTS SP1
  • 实际结果:每次升级完成后重启,系统自动回滚至原始版本 25.12.01.02
  • 关键表现
    • 应用层显示“升级成功”
    • M3底层固件检测到异常,触发回滚
    • 双分区(active与backup)均启动失败

根本原因分析

:white_check_mark: 核心问题:rootfs镜像大小不匹配导致M3校验失败

根据日志中的关键错误信息:

NVOPS: size=0x17847000 rd size=0x17859000 — 尺寸不匹配!
  • 预期 rootfs 大小0x17847000(约 377MB
  • 实际读取大小0x17859000(约 377MB + 72KB
  • 偏差值0x12000 = 72KB

此尺寸偏差导致以下连锁反应:

阶段 错误信息 含义
NVOPS size mismatch 分区定义与实际写入文件大小不符
SA nv 1 code failed NVRAM/SPI NAND 校验失败
FWUPD verify tmp region rootfs error 临时区rootfs校验失败
FWUPD ret:-22 (-EINVAL) 无效参数,验证失败
L1FW rootfs both boot fail 主备分区均无法加载

最终导致 BMC启动失败 → 触发回滚机制 → 切换回旧版本启动成功


技术溯源与背景支持

1. rootfs镜像与分区一致性的重要性

  • Rootfs_BMC.img 是 BMC 系统的根文件系统镜像,其解压后大小为 377MB(即 0x17847000 字节)。
  • 在升级流程中,rootfs_openUBMC.hpm 包含了 rootfs_BMC.imgrootfs_iBMC.img,被提取并写入 flash 的 tmp 区。
  • M3 固件控制器负责执行最终的分区同步操作(tmp → active/gold),但会严格校验镜像大小与分区表声明的一致性。

来自知识库支持:

  • Rootfs_BMC.img 的 apparent size 为 377MB(来自 du --apparent-size
  • 394272768 bytes = 377MB,与该值吻合
  • 若构建出的镜像超出此大小或未对齐,将引发底层校验失败

2. 升级流程中的“虚假成功”机制

虽然上层服务(如 web_backend、firmware_mgmt)完成了 HPM 包解析、解压和写入 tmp 区的操作,并报告“升级成功”,但这仅代表应用层处理完成,并不代表底层刷写和校验成功。

M3 固件在下一次启动时才进行最终的 fw_upgrade_rootfs_process,若此时发现:

  • 镜像损坏
  • 签名无效
  • 尺寸不匹配

则直接判定为升级失败,并执行自动回滚。


解决方案

:white_check_mark: 方案一:确保 rootfs 镜像大小与分区表严格一致

1. 检查构建输出的 rootfs_BMC.img 实际大小

ls -l output/images/rootfs_BMC.img
# 应等于 394272768 字节(即 0x17847000)

# 或使用 hex 查看
stat -c "%s" rootfs_BMC.img

2. 若超过 394272768 字节 → 削减文件系统内容

  • 移除非必要组件(如调试工具、冗余日志、测试脚本)
  • 检查是否误加入了 busyboxgdbstrace 等大型工具
  • 使用 du -sh * 分析根目录占用

3. 强制限制镜像最大尺寸(build 配置)

在构建系统中添加限制规则,防止超标:

# 在构建脚本中加入检查
if [ $(stat -c "%s" rootfs_BMC.img) -gt 394272768 ]; then
    echo "ERROR: rootfs image too large!" >&2
    exit 1
fi

:white_check_mark: 方案二:更新 M3 分区表以适配更大的 rootfs(需硬件支持)

若必须使用更大镜像,需同步更新 M3 固件中的 NOR Flash 分区表定义

1. 修改分区配置(示例)

// flash_layout.h 或类似文件
#define PARTITION_ROOTFS_SIZE      0x1785A000  // 扩展至略大于实际大小

2. 重新编译并烧写 M3 固件(bootloader/firmware updater)

  • 此操作风险较高,需确保 M3 固件版本与主 BMC 固件兼容
  • 建议仅在产品迭代阶段进行,现场升级慎用

3. 验证新分区能否容纳目标镜像

# 检查是否满足:img_size ≤ partition_size
echo $((0x17859000 < 0x1785A000))  # 应为真

:white_check_mark: 方案三:修复构建流程,避免引入多余数据

1. 检查 HPM 构建过程是否污染 rootfs

  • 查看 packethpm_ext4.sh 脚本是否有动态注入文件行为
  • 确保 bmcgo/tasks/task_build_rootfs_img 执行无误
  • 若使用了 gpp 模块,确认其未覆盖 rootfs_iBMC.img 为更大版本

关系支持:
"Gpp" --overrides--> "rootfs_iBMC Img"
若 GPP 模块注入了额外大文件,则可能导致镜像膨胀

2. 检查是否正确替换了路径名

从旧版 BMC 升级时,必须将 rootfs_BMC 替换为 rootfs_iBMC

# 构建前执行批量替换
find . -type f -name "*.py" | xargs sed -i 's/rootfs_BMC/rootfs_iBMC/g'

引用文档 #4 明确指出:
“BMC 3.xx.xx.xx版本直升openubmc指导”中要求在 manifest.yml 中将 rootfs_BMC 替换为 rootfs_iBMC


推荐操作流程(现场恢复建议)

步骤 操作 说明
1 获取当前构建产物的 rootfs_BMC.img 大小 确认是否超标
2 对比标准大小 394272768 字节 计算偏差
3 若超标 → 回溯构建变更,精简镜像 删除新增大文件
4 重新构建 HPM 包(rootfs_openUBMC.hpm) 保证 clean build
5 在测试环境验证 M3 启动与同步过程 使用 real board 测试
6 部署修正后的固件包至现场 避免再次触发回滚

:warning: 严禁强制跳过校验:M3 层的安全校验是防止砖机的关键机制,不可绕过


临时诊断命令(可用于现场排查)

# 查看当前运行系统中 rootfs 实际挂载大小
df -h /

# 查看 tmp 区固件包大小
ls -l /dev/shm/upgrade/rootfs_img.tar.gz

# 提取 HPM 包内 rootfs 并检查大小
tar -xzf rootfs_img.tar.gz rootfs_BMC.img
stat -c "Size: %s bytes" rootfs_BMC.img

总结

项目 内容
问题本质 rootfs 镜像大小(377MB+72KB)超出分区定义(377MB),导致 M3 固件校验失败
根本原因 构建系统生成的 rootfs_BMC.img 超出原始分区容量
错误码 ret:-22 (-EINVAL),源于 verify tmp region rootfs error
解决方案 1. 缩减镜像至 ≤394272768 字节
2. 或更新 M3 分区表以支持更大尺寸
预防措施 在 CI/CD 流程中加入镜像大小断言检查

:white_check_mark: 最终结论请立即检查构建产物 rootfs_BMC.img 的实际大小,确保其等于 394272768 字节(0x17847000);若不一致,则需精简内容或调整分区表,否则所有升级都将因底层校验失败而触发回滚。

你出升级包使用的是个人manifest还是社区manifest?

用的社区manifest br_release_openUBMC2512_20261231_LTS_SP1分支,在此基础上增加了高可用出包相关修改,新增相关组件,和开源组件的修改。

有一键日志收集吗

有一键收集

有一键收集,您看下
openUBMC_19700101-0012.tar.gz (4.9 MB)

这是另一台机器,同样页面升级成功,但是起来后还是恢复到上一个版本25.12.01.07版本。
openUBMC_19700101-0038.tar.gz (3.8 MB)