高可用版本多厂商Raid卡混插无法正常显示Raid卡的信息

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

问题描述

在用高可用版本适配博通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生成,仅供参考:

:white_check_mark: 结论

当前多厂商RAID卡混插时信息错乱的根本原因是:

SML驱动未实现多厂商上下文隔离 + Controller ID复用 + 协议资源竞争导致博通卡I2C访问被异常终止

推荐解决路径:

  1. :white_check_mark: 为不同厂商RAID卡配置独立的 .sr 和 CSR 文件
  2. :white_check_mark: 使用全局唯一 controller_id,避免对象冲突
  3. :white_check_mark: 确保 libsm_lsi.so 等核心库被打包进固件
  4. :white_check_mark: 优化 sml.get_ctrl_pd_list 调用异常处理机制
  5. :white_check_mark: 增加初始化阶段的日志追踪(协议类型、芯片路径、SML库)

完成上述整改后,可实现华为与博通RAID卡在高可用OpenUBMC环境中稳定共存、独立管理。

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

多厂商RAID卡混插显示异常问题分析与解决方案

在OpenUBMC高可用版本中,当同时插入华为SP686C-M-16i 4G和博通9580-8i8e RAID卡时出现信息显示错乱的问题,即两张RAID卡的信息相互混淆,且博通RAID卡的芯片访问失败。这个问题经过深入分析,可归结为多厂商RAID卡管理中的驱动加载、资源隔离及通信协议冲突等关键因素。


:magnifying_glass_tilted_left: 问题现象总结

  1. 信息错乱

    • 华为RAID卡(SP686C-M-16i 4G)显示的信息被错误地映射到博通RAID卡(9580-8i8e)上。
    • 点击华为RAID卡界面会自动跳转至博通RAID卡的信息页面。
  2. 日志异常

    • 博通RAID卡芯片 Chip_RaidChip_0101010901 出现 “access has been closed after reboot” 错误。
    • 关键调用 pcall(sml.get_ctrl_pd_list, controller_id) 失败,导致无法获取物理盘列表。
    • 缺少类似华为卡的 register firmware info success 成功日志。
  3. 单卡正常、双卡异常

    • 单独使用任一张RAID卡功能正常,说明适配本身是有效的。
    • 混插时才暴露问题,表明存在资源竞争或驱动干扰

:puzzle_piece: 根本原因分析

结合知识库信息和日志线索,问题根源如下:

1. SML层未正确区分多厂商驱动上下文

  • 在OpenUBMC架构中,SML (Storage Management Library) 是屏蔽不同厂商RAID SDK差异的中间层。
  • 不同RAID卡需通过不同的SML插件(如 sml_lsi.so 用于博通,sml_histore.so 用于华为)来实现通信。
  • 当两张卡同时存在时,若没有正确的驱动隔离机制,可能导致:
    • SML调用上下文混乱
    • 协议处理函数(如I2C vs MCTP)被错误复用
    • 芯片访问句柄被覆盖或提前释放

:white_check_mark: 日志中 "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),也可能导致运行时符号缺失。

:check_mark: 文档 [Search Result #6] 提到:新增RAID卡适配需关注“卸载后ID不一致”问题,说明动态加载机制存在状态残留风险。


:white_check_mark: 解决方案建议

:white_check_mark: 1. 确保南向驱动标准化与隔离

推荐方案:基于 openUBMC 南向驱动规范实现驱动解耦

:white_check_mark: 实施步骤:

  1. 按厂商划分CSR配置文件

    • 为华为卡创建 csr/broadcom/...csr/huawei/... 独立目录
    • 避免共用同一套SML初始化参数
  2. 确保SML驱动插件正确加载

    /opt/bmc/lib64/libsm_lsi.so        # 博通专用
    /opt/bmc/lib64/libsm_histore.so    # 华为专用
    
    • 检查 .sr 包内是否包含对应so库
    • 启动时确认 LD_LIBRARY_PATH 正确加载
  3. 启用多控制器独立任务调度

    • 修改 controller_object.lua,确保每个 controller_id 具备唯一任务上下文
    • 增加 debug log 输出每张卡使用的 SML 库名、协议类型

:white_check_mark: 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

:white_check_mark: 3. 强化协议链路管理

:white_check_mark: 措施:

  1. 先等待MCTP链路就绪再注册华为卡

    if is_huawei_card then
        wait_for_mctp_ready()
        register_controller_to_mctp()
    end
    
  2. 独立初始化I2C访问上下文

    • 为博通卡设置专用I2C通道超时与重试机制
    • 防止MCTP操作干扰I2C总线稳定性
  3. 添加协议隔离检查

    log:notice("Controller %d uses protocol: %s", id, get_protocol_by_type(typeId))
    

:white_check_mark: 4. 修改SML代理调用逻辑避免超时误判

当前代码存在缺陷:

if ret == common_def.SML_ERR_MCTP_TIME_OUT and
   method.misc:test_controller_vendor(self.typeId, common_def.VENDER_HUAWEI)

:cross_mark: 仅对华为卡做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

:hammer_and_wrench: 调试建议与验证方法

步骤 操作 目的
1 `lsmod grep i2cdmesg
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/* 验证设备树输出是否一致

:books: 相关参考资料摘要

来源 关键结论
[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 CardopenUBMC 社区版缺SML组件会导致信息获取失败,需引入高可用组件

:white_check_mark: 结论

当前多厂商RAID卡混插时信息错乱的根本原因是:

SML驱动未实现多厂商上下文隔离 + Controller ID复用 + 协议资源竞争导致博通卡I2C访问被异常终止

推荐解决路径:

  1. :white_check_mark: 为不同厂商RAID卡配置独立的 .sr 和 CSR 文件
  2. :white_check_mark: 使用全局唯一 controller_id,避免对象冲突
  3. :white_check_mark: 确保 libsm_lsi.so 等核心库被打包进固件
  4. :white_check_mark: 优化 sml.get_ctrl_pd_list 调用异常处理机制
  5. :white_check_mark: 增加初始化阶段的日志追踪(协议类型、芯片路径、SML库)

完成上述整改后,可实现华为与博通RAID卡在高可用OpenUBMC环境中稳定共存、独立管理。

听同事说已经解决了,帮忙关闭下吧
原因:是组件版本不配套