devmon

版本信息

项目内容
组件版本1.2.109
首发版本openUBMC 26.09
文档作者openUBMC 社区
最后更新2026-09-15
许可证Mulan PSL v2

1. 组件概述

1.1 组件简介

devmon(Device Monitor)是 openUBMC 的设备监控与南向设备管理组件。它解析 CSR(.sr 自描述文件),按 driver_abi.hdlopen 加载 component_drivers 产出的设备驱动 .so,并按 Position 管理对象组、拓扑与热插拔生命周期。

组件类型为 applicationmds/service.json)。Linux 产物安装到 /opt/bmc/apps/devmon,可执行文件为 /opt/bmc/apps/devmon/devmon。systemd 单元 devmon.serviceframework.service 之后启动,依赖 dbus.serviceframework.serviceMemoryMax=150M

默认构建选项 unidev=false 时,进程只注册 D-Bus 服务名 bmc.kepler.devmonunidev=true 时,同一进程内再注册 bmc.kepler.hwproxybmc.kepler.hwdiscovery

仓库中没有 mds/ipmi.json,组件不提供 IPMI 命令。业务侧也没有可 require 的公开 Lua 模块;应用层 Lua 插件由 hwproxy 加载,业务通过 Chip 的 PluginRequest 点名调用。根目录 mds/model.json 当前为空对象;Scanner / Accessor / Chip / Bus 定义在 mds/hwproxy/model.json,Connector / ObjectGroup 定义在 mds/hwdiscovery/model.json

1.2 解决什么问题

BMC 需要把机型与部件的硬件自描述变成可协作的对象树,并在热插拔时完成驱动加载、对象上树和下树。devmon 把这些公共能力收敛到统一服务:

  • 解析 CSR,实例化总线、芯片、Scanner、Accessor 以及业务设备对象。
  • 按 Position 维护对象组,供其他组件查询本位置上的对象与拓扑。
  • 通过 bmc.dev 提供 AddDevice / RemoveDevice 热插拔入口。
  • 对硬件访问做域调度(AccessScheduler),避免总线过载。
  • 通过驱动 ABI 加载厂商 .so,使具体网卡 / GPU 等实现不进入本仓。

1.3 核心功能

  • 核心功能一:CSR 解析与对象实例化

    解析 .sr 中的 ObjectsManagementTopology$ref|> 表达式和定制合并,生成引擎对象树。

  • 核心功能二:热插拔与对象组

    对外暴露 bmc.devAddDevice / AddDeviceWithData / RemoveDevice;按 Position 创建 bmc.dev.ObjectGroup

  • 核心功能三:驱动 ABI 动态加载

    register_device_driver 函数表 dlopen component_drivers 产出的 lib<Name>.so(CSR1 另试 libCsr1<Name>.so)。运行时按 gold → temp → image 选库:生产默认 image 目录为配置项 driver_path/opt/bmc/drivers/),升级副本默认在 /data/opt/bmc/drivers/gold/data/opt/bmc/drivers/temp

  • 核心功能四:可选三层架构(unidev)

    同一进程拆成 devmon_servicehwproxy_servicediscovery_serviceFormatVersion < 5.00 走 CSR1 / abi_v1 并转发到 hwdiscovery;>= 5.00(缺省)走 CSR2 / abi_v2

1.4 关键术语表

术语解释
CSR / .srComponent Self-Description Record,硬件自描述文件。
Position / GroupPosition对象组位置。热插拔与对象组都以它为键。
FormatVersionCSR 格式版本。阈值 5.00:小于阈值走 CSR1 / abi_v1,否则走 CSR2 / abi_v2
unidev构建选项。为 true 时本进程同时注册 hwproxy 与 hwdiscovery。
driver ABIinclude/devmon/driver_abi.h 中的 C 函数表,设备 .so 必须导出 register_device_driver
ObjectGroup某一 Position 上已上树对象的集合,供其他组件拉取类名、对象名和属性。
Connector连接器对象,描述下级板卡的 Bom / Id / AuxId / Presence / 总线等。
Scanner / Accessor周期性扫描对象与按需读写对象,通常挂在 hwproxy。
PluginRequestChip.BlockIO 上的应用层 Lua 插件调用入口。
AccessScheduler硬件访问域调度器,限制并发硬件事务与等待队列。

1.5 外部交互边界图

构建依赖见 mds/service.jsoncomponent_drivers/[>1.1.0]@openubmc/stable。运行时还依赖 libmcpp、会话总线和 systemd。组件自身没有独立监听端口。


2. API 使用说明与示例

对外发布的主服务名为 bmc.kepler.devmon。热插拔入口路径为 /bmc/dev,接口名为 bmc.dev。均可通过 busctl 调试。

方法不使用 libmc4lua 风格的首参 a{ss} 上下文;AddDevice 的 connector 为 a{sv} 字典。

bash
# 查看资源协作接口
busctl --user tree bmc.kepler.devmon

默认单层模式下,Scanner / Chip / Connector 不由本进程创建,而是订阅外部 bmc.kepler.hwdiscovery。以下 2.4~2.6 节接口的 MDS 在本仓,运行时仅在 unidev=true 或由独立 hwproxy / hwdiscovery 进程提供时可用。

2.1 bmc.dev(Devmon 根对象)

功能说明

热插拔入口:按 CSR 文件或 CSR 数据加载设备,或按 connector 卸载设备。

路径/bmc/dev

对象名Devmon

服务名bmc.kepler.devmon

属性内容
首发版本openUBMC 26.09
废弃状态正常可用

参数说明

方法D-Bus 签名入参出参说明
AddDevicesa{sv}csr_file(CSR 文件路径)、connector读取文件后转调 AddDeviceWithData
AddDeviceWithData变体 + a{sv}csr_data(JSON 字符串或 dict)、connector解析 CSR 并创建对象组。
RemoveDevicea{sv}connector按 Position 卸载设备及对象组。

connector 常用键:

类型说明
Positioninteger / string槽位或位置。源码用它生成 GroupPosition;为空则抛 Connector Position is not initialized
SystemIdinteger系统标识,缺省为 1
Slotinteger槽位号。
GroupPositionstring对象组位置。未提供时由 Position 推导并写回 connector。
ManagerId / ChassisIdstring管理标识 / 机框标识,缺省均为 "1"

返回值与异常

成功无返回值(mc::resolve())。失败抛 libmcpp 异常,不能当作整数完成码解读。

异常 / 行为含义触发条件处理建议
invalid_arg_exceptionFailed to read csr file读文件失败AddDevice 的路径不存在或不可读核对 CSR 路径与权限。
invalid_arg_exceptioninvalid csr_data typeCSR 数据类型非法csr_data 既不是 string 也不是 dict传入 JSON 文本或字典。
parse_error_exceptionConnector Position is not initialized无法得到 Positionconnector 缺少可推导的位置PositionGroupPosition
system_exceptionno valid service for AddDeviceWithData服务指针为空unidev 转发路径上服务未就绪确认进程已完成 on_start
日志 device already exists, skip add device幂等跳过该 Position 已有 unit 信息视为成功;需要重建时先 RemoveDevice

unidev 且 FormatVersion < 5.00 时,本方法把请求转发到 bmc.kepler.hwdiscovery 的同名 bmc.dev 接口(转发签名为 sa{sv})。

应用场景

开发调试时手动加载一块网卡 CSR;自动化测试模拟热插拔;Connector 驱动 Reload 时内部调用 RemoveDevice 再重新发现。

限制条件

  • Position 重复时直接跳过,不会覆盖已有设备。
  • 单层模式强制 abi_v2。CSR1 转发只在 unidev=true 时发生。
  • RemoveDevice 在 Position 为空时直接成功返回,不卸载任何对象。
  • 卸载由 device_manager 统一处理共享总线 / 芯片引用,调用方不要自行按路径递归删对象。

调试示例

bash
busctl --user call bmc.kepler.devmon /bmc/dev bmc.dev AddDevice sa{sv} \
  "../tests/tests_data/csr/14140130_19e50222_19e500a1.sr" \
  3 Position i 2 SystemId i 1 Slot i 2

busctl --user call bmc.kepler.devmon /bmc/dev bmc.dev RemoveDevice a{sv} \
  3 Position i 2 SystemId i 1 Slot i 2

2.2 bmc.dev.ObjectGroup

功能说明

查询某一 Position 上已上树对象的类名、对象名、属性 JSON 和拓扑。

路径

  • 根:/bmc/dev/ObjectGroup
  • 实例:/bmc/dev/ObjectGroup/${Position}
属性内容
首发版本openUBMC 26.09
废弃状态正常可用

unidev 下 hwdiscovery 另有 bmc.kepler.ObjectGroup,路径为 /bmc/kepler/ObjectGroup/${Position},方法名与字段含义相同(MDS:mds/hwdiscovery/model.json)。

参数说明

属性类型读写说明
Positions只读对象组位置。
Ownersas只读对象组所有者 App 名称列表。
OnlineTimestampt只读上树时刻,单位 ms(tick)。
Sloty只读槽位号。
方法入参出参说明
GetObjectssOwner,App 名称)(s a(ssss) u):Position、对象元组数组、LifeCycleId每项元组为 (ClassName, ObjectName, ObjectProps, ObjectExtends)
GetTopologys该 Position 的拓扑 JSON 字符串。

返回值与异常

GetObjects 始终返回元组;无对象时数组为空,LifeCycleId 来自对象组数据(CSR 解析默认 1)。调用成功会打 notice 日志 get objects count

应用场景

业务组件在硬件对象上树后,按 Owner 拉取本位置的设备对象并完成自身注册。

限制条件

对象组在 AddDevice 成功创建之后才存在。RemoveDevice 会注销 /bmc/dev/ObjectGroup/${Position}

调试示例

bash
busctl --user introspect bmc.kepler.devmon /bmc/dev/ObjectGroup/02
busctl --user call bmc.kepler.devmon /bmc/dev/ObjectGroup/02 \
    bmc.dev.ObjectGroup GetObjects s general_hardware
busctl --user call bmc.kepler.devmon /bmc/dev/ObjectGroup/02 \
    bmc.dev.ObjectGroup GetTopology

2.3 bmc.dev.Devmon.AccessScheduler

功能说明

查询硬件访问域调度器快照,用于诊断并发硬件事务、拒绝和超时。接口挂在 Devmon 根对象上,与 bmc.dev 同路径。

路径/bmc/dev

属性内容
首发版本openUBMC 26.09
废弃状态正常可用

参数说明

方法入参出参说明
GetSummarya{sv}全局摘要。调度器不可用时 Available=falseError=scheduler_unavailable
GetDomainsaa{sv}全部域快照;调度器不可用时返回空数组。
GetDomains(域 ID)a{sv}单个域。未找到时 Found=falseErrorscheduler_unavailabledomain_unresolved

GetSummary 已核实字段包括:Version1)、SnapshotIdTimestampUsAvailableAcceptingWorkThreadsMaxActiveHardwareActiveHardwareReadyDomainsDomainCountPermitWaitP50Us / P95Us / P99Us / MaxUsRawP50Us / P95Us / P99Us / MaxUs,以及累计 Submitted / Completed / Failed / Rejected / TimedOut / Cancelled / Coalesced / SourceLimited / ResourceLimited / PhysicalLimited / LogicalDispatches / HardwareDispatches

访问来源名(域快照使用):interactivecontrolplugin_highplugin_secondaryaccessorscannerbackgroundunknown。优先级名:highsecondarynormallow

配置项见 config.single.json.inmax_active_hardware 默认 2max_domain_waiters 默认 512hardware_request_timeout_ms 默认 120000

返回值与异常

方法本身不抛业务完成码。调度器未绑定到根对象时返回带 Error 的字典或空数组。

应用场景

硬件访问超时、请求被拒绝、总线排队过长时抓调度快照。一键收集也会把同样的摘要写入 access_scheduler.json

限制条件

诊断接口,不改变调度策略。生产环境不要高频轮询全部域。

调试示例

bash
busctl --user call bmc.kepler.devmon /bmc/dev \
    bmc.dev.Devmon.AccessScheduler GetSummary
busctl --user call bmc.kepler.devmon /bmc/dev \
    bmc.dev.Devmon.AccessScheduler GetDomains

2.4 bmc.kepler.Connector(MDS:mds/hwdiscovery/model.json

功能说明

连接器对象:描述下级板卡身份、在位和加载状态,并提供 Reload 重新加载。

路径/bmc/kepler/Connector/:ID

服务名:unidev 下为 bmc.kepler.hwdiscovery;独立 hwdiscovery 进程同名。实现位于 component_drivers 的 Connector 驱动,Reload 在加载成功时会向名为 Devmon 的对象调用 RemoveDevice

参数说明

属性类型读写说明
Boms只读下级板卡 Bom。
Sloty可读写槽位号。
Presencey可读写0 不在位,1 在位,255 初始化。
Id / AuxIds可读写唯一标识 / 辅助标识。
Busesas只读下级板卡连接的总线名。
SystemIdy只读缺省 1
ManagerId / ChassisIds只读管理标识 / 机框标识。
Types只读PCIeSlotPCIeRiser
GroupPositions只读对象组位置。
LoadStatusy只读0 加载成功,非 0 失败,255 初始化。
方法入参出参权限说明
ReloadBomIdAuxId(string)、IdentifyModeyBasicSetting按新身份重新加载连接器。

CSR 额外字段(不上 D-Bus 接口,仅模型):ChiprefInterfacebmc.kepler.Chip.BlockIO)、ContainerPositionIdChipAddrCSRVersion

返回值与异常

属性按模型读写。Reload 失败时 Connector 驱动打 Reload attempt ... failed 日志;成功打 Reload successfully

应用场景

热插拔后强制按新 Bom/Id 重新发现;装备或维护时手动改身份再加载。

限制条件

需要 Connector 驱动 .so 已加载。不要用客户定制 CSR 的 DeletedObjects 删除 Connector_*I2c_* 等硬件 / 拓扑对象。

调试示例

bash
busctl --user introspect bmc.kepler.hwdiscovery /bmc/kepler/Connector/1

2.5 bmc.kepler.Scanner / bmc.kepler.Accessor

功能说明

Scanner 按周期从 Chip 读值;Accessor 提供可写的按需访问,并给出可打印 ASCII 值。

路径/bmc/kepler/Scanner/:Id/bmc/kepler/Accessor/:Id

服务名:unidev 下为 bmc.kepler.hwproxy

参数说明

Scanner / Accessor 公共状态枚举(Status):

取值含义
0正常获取值
1获取值失败
2预失败,正在防抖
3无效状态
4初始状态(默认)
接口属性类型读写说明
bmc.kepler.ScannerValuet只读Scanner 当前值。
bmc.kepler.ScannerStatusy只读见上表。
bmc.kepler.Scanner.AggregateAggregateOffsetu只读汇聚数据相对偏移。
bmc.kepler.Scanner.AggregateAggregateStatusb只读是否从汇聚数据读到。
bmc.kepler.AccessorValuet可读写Accessor 值。
bmc.kepler.AccessorStatusy只读含义同 Scanner。
bmc.kepler.AccessorPrintableValues只读可打印 ASCII;含不可见字符时不更新。不能用该属性触发写硬件。
方法接口入参权限说明
TraceDebouncebmc.kepler.Release.ScannerActionstart / stopDiagnoseMgmt跟踪该 Scanner 的防抖输入、表达式和结果。CLI 名 tracedebounce

CSR 字段(不上接口,仅配置):ChipSizeOffsetMaskPeriodType0 位读 / 1 块读)、DebounceScanEnabledNominalValueFailureDebounceCount / SuccessDebounceCount(默认 10)。

返回值与异常

属性只读失败表现为 Status 非 0,而不是 D-Bus 完成码。TraceDebounceAction 必须为 startstop

应用场景

温度 / 在位等周期采样;维护时跟踪防抖是否把瞬时毛刺滤掉。

限制条件

ScanEnabled 可通过表达式同步其他 Scanner,但不能依赖成环。块读时 Mask 无效。Accessor 仅块读场景更新 PrintableValue

调试示例

bash
busctl --user get-property bmc.kepler.hwproxy /bmc/kepler/Scanner/1 \
    bmc.kepler.Scanner Value
busctl --user call bmc.kepler.hwproxy /bmc/kepler/Scanner/1 \
    bmc.kepler.Release.Scanner TraceDebounce s start

2.6 bmc.kepler.Chip.*(MDS:mds/hwproxy/model.json

功能说明

芯片访问接口。本仓以 Chip 类(路径 /bmc/kepler/Chip/Complex/:Id)为完整模板;Eeprom 等其它器件类复用同一套 BlockIO / BitIO / TraceChip 方法,仅路径与 CSR 字段不同。方法由 component_drivers 的 Chip 驱动实现,unidev 时对象挂在 bmc.kepler.hwproxy

参数说明

bmc.kepler.Chip
属性类型读写说明
HealthStatusy可读写0 访问正常,1 访问失败。
PowerStatusy只读上电状态,默认 1
SelfTestResulty只读自检结果,默认 1
ChipTypes只读器件类型名。
HealthStatusValidityb只读HealthStatus 是否有效。
LockStatusy只读0 未锁定,1 锁定。
方法入参出参说明
SetAccessibilityStatusb)、DisableDurationq,秒,11800禁止访问后到期自动恢复。MDS 英文描述写 “status is true 时 DisableDuration 生效”,中文描述写禁止时长;以实现与现场验证为准。
SetLockStatusOpTypey0 解锁 / 1 加锁)、LockTimeu,秒,加锁时 <= 30minResultCode见下表。

SetLockStatusResultCode

含义
0OK成功。
1InvalidParameterLockTime 非法。
2UnlockedError通道未锁定(解锁时)。
3RequestorMismatchedError请求者与锁定者不一致。
4ChipMismatchedError同通道其它器件已锁总线。
5ChannelMismatchedError同总线其它通道已锁总线。
bmc.kepler.Chip.BlockIO
方法入参出参说明
ReadOffsetu)、LengthuOutDataay按字节读取。
WriteOffsetu)、InDataay按字节写入。
WriteReadInDataay)、ReadLengthuOutData先写再从固定 offset 读。
ComboWriteReadWriteOffsetInDataReadOffsetReadLengthOutData指定写/读偏移的组合事务。
BatchWriteWriteData 数组,每项 {Offset, InData}一次写入多个偏移。
PluginRequestPluginNameCmdParamsayOutData加载 hwproxy 插件并执行命令;占用总线通道。
PluginRequestEx同上,外加 ControlParamsa{ss}OutData拓展插件请求。MDS 声明 Priority 可为 High / Secondary
WriteReadByProtocolInDataReadLengthProtocolyOutData当前仅支持 0x02 SMBus/I2C。
bmc.kepler.Chip.BitIO
方法入参出参说明
ReadOffsetu)、Lengthy)、MaskuOutData读值与 Mask 按位与。
WriteOffsetLengthMaskInData先读后按 Mask 改写。
bmc.kepler.Release.TraceChip
方法入参权限说明
TraceChipActionstart / stopDiagnoseMgmt跟踪该 Chip 读写数据。CLI 名 tracechip
bmc.kepler.Release.Chip

维护 CLI read:按 Offset/Length 读原始字节,权限 DiagnoseMgmt

bmc.kepler.Bus / bmc.kepler.Bus.BlockIO

总线类(I2c 路径 /bmc/kepler/Bus/I2c/:Id 等)提供 AccessEnabledTimeoutSetAccessibilityDisableDuration 范围 11800 秒)。I2C 另有 Read / Write / WriteRead(按从地址)。

返回值与异常

硬件访问失败通常反映为 Chip HealthStatus=1 或 D-Bus 调用异常,而不是 IPMI 完成码。PluginRequest 查不到插件命令时由宿主报错,不会落到其它函数。

应用场景

业务组件通过 Chip 代理读写 EEPROM / 温度传感器;mctpd / storage / power_mgmt 通过 PluginRequest 调用 smbus / sml / power_mgmt 等插件。

限制条件

  • 调用方须在自身 mds/service.json 声明对相应 Chip 接口的依赖。
  • PluginRequest 执行期间占据总线,长事务应按插件文档使用可调度模式,避免独占。
  • 本仓文档只列出 MDS 已核实的方法名与字段;各厂商 Chip 的超时、重试和页切换行为以 component_drivers 实现为准。

调试示例

bash
busctl --user introspect bmc.kepler.hwproxy /bmc/kepler/Chip/Complex/1
busctl --user call bmc.kepler.hwproxy /bmc/kepler/Chip/Complex/1 \
    bmc.kepler.Chip.BlockIO Read uu 0 2
busctl --user call bmc.kepler.hwproxy /bmc/kepler/Chip/Complex/1 \
    bmc.kepler.Release.TraceChip TraceChip s start

2.7 驱动 ABI(C 接口,include/devmon/driver_abi.h

功能说明

设备 .so 必须导出 register_device_driver,向 devmon 登记一张或多张 device_driver 函数表。这是进程内 C ABI,不能通过 busctl 调用。

参数说明

符号说明
register_device_driver(device_driver_t** device_driver, uint8_t* count)输出驱动表指针与条数。
device_name驱动名,与 CSR 类名对应。
ctor(service, object_name)创建 driver_handle_t
init(handle, csr_object, connector)用 CSR 与 connector 初始化。
start / stop启动 / 停止。
dump返回诊断文本;指针由驱动持有,调用方不得 free,跨下一次 dump 前应自行拷贝。
status_t(返回值)register_device_driverinitstartstop 的返回类型,取值见下表。

status_t

含义
0STATUS_OK成功
1STATUS_ERROR一般错误
2STATUS_NOT_FOUND未找到
3STATUS_INVALID_ARG参数非法
4STATUS_NOT_IMPLEMENTED未实现
5STATUS_TIMEOUT超时
6STATUS_BUSY
7STATUS_NO_MEMORY内存不足

返回值与异常

register_device_driverinit / start / stop 返回 status_t。C 接口不抛异常。

应用场景

component_drivers 仓实现新器件 / 新总线驱动,而不是在 devmon 仓新增 plugins/

限制条件

不要在设备 so 里重写应用层 has_cmd / run_cmd。应用层 Lua 插件见仓内 docs/2.2.应用层插件.md。Zephyr 形态无 dlopen,驱动在 SYS_INIT 期静态注册。

调试示例

c
#include "devmon/driver_abi.h"

status_t register_device_driver(device_driver_t** device_driver, uint8_t* count)
{
    static device_driver_t table[] = {
        {"MyChip", my_ctor, my_init, my_start, my_stop, my_dump},
    };
    *device_driver = table;
    *count = 1;
    return STATUS_OK;
}

3. 组件扩展案例

3.1 扩展能力概述

devmon 不在本仓扩展具体网卡 / GPU 逻辑。支持的扩展方式:

  • component_drivers 实现 driver_abi.h,由 bingo/Conan 把 .so 装到驱动目录。
  • 机型 CSR 增加 Connector / Endpoint / Chip / Scanner 对象。
  • 客户定制 CSR:/opt/bmc/extend/{customer}/sr/{identity}_cust.sr,或 index.json 按前缀 / 后缀共享定制文件。
  • 应用层 Lua 插件放到 hwproxy 插件目录,经 PluginRequest 调用。
  • 构建选项 unidev 切换单层 / 三层。

3.2 扩展点说明

扩展点位置触发时机
设备 socomponent_drivers,ABI 见 include/devmon/driver_abi.hAddDevice / 发现加载
应用层 Lua 插件/opt/bmc/lualib/hwproxy/plugins/<PluginName>/PluginRequest
客户定制 CSR/opt/bmc/extend/{customer}/sr/CSR 合并
机型定制 CSR/opt/bmc/extend/{platform_id}_{board_id}/sr/CSR 合并;不读 index.json
直挂对象路由DIRECT_SERVICE_OBJECT_POLICIESunidev 解析 CSR 时
白名单重命名whitelist.json对象名冲突时

直挂策略表已核实的类名:Connector → hwdiscovery;Accessor / Scanner / SmcDfxInfo / Median / MidAvg / Cont / ContBin / DftPca9545 / DftPca9555 / DftLm75 / DftI2c / DftCan → hwproxy。

3.3 二次开发指导

3.3.1 客户定制 CSR

{Bom}_{Id}_{AuxId}_cust.sr 放到 /opt/bmc/extend/{customer}/sr/。加载时与基础 CSR 的 Objects 合并:同名对象合并属性,新对象直接加入。

仅允许删除软件对象(如 PCIeNicCard_1NetworkPort_0OpticalModule_0SRUpgrade_1):

json
{
  "Objects": {
    "PCIeNicCard_1": {
      "bmc.dev.PCIeDevice": {
        "DeviceName": "hisi_1822"
      }
    }
  },
  "Customization": {
    "DeletedObjects": ["OpticalModule_0"]
  }
}

index.jsonRules 仅支持 Prefix / Suffix。命中优先级:Prefix 优于 Suffix;同类中 Pattern 更长者胜。机型定制目录不读索引。

验证方法:加载部件后检查对象属性是否被覆盖,以及 DeletedObjects 中的软件对象是否消失。

注意事项:不要删除 I2c_*Eeprom_*Connector_*Scanner_* 等硬件或拓扑对象。

3.3.2 新增设备驱动

  1. component_drivers 实现 register_device_driver
  2. 不要修改 devmon 仓 subprojects/component_drivers 副本后当作上游。
  3. bingo test -ut -jit 跑 devmon 侧 UT(需 -jit)。

3.3.3 应用层插件

业务进程只拿 Chip 代理调用 PluginRequest,不要 require 插件、不要 open("/dev/i2c-x")。公开点名与仓名的差异(如 mctpd 点 'smbus'、storage 点 'sml')见仓内 docs/2.2.应用层插件.md


4. 日志说明

组件使用 libmcpp 日志。配置模板 config.single.json.in 中 Logging 的 module_namedevmon,默认级别 notice。unidev 下 hwdiscovery / hwproxy 各自安装组件日志作用域,文件日志归属对应组件,不随执行线程漂移。

4.1 一键日志收集

devmon_service::on_dumphwproxy_service::on_dumpdiscovery_service::on_dump 分别在对应服务的 Dump 回调中执行。

文件产生服务内容说明
<dump_path>/access_scheduler.jsondevmonGetSummary + GetDomains 的 JSON。
<dump_path>/topology.txtdevmon / hwproxy根对象 DevTopologyHwProxy 下的拓扑树。
<dump_path>/snapshot.csvdevmon / hwproxyScanner / Accessor dump 文本。
<dump_path>/drivers_load_info.csvdevmon驱动加载信息。
<dump_path>/chips_access_statistic.csvdevmon / hwproxy芯片访问统计;Release 构建跳过
JBOG box_infodevmon目录权限 0750basic_info / cpld_info 文件权限 0640
<dump_path>/connectors.txthwdiscoveryConnector dump,含 root 头。
<dump_path>/root.srplatform.srhwdiscovery从允许路径复制的根 / 机型 CSR。
<dump_path>/<connector>.sr / .binhwdiscovery按 Connector dump 中的 SourcePath 复制;在位且 IdentifyMode=3 时最多复制 65 份 EEPROM 备份。

4.2 关键日志信息

日志片段日志级别含义解读建议处理动作
architecture mode: three-layer | single启动日志当前是 unidev 还是单层与构建选项核对
AddDevice forward to hwdiscoveryINFOCSR1 已转发确认 FormatVersion 是否故意小于 5.00
device already exists, skip add deviceWARNPosition 重复,幂等跳过先 RemoveDevice 再加载
object_group created for positionNOTICE对象组已创建
Connector Position is not initialized异常connector 无位置补 Position
Failed to read csr file异常文件不可读检查路径
RemoveDevice routing CSR1 position ... to hwdiscoveryINFOCSR1 卸载转发
open mctp device failed 等驱动错误视驱动不在本组件核心路径查对应驱动仓
discovery dump started / connectors dump successNOTICEhwdiscovery Dump
failed to dump access scheduler diagnosticsWARN调度快照写出失败检查 Dump 目录权限

5. 问题定界指南

5.1 典型问题定界

问题描述是否为本组件问题判断依据关键证据收集方法
AddDevice 抛读文件失败是。若调用方传入的 CSR 路径不可读,则根因在调用方异常文本含 Failed to read csr file核对路径是否在板端可读
设备未上树但 AddDevice 成功可能是幂等跳过device already exists 日志busctl tree 看 ObjectGroup;必要时先 RemoveDevice
PCIe 业务对象不上树可能是 CSR / 路由 / 驱动无对应 ObjectGroup 或驱动未 dlopen查 FormatVersion、drivers_load_info.csv、驱动目录
Scanner 值为空或 Status=1可能是 hwproxy / 硬件对象在 hwproxy 树上查 Chip HealthStatus、总线 AccessEnabled、防抖
PluginRequest 失败通常是插件或 Chip插件目录名 / Cmd 不匹配对照 docs/2.2.应用层插件.md 的点名表
IPMI 命令失败本组件无 IPMI 接口转向实现该命令的业务组件
进程被 systemd 杀掉可能是内存MemoryMax=150M查 OOM 与 RSS
require('devmon...') 找不到模块本组件不导出业务 Lua 模块改用 D-Bus 或 Chip 代理

5.2 错误码速查表

错误码来源含义排查建议
(无返回值)bmc.dev 成功mc::resolve()结合日志确认是否 skip
invalid_arg_exception根接口文件或 csr_data 类型非法见 2.1
parse_error_exception根接口 / CSR 解析Position 或 CSR 内容非法保存脱敏 CSR 与 connector
system_exception根接口服务未就绪或转发目标无效查进程启动与 unidev 服务名
07driver_abi.h status_t驱动内部状态见 2.7
SetLockStatus 05Chip MDS锁结果见 2.6
Found=falseAccessScheduler域不存在或调度器不可用GetSummaryAvailable

仓库没有 mds/errors.json,没有 IPMI 完成码表。

5.3 最小化复现与证据收集

  1. 记录 unidev 构建选项、CSR FormatVersion、connector 的 Position / SystemId / Slot。
  2. busctl --user tree bmc.kepler.devmon,必要时再看 bmc.kepler.hwproxy / bmc.kepler.hwdiscovery
  3. 保存 AddDevice 异常文本与 device already exists / forward to hwdiscovery 日志。
  4. 执行一键收集,保留 topology.txtsnapshot.csvdrivers_load_info.csvaccess_scheduler.jsonconnectors.txt
  5. 插件问题记录 PluginNameCmd 和 Chip 路径,不要采集完整 EEPROM 明文。

5.4 调试方法

bash
busctl --user tree bmc.kepler.devmon
busctl --user introspect bmc.kepler.devmon /bmc/dev
busctl --user call bmc.kepler.devmon /bmc/dev \
    bmc.dev.Devmon.AccessScheduler GetSummary
  • 单元测试:bingo test -ut -jit(必须加 -jit)。
  • 本地 meson:./scripts/smart_build.sh;三层测试加 -Dunidev=true
  • 对单个 Chip 调用 TraceChip start,对 Scanner 调用 TraceDebounce start

6. 常见问题解答

Q1:AddDeviceFailed to read csr file 怎么办?

  • 问题描述:busctl 调用 AddDeviceinvalid_arg_exception
  • 一句话答案:第一个参数必须是进程能读到的 .sr 路径。
  • 根因说明:add_deviceread_file,失败即抛错,不会进入解析。
  • 解决方案:使用板端绝对路径,或改用 AddDeviceWithData 传入 JSON 文本。
  • 规避方案:通过正式发现流程加载 CSR,而不是从开发机相对路径调用。
  • 适用版本:1.2.109。

Q2:为什么 AddDevice 成功但对象没有变化?

  • 问题描述:重复加载同一 Position,树上仍是旧对象。
  • 一句话答案:该 Position 已存在时实现会跳过解析并返回成功。
  • 根因说明:日志为 device already exists, skip add device,避免重复创建。
  • 解决方案:先 RemoveDeviceAddDevice,或使用 Connector Reload
  • 规避方案:热插拔脚本以 Position 为键做卸载/加载配对。
  • 适用版本:1.2.109。

Q3:单层构建下为什么没有 bmc.kepler.hwproxy

  • 问题描述:busctl tree 看不到 Scanner / Chip,或 hwproxy 服务名不存在。
  • 一句话答案:默认 unidev=false 只注册 bmc.kepler.devmon
  • 根因说明:三层服务由编译宏 DEVMON_ENABLE_UNIDEV 控制;单层通过 topology_discovery 订阅外部 hwdiscovery。
  • 解决方案:产品若拆分进程,分别查 hwproxy / hwdiscovery 组件;需要同进程三层时用 -o unidev=True 构建。
  • 规避方案:不要假设 Chip 路径一定在 bmc.kepler.devmon 树上。
  • 适用版本:1.2.109。

Q4:业务能否 require 某个 devmon Lua 模块?

  • 问题描述:Lua 报 module not found。
  • 一句话答案:devmon 不向业务导出 Lua API;设备管理走 D-Bus,插件走 PluginRequest
  • 根因说明:进程是 C++ mc::app,驱动是 C ABI .so,应用层插件由 hwproxy 加载。
  • 解决方案:对热插拔用 bmc.dev;对硬件命令用 Chip 代理的 PluginRequest,第二参为插件目录名。
  • 规避方案:不要把 hwproxy 插件路径加入业务进程的 package.path 再直接 require
  • 适用版本:1.2.109。

Q5:CSR1 设备加不上或卸不掉?

  • 问题描述:FormatVersion 小于 5.00 时加载或卸载不符合预期。
  • 一句话答案:unidev 会把 CSR1 转发到 bmc.kepler.hwdiscoverybmc.dev
  • 根因说明:阈值定义为 FORMAT_VERSION_THRESHOLD = 5.00;缺省 FormatVersion 按 5.00 走 CSR2。单层模式不转发,且强制 abi_v2
  • 解决方案:查 AddDevice forward to hwdiscovery / RemoveDevice routing CSR1 日志,并确认 hwdiscovery 服务已就绪。
  • 规避方案:新机型 CSR 使用 FormatVersion ≥ 5.00。
  • 适用版本:1.2.109。