硬件自发现FAQ
更新时间: 2025/06/27
在Gitcode上查看源码

【Q】硬件自发现业务流程

可参考该文档 硬件自发现介绍

【Q】[>0.0.14]如何查看硬件自发现有哪些对象资源?

硬件自发现会将每个硬件组件的对象以 ObjectGroup 的方式呈现在资源树上,ID 以 Position 命名。

shell
~ # busctl --user tree bmc.kepler.hwdiscovery
└─/bmc
  └─/bmc/kepler
    ├─/bmc/kepler/Connector
 ├─/bmc/kepler/Connector/Connector_AppDemo_00
 ├─/bmc/kepler/Connector/Connector_BCU_1_0001
 ├─/bmc/kepler/Connector/Connector_CLU_1_0001
 ├─/bmc/kepler/Connector/Connector_Cooling_00
 ├─/bmc/kepler/Connector/Connector_EXU_1_00
 ├─/bmc/kepler/Connector/Connector_EXU_EEP_00
 ├─/bmc/kepler/Connector/Connector_Event_00
 ├─/bmc/kepler/Connector/Connector_Fructrl_00
 ├─/bmc/kepler/Connector/Connector_Frudata_00
 ├─/bmc/kepler/Connector/Connector_IEU_1_000101
 ├─/bmc/kepler/Connector/Connector_IEU_2_000101
 ├─/bmc/kepler/Connector/Connector_IEU_3_000101
 ├─/bmc/kepler/Connector/Connector_LOM_1_0001
 ├─/bmc/kepler/Connector/Connector_LOM_2_0001
 ├─/bmc/kepler/Connector/Connector_PCIE_1_00010101
 ├─/bmc/kepler/Connector/Connector_PCIE_2_00010101
 ├─/bmc/kepler/Connector/Connector_PCIE_3_00010101
 ├─/bmc/kepler/Connector/Connector_PCIE_4_00010101
 ├─/bmc/kepler/Connector/Connector_PCIE_5_00010101
 ├─/bmc/kepler/Connector/Connector_PSR_1_0001
 ├─/bmc/kepler/Connector/Connector_PowerStrategy_00
 ├─/bmc/kepler/Connector/Connector_SEU_1_0001
 └─/bmc/kepler/Connector/Connector_Sensor_00
    ├─/bmc/kepler/ObjectGroup
 ├─/bmc/kepler/ObjectGroup/00
 ├─/bmc/kepler/ObjectGroup/0001
 ├─/bmc/kepler/ObjectGroup/000101
 ├─/bmc/kepler/ObjectGroup/00010101
 ├─/bmc/kepler/ObjectGroup/0001010105
 ├─/bmc/kepler/ObjectGroup/00010103
 ├─/bmc/kepler/ObjectGroup/000102
 ├─/bmc/kepler/ObjectGroup/000103
 ├─/bmc/kepler/ObjectGroup/000104
 ├─/bmc/kepler/ObjectGroup/000106
 ├─/bmc/kepler/ObjectGroup/0002
 ├─/bmc/kepler/ObjectGroup/0003
 ├─/bmc/kepler/ObjectGroup/0004
 ├─/bmc/kepler/ObjectGroup/0005
 ├─/bmc/kepler/ObjectGroup/0006
 └─/bmc/kepler/ObjectGroup/0007
    └─/bmc/kepler/hwdiscovery
      └─/bmc/kepler/hwdiscovery/MicroComponent

ObjectGroup 对象组对外提供 GetObjects 接口,输入参数:s(Owner,即获取指定对象所有者App名称),输出参数:s(组件Position)a{ssss(类名、对象名、对象属性、扩展属性)}u(组件对象生命周期Id标识) 组件对象生命周期 Id 标识:用于标识对象是否发生变化,服务侧框架收到响应后根据 Id 标识判断是否需要更新对象。

shell
~ # busctl --user introspect bmc.kepler.hwdiscovery /bmc/kepler/ObjectGroup/00
NAME                                TYPE      SIGNATURE RESULT/VALUE  FLAGS
bmc.kepler.ObjectGroup              interface -         -             -
.GetObjects                         method    a{ss}s    sa(ssss)u     -
.Position                           property  s         "00"          emits-change
org.freedesktop.DBus.Introspectable interface -         -             -
.Introspect                         method    -         s             -
org.freedesktop.DBus.ObjectManager  interface -         -             -
.GetManagedObjects                  method    -         a{oa{sa{sv}}} -
org.freedesktop.DBus.Peer           interface -         -             -
.GetMachineId                       method    -         s             -
.Ping                               method    -         -             -
org.freedesktop.DBus.Properties     interface -         -             -
.Get                                method    ss        v             -
.GetAll                             method    s         a{sv}         -
.Set                                method    ssv       -             -
.PropertiesChanged                  signal    sa{sv}as  -             -

可以通过传入指定服务名称,获取对应Position组件包含的对象资源:

shell
~ # busctl --user call bmc.kepler.hwdiscovery /bmc/kepler/ObjectGroup/00 bmc.kepler.ObjectGroup GetObjects 'a{ss}s' 0 'hwdiscovery'

【Q】[>0.0.14]组件资源树上没有XXX对象?对象到底有没有分发?

定位步骤(三步走)

1.找到正常环境下的该资源

abap
busctl --user tree bmc.kepler.<service_name>

例如: 输入 busctl --user tree bmc.kepler.general_hardware,可以看到/bmc/kepler/Systems/1/Boards/RiserCard/RiserCard_1_01010102对象资源

2.去正常环境中找到这个资源的position(最后一个_后面的一串数字)

【特别说明】有的资源路径后面并没有对象名(如果有对象名,可以直接看到),因此可以用introspect命令来查询:

abap
busctl --user introspect bmc.kepler.<service_name> <path>

例如: 输入 busctl --user introspect bmc.kepler.general_hardware /bmc/kepler/Systems/1/Boards/RiserCard/RiserCard_1_01010102,可以看到对象名(.ObjectName)对应的值为RiserCard_1_01010102,position即为01010102

3.去故障环境上查询debug日志中对应position发生了什么

【特别说明】以下展示的是正常自发现流程

abap
cat /var/log/framework.log | grep hwdiscovery | grep <position>

例如: 输入命令 cat /var/log/app_debug_all | grep hwdiscovery | grep 01010102 可以看到日志中出现 "start to get component sr, position: 01010102",代表自发现开始解析数据 日志中出现"component was discovered, position: 01010102, life cycle:1",代表数据解析完成 日志中出现"add objects completely, path: /bmc/kepler/ObjectGroup/01010102",代表自发现资源上树完成

abap
cat /var/log/framework.log | grep <service_name> | grep <position>

例如: 输入命令 cat /var/log/app_debug_all | grep general_hardware | grep 01010102 日志中出现"add objects completely, path: /bmc/kepler/ObjectGroup/01010102",代表对象分发完成 【特别注意】若以上任意一步中间有 ERROR 日志,则表示自发现失败,需要结合 ERROR 级别日志进行分析具体故障原因,具体请参考本文【对象解析失败常见错误场景】

【Q】[>0.0.14]怎么看自发现的是不是eeprom中的数据?还是程序区的sr数据?读的是哪个文件?

目前自发现机制有三种读取方式:

abap
1、从 Eeprom 读取数据
2、从 /opt/bmc/sr 下读取json形式的sr文件数据
3、从 /data/opt/bmc/sr 下读取二进制形式的sr文件数据

通过自发现日志观察

当前自发现会直接报出读取的文件和来源。 全都读取不到的情况下,出现以下格式日志:

  • hwdiscovery WARNING: fail to get psr data from eeprom, exception: ... , position: ...
  • hwdiscovery WARNING: fail to get sr data from local json, exception: ... , position: ...
  • hwdiscovery WARNING: fail to get sr data from program area, exception: ... , position: ...
  • hwdiscovery WARNING: fail to get sr data from data area, exception: ... , position: ...
  • hwdiscovery ERROR: fail to get component sr, exception: ... , position: ...
从opt/bmc/sr下读取json形式sr文件成功时的日志示例:
  • hwdiscovery NOTICE: get csr data from local json,format version: 1.0, data version: 1.0, position: 010104

通过一键收集日志观察

通过一键日志导出功能,可以找到数据来源。 服务器web端按照 “首页-快捷操作-一键收集” 顺序可以找到 “一键收集” 按钮,点击后可收集日志; 在日志压缩包中找到 dump_info/AppDump/hwdiscovery/connectors.txt 文件; 在 connectors.txt 文件中可以看到 “.GroupPosition” 和 “-SourcePath” 的内容

【特别注意】若多种方式都读到了数据,硬件自发现将会根据【Q】CSR版本比较 选择CSR

【Q】CSR 版本比较

基本原则:在格式版本兼容范围内,比较数据版本,选用较高者作为 csr加载解析数据源 注: 兼容范围:hwdiscovery 组件1.60.5版本之前,格式版本限制为3.10,即格式版本大于3.10的 csr 不作为数据源。hwdiscovery 组件1.60.5及以后版本,格式版本限制为4.00,即格式版本大于4.00的 csr 不作为数据源。 格式版本表示:hwdiscovery 组件1.60.5之前,硬件 Eeprom 格式版本即为 csr 文件的 FormatVersion 字段。hwdiscovery 组件1.60.5及以后版本,硬件Eeprom 格式版本即为二进制数据定义 “天池规范版本” 字段,当前默认为3。 hwdiscovery 组件1.60.5之后,若 Eeprom 的 csr 版本和内置版本一致,则使用内置 csr,其余版本使用 Eeprom 的 csr.

【Q】[>=0.0.1] Connector 对象如何配置?

分析天池及传统产品,可以按管理维度将组件和板卡划分为几类,不同类型组件的 Connector 连接器对象配置有一定的差异。以下根据组件类型分别说明。

特别注意点

1、同一个 sr 文件中,不同 Connector 对象中的 position 不允许相同! 后果和现象: a、硬件自发现资源树虽然可以正常加载,但是会概率性出现某一个connector下级组件无法加载,也不会有报错 b、利用 busctl 命令修改 Connector 对象的 persence 值,不会触发在位状态检测

天池标准组件

json
"Connector_Exu_1":{
    "Bom": "14100513",
    "Slot": 1,
    "Position": 1,
    "Presence": "<=/Scanner_Presence_1.Value",
    "Id": "",
    "AuxId": "",
    "Buses":[
        "I2c_c"
    ],
    "SystemId": 1,
    "SilkText": "exu",
    "IdentifyMode": 3,
    "Type": ""
}

主要参数说明:

  • "Bom": "14100513" 表示下级组件 Bom Id。
  • "Type": "" 描述连接器后端设备的类型(如 PCIeSlot、PCIeRiser、NVMe、PSU、BCU、SEU等)。
  • "IdentifyMode": 3 表示下级组件识别方式,3对应下级组件识别方式为天池标准类型组件。
  • "Presence": "<=/Scanner_Presence_1.Value" 表示 Presence 状态获取方式,天池标准组件类型需要指定在位状态获取方式,一般使用同步属性语法通过硬件代理读取指定器件寄存器数据,例如SMC。
  • "Id": "" 表示下级组件 Board Id,天池标准组件的 BoardId 通过 Chip 属性关联的器件对象,调用对应的读写接口获取 Eeprom 数据中的 Board Id信息。该项必须配置为 null 或 "" 。

BoardId 不可读类型组件

json
"Connector_IdReport_1":{
    "Bom": "14100513",
    "Slot": 1,
    "Position": 1,
    "Presence": 0,
    "Id": "",
    "AuxId": "",
    "Buses":[
        "I2c_2"
    ],
    "SystemId": 1,
    "SilkText": "exu",
    "IdentifyMode": 2,
    "Type": ""
}

主要参数说明:

  • "Bom": "14100513" 表示下级组件 Bom Id。
  • "Type": "" 描述连接器后端设备的类型(如 PCIeSlot、PCIeRiser、NVMe、PSU、BCU、SEU等)。
  • "IdentifyMode": 2 表示下级组件识别方式,2对应下级组件识别方式为 BoardId 不可读(上报)类型组件。
  • "Presence": 0 表示 初始 Presence 状态,BoardId 不可读类型由多样化硬件上报设置,值必须配置为0,否则会导致下级组件无法正确触发自发现逻辑。
  • "Id": "" 表示下级组件 Board Id,BoardId 不可读类型由多样化硬件上报设置,值必须为 "" 。
  • "AuxId" 表示下级组件 aux id,BoardId 不可读类型由多样化硬件上报设置,值必须为 "" 。

BoardId 可读类型组件

json
"Connector_IdRead_1":{
    "Bom": "14100513",
    "Slot": 1,
    "Position": 1,
    "Presence": "<=/Scanner_Presence_1.Value",
    "Id": "#/Accessor_Id_1.Value",
    "AuxId": "",
    "Buses":[
        "I2c_2"
    ],
    "SystemId": 1,
    "SilkText": "exu",
    "IdentifyMode": 1,
    "Type": ""
}

主要参数说明:

  • "Bom": "14100513" 表示下级组件 Bom Id。
  • "Type": "" 描述连接器后端设备的类型(如 PCIeSlot、PCIeRiser、NVMe、PSU、BCU、SEU等)。
  • "IdentifyMode": 1 表示下级组件识别方式,1对应下级组件识别方式为 BoardId 可读类型组件。
  • "Presence": "<=/Scanner_Presence_1.Value" 表示 Presence 状态获取方式,BoardId 可读类型需要指定在位状态获取方式,一般使用同步属性语法通过硬件代理读取指定器件寄存器数据。
  • "Id": "#/Accessor_Id_1.Value" 表示下级组件 Board Id,BoardId 可读类型需要指定 Board Id 获取方式,一般使用引用属性语法通过硬件代理读取指定器件寄存器数据。

【Q】[>=0.0.3]对象的重命名规则是什么?

对象的重命名规则是固定的,即由 SR 定义的对象名 + _${Position} 后缀组成。 其中 Position 后缀是由多个两位十六进制数组合而成;每个两位十六进制数,分别代表不同 SR 中对应 Connector 的 Position 属性。 第一个两位十六进制数,是 sr 数据解析的入口,有固定的命名,“00” 表示 platform.sr,“01” 表示 root.sr,“02” 表示 PSR。

【Q】[>=0.0.3]如何确定对象是在哪个SR文件中定义的?

1.确定对象的 Position 后缀 通过日志或资源树可以查看需要确定对象的 Position 后缀。例如 Retimer_Cdr5902L_Obj_0_000106 的 Position 后缀为 000106

2.根据后缀的第一个两位 Position,找到 SR 数据解析入口 Position 后缀是由多个两位十六进制数组合而成;每个两位十六进制数,分别代表不同 SR 中对应 Connector 的 Position 属性。第一个两位十六进制数,是 sr 数据解析的入口,有固定的命名,“00” 表示 platform.sr,“01” 表示 root.sr,“02” 表示 PSR。 根据 Retimer_Cdr5902L_Obj_0_000106 对象的后缀,可以知道对象来源的sr数据解析入口,是 root.sr

3.依次分析后续每个两位 Position,找到对应的 Connector 例如 Retimer_Cdr5902L_Obj_0_000106 对象的后缀的第二个两位 Position 为 “01”,在 root.sr 中找到 Position 为1的 Connector 对象。

json
"Connector_EXU_1":{
    "Bom": "14100513",
    "Slot": 1,
    "Position": 1,
    "Presence": 1,
    "Id": "EXU",
    "AuxId": "01",
    "Buses": [
        "I2c_1",
        "I2c_2",
        "I2c_3",
        "I2c_4",
        "I2c_5",
        "I2c_7",
        "Jtag_1",
        "JtagOverLocalBus_1",
        "Hisport_5",
        "Hisport_6"
    ],
    "SystemId": 1,
    "SilkText":"EXU",
    "TargetType": 2
}

根据${Bom}_${Id}_${AuxId}.sr,可以得知查找的下级 SR 文件为 14100513_EXU_01.sr。

4.重复第三步,查找第三个两位 Position 为 “06” 的 Connector 在 14100513_EXU_01.sr 查找 Position 为 “06” 的 Connector 对象。

json
"Connector_LOM_2":{
    "Bom": "14220246",
    "Slot": 6,
    "Position": 6,
    "Presence": "#/Accessor_SerdesLom2Pres.Value",
    "Id": "VG",
    "AuxId":  "#/Accessor_Serdes2LomId.Value",
    "Buses": [
        "I2c_2",
        "I2cMux_pca9545_chan2",
    ],
    "SystemId": 1,
    "SilkText":"Connector_LOM",
    "TargetType": 2
}

这里的属性是从硬件获取的,需要从资源树查找对应属性

shell
~ # busctl --user tree bmc.kepler.hwdiscovery | grep Connector_LOM_2
 ├─/bmc/kepler/Connector/Connector_LOM_2_0001
~ # busctl --user introspect bmc.kepler.hwdiscovery /bmc/kepler/Connector/

busctl --user introspect bmc.kepler.hwdiscovery /bmc/kepler/Connector/命令可以查找到 "AuxId" 对应的值是 "9",根据${Bom}_${Id}_${AuxId}.sr,可以得知查找的下级 SR 文件为 14220246_VG_9.sr。

5.在 14220246_VG_9.sr 即可找到对应 Retimer_Cdr5902L_Obj_0 的定义

json
"Retimer_Cdr5902L_Obj_0":{
    "RetimerId": 0,
    "LoadSequence": 0,
    "ChipName": "Cdr5902L_Board",
    "ChipType": 0,
    "RefChip": "#/Chip_Cdr5902L_0",
    "ChipVersion": "",
    "ChipLocation": "U1",
    "UpgradeGroup": 0,
    "ReqAccNotify": "#/Accessor_Cdr5902L_AccNotify.Value",
    "Reset": 0,
    "LinkStatus": 0,
    "Switch": "#Accessor_Cdr5902L_ChSwitch.Value",
    "IpmiChannelId": 255
}

【Q】[>=0.0.14]集成测试Connector对象分发失败?

最常见的Connector对象分发失败原因是由于之前的集成测试异常退出,例如Ctrl+Z,进程没有关闭导致资源树对象已存在。通过Kill命名杀掉进程,即可解决。

【Q】[>=0.0.1]SR文件对象解析失败或异常,如何定位?

当前自发现已经包含了比较充分的异常场景日志记录,最简单的定位方法是通过查看日志来分析。 而 /var/log/app_debug_log_all 由于日志较多,容易触发日志风暴,导致日志打印不全。

  • 对于不适合重启服务的场景,可以通过grep hwdiscovery /var/log/app_debug_log_all | grep ERROR命令,查看硬件自发现的关键错误日志。
  • 对于适合重启服务的场景,推荐通过在 /opt/bmc/apps/hwdiscovery/lualib/hwdiscovery_app.lua添加日志重定向代码,输出error级别日志到/data/var/log/bmc/framework.log。可以通过观察子系统日志获取错误信息。
lua
-- 将如下代码添加到 local log = require 'mc.logging' 之后
local old_error = log.error
log.error = function(self, fmt, ...)
    skynet.error('ERROR', string.format(fmt, ...))
    old_error(self, fmt, ...)
end

通过命令 tail -f /data/var/log/bmc/framework.log 观察子系统日志,并执行systemctl restart framework命令重新拉起框架子系统,即可观察到硬件自发现的错误日志。 错误信息示例: fail to get class information, object: BMC_02, class: BMC 对象后缀为02,表示是platform.sr中的定义,可以在platform.sr中查找修改。 获取类信息失败,原因可能是类没有定义,或者类已经在业务侧定义,但是业务侧版本还没发布或同步。

【Q】[>1.60.9]集成测试的时候出现set unknow d-bus object property: bmc.kepler.ObjectGroup.OnlineTimeStamp

自发现在1.60.9后给对象组新增了OnlineTimestamp属性,用于框架根据实际上树时间对对象组排序,因此自发现和libmc4lua的版本需要配套,libmc4lua版本需要大于等于1.60.26,出现该报错建议执行命令 rm -rf ~/.conna/data 清下缓存。

【Q】对象解析错误常见错误场景

1.decode error: unexpected end of data

json解析失败,原因可能为json语法配置出错,例如少逗号、少括号等。

2.fail to get class information, object:xxx, class:xxx

对象名配置有误,请检查该对象是否在MDS(Model.json)中配置,对应的类名是否正确。例如硬件自发现的connector类,对象名必须为Connector_xx_xx。

3.ignore property: %s, value: %s, object: %s, error: fail to analyse property

解析属性失败,该由框架填充默认值 1.当属性为引用对象,而被引用的对象获取失败时 2.当属性为同步对象,而被同步的对象获取失败时

4.ignore object: %s, class: %s, error: fail to get class information

获取对象的类信息失败(组件mds中无该对象定义),或当组件裁剪场景下获取@parent属性失败,将会忽略该对象(不影响其它对象)

5.fail to get sr data from xxx, exception:xxx

根据具体exception定位: (1)exception: signature data is invalid 【结论】该问题只会是从eeprom中读取上报的错误,是在数据区特定偏移下做数据校验,签名校验失败,则不允许读取数据(主要为防范数据被篡改、硬件攻击等) 【解决】重新升级或烧录该eeprom中的数据,该情况一定是eeprom中有脏数据导致

(2)exception: open sr file failed: xxx 【结论】路径下没有对应文件名的文件 【解决】查验文件是否真实存在,是否正常打包上、文件名正不正确

6.AddObject failed、AddObjectComplete failed、DeleteObject failed、DeleteObjectComplete failed 等

【结论】对象分发和卸载过程报错 【解决】优先排查业务在on_add_object、on_add_object_complete、on_delete_object、on_delete_object_complete注册的自定义回调是否存在问题,可以在调用自定义回调的地方把调用栈打印出来

7.failed to verify Eeprom header integrity 或者卡在start to process sr data

【结论】(仅适用于自发现版本大于等于1.60.5的)Eeprom内的数据过老或者手动修改过,导致Eeprom头校验不通过或者使用了设备树版本(废弃)的sr数据 【解决】回退bmc,按下面的方法重新出sr包,升级sr包,之后再升级bmc 1.BMC Studio接口字段出sr包 2.BMC Studio后端接口打包多个SR文件到一个HPM csr来源: 1.一键收集日志后在dump_info\AppDump\hwdiscovery目录下有环境使用的csr 2.从vpd等csr仓中查找需要的csr,可以通过日志看csr文件名 3.将环境上/opt/bmc/sr目录拷贝到本地(不推荐,太多了) 多个打包失败建议一个个打包