Nvme盘加载调速失败问题分析
更新时间: 2026/06/08
在Gitcode上查看源码问题背景
- 单板类型:NA
- 软件版本:openUBMC 25.12。
- 涉及功能:风扇调速。
- 触发条件:Presence信号未正确上报或初始化失败(可能由硬件抖动、I2C延迟、配置错误等引起)。
- 业务表现:Nvme热插拔遍历,每个槽位都能正常读取温度并调速;在Disk22槽位发现没有温感,定位后发现没有调速且没有识别到在位。
问题复现步骤
- 在 openUBMC 25.12 LTS SP1 环境下对 NVMe 盘进行热插拔遍历测试。
- 将 NVMe 盘从某槽位拔出,观察系统日志。
- 将同一 NVMe 盘重新插入相同槽位。
- 检查该槽位对应的风扇调速策略是否正常加载、温度是否可感知。
关键日志信息
- 查看app.log日志,确认报错如下:
text
storage ERROR: tasks.lua(92): task [update_policy_connector22] error: ./opt/bmc/libmc/ lualib/mc/orm/object.lua:515: attempt to index field '__mdb_obj' (a boolean value)- 确认
connector_Policy_01010217对象的.Presence属性值为0,系统未检测到设备在位:
定位过程
- 从app.log中的报错日志入手,分析 tasks.lua 中
update_policy任务函数逻辑:通过orm.get_object(connector_id)获取对象失败返回false,但代码未做有效性检查,直接访问其__mdb_obj字段导致运行时错误。 - 排查
Presence = 0的原因:设备在位信号未正确上报或初始化失败,可能由硬件抖动、I2C 延迟、配置错误等引起。 - 进一步分析发现更深层原因:NVMe 盘上次拔出时,名为
update_policy_connector[Slot]的定时任务未被正确停止。物理对象(VPD Connect 对象)虽已卸载,但其关联任务仍在后台运行。 - 同槽位硬盘再次插入时,系统尝试创建同名新任务,框架的同名任务机制阻止创建新任务,导致过期旧任务持续运行,反复访问已失效的对象变量,日志持续报错。
- 定位到代码层面根因:任务使用
c_tasks.get_instance()方式创建,不属于"发起创建的对象";c_vpd_connect对象的析构函数dtor()中缺少停止任务的代码,导致拔出时任务成为"孤儿"未被清理。
问题原因
NVMe 盘拔出时,c_vpd_connect 对象的析构函数 dtor() 未停止关联的 update_policy_connector 定时任务,导致旧任务残留运行;重新插入同槽位硬盘后,框架的同名任务机制阻止创建新任务,旧任务持续访问已失效对象变量,调速策略无法正常加载。
解决方案
- 推荐方案:改用
self:new_task方式创建任务。此方式创建的任务会自动与对象实例绑定,对象被卸载(析构)时框架自动停止所有属于该对象的任务,无需手动清理。 - 备选方案:在
c_vpd_connect对象的析构函数dtor()中手动停止相关任务:
lua
function c_vpd_connect:dtor()
local task_name = string.format('update_vpd_connector%s', self.Slot)
local task = c_tasks.get_instance():get_task(task_name)
if task then
task:stop()
end
end- 辅助优化:在访问对象字段前增加类型校验,增强代码健壮性;优化 Scanner 防抖计数配置,避免硬件抖动导致 Presence 误判。