散热调速模块定制化verify报错分析

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

问题描述

执行空定制化后,再执行verify.sh,出现"Verify custom fail!"错误,具体查看日志,发现提示“oms ERROR: export.lua(287): Some components failed, details: [“thermal_mgmt(Export failed)”]”

环境信息

  • 软件版本:OpenUBMC2512

重现步骤

  1. 执行空定制化,执行成功

    image

  2. 执行空定制化:0502XXXX_verify.sh a.ini b.ini

问题分析

  1. 执行空定制化的时候,app日志报错如下:

  2. 在thermal_mgmt\src\lualib\config_mgmt\customize_config.lua中加打印,信息如下:

2026-03-07 16:42:06.272935 thermal_mgmt NOTICE: server.lua(63): Export type [custom]
2026-03-07 16:42:06.273727 thermal_mgmt NOTICE: customize_config.lua(199): customize_config on_export
2026-03-07 16:42:06.278416 thermal_mgmt NOTICE: customize_config.lua(185): obj.TemperatureType: 1
2026-03-07 16:42:06.278854 thermal_mgmt NOTICE: customize_config.lua(188): rsp.Custom_CoreRemObjTem: 85
2026-03-07 16:42:06.279235 thermal_mgmt NOTICE: customize_config.lua(185): obj.TemperatureType: 2
2026-03-07 16:42:06.281487 thermal_mgmt NOTICE: customize_config.lua(191): rsp.Custom_OutletObjTem: 0
2026-03-07 16:42:06.282373 thermal_mgmt NOTICE: customize_config.lua(185): obj.TemperatureType: 3
2026-03-07 16:42:06.283154 thermal_mgmt NOTICE: customize_config.lua(185): obj.TemperatureType: 4
2026-03-07 16:42:06.283940 thermal_mgmt NOTICE: customize_config.lua(185): obj.TemperatureType: 5
2026-03-07 16:42:06.284627 thermal_mgmt NOTICE: customize_config.lua(185): obj.TemperatureType: 6
2026-03-07 16:42:06.285283 thermal_mgmt NOTICE: customize_config.lua(185): obj.TemperatureType: 7
2026-03-07 16:42:06.285932 thermal_mgmt NOTICE: customize_config.lua(185): obj.TemperatureType: 8
2026-03-07 16:42:06.286592 thermal_mgmt NOTICE: customize_config.lua(185): obj.TemperatureType: 9
2026-03-07 16:42:06.287377 thermal_mgmt NOTICE: customize_config.lua(185): obj.TemperatureType: 10
2026-03-07 16:42:06.288068 thermal_mgmt NOTICE: customize_config.lua(210): smart_cooling_mode_str: EnergySaving
2026-03-07 16:42:06.289784 thermal_mgmt NOTICE: customize_config.lua(215): BMCSet_FanInitDefaultLevel: 80
2026-03-07 16:42:06.293816 thermal_mgmt NOTICE: customize_config.lua(218): Custom_Inlet_Temp_Level: 3,20,30,40,20,32,70,100
2026-03-07 16:42:06.294515 thermal_mgmt NOTICE: customize_config.lua(219): Export customize config successfully
2026-03-07 16:42:06.295304 thermal_mgmt NOTICE: server.lua(73): Export data [{"CustomSettings":{"BMCSet_Thermal_Policy":16,"BMCSet_FanInitDefaultLevel":80,"Custom_CoreRemObjTem":85,"Custom_OutletObjTem":0,"Custom_Inlet_Temp_Level":"3,20,30,40,20,32,70,100"}}]
2026-03-07 16:42:06.595441 oms ERROR: export.lua(204): Export service(thermal_mgmt) config failed, ret: ...mc/apps/oms/lualib/config/import_export/data_process.lua:103: attempt to index a nil value.
2026-03-07 16:42:07.696523 oms ERROR: export.lua(287): Some components failed, details: ["thermal_mgmt(Export failed)"]

lsprop查看CoolingConfig对象结果如下:

% lsprop CoolingConfig_1_010102
bmc.kepler.Object.Properties
ClassName=“CoolingConfig”
ObjectIdentifier=[1,“1”,“1”,“010102”]
ObjectName=“CoolingConfig_1_010102”
TraceSamplingRate=0
bmc.kepler.Systems.CoolingConfig
CtrlMode=“Auto”
LevelPercentRange=[10,100]
ManualLevel=0
Medium=“Air”
MinAllowedFanSpeedEnabled=false
MinAllowedFanSpeedPercent=255
MixedModeSupported=false
SensorLocationSupported=false
SmartCoolingMode=“EnergySaving”
SmartCoolingState=“Enabled”
TimeOut=30
bmc.kepler.Systems.DiskCoolingConfig
DiskRowTemperatureAvailable=true
FrontHddMaxTemperatureCelsius=0
FrontNVMeSSDMaxTemperatureCelsius=0
RearHddMaxTemperatureCelsius=0
RearNVMeSSDMaxTemperatureCelsius=0
SysAllSSDsMaxTemperature=58
SysHDDsMaxTemperature=0
SysM2sMaxTemperature=32768
SysSSDsMaxTemperature=0
Private
CoolingWay=“Proactive”
FanBoardNum=2
FanCtrlEnable=“Enabled”
FanLevel=20
Id=0
InitLevelInStartup=80
MaxLimitLevel=100
MinimalLevel=0
OriginalSmartCoolingMode=“EnergySaving”

lsprop CoolingPolicy结果如下:

% lsprop CoolingPolicy_1_9_010102
bmc.kepler.Object.Properties
ClassName=“CoolingPolicy”
ObjectIdentifier=[1,“1”,“1”,“010102”]
ObjectName=“CoolingPolicy_1_9_010102”
TraceSamplingRate=0
bmc.kepler.Systems.CoolingPolicy
ActualCondVal=“EnergySaving”
CustomSupported=true
ExpCondVal=“Custom”
FanSpeedRangePercents=[20,100]
Hysteresis=1
IsValid=1
PolicyIdx=9
PolicyType=1
SpeedRangeHigh=[20,32,70,100]
SpeedRangeLow=[20,32,70,100]
TemperatureRangeHigh=[20,30,40,127]
TemperatureRangeLow=[-127,20,30,40]
Private
CoolingMedium=“Air”
DiskTempUnavailableToValid=false
FanSpeedArray=" Fd"
FanType=[]
HDDBackPlaneName=[]
HDDBackPlaneType=“”
HDDRearBackPlaneName=[]
OriginSpeedRangeHigh=[20,32,70,100]
OriginSpeedRangeLow=[20,32,70,100]
OriginTemperatureRangeHigh=[20,30,40,127]
OriginTemperatureRangeLow=[-127,20,30,40]
PCIeCardName=[]
TemperatureArray=“(”

单独执行配置导入和导出是没问题的

期望结果

期望校验能通过

实际结果

校验未通过

这是哪里出了问题

答案内容由AI生成,仅供参考:

:white_check_mark: 结论

项目 内容
问题类型 数据格式不匹配
故障模块 thermal_mgmt 组件的 custom_export 函数
根本原因 返回数据未按 { ConfigData = { ... } } 格式封装,导致 OMS 解析失败
解决方案 修改 customize_config.lua,正确封装返回结构
影响范围 所有依赖 verify.sh 的定制化流程

:light_bulb: 一句话总结thermal_mgmt 少返回了一层 ConfigData 包装,导致 OMS 认为“啥都没导出来”,触发 nil 异常。补上即可!

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

定制化 verify 报错分析:thermal_mgmt(Export failed) 根因与解决方案


:white_check_mark: 问题描述

在执行空定制化(即不带配置项的定制化脚本)后,运行 verify.sh 进行校验时失败,日志中提示:

Verify custom fail!
oms ERROR: export.lua(287): Some components failed, details: ["thermal_mgmt(Export failed)"]

尽管 thermal_mgmt 模块自身日志显示导出成功,但最终 OMS 框架报错,提示 attempt to index a nil value,导致整体定制化校验失败。


:puzzle_piece: 环境信息

  • 软件版本:OpenUBMC2512
  • 故障场景:执行空定制化 → 执行 verify.sh → 校验失败
  • 关键日志来源
    • /opt/bmc/apps/oms/lualib/config/import_export/data_process.lua
    • thermal_mgmt/src/lualib/config_mgmt/customize_config.lua

:repeat_button: 重现步骤

  1. 执行空定制化(无参数或默认参数):

    ./XXX_custom.sh a.ini b.ini
    

    → 成功完成。

  2. 执行校验脚本:

    ./XXX_verify.sh a.ini b.ini
    

    → 输出:

    Start custom verification successfully!
    Verify custom fail!
    
  3. 查看日志,核心报错为:

    oms ERROR: export.lua(204): Export service(thermal_mgmt) config failed, ret: ...mc/apps/oms/lualib/config/import_export/data_process.lua:103: attempt to index a nil value.
    oms ERROR: export.lua(287): Some components failed, details: ["thermal_mgmt(Export failed)"]
    

:magnifying_glass_tilted_left: 问题分析

1. thermal_mgmt 日志看:导出逻辑已执行成功

customize_config.lua 中添加打印后,可见以下输出:

thermal_mgmt NOTICE: customize_config.lua(219): Export customize config successfully
thermal_mgmt NOTICE: server.lua(73): Export data [
  {
    "CustomSettings": {
      "BMCSet_Thermal_Policy": 16,
      "BMCSet_FanInitDefaultLevel": 80,
      "Custom_CoreRemObjTem": 85,
      "Custom_OutletObjTem": 0,
      "Custom_Inlet_Temp_Level": "3,20,30,40,20,32,70,100"
    }
  }
]

:white_check_mark: 这说明 thermal_mgmt 组件内部导出逻辑已完成,并返回了结构化数据。


2. 从 OMS 日志看:框架层处理异常

然而,在 OMS 主服务中报错:

ERROR: export.lua(204): Export service(thermal_mgmt) config failed, ret: ...data_process.lua:103: attempt to index a nil value

关键线索:

  • 错误文件:data_process.lua
  • 行号:103
  • 错误类型:attempt to index a nil value尝试对 nil 变量进行字段访问

这类错误通常出现在以下场景:

local obj = nil
print(obj.field)  -- 就会抛出 "attempt to index a nil value"

结合代码逻辑推断:

oms 在接收到 thermal_mgmt 返回的导出数据后,会调用 data_process.lua 对数据进行解析、合并、存档。如果该模块期望返回的是一个 Table 对象,但实际接收到的是 nil 或非 table 类型数据,则会导致此错误。

进一步查看 data_process.lua:103 的上下文(虽未直接提供),可合理推测如下流程发生了异常:

-- 伪代码示意
local export_data = component:export('custom')  -- 获取组件导出数据
for k, v in pairs(export_data.ConfigData.CustomSettings) do  -- ❌ 若 export_data 为 nil,则此处报错
    ...
end

2. 为什么 thermal_mgmt 日志显示“Export successfully”,OMS 却失败?

关键在于:

:red_exclamation_mark: thermal_mgmt 只完成了“生成导出数据”的动作,但未确保数据被正确返回给 OMS 框架

观察其日志最后一行:

thermal_mgmt NOTICE: server.lua(73): Export data [{"CustomSettings":{...}}]

这是一个 数组(array) 包裹的表。

而标准的导出接口规范要求返回的是一个 JSON 对象,格式应为:

{
  "ConfigData": {
    "CustomSettings": {
      ...
    }
  },
  "Description": "..."
}

:warning: 问题定位:

thermal_mgmt 返回的数据结构不符合 OMS 框架预期!

  • :white_check_mark: 正确格式:{ ConfigData = { ... } }
  • :cross_mark: 当前格式:[ { CustomSettings = { ... } } ](数组包裹)

这导致 oms/data_process.lua 在尝试访问 ret.ConfigData 时,ret 是一个数组,ret.ConfigData == nil,从而触发 attempt to index a nil value


3. 为何单独执行导入导出没问题?

因为:

  • 单独执行导入导出 是通过 Web UI 或 Redfish API 调用,走的是 export_type = 'configuration' 路径。
  • 定制化校验(verify) 走的是 export_type = 'custom' 路径。

两者调用的导出函数分支不同:

function app:export(ctx, export_type)
    if export_type == 'configuration' then
        return self:configuration_export()
    elseif export_type == 'custom' then
        return self:custom_export()  -- 当前路径出错
    end
end

说明:configuration_export 返回格式正确,而 custom_export 存在格式错误。


:package: 根因总结

thermal_mgmt 组件在 custom_export 流程中,返回的导出数据结构格式错误,未按 OMS 框架要求封装为 { ConfigData = { ... } },而是直接返回了一个数组,导致 OMS 在解析时访问 ConfigData 字段时出现 nil 引用,最终报错 attempt to index a nil value,致使定制化校验失败。


:white_check_mark: 解决方案

:white_check_mark: 修复 thermal_mgmtcustom_export 返回格式

修改 thermal_mgmt/src/lualib/config_mgmt/customize_config.lua 中的导出返回逻辑。

:cross_mark: 当前错误写法(推测):

function customize_config.custom_export()
    local rsp = {}
    -- ... 构造 CustomSettings
    return { rsp }  -- 错误:返回数组
end

:white_check_mark: 正确写法:

function customize_config.custom_export()
    local export_data = {}

    -- 构造 CustomSettings
    export_data.CustomSettings = {
        BMCSet_Thermal_Policy = obj.PolicyType,
        BMCSet_FanInitDefaultLevel = obj.InitLevelInStartup,
        Custom_CoreRemObjTem = ..., -- 如85℃
        Custom_OutletObjTem = ...,
        Custom_Inlet_Temp_Level = "3,20,30,40,20,32,70,100"
    }

    -- 必须包装为 ConfigData
    return {
        ConfigData = export_data,
        Description = "Custom configurations of thermal_mgmt"
    }
end

:wrench: 验证方法

  1. 修改代码并重新编译 thermal_mgmt 组件;
  2. 刷入新版本 BMC 固件;
  3. 再次执行空定制化 + verify 流程;
  4. 检查 oms 日志是否仍有 nil value 报错;
  5. 检查 app.logExport service(thermal_mgmt) 是否成功。

:shield: 预防建议

  1. 组件开发规范强制校验导出格式:所有实现 custom_export 的组件必须返回符合 schema 的结构。
  2. OMS 增加容错机制:在 data_process.lua 中增加判空处理:
    if not ret or not ret.ConfigData then
        log:error("Invalid export data from %s", service_name)
        return false
    end
    
  3. 自动化测试覆盖:在 CI 流程中加入定制化 verify 的回归测试,确保不因格式问题引入故障。

:white_check_mark: 结论

项目 内容
问题类型 数据格式不匹配
故障模块 thermal_mgmt 组件的 custom_export 函数
根本原因 返回数据未按 { ConfigData = { ... } } 格式封装,导致 OMS 解析失败
解决方案 修改 customize_config.lua,正确封装返回结构
影响范围 所有依赖 verify.sh 的定制化流程

:light_bulb: 一句话总结thermal_mgmt 少返回了一层 ConfigData 包装,导致 OMS 认为“啥都没导出来”,触发 nil 异常。补上即可!

确认在/opt/bmc/profile_schema/路径下是否存在文件thermal_mgmt.json

busctl 手动执行下export看能导出什么东西