hwdiscovery
版本信息
| 项目 | 内容 |
|---|---|
| 组件版本 | 1.130.20 |
| 首发版本 | openUBMC 26.09 |
| 文档作者 | openUBMC 社区 |
| 最后更新 | 2026-09-15 |
| 许可证 | Mulan PSL v2 |
1. 组件概述
1.1 组件简介
hwdiscovery 是 openUBMC 的硬件自发现组件,归属基础框架子系统,是南向硬件访问的一部分。它以独立 Skynet 应用运行,D-Bus 服务名为 bmc.kepler.hwdiscovery,工作目录 /opt/bmc/apps/hwdiscovery。组件解析机型 CSR(.sr)与 EEPROM 自描述数据,按对象组发布对象,并驱动下级板卡的并发发现与热插拔。
mds/service.json 中 type 为 application,description 为 hardware self-discovery component,deployConfig 为 framework.service。systemd 单元 hwdiscovery.service 在 mdb_mgmt.service 之后启动,依赖 mdb_mgmt.service 与 persistence.service。
组件不提供 IPMI 命令(仓库无 mds/ipmi.json)。对外资源协作接口来自本仓 mds/model.json 与 mdb_interface 中的 bmc.kepler.ObjectGroup、bmc.kepler.Connector。内部 Skynet 解析服务 .parser_service 不对外暴露 D-Bus 方法。
构建依赖 libmc4lua、persistence;测试依赖 hwproxy、maca、ipmi_core、dtframeforlua、mdb_interface、libmgmt_protocol。运行时还依赖 bmc.kepler.Chip.BlockIO、bmc.kepler.Accessor、bmc.kepler.Scanner、bmc.kepler.EepromData、bmc.kepler.Managers.Package(见 mds/service.json 的 required)。
1.2 解决什么问题
BMC 上电后需要根据机型 CSR / EEPROM 自描述构建硬件对象树,并把对象按归属组件分发给 hwproxy 与各业务 App。hwdiscovery 把以下工作收敛到统一服务:
- 从程序区、数据区、EEPROM 或客户定制目录加载
root.sr、platform.sr及下级部件 CSR。 - 按 MDS Schema 解析对象、引用、同步、表达式与层级关系,完成对象重命名。
- 以
ObjectGroup上树并提供按 Owner 拉取对象、按 Position 拉取拓扑的接口。 - 根据 Connector 的识别模式与在位状态并发发现下级组件,并支持热插拔卸载/重载。
1.3 核心功能
核心功能一:对象组发布
每个 SR 硬件组件对应一个 ObjectGroup,路径
/bmc/kepler/ObjectGroup/${Position}。业务组件与 hwproxy 收到上树信号后,调用GetObjects/GetBinaryObjects/GetTopology拉取归属本 App 的对象或拓扑链路。核心功能二:连接器与下级发现
Connector 描述下级板卡的 Bom、槽位、在位、BoardId、总线和识别方式。Presence 变化时触发加载或卸载;
Reload可按指定身份强制重载。核心功能三:CSR 解析流水线
解析服务按 match → rename → append → arrange → analyse 处理 CSR。支持变量、同步(
<=/)、引用(#/)、层级(@Parent)、表达式(|>),以及客户定制 CSR 与index.json索引。
1.4 关键术语表
| 术语 | 解释 |
|---|---|
| CSR / SR | Component Self-description Record,JSON 格式自描述文件,扩展名 .sr。 |
| ObjectGroup | 某一 Position 上全部对象的发布单元,业务按 Owner 拉取。 |
| Connector | 连接器对象,描述下级板卡身份、在位与总线,路径 /bmc/kepler/Connector/${ID}。 |
| Position / GroupPosition | 对象组位置。由上级 Connector 的 GroupPosition 与本级 Connector Position(两位十六进制)拼接。00 为 platform.sr,01 为 root.sr,02 为 PSR。 |
| IdentifyMode | 下级板卡识别方式,见 2.5。 |
| Owner | 对象归属的业务 App 名,如 hwproxy、hwdiscovery、bmc_soc。 |
| LifeCycleId | 对象组生命周期标识;变化时框架需重新拉取对象。 |
| Anchor | CSR ManagementTopology 中的锚点,声明本部件总线列表。 |
| PSR | 虚拟组件,Position 为 02,用于 UID-Slot 等配置映射。 |
1.5 外部交互边界图
进程日志默认写入 dist/config.cfg 中的 /data/var/log/bmc/hwdiscovery.log。组件自身没有独立监听端口。
2. API 使用说明与示例
对外发布的 API 为资源协作接口,服务名 bmc.kepler.hwdiscovery。方法首参 a{ss} 为框架调用上下文;命令行调试可传空字典 0。均可通过 busctl / mdbctl 调试。
# 查看资源协作接口
busctl --user tree bmc.kepler.hwdiscovery典型树形结构(对象名随机型变化):
/bmc/kepler/Connector/...
/bmc/kepler/ObjectGroup/00
/bmc/kepler/ObjectGroup/01
/bmc/kepler/ObjectGroup/0101
/bmc/kepler/hwdiscovery/MicroComponent业务组件通常不直接解析 CSR,而是通过 mc.mdb.object_manage 订阅对象组上树信号,再调用本节接口。这是 libmc4lua 侧的消费方式,不是 hwdiscovery 导出的 Lua 模块。
2.1 bmc.kepler.ObjectGroup
功能说明
某一 Position 上的对象组。硬件自发现完成某级 SR 解析后创建该对象,供业务按 Owner 拉取对象,供 hwproxy 拉取拓扑。
路径:/bmc/kepler/ObjectGroup/${Id}(Id 即 Position,如 01、0101)
参数说明
| 属性 | 类型 | 读写 | 说明 |
|---|---|---|---|
Position | s | 只读 | 对象组位置。 |
Owners | as | 只读 | 本对象组包含对象的归属 App 名列表。 |
OnlineTimestamp | t | 只读 | 对象组上树时刻。来源为进程内 tick 差,单位毫秒;不发射 emits-change。框架按该时间升序拉取对象组。 |
Slot | y | 只读 | 对象组对应的槽位号,来自上级锚点 Slot。 |
接口定义见 mdb_interface 的 bmc.kepler.ObjectGroup,hwdiscovery 在 src/lualib/module/component/component.lua 的 setup 中赋值。
返回值与异常
属性只读。对象组不存在时路径不在资源树上。
应用场景
确认某 Position 是否已完成自发现、有哪些 Owner、上树先后顺序。
限制条件
Owners 来自解析结果中的 app_name 计数。设备树格式路径会把 devmon 记入 Owners(见 hwcomponent:process)。
调试示例
busctl --user introspect bmc.kepler.hwdiscovery /bmc/kepler/ObjectGroup/01
busctl --user get-property bmc.kepler.hwdiscovery /bmc/kepler/ObjectGroup/01 \
bmc.kepler.ObjectGroup Position2.2 GetObjects
功能说明
按 Owner 返回该 Position 下归属指定 App 的对象列表。属性与扩展属性以 JSON 字符串给出。
| 属性 | 内容 |
|---|---|
| 首发版本 | openUBMC 26.09 |
| 废弃状态 | 正常可用 |
D-Bus 签名:a{ss}s → sa(ssss)u
参数说明
| 参数名 | 方向 | 类型 | 描述 | 取值范围 |
|---|---|---|---|---|
| 上下文 | 输入 | a{ss} | 框架调用上下文。 | 调试可传 0。 |
Owner | 输入 | s | 对象所有者 App 名称。 | 非空;需与 MDS / Owners 中的名称一致,如 hwdiscovery、hwproxy。 |
Position | 输出 | s | 组件 Position。 | 与对象组路径中的 Id 相同;对象组未登记时仍返回路径上的 Position。 |
Objects | 输出 | a(ssss) | 对象数组,每项见下表。 | 无匹配对象时为空数组。 |
LifeCycleId | 输出 | u | 生命周期标识。 | 对象组不存在时实现返回默认值 1。 |
Objects 单项(ObjectInfo):
| 字段 | 类型 | 描述 |
|---|---|---|
ClassName | s | 类名,如 Connector、Chip。 |
ObjectName | s | 重命名后的对象名,通常带 _${Position} 后缀。 |
ObjectProps | s | 对象属性 JSON 字符串。内部先按 serialize 解码再 cjson.encode。 |
ObjectExtends | s | 扩展属性 JSON 字符串。解析阶段写入的字段包括 Path、Bom、BoardId、AuxId、@Parent、@Children、Framework。 |
Framework 为 true 表示该对象被标记为框架依赖对象(本组件对象及其引用闭包)。
返回值与异常
成功返回上述三元组。Position 在组件表中不存在时返回该 Position、空数组和 LifeCycleId=1,不抛 D-Bus 错误。mds/errors.json 仅定义 kepler.hwdiscovery.Unkown(拼写与源码一致),本方法成功路径不使用该错误。
应用场景
业务 App 在对象组上树后拉取本组件对象;hwdiscovery 自身也用 Owner=hwdiscovery 把 Connector 等框架对象交给 object_manage。
限制条件
Owner必须与对象app_name精确匹配。ObjectProps/ObjectExtends若serialize解码失败,对应字符串为空(日志transfer serialize string failed)。- 调用会计入硬件初始化完成等待的
GetObjects静默窗口(见 2.7)。
调试示例
busctl --user call bmc.kepler.hwdiscovery \
/bmc/kepler/ObjectGroup/01 \
bmc.kepler.ObjectGroup GetObjects a{ss}s 0 hwdiscoveryLua 侧(业务进程内,需已声明对 bmc.kepler.ObjectGroup 的依赖):
local mdb = require 'mc.mdb'
local ctx = require('mc.context').get_context_or_default()
local obj_group = mdb.get_object(bus, '/bmc/kepler/ObjectGroup/01', 'bmc.kepler.ObjectGroup')
local position, objects, life_cycle_id = obj_group:GetObjects(ctx, 'hwproxy')2.3 GetBinaryObjects
功能说明
与 GetObjects 相同的过滤逻辑,但 ObjectProps / ObjectExtends 以 serialize 二进制(D-Bus ay)返回,避免 JSON 往返。hwdiscovery 在 setup 时用 Owner=hwdiscovery 调用本方法,再交给 object_manage.add_objects。
| 属性 | 内容 |
|---|---|
| 首发版本 | openUBMC 26.09 |
| 废弃状态 | 正常可用 |
D-Bus 签名:a{ss}s → sa(ssayay)u
参数说明
| 参数名 | 方向 | 类型 | 描述 |
|---|---|---|---|
| 上下文 | 输入 | a{ss} | 框架调用上下文。 |
Owner | 输入 | s | 对象所有者 App 名称。 |
Position | 输出 | s | 组件 Position。 |
Objects | 输出 | a(ssayay) | ClassName、ObjectName、二进制 ObjectProps、二进制 ObjectExtends。 |
LifeCycleId | 输出 | u | 生命周期标识;对象组不存在时为 1。 |
返回值与异常
与 2.2 相同:对象组不存在时返回空数组和 LifeCycleId=1。
应用场景
框架高性能对象分发;需要自行 serialize.decode 的调用方。
限制条件
二进制内容是 Lua serialize 编码,不是 JSON、也不是普通 UTF-8 文本。
调试示例
busctl --user call bmc.kepler.hwdiscovery \
/bmc/kepler/ObjectGroup/01 \
bmc.kepler.ObjectGroup GetBinaryObjects a{ss}s 0 hwdiscovery2.4 GetTopology
功能说明
返回该对象组的管理拓扑字符串,供 hwproxy 建立芯片/总线链路。拓扑在 CSR 流水线 append 阶段由 ManagementTopology 展开生成,并以 serialize 编码后存入组件记录。
| 属性 | 内容 |
|---|---|
| 首发版本 | openUBMC 26.09 |
| 废弃状态 | 正常可用 |
D-Bus 签名:a{ss} → s
参数说明
| 参数名 | 方向 | 类型 | 描述 |
|---|---|---|---|
| 上下文 | 输入 | a{ss} | 框架调用上下文。 |
Topology | 输出 | s | 拓扑数据。传统 CSR 路径为 serialize 编码的层级表;设备树路径见限制条件。 |
返回值与异常
- 传统路径(
FormatVersion小于3.1):返回持久化的拓扑字符串。 - 设备树路径(
FormatVersion在3.1到5.0之间且device_processed=true):实现会调用add_devmon_object,经.parser_service向bmc.kepler.devmon的bmc.dev.AddDevice转发 CSR,本方法返回空字符串。 - Position 不在组件表中:返回空字符串。
应用场景
hwproxy 在对象组上树后获取总线、Chip、Connector 层级关系。
限制条件
不要把返回值当作 JSON 解析。设备树格式不要期望本方法返回可用拓扑文本。
调试示例
busctl --user call bmc.kepler.hwdiscovery \
/bmc/kepler/ObjectGroup/01 \
bmc.kepler.ObjectGroup GetTopology a{ss} 02.5 bmc.kepler.Connector
功能说明
连接器对象,描述下级板卡身份、在位、总线和识别方式。对象由 CSR 中的 Connector_* 上树,路径中的 ID 为重命名后的对象名。
路径:/bmc/kepler/Connector/${ID}
模型中仅出现在接口上的属性如下。Chip、Container、Position、IdChipAddr、CSRVersion 定义在 mds/model.json / schema.json 中,usage 含 CSR,用于自描述解析,不在 bmc.kepler.Connector 接口属性表上。
参数说明
| 属性 | 类型 | 读写 | 默认值 | 说明 |
|---|---|---|---|---|
Bom | s | 只读 | "" | 下级板卡 Bom 标识。 |
Slot | y | 可写 | 0 | 下级板卡槽位号。 |
Presence | y | 可写 | 0 | 在位状态:0 不在位,1 在位,255 初始化(接口描述)。变化会触发下级发现/卸载。 |
Id | s | 可写 | "" | 下级板卡 BoardId / UID。 |
AuxId | s | 可写 | "" | 下级板卡辅助标识。 |
Buses | as | 只读 | [] | 与下级板卡关联的总线名列表。 |
SystemId | y | 只读 | 1 | 系统标识。 |
ManagerId | s | 只读 | "1" | 管理标识。 |
SilkText | s | 只读 | "" | 丝印。 |
IdentifyMode | y | 只读 | 0 | 识别方式,见下表。 |
Type | s | 只读 | "" | 后端设备类型,如 PCIeSlot、ExpandBoard。 |
ChassisId | s | 只读 | "" | 机框标识。 |
HotPluggable | b | 只读 | true | 是否支持热插拔;下级 CSR Anchor.HotPluggable 会回写。上树时实现先置为 true。 |
GroupId | u | 只读 | 0 | 对象组 Id。 |
GroupPosition | s | 只读 | "" | 下级组件 Position,由本级 Position 后缀与 Connector Position 拼接。 |
LoadStatus | y | 只读 | 255 | 下级加载状态,见 5.2。 |
IdentifyMode(src/lualib/common/define.lua 的 component_type):
| 取值 | 符号 | 含义 |
|---|---|---|
0 | COM_ROOT | BMC 芯片所在管理板(root.sr)。 |
1 | COM_ID_READ | BoardId 可读,通常用 Accessor 引用。 |
2 | COM_ID_REPORT | BoardId 不可读,由多样化硬件上报;初始 Presence 须为 0。 |
3 | COM_E2P | 标准组件,CSR 在 EEPROM 中。 |
4 | COM_MCU | 标准组件,CSR 在 MCU 中。 |
5 | COM_FLASH | 非标组件,传统硬件。 |
返回值与异常
读写走 bmc.kepler.Object.Properties。非法类型由框架校验抛错。
应用场景
查询板卡在位与加载结果;IdentifyMode=2 时由外部写 Presence / Id / AuxId 触发发现。
限制条件
- EEPROM 标准组件(
IdentifyMode=3)在读取 Presence 时会先访问关联Chip.Read,Chip 未上树会导致本次读取失败并沿用上次缓存 Presence。 - 同一 SR 内不同 Connector 的
Position不能相同(决定 GroupPosition 唯一性)。 - 上级 Connector.
Buses与下级 Anchor.Buses按顺序配对;当前实现对数量不一致打 WARN(unmatched anchor buses)后仍继续,缺少的项无法建立映射。
调试示例
busctl --user introspect bmc.kepler.hwdiscovery \
/bmc/kepler/Connector/Connector_EXU_1_01
busctl --user get-property bmc.kepler.hwdiscovery \
/bmc/kepler/Connector/Connector_EXU_1_01 \
bmc.kepler.Connector Presence2.6 Reload
功能说明
按给定 Bom / Id / AuxId / IdentifyMode 重新加载该连接器的下级组件:先在 LoadStatus==0 时卸载已加载子树,再按新身份发现。
| 属性 | 内容 |
|---|---|
| 首发版本 | openUBMC 26.09 |
| 废弃状态 | 正常可用 |
D-Bus 签名:a{ss}sssy → 空。权限:BasicSetting(mds/model.json)。
参数说明
| 参数名 | 方向 | 类型 | 描述 |
|---|---|---|---|
| 上下文 | 输入 | a{ss} | 调用上下文;成功/失败写操作日志。 |
Bom | 输入 | s | 连接器 Bom。 |
Id | 输入 | s | 连接器 BoardId。 |
AuxId | 输入 | s | 连接器 AuxId。 |
IdentifyMode | 输入 | y | 写入 Connector 的识别方式。 |
方法无出参。实际加载在 skynet.fork_once 中排队执行(skynet.queue),调用返回不表示发现已完成。
返回值与异常
成功无返回。对象路径无法解析出 ObjectName / Position 时,Lua 侧 mdb.get_object 会失败。加载结果体现在后续 LoadStatus 与操作日志 Reload %s successfully / Reload %s failed。
应用场景
维护场景强制按指定身份重新发现板卡;集成测试中模拟更换 CSR。
限制条件
- 仅当原组件
LoadStatus为成功(0)时先执行卸载。 - 不支持热插拔的连接器,Presence 下降时不会卸载(日志
hotplug NOT supported, skip unload);Reload仍走connector_reload。 - 发现失败最多重试
MAX_RETRY_COUNT(2)次。
调试示例
busctl --user call bmc.kepler.hwdiscovery \
/bmc/kepler/Connector/Connector_EXU_1_01 \
bmc.kepler.Connector Reload a{ss}sssy \
0 12345678 00000001010100000001 0 32.7 MicroComponent 与硬件初始化状态
功能说明
框架在 /bmc/kepler/hwdiscovery/MicroComponent 注册标准微组件接口。hwdiscovery 额外实现:
discovery:start将状态设为硬件初始化(HW_INIT_DES),完成后设为硬件初始化完成(HW_INIT_COMPLETED_DES)。debug.on_dump:一键收集,见第 4 章。debug.dlog_level_change/dlog_type_change:转发到.parser_service。reboot.on_action:返回0。
完成等待由环境变量控制(discovery.lua):
| 环境变量 | 默认 | 含义 |
|---|---|---|
HW_INIT_COMPLETE_QUIET_SECOND | 10 | 无连接器任务/解析活动后的静默秒数。 |
HW_INIT_COMPLETE_GET_OBJECTS_QUIET_SECOND | 0 | 距最近一次 GetObjects/GetBinaryObjects 的静默秒数。 |
HW_INIT_COMPLETE_MAX_WAIT_SECONDS | 120 | 最长等待,超时仍标记完成。 |
参数说明
标准 HealthCheck / Dump / SetDlogLevel 签名由 libmc4lua 框架提供,本组件未再声明自定义方法。
返回值与异常
HealthCheck 返回值约定见 libmc4lua 文档。Dump 目录由调用方传入。
应用场景
判断自发现是否已走出硬件初始化;收集 connectors 与 CSR 快照。
限制条件
超时完成只表示等待结束,不保证所有 Position 的 LoadStatus 为 0。
调试示例
busctl --user introspect bmc.kepler.hwdiscovery \
/bmc/kepler/hwdiscovery/MicroComponent2.8 无 IPMI 命令、无独立 Lua 公开模块
功能说明
仓库没有 mds/ipmi.json。解析、发现、插件均为进程内 Lua 实现,不通过 require('hwdiscovery') 向其他 App 导出稳定 Lua API。其他组件应使用本节 D-Bus 接口及 mc.mdb.object_manage。
参数说明
不适用。
返回值与异常
不适用。
应用场景
避免把内部模块(discovery、parser_work、module.sdr.*)当作跨组件 API。
限制条件
.parser_service 的 parser_msg 仅供本进程使用。
调试示例
无。
3. 组件扩展案例
3.1 扩展能力概述
hwdiscovery 的主要扩展面是机型 CSR 与客户定制,而不是新增 D-Bus 方法。运行时插件目前核实到 PSR 路径上的 unit_configuration(UID → Slot)。热修复通过 plugins.fix.load_all_patches('hwdiscovery') 加载。不要手工修改带生成标记的 gen/ 文件。
3.2 扩展点说明
| 扩展点 | 位置 | 触发时机 |
|---|---|---|
| 机型 CSR | PROG_CSR_PATH(默认 /opt/bmc/sr)的 root.sr / platform.sr / {Bom}_{Id}_{AuxId}.sr | 上电自发现 |
| 客户定制 CSR | /opt/bmc/extend/{customer}/sr/{name}_cust.sr | 与基础 CSR 的 Objects 合并 |
| 定制索引 | 同目录 index.json 的 Rules | 仅客户定制层;机型定制目录不读索引 |
| 机型定制目录 | CUSTOMER_CSR_PATH 下 {platform_id}_{board_id}/sr/ | 产品级覆盖 |
| IdentifyMode / Connector | CSR Objects 中的 Connector_* | 下级发现 |
| PSR 插件 | src/lualib/module/plugin/unit_configuration.lua | PSR 对象上树后更新 Connector.Slot |
| 对象组/连接器接口 | mds/model.json + mdb_interface 后 bingo gen | 新增 D-Bus 方法时 |
| Dump | src/lualib/common/dump.lua | MicroComponent.Debug.Dump |
CSR 变量(define.csr_variable):${Slot}、${SystemId}、${ManagerId}、${Container}、${GroupId}、${ChassisId}、${GroupPosition}、${SilkText}、${Bom}。
3.3 二次开发指导
3.3.1 机型增加一块可发现板卡
- 在上级 SR 增加
Connector_*,配置Bom、Position、Buses、IdentifyMode、Presence(及 Mode=1 时的Id引用,Mode=3 时的Chip引用)。 - 在下级 SR 的
ManagementTopology.Anchor.Buses中按顺序对应上级Buses。 - 将下级 SR 放到程序区或由 EEPROM 承载,文件名与
{Bom}_{Id}_{AuxId}规则一致。 - 重启 hwdiscovery 或对连接器
Reload。
验证方法:busctl --user tree bmc.kepler.hwdiscovery 出现新的 ObjectGroup;LoadStatus 为 0;业务服务树上出现带 Position 后缀的对象。
注意事项:Mode=2 时 Presence 初始必须为 0,否则无法正确触发上报式发现。
3.3.2 客户定制 CSR
将 {name}_cust.sr 放到 /opt/bmc/extend/{customer}/sr/。同名对象合并属性,新对象加入。删除软件对象时使用顶层 Customization.DeletedObjects。不要删除 I2c_*、Eeprom_*、Connector_*、Scanner_* 等硬件/拓扑对象。
一批部件共用同一份定制时,使用 index.json(Prefix / Suffix,MatchedFile 不含路径分隔符或 ..)。规则优先级:Prefix 优于 Suffix;同类中 Pattern 更长者胜。
3.3.3 新增资源协作方法
- 在
mdb_interface与本仓mds/model.json声明方法。 bingo gen生成Impl*。- 在
hwdiscovery_app:register_callback中绑定实现。 - 同步更新本文第 2、4、5、6 章。
示例:现有 Reload 绑定:
self:ImplConnectorConnectorReload(function(obj, ctx, ...)
self.discovery:reload(obj, ctx, ...)
end)4. 日志说明
组件使用 mc.logging。dist/config.cfg 设置 logger = "/data/var/log/bmc/hwdiscovery.log"。另有 log:hw_stream_* 与 log:operation。
4.1 一键日志收集
HwdiscoveryApp 注册 mc.mdb.micro_component.debug.on_dump,回调 discovery:dump。收集目录(相对 Dump 传入路径)主要包括:
| 文件 | 内容 |
|---|---|
connectors.txt | 连接器树与属性快照 |
root.sr / platform.sr | 实际加载的根 / 平台 CSR 副本 |
{connector}.sr 或 .bin | 各连接器 CSR;可能另有 {connector}_soft.sr |
| 额外 EEPROM 二进制 | 必要文件复制后再读,最多 65 份(MAX_EEPROM_DUMP_NUM) |
写文件失败时打 dump hwdiscovery information failed。
4.2 关键日志信息
| 日志片段 | 日志级别 | 含义解读 | 建议处理动作 |
|---|---|---|---|
app start to hardware self-discovery | NOTICE | 开始自发现 | 无 |
position: 01, get root sr failed | ERROR | 读不到 root.sr | 检查 PROG_CSR_PATH 与机型文件 |
position: 00, get platform sr failed | WARN | 读不到 platform.sr | 确认是否需要软件对象 |
start to process sr data | NOTICE | 开始解析某 Position | 记录 source / FormatVersion / DataVersion |
process sr data failed | ERROR | 解析流水线失败 | 结合紧随的 err 与 5.1 |
process sr data successfully / setup resource tree successfully | NOTICE | 解析并上树完成 | 无 |
analyse sr data failed | ERROR | 解析服务失败 | 查 .parser_service 与 CSR JSON |
unmatched anchor buses | WARN | 上下级 Buses 数量不一致 | 核对 Connector 与 Anchor |
get current anchor buses failed | ERROR | 缺少 ManagementTopology.Anchor.Buses | 补齐 CSR |
expression level exceeds limit | ERROR | 表达式超过 10 级 | 简化 ` |
circular references of object definition in sr are forbidden | ERROR | 对象定义成环 | 检查 @Parent / 引用 |
no valid CSR source | ERROR | 各数据源都未读到合法 CSR | 对照 5.1 数据源 |
Reload %s successfully / failed | operation | Reload 结果 | 查 LoadStatus |
HW init completion wait finished, status: ready/timeout | NOTICE | 硬件初始化等待结束 | timeout 时逐 Position 查 LoadStatus |
Connector task failed | ERROR | 连接器发现协程异常 | 保存 err 与 connector 名 |
5. 问题定界指南
5.1 典型问题定界
| 问题描述 | 是否为本组件问题 | 判断依据 | 关键证据收集方法 |
|---|---|---|---|
| 业务树上没有预期对象 | 可能是 | ObjectGroup 未上树或 Owner 不匹配 | busctl tree;GetObjects 指定 Owner;日志 setup resource tree |
GetObjects 返回空但 Owners 含该 App | 可能是 | 生命周期未更新或对象 app_name 不一致 | 对比 MDS 应用名与 Owners |
LoadStatus 非 0 | 是或硬件/CSR | 加载阶段失败码见 5.2 | Dump connectors.txt、Chip/EEPROM、CSR 版本 |
| Presence 已 1 但未发现 | 可能是 | Mode=3 时 Chip 未上线;Mode=2 初始 Presence 非 0 | introspect Connector 与关联 Chip |
GetTopology 为空 | 可能是预期行为 | 设备树格式会转发 devmon 并返回空串 | 查 FormatVersion 与 devmon |
| IPMI 命令失败 | 否 | 本组件无 IPMI 接口 | 转向业务组件 / ipmi_core |
require 找不到 hwdiscovery Lua API | 否 | 无跨进程 Lua 模块 | 改用 D-Bus 与 object_manage |
5.2 错误码速查表
Connector.LoadStatus(include/hwproxy/plugins/eeprom/status.lua):
| 值 | 符号 | 含义 |
|---|---|---|
0 | SUCCESS | 加载成功 |
1 | DEVICE_ACCESS_ERROR | 器件访问失败 |
2 | SIGN_VERIFY_ERROR | 签名校验失败 |
3 | DATA_FORMAT_ERROR | 数据格式非法 |
4 | LOCAL_FILES_ERROR | 本地文件未找到 |
5 | OBJECT_PARSING_ERROR | 对象解析失败 |
6 | INTEGRITY_VERIFY_ERROR | 完整性校验失败 |
7 | FORMAT_VERSION_ERROR | 格式版本检查失败 |
255 | INITIAL_STATUS | 初始化 / 已卸载重置 |
资源协作错误(mds/errors.json):
| 名称 | HTTP | IPMI | 含义 |
|---|---|---|---|
kepler.hwdiscovery.Unkown | 400 | 0xFF | 源码消息为 Unkown error.(拼写与仓内一致) |
ObjectGroup 三个 Get 方法在实现中不以该错误名返回失败,缺对象组时返回空数据。
5.3 最小化复现与证据收集
- 记录 Position、Connector 对象名、IdentifyMode、Presence、LoadStatus、Owner。
busctl --user tree bmc.kepler.hwdiscovery,确认 ObjectGroup 与 Connector。- 对目标 ObjectGroup 调用
GetObjects/GetTopology。 - 检索 hwdiscovery 日志中的 Position 关键字与 4.2 节片段。
- 执行一键收集,保存
connectors.txt与复制出的.sr。
5.4 调试方法
busctl --user tree bmc.kepler.hwdiscovery
busctl --user introspect bmc.kepler.hwdiscovery /bmc/kepler/ObjectGroup/01
busctl --user call bmc.kepler.hwdiscovery /bmc/kepler/ObjectGroup/01 \
bmc.kepler.ObjectGroup GetObjects a{ss}s 0 hwproxy- 单元测试:
test/unit/(如test_discovery.lua、test_sdr/、test_hwcomponent_hotplug.lua)。 - 集成测试:
test/integration/test_hwdiscovery.lua。 - 不要在生产环境改
Presence/Reload做破坏性试验。
CSR 数据源(dist/config.cfg / manage.csr_paths):
| 路径 | 环境变量 | 用途 |
|---|---|---|
/opt/bmc/sr | PROG_CSR_PATH | 程序区内置 CSR |
/data/opt/bmc/sr | DATA_CSR_PATH | 数据区 |
/data/opt/bmc/sr/gold | FLASH_GOLD_CSR_PATH | Flash 金区 |
/data/opt/bmc/sr/temp | FLASH_TEMP_CSR_PATH | Flash 临时区 |
/opt/bmc/extend | CUSTOMER_CSR_PATH | 客户/机型扩展 |
/dev/shm/import | IMPORT_CSR_PATH | 导入 CSR |
6. 常见问题解答
框架侧排障步骤(对象未分发、CSR 版本比较、Connector 配置样例等)见 FAQ 文档 zh/development/faq/framework/hwdiscovery.md,本节只覆盖资源协作接口使用问题。
Q1:如何确认某 App 是否已从对象组拿到对象?
- 问题描述:业务服务树缺少带 Position 后缀的对象。
- 一句话答案:先看 ObjectGroup 是否上树、
Owners是否包含该 App,再用GetObjects按 Owner 拉取。 - 根因说明:对象只在解析后的
app_name与 Owner 一致时返回;未上树或 Owner 拼写不同都会表现为“没对象”。 - 解决方案:
busctl tree找到/bmc/kepler/ObjectGroup/<position>,读取Owners,调用GetObjects。 - 规避方案:业务
service.json声明对bmc.kepler.ObjectGroup的依赖,并用object_manage.on_add_object消费,而不是轮询猜测路径。 - 适用版本:1.130.20。
Q2:GetObjects 与 GetBinaryObjects 应如何选择?
- 问题描述:调试时二进制结果不可读。
- 一句话答案:人工调试用
GetObjects(JSON 字符串);框架分发用GetBinaryObjects(serialize字节)。 - 根因说明:二者过滤逻辑相同,编码不同。
- 解决方案:
busctl调试使用 2.2;不要对ay做 JSON 解析。 - 规避方案:Lua 业务优先走
object_manage,避免手写解码。 - 适用版本:1.130.20。
Q3:Reload 调用立刻返回,板卡却未换上新 CSR?
- 问题描述:方法无出参,调用成功但 LoadStatus 仍旧。
- 一句话答案:Reload 只把任务投入队列,完成与否看后续
LoadStatus和操作日志。 - 根因说明:
discovery:reload使用skynet.fork_once+queue,D-Bus 返回早于发现结束。 - 解决方案:等待
LoadStatus从255变为0或其他失败码;检索Start to reload/Reload %s successfully。 - 规避方案:自动化里轮询 LoadStatus,不要把 D-Bus 返回当作发现完成。
- 适用版本:1.130.20。
Q4:IdentifyMode=2 的板卡为什么一直不发现?
- 问题描述:上报型连接器下级 ObjectGroup 不出现。
- 一句话答案:该模式依赖外部把
Presence从 0 写成在位,并填写Id/AuxId。 - 根因说明:实现把 Mode=2 的初始 Presence 约定为 0;非 0 会跳过上报触发。身份也不是从 EEPROM 读取。
- 解决方案:由多样化硬件或调试写入 Presence=1 及 BoardId;必要时再
Reload。 - 规避方案:CSR 中 Mode=2 的 Presence 固定写
0。 - 适用版本:1.130.20。
Q5:GetTopology 返回空,hwproxy 拓扑是否失败?
- 问题描述:传统机型能拿到拓扑,新格式返回空字符串。
- 一句话答案:
FormatVersion落在 3.1~5.0 时走设备树路径,拓扑改为devmon.AddDevice,本方法返回空。 - 根因说明:
device_processed为真时get_topology调用add_devmon_object后返回''。 - 解决方案:查 CSR
FormatVersion与 devmon 是否收到 AddDevice;传统 CSR 再查process sr data failed。 - 规避方案:不要用
GetTopology非空作为设备树机型的成功判据。 - 适用版本:1.130.20。