问题描述
进行了一次常规升级后,BMC 出现网页无法登录、无法重启、无法回滚等严重功能异常
最终 telnet 登录后使用 systemctl reboot 强制重启 BMC 后恢复
AI 问题初步分析
基本信息
| 项目 | 内容 |
|---|---|
| 问题单号 | (未提供 DTS 单号) |
| 硬件平台 | KunLun 2280 V2(序列号 2102315TXA10S5100024) |
| 服务器IP | 192.168.111.178 / 192.168.111.247 / 192.168.110.61 |
| BMC版本号 | Active iBMC 6.00.51.02 (Build 012, Built 18:43:59 Jul 13 2026) |
| CPU | Hi1711 |
| 物理内存 | 1718396 KB ≈ 1.68 GB(可用 1666672 KB ≈ 1.6 GB) |
| 问题模块 | hardware 主框架下所有子组件(chassis / general_hardware / network_adapter / storage / mctpd / lsw) |
| 问题描述 | BMC 升级并自动重启后,核心组件反复启动失败,无法正常工作,用户被迫 systemctl reboot 整个系统 |
现象还原
时间线
| 时间 | 事件 | 来源 |
|---|---|---|
| 12:03:51 | 用户 192.168.111.247 通过 WEB 发起 BMC 升级 image.hpm(从 6.00.51.02) |
operation.log:524 |
| 12:05:22 | BMC 升级成功,注册激活动作 | operation.log:526 |
| 12:05:28 | 因升级触发 BMC 重启,hardware service 停止,dev-shm-bmc_mount.mount Deactivated |
journalctl.log |
| 12:07:47 | 第一次升级后重启完成(完整 kernel boot:Startup finished in 2.203s (kernel) + 1min 26.761s (userspace)) |
journalctl.log |
| 12:07 - 13:45 | 系统正常运行约 1 小时 38 分钟:0 条 bad_alloc,0 条 SHM 延迟告警,0 条 “data size too large” 告警 | app.log |
| 13:45:51 | 用户 192.168.111.178 通过 WEB 再次发起 BMC 升级 image.hpm |
operation.log:554 |
| 13:47:18 | 第二次 BMC 升级成功 | operation.log:556 |
| 13:47:30 | 因升级触发 BMC 重置(active_comm.lua(72): start exec bmc reset,Reboot BMC successfully) |
app.log:508-544 |
| 13:47:27 - 13:49:41 | 完整 kernel boot 过程(Startup finished in 2.227s (kernel) + 1min 26.800s (userspace)),与第一次升级的 boot 过程结构相同 |
journalctl.log |
| 13:49:18 | hardware service 启动 | journalctl.log |
| 13:49:20 | firmware_mgmt 读取回滚状态表:RollbackFlag:1, CurrentStatus:InProgress,nvm_active 从 mmcblk0gp1 变为 mmcblk0gp0,标记 Completed |
app.log:7860-7862 |
| 13:49:21 | 首次 SHM 延迟告警:815ms(sensor → persistence BatchRead) | app.log:1590 |
| 13:49:22 - 13:49:48 | SHM 延迟告警急剧恶化:815ms → 927ms → 2301ms → 6407ms(1 分钟内 36 条告警) | app.log |
| 13:50:48 | 首次 boost::interprocess::bad_alloc:event 模块 AddObject 失败 |
app.log:5427 |
| 13:50:48 - 13:50:57 | 连锁失败:sensor / storage / network_adapter / general_hardware / host_agent / frudata / event 等组件 pre_init 阶段全部因 bad_alloc 失败 |
app.log:5432-5527 |
| 13:50:50 | devmon 底层确认:shm_tree.cpp(1372): failed to update shm property value, error: boost::interprocess::bad_alloc |
app.log:5469 |
| 13:58:27 | 用户 192.168.111.178 通过 CLI 手动发起回滚,尝试 reset BMC |
operation.log:586-587 |
| 13:58:27 - 14:07+ | BMC reset 本身因 bad_alloc 反复失败:Reboot BMC failed, ret=...bad_alloc Sleep 60s and try again(每分钟重试一次,至少 10 次失败) |
app.log:5901-6395 |
| 14:01 - 14:50 | 组件持续启动失败,chassis / general_hardware / network_adapter / storage 各退出 14-15 次,maca 尝试重启恢复后立即再次失败 | framework.log |
| 14:46:05 | 关键调用栈:shm_global_lock_exec → add_named_object_view → register_mdb_objects → CreateEnclosure → boost::interprocess::bad_alloc |
framework.log:95 |
| 14:50:37 | 最后一条 bad_alloc 记录 | app.log |
| ~14:50 | 用户从 OS shell 执行 systemctl reboot |
用户确认 |
| 14:52:14 | dev-shm-bmc_mount.mount: Deactivated successfully(系统级 reboot 开始) |
journalctl.log |
| 14:52:43 | reboot 后重新启动完成:Startup finished in 2.251s (kernel) + 1min 26.938s (userspace) |
journalctl.log |
| 14:52 - 14:57 | 本次启动后出现 7 条 shm reply failed: data size too large 告警,但无 bad_alloc,系统恢复基本功能 |
framework.log:1203+ |
| 14:57:41 | 用户执行一键收集 | dump_log |
关键现象
- 第一次升级后正常:12:07-13:45 期间,0 条 bad_alloc,0 条 SHM 延迟告警,0 条 “data size too large” 告警
- 第二次升级后立即异常:13:49:21 起 SHM 延迟从 815ms 飙升到 6407ms,13:50:48 起全面 bad_alloc
- 两次启动的 SHM 行为对比(boot vs boot,非 boot vs 稳态):
- 第一次升级启动(12:07-12:12):0 条 SHM 延迟告警
- 第二次升级启动(13:49-13:50):36 条 SHM 延迟告警
- 这一对比表明第二次启动的 SHM 行为确实异常,不是正常的 boot 争用
- BMC 自复位机制失效:13:58 手动回滚尝试 reset BMC,但 reset 操作本身因 bad_alloc 失败,系统从 13:49 到 14:50 困在同一个 kernel 实例中无法自复位
- systemctl reboot 恢复但非完全清洁:14:52 整机重启后无 bad_alloc,但出现 7 条 “data size too large” 告警(第一次升级后的 1.5 小时清洁期内此告警为 0)
- July 7 的 core dump 已包含 bad_alloc:CoreDump 目录中的
core-skynet-11-alarm-20260707174950文件内含boost::interprocess::bad_alloc字符串,表明此 SHM 分配缺陷早于本次事件一周就存在
根因分析
直接原因:boost::interprocess::bad_alloc(共享内存段内部分配失败)
所有失败的组件在启动时执行 shm_global_lock_exec → add_named_object_view → register_mdb_objects 时,底层 boost::interprocess managed shared memory segment 抛出 bad_alloc 异常。
关键调用栈(framework.log:95):
shm_global_lock_exec (mc/utils.lua:1147)
└→ add_named_object_view (sd_bus/init.lua:322)
└→ register_mdb_objects (mdb_mgmt/init.lua:152)
└→ CreateEnclosure (mdb/object_manage.lua:192)
└→ chassis enclosure_service.lua:26 (ctor)
boost::interprocess::bad_alloc
boost::interprocess::bad_alloc 表示 managed shared memory segment 内部无法满足一次分配请求。这可能由以下原因导致(本次 dump 中无法进一步区分,见"证据局限"):
| 可能原因 | 说明 | 验证方式 |
|---|---|---|
| 段空间耗尽 | segment 已满,无足够自由空间 | 需 segment 的 get_free_memory() 数据 |
| 段碎片化 | 有自由空间但无足够连续块 | 需 segment 的 free list 分析 |
| 段元数据损坏 | 内部簿记结构损坏导致自由空间不可用 | 需 segment 的完整性校验 |
| 单次分配过大 | 某个对象的分配请求异常大 | 需 add_named_object_view 的请求大小 |
根因推断:长期存在的 SHM 分配缺陷间歇性发作
基于以下证据,推断根因为长期存在的 SHM 分配缺陷,而非一次性的回滚损坏。该缺陷的触发条件尚不明确——第一次升级后的 boot 正常运行 1.5 小时,第二次升级后的 boot 立即异常,两次 boot 的差异(分区切换 / 回滚状态处理 / 对象树规模)仅为关联因素,确切的触发机制需进一步排查:
证据 1:July 7 的 core dump 已包含 bad_alloc
CoreDump 目录中的 core 文件(core-skynet-11-alarm-20260707174950)经 strings 分析包含 boost::interprocess::bad_alloc 字符串,且时间戳 20260707174950 与 Jul 7 build 的时间戳(17:49:50 Jul 7 2026)完全吻合。这表明 SHM 分配失败早于本次事件一周就存在,是一个反复出现的构建级缺陷,而非本次回滚一次性引入的损坏。
方法局限说明:strings 分析发现的是进程内存中的字符串,该字符串可能源于异常抛出时栈上的 bad_alloc 对象(崩溃时的异常),也可能源于二进制只读段中对 bad_alloc 的 catch 处理代码(仅表示代码中有处理逻辑)。但对于 core dump 而言,进程在崩溃时被捕获了内存状态,发现 bad_alloc 字符串高度提示崩溃异常即为 bad_alloc,虽不等同于 backtrace 级别的确证。建议后续对 July 7 的 core 文件进行完整的 backtrace 分析以最终确认。
证据 2:BMC reset 是完整 SoC 复位,会清空 tmpfs
journalctl 日志显示,13:47 的 BMC reset 触发了完整的 kernel boot(Startup finished in 2.227s (kernel) + 1min 26.800s (userspace)),与 systemctl reboot(Startup finished in 2.251s (kernel) + 1min 26.938s (userspace))结构相同。两者都经历了完整的 kernel 初始化 + userspace 启动。reset cause code is 0x2(warm reset),但仍然触发了 SoC 级复位和完整重启。
因此,原假设"BMC reset 不清 tmpfs 导致 SHM 状态持续"是错误的。BMC reset 确实清空了 tmpfs。
证据 3:系统无法自复位是因为 reset 机制本身被 bad_alloc 破坏
13:58 手动回滚尝试 reset BMC 时,reset 操作本身因 bad_alloc 失败:
bmc_upgrade ERROR: init.lua(71): Reboot BMC failed, ret=...boost::interprocess::bad_alloc Sleep 60s and try again
此错误从 13:58:27 开始每分钟重试一次,最后一次记录出现在 14:50:27(app.log:7417)。系统从 13:49(第二次升级后的 boot)到 14:50 一直困在同一个 kernel 实例中。这解释了为什么 bad_alloc 持续 1 小时——不是因为 tmpfs 持久化,而是因为系统根本无法重启。
系统无法自恢复,最终由外部干预解除:journalctl 日志显示,14:50:38 开始出现 OS 级关机序列(Remove pcie drivers、killall busybox_x、Remove cdev_veth_drv successfully 等),14:52:14 dev-shm-bmc_mount.mount: Deactivated successfully。这正是用户从 OS shell 执行 systemctl reboot 的结果。系统本身无法从 bad_alloc 死循环中自恢复——BMC 应用层的 reset 机制被 bad_alloc 破坏,没有 watchdog 超时或其他备用通道在 1 小时内触发复位。最终恢复完全依赖用户的外部 OS 级干预。
证据 4:第一次升级后正常运行 1.5 小时
12:07-13:45 期间系统完全正常(0 bad_alloc,0 SHM 延迟)。第一次升级和第二次升级都经历了完整的 kernel boot(结构相同),但第一次 boot 后 SHM 正常,第二次 boot 后 SHM 异常。两个 boot 的区别在于第二次升级涉及了分区切换(nvm_active 从 mmcblk0gp1 到 mmcblk0gp0)和回滚状态处理(RollbackFlag:1)。
关于"数百次重启累积状态"假说的排除:一种可能的替代解释是 bad_alloc 源于数百次重启累积的 SHM 状态残留。但 July 7 的 core dump 证据表明该缺陷在独立的时间点(一周前)就已出现,且 BMC reset 和 systemctl reboot 都会触发完整 kernel boot 并清空 tmpfs,不存在跨重启的状态累积路径。因此累积状态假说的可能性较低,但无法完全排除——本 dump 未包含 reboot 历史计数数据,无法确认系统在本次事件前经历了多少次重启。
关于回滚方向的说明:回滚日志 version from 6.00.51.02(17:49:50 Jul 7 2026) to 6.00.51.02(18:43:59 Jul 13 2026) 中,目标版本(Jul 13)比源版本(Jul 7)更新,与"回滚应回退到旧版本"的语义矛盾。可能的解释:(a) 日志格式记录的是整体迁移历史而非回滚方向;(b) RollbackFlag:1 表示检测到待处理的回滚状态并标记为已完成,而非执行了一次回滚;(c) 双分区方案中的分区激活被标记为"rollback"。本报告无法确定确切含义,需结合代码确认。
证据 5:reboot 后仍有 “data size too large” 告警
14:52 systemctl reboot 后,系统无 bad_alloc,但出现 7 条 shm reply failed: data size too large 告警。而在第一次升级后的 1.5 小时清洁期内,此类告警为 0。
对此现象有两种可能的解释:
- 解释 A(持续 sizing 问题):对象树规模或某些操作的数据量本身接近 SHM 限制边界,reboot 后重建的 segment 同样面临此压力,但尚未恶化到 bad_alloc 程度。
- 解释 B(降级状态下的初始化压力):reboot 前系统经历了 1 小时的 bad_alloc 死循环,大量组件反复崩溃重启,可能产生了异常的事件积压、告警积压或未完成的数据库事务。reboot 后系统在消化这些积压时,单次 SHM 操作的数据量临时超限。
本报告无法确认哪种解释更准确。解释 A 的困难在于:如果 sizing 是持续的配置问题,第一次升级后的 1.5 小时清洁期内为何 0 告警?解释 B 的困难在于:reboot 已清空 tmpfs,积压数据是否能在 reboot 后延续尚不确定。两种解释不互斥——可能 sizing 边界紧张(解释 A)叠加 reboot 后初始化负载(解释 B)共同导致了 “data size too large” 告警。此问题需补充 SHM segment 诊断数据后进一步分析。
推断的因果链
长期存在的 SHM 分配缺陷(July 7 已出现 bad_alloc core dump)
↓
第二次升级后的 boot 异常(分区切换 / 回滚状态处理 / 对象树规模可能为关联因素,确切触发条件未知)
↓
SHM segment 在初始化阶段无法满足分配请求(bad_alloc)
↓
chassis / general_hardware / network_adapter / storage 等组件启动失败
↓
maca 检测到组件异常,尝试重启恢复 → 组件再次启动 → 再次 bad_alloc → 死循环
↓
BMC reset 机制本身依赖 sd_bus / shm 通信,也被 bad_alloc 破坏
↓
系统无法自复位,困在同一 kernel 实例中,bad_alloc 持续 1 小时
↓
用户从 OS shell 执行 systemctl reboot(绕过 BMC 应用层的 sd_bus 通信,外部干预)
↓
完整 kernel reboot 清空 tmpfs,SHM segment 重建
↓
系统恢复基本功能,但出现 7 条 "data size too large" 告警(原因待定,见证据 5)
证据局限
本报告基于一键收集日志分析,以下关键信息缺失,无法进一步精确定位:
- SHM segment 实际大小:openubmc-docs 记载默认 32MB、推荐 64MB+,但本系统的实际配置未确认
- 故障时刻的 segment 自由空间:收集时
/dev/shm使用 15%(125712KB/836824KB),但这是 reboot 后的快照,非故障时刻 - 故障时刻的对象数量:无法确认 segment 中的对象数是否接近 10000 上限
- bad_alloc 的分配请求大小:
add_named_object_view请求分配的具体大小未知 - segment 完整性状态:无法确认是空间耗尽、碎片化还是元数据损坏
- 回滚的确切语义:
RollbackFlag:1和版本方向日志的含义需结合代码确认 - reboot 后的长期稳定性:仅观察到 14:52-14:57(约 5 分钟)的运行数据,无法确认系统是否长期稳定(第一次升级后 90 分钟才出现问题)
- 缺陷的触发条件:第一次 boot 正常、第二次 boot 异常,但两次 boot 的差异(分区切换 / 回滚状态处理 / 对象树规模)仅为关联因素,确切的触发机制无法从日志中确定
- 系统自恢复能力:BMC 应用层无 watchdog 超时或备用复位通道在 1 小时内触发恢复,系统完全依赖外部 OS 级干预(systemctl reboot)才解除死循环——是否存在其他自恢复机制(如硬件 watchdog)在本次事件中被绕过或超时设置更长,本 dump 无法确认
- “data size too large” 告警的成因:reboot 后 7 条告警是持续 sizing 问题、降级状态初始化压力还是两者叠加,无法区分(见证据 5)
修改建议
短期(规避)
- 升级后若出现组件启动失败,直接从 OS shell 执行
systemctl reboot,因为 BMC 应用层的 reset 机制本身可能被 bad_alloc 破坏而无法执行 - 关注 “data size too large” 告警:此告警与 bad_alloc 的关系尚不明确(见证据 5 的两种解释),但其在 reboot 后出现而清洁期为 0,提示系统在降级状态下存在 SHM 操作数据量超限的风险,出现时应及早排查
中期(定位)
-
确认 SHM segment 的实际配置大小:检查 openUBMC 中 managed shared memory segment 的创建参数(size、growth policy),确认是否为 32MB 或其他值
-
在 dump_info 中增加 SHM segment 诊断数据:
- segment 的
get_free_memory()和get_size()快照 - segment 中的对象计数
/dev/shm/bmc_*文件大小- 本次 dump 缺少这些直接证据,导致无法区分耗尽 / 碎片化 / 损坏
- segment 的
-
分析 July 7 的 core dump:
core-skynet-11-alarm-20260707174950和core-skynet-11-hardware-20260707174950经strings分析发现bad_alloc字符串(与崩溃异常高度一致但非 backtrace 级确证),应进行完整的 backtrace 分析以最终确认一周前的崩溃是否与本次同一根因 -
排查 BMC reset 对 sd_bus / shm 的依赖:13:58 的日志显示 BMC reset 操作本身通过 sd_bus 通信执行,当 sd_bus/shm 被 bad_alloc 破坏时 reset 无法执行。应评估是否需要为 reset 机制提供绕过 sd_bus 的备用通道
-
确认回滚日志的语义:结合
bmc_upgrade/firmware_mgmt代码确认RollbackFlag:1和version from...to...日志的确切含义,判断是否发生了真正的版本回退
长期(健壮性)
-
评估 SHM segment 容量是否匹配资源树规模:KunLun 2280 V2 有大量 PCIe 设备(NIC 卡 E610XT2M5、RAID 卡 SP686C-M-16i 等),reboot 后出现的 “data size too large” 告警可能与 segment 容量不足有关(见证据 5 解释 A),但也可能仅是降级状态下的初始化压力(解释 B)。需先确认实际 segment 大小和故障时刻的自由空间,在缺乏直接证据的情况下不建议盲目增大 segment
-
为
bad_alloc增加段重建机制:当shm_global_lock_exec捕获bad_alloc时,触发段的 unlink + 重建 + 重新初始化,而非让组件直接退出进入死循环重启。注意:段重建会导致其他进程的 SHM 对象失效,需要协调多进程的重初始化 -
增加 SHM 段健康检查:进程启动 attach segment 时校验段头版本标识和 magic number,若检测到段损坏则主动重建
结论
本次组件启动异常的直接原因是 boost::interprocess::bad_alloc——共享内存 managed segment 内部分配失败,导致 chassis / general_hardware / network_adapter / storage 等核心组件在 register_mdb_objects 阶段全部启动失败。
根因是一个长期存在的 SHM 分配缺陷,而非一次性的回滚损坏。关键证据:
- July 7 的 core dump 中发现
boost::interprocess::bad_alloc字符串(与崩溃异常高度一致),缺陷早于本次事件一周 - BMC reset 是完整 SoC 复位(会清空 tmpfs),但 reset 机制本身被 bad_alloc 破坏导致系统无法自复位
- 第一次升级后正常运行 1.5 小时,第二次升级后的 boot 异常——两次 boot 的差异(分区切换 / 回滚状态处理)仅为关联因素,确切触发条件未知
- reboot 后仍出现 7 条 “data size too large” 告警(清洁期为 0),其原因可能是持续 sizing 问题、降级状态初始化压力或两者叠加(见证据 5),尚无法确认
无法确认的:bad_alloc 的具体原因是 segment 空间耗尽、碎片化、元数据损坏还是单次分配过大——本 dump 缺少 segment 大小、自由空间和对象计数的直接证据。建议优先补充 SHM segment 诊断数据的采集,以精确定位失败模式并指导修复方向。
环境信息
26.03 基线