// 此模板仅供参考,如果不适用可以修改
问题描述
在用高可用版本适配博通Raid卡时遇到了这样一个问题:
服务器插着一张华为的SP686CM16i4G卡,一张博通的9580-8i8e卡,将我适配好的博通sr
打包更新后,发现9580-8i8e显示的为SP686CM16i4G的信息,同时,点击SP686CM16i4G会自动跳转到9580-8i8e卡
经过排查,发现在读取博通的Raid芯片时出现了这样的错误,
the chip Chip_RaidChip_0101010901 access has been closed after reboot
加载流程也没有出现和SP686CM16i4G一样的加载成功日志
storage NOTICE: method_misc.lua(295): [MethodMisc] register firmware info success, Id=PCIeCard2SP686CM16i4G, Version=N/A
继续跟踪,发现是controller_object.lua中调用pcall(sml.get_ctrl_pd_list, controller_id)获取控制器pd_list 时失败,
最终定位到sml的这个请求
目前不清楚是什么原因导致这个请求失败,没有解决头绪,希望提供帮助
之后还用插着这两张卡的服务器,将两张卡单独测试,只单独加载SP686CM16i4G卡或者适配的博通的9580-8i8e卡的sr,发现功能和显示的信息均正常,硬盘信息也能正常加载,并能组建逻辑盘
环境信息
- 软件版本:[OpenUBMC2603 高可用HA版本]
答案内容由AI生成,仅供参考:
结论
当前多厂商RAID卡混插时信息错乱的根本原因是:
SML驱动未实现多厂商上下文隔离 + Controller ID复用 + 协议资源竞争导致博通卡I2C访问被异常终止
推荐解决路径:
为不同厂商RAID卡配置独立的 .sr 和 CSR 文件
使用全局唯一 controller_id,避免对象冲突
确保 libsm_lsi.so 等核心库被打包进固件
优化 sml.get_ctrl_pd_list 调用异常处理机制
增加初始化阶段的日志追踪(协议类型、芯片路径、SML库)
完成上述整改后,可实现华为与博通RAID卡在高可用OpenUBMC环境中稳定共存、独立管理。
点击此处查看详细分析解答
多厂商RAID卡混插显示异常问题分析与解决方案
在OpenUBMC高可用版本中,当同时插入华为SP686C-M-16i 4G和博通9580-8i8e RAID卡时出现信息显示错乱的问题,即两张RAID卡的信息相互混淆,且博通RAID卡的芯片访问失败。这个问题经过深入分析,可归结为多厂商RAID卡管理中的驱动加载、资源隔离及通信协议冲突等关键因素。
问题现象总结
-
信息错乱:
- 华为RAID卡(SP686C-M-16i 4G)显示的信息被错误地映射到博通RAID卡(9580-8i8e)上。
- 点击华为RAID卡界面会自动跳转至博通RAID卡的信息页面。
-
日志异常:
- 博通RAID卡芯片
Chip_RaidChip_0101010901 出现 “access has been closed after reboot” 错误。
- 关键调用
pcall(sml.get_ctrl_pd_list, controller_id) 失败,导致无法获取物理盘列表。
- 缺少类似华为卡的
register firmware info success 成功日志。
-
单卡正常、双卡异常:
- 单独使用任一张RAID卡功能正常,说明适配本身是有效的。
- 混插时才暴露问题,表明存在资源竞争或驱动干扰。
根本原因分析
结合知识库信息和日志线索,问题根源如下:
1. SML层未正确区分多厂商驱动上下文
- 在OpenUBMC架构中,
SML (Storage Management Library) 是屏蔽不同厂商RAID SDK差异的中间层。
- 不同RAID卡需通过不同的SML插件(如
sml_lsi.so 用于博通,sml_histore.so 用于华为)来实现通信。
- 当两张卡同时存在时,若没有正确的驱动隔离机制,可能导致:
- SML调用上下文混乱
- 协议处理函数(如I2C vs MCTP)被错误复用
- 芯片访问句柄被覆盖或提前释放
日志中 "the chip access has been closed" 表明:对博通卡的I2C通道在初始化后被意外关闭,极可能因华为卡使用MCTP协议过程中影响了共享资源或调度逻辑。
2. Controller ID 复用导致对象注册冲突
controller init obj.Id = 0, object_id = 1 --> 华为卡
controller init obj.Id = 0, object_id = 2 --> 博通卡
- 两个RAID卡控制器均以
obj.Id = 0 初始化,说明控制器实例未做全局唯一标识。
- 若底层SML或任务调度模块仍以
controller_id = 0 作为主键,则会出现:
- 后加载的卡覆盖前卡的注册信息
- Web UI 显示错乱(ID冲突导致跳转异常)
参考文档 [Search Result #2] 明确指出:“控制器加载与一般对象不同”,需确保 MCTP/I2C 链路注册独立且不冲突。
3. 协议资源未隔离(I2C vs MCTP)
| RAID卡类型 |
通信协议 |
协议特点 |
| 华为 SP686C-M-16i 4G |
MCTP over SMBus |
需先建立MCTP链路,再注册节点 |
| 博通 9580-8i8e |
I2C |
直接通过I2C读写 |
- 若系统未对两种协议路径进行隔离管理,容易发生:
- I2C总线争抢
- MCTP注册干扰I2C设备存活状态
- 共享插件中的协议读写函数指针被错误替换
特别注意:华为卡依赖 mctp 注册成功后再轮询信息,而博通卡基于 i2c,若调度顺序不合理,会造成后加载的卡初始化失败。
4. .sr 文件打包或加载顺序问题
- 用户将适配好的博通
.sr 文件打包更新,但未说明是否清除了缓存或重置了设备树状态。
- 若旧的驱动状态未清除,可能导致新驱动加载异常。
.sr 包若未正确声明其依赖库(如 libsm_lsi.so),也可能导致运行时符号缺失。
文档 [Search Result #6] 提到:新增RAID卡适配需关注“卸载后ID不一致”问题,说明动态加载机制存在状态残留风险。
解决方案建议
1. 确保南向驱动标准化与隔离
推荐方案:基于 openUBMC 南向驱动规范实现驱动解耦
实施步骤:
-
按厂商划分CSR配置文件
- 为华为卡创建
csr/broadcom/... 和 csr/huawei/... 独立目录
- 避免共用同一套SML初始化参数
-
确保SML驱动插件正确加载
/opt/bmc/lib64/libsm_lsi.so # 博通专用
/opt/bmc/lib64/libsm_histore.so # 华为专用
- 检查
.sr 包内是否包含对应so库
- 启动时确认
LD_LIBRARY_PATH 正确加载
-
启用多控制器独立任务调度
- 修改
controller_object.lua,确保每个 controller_id 具备唯一任务上下文
- 增加 debug log 输出每张卡使用的 SML 库名、协议类型
2. 修复Controller ID冲突问题
修改建议(伪代码):
-- 在 controller init 阶段绑定唯一 controller_index
function Controller:init(obj)
self.Id = assign_unique_controller_id() -- 全局递增或基于PCIe BDF生成
self.typeId = obj.TypeId
self.refChip = obj.RefChip
log:notice("Initializing controller %d, TypeId=%d, Chip=%s", self.Id, self.typeId, self.refChip)
end
- 避免所有卡共用
controller_id=0
- 建议根据 PCIe Slot 或 Chip UID 生成唯一 ID
3. 强化协议链路管理
措施:
-
先等待MCTP链路就绪再注册华为卡
if is_huawei_card then
wait_for_mctp_ready()
register_controller_to_mctp()
end
-
独立初始化I2C访问上下文
- 为博通卡设置专用I2C通道超时与重试机制
- 防止MCTP操作干扰I2C总线稳定性
-
添加协议隔离检查
log:notice("Controller %d uses protocol: %s", id, get_protocol_by_type(typeId))
4. 修改SML代理调用逻辑避免超时误判
当前代码存在缺陷:
if ret == common_def.SML_ERR_MCTP_TIME_OUT and
method.misc:test_controller_vendor(self.typeId, common_def.VENDER_HUAWEI)
仅对华为卡做MCTP超时重试,忽略博通卡I2C超时处理
修正建议:
if ret == common_def.SML_ERR_I2C_TIME_OUT or ret == common_def.SML_ERR_MCTP_TIME_OUT then
self.timeout_times = self.timeout_times + 1
if self.timeout_times >= MAX_RETRY_TIMES then
log:warning("Max retry exceeded, restarting controller %d", self.Id)
self:register() -- 重新注册
self.timeout_times = 0
end
end
调试建议与验证方法
| 步骤 |
操作 |
目的 |
| 1 |
`lsmod |
grep i2c和dmesg |
| 2 |
find /opt/bmc/lib64 -name "*sm*.so" |
确认所需SML库存在 |
| 3 |
`cat /var/log/app.log | grep -E "add_controller_to_sml |
register_controller_to_sml"` |
| 4 |
objdump -T libsm_lsi.so | grep get_ctrl_pd_list |
验证符号存在性 |
| 5 |
使用 Redfish 或 CLI 查询 /redfish/v1/Systems/1/Storage/* |
验证设备树输出是否一致 |
相关参考资料摘要
| 来源 |
关键结论 |
[Search Result #2] storage组件设计 |
SML需封装不同厂商SDK;MCTP卡需先建链再注册 |
[Search Result #5] RAID南向部件驱动设计 |
应按厂商组织CSR配置,避免混用 |
| [Doc Chunk 4] |
ret:4357 表示 add_controller_to_sml() 失败,主因为so库缺失 |
KG Broadcom 9560 16i RAID Card → openUBMC |
社区版缺SML组件会导致信息获取失败,需引入高可用组件 |
结论
当前多厂商RAID卡混插时信息错乱的根本原因是:
SML驱动未实现多厂商上下文隔离 + Controller ID复用 + 协议资源竞争导致博通卡I2C访问被异常终止
推荐解决路径:
为不同厂商RAID卡配置独立的 .sr 和 CSR 文件
使用全局唯一 controller_id,避免对象冲突
确保 libsm_lsi.so 等核心库被打包进固件
优化 sml.get_ctrl_pd_list 调用异常处理机制
增加初始化阶段的日志追踪(协议类型、芯片路径、SML库)
完成上述整改后,可实现华为与博通RAID卡在高可用OpenUBMC环境中稳定共存、独立管理。
听同事说已经解决了,帮忙关闭下吧
原因:是组件版本不配套