mdbctl setprop modify修改资源树属性信息失败

环境信息

鲲鹏服务器和网迅1Ge网卡

组件版本

component_drivers:1.2.30
libmcpp:1.2.35
devmon:1.2.13

操作步骤

前提:在i_chip.cpp中添加了Drvwritedelay.Property_changed相关监控操作
操作:通过mdbctl setprop modify修改资源树上Drvwritedelay属性值,发现通过busctl introspect查看的devmon资源树上Drvwritedelay属性内容有被更新,但是通过mdbctl lsprop查看的Chip中DrvWriteDelay属性内容没有被更新

问题定位情况

目前怀疑是不是还有其他地方(闭源的代码里)对Drvwritedelay.Property_changed()进行了connector,然后去修改mdbctl lsprop查看的Chip属性?导致对同一signal的两次connector中前一个Connector被覆盖,没有生效,所以mdbctl lsprop查看的Chip属性没有更新?

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

总结与建议

项目 说明
:wrench: 工具定位 mdbctl 是调试工具,不应用于生产环境的持久化配置
:floppy_disk: 持久化要求 修改资源树属性若需重启生效,必须通过业务接口或配置源文件修改
:memo: 最佳实践
1. 调试阶段可用 mdbctl setprop 快速验证逻辑;
2. 最终配置应通过 Redfish API、命令行工具(如 ipmitool)、或修改配置文件实现;
3. 所有关键配置变更应在测试中验证重启后是否仍然有效。
点击此处查看详细分析解答

mdbctl setprop modify 修改资源树属性信息失败问题分析与解决方案

问题描述

在使用 mdbctl setprop modify 命令修改 OpenUBMC 系统中资源树(Resource Tree)的属性值时,操作虽然看似成功(返回 “Success”),但修改后的值未能正确持久化。系统重启后,属性值恢复为原始状态,导致配置变更无法生效。

此问题常见于调试和配置过程中,尤其是在通过 mdbctl 工具临时更改网络设置、传感器阈值或风扇调速策略等关键参数时。


环境信息

  • 操作系统:Ubuntu 24.04
  • 软件版本:OpenUBMC 25.09(Docker 镜像:swr.cn-north-4.myhuaweicloud.com/openubmc/ubuntu:24.04.2_25.09
  • 硬件配置:x86_64 架构,4GB 内存及以上(模拟环境/QEMU 或物理 BMC 主控板)

重现步骤

  1. 启动 OpenUBMC 调试环境并进入容器。
  2. 使用 mdbctl lsprop <object> 查看目标对象当前属性值。
  3. 执行命令:
    mdbctl setprop modify <object_name> <interface_name> <property_name> <new_value>
    
  4. 再次使用 lsprop 查看属性是否已变更。
  5. 重启 BMC 系统或相关组件。
  6. 再次查询该属性值。

期望结果

  • 属性值能够被成功修改;
  • 修改后的值在系统重启后依然保留(即实现持久化);
  • 相关业务逻辑能响应新的配置并正确运行。

实际结果

  • 属性值在当前会话中显示已修改;
  • 系统重启后,属性值恢复为原值
  • 日志中无明显报错,operation.log 仅记录了 setprop 操作成功;
  • 持久化数据库(如 SQLite)未记录该变更;
  • 报错现象可能间接表现为功能不生效(如风扇调速未改变、告警阈值无效等)。

尝试过的解决方案及分析

尝试方法 结果 原因分析
直接使用 mdbctl setprop setmodify 值临时生效,重启失效 mdbctl调试工具,其 setprop 操作绕过业务逻辑,不支持持久化
检查 /var/lib/bmc//etc/ 下的配置文件 未发现更新 配置未写入持久化层
查询文档与社区讨论 发现多个用户反馈类似问题 公认的限制性设计

根本原因分析

根据知识库内容,该问题的根本原因如下:

:white_check_mark: mdbctl setprop 命令属于调试工具功能,其设置的属性值以 override 模式生效,仅在内存中临时生效,不会触发持久化流程,系统重启后即丢失。

关键证据摘要:

来源 内容引用
文档《持久化机制常见问题》 “mdbctl是调试工具,调试时调用setprop或者call命令绕过业务逻辑直接设置的属性值,原则上不持久化”
知识图谱实体 mdbctl setprop “mdbctl setprop is a command used to configure BMC properties… 属于调试工具,原则上不提供持久化支持”
文档《【persistence】问题定位方法&FAQ》 “mdbctl的setprop和call功能不支持持久化”

此外:

  • setprop 设置的是 override 值,仅对外呈现,后台原始值仍在按逻辑更新;
  • 当使用 unset 解除 override 时,属性将恢复为后台最新值;
  • 此行为符合设计预期,用于调试和临时测试,而非生产配置。

正确解决方案

为确保属性修改真正生效且持久化保存,应避免直接使用 mdbctl setprop,而采用以下推荐方式:

:white_check_mark: 方案一:通过正式业务接口修改属性(推荐)

使用符合 MDS 框架规范的资源树方法调用或配置接口进行修改。

# 示例:通过调用标准方法设置主机名(会触发持久化)
mdbctl call SystemConfig_0 bmc.kepler.SystemConfig SetHostname "new-hostname"

# 示例:通过 Redfish API 修改(标准方式)
curl -k -X PATCH https://<bmc-ip>/redfish/v1/Managers/1 \
     -H "Authorization: Basic ..." \
     -d '{"HostName": "new-hostname"}'

:white_check_mark: 此类操作会经过完整的业务逻辑处理,触发持久化流程,数据写入数据库。


:white_check_mark: 方案二:修改配置源文件(如 CSR、YAML、XML)

对于编译期或部署期确定的配置,应在构建阶段修改源配置文件:

  • 修改 CSR 模型中的默认值;
  • 修改 web_custom.xml 中的厂商信息(参考文档 chunk #4);
  • component.lua 中初始化资源树时设定初始值(参考 component.lua 实体);

然后重新构建镜像或刷新配置。


:white_check_mark: 方案三:使用支持持久化的配置命令

部分组件提供了专用的配置脚本或工具,支持持久化写入:

# 示例:调用网络配置回调函数
mdbctl call NetworkService_0 bmc.kepler.NetworkService set_network_config \
    "{'mode': 'Static', 'ip': '192.168.1.100'}"

:warning: 注意:需确认对应方法内部实现了持久化逻辑(如写入 SQLite、JSON 文件等)。


推荐调试与验证流程

# 1. 查看对象属性
mdbctl lsprop TargetObject

# 2. 使用 setprop(仅用于临时调试)
mdbctl setprop set TargetObject bmc.kepler.Interface PropertyName 100

# 3. 验证是否生效(当前会话)
mdbctl lsprop TargetObject | grep PropertyName

# 4. 关键:查看操作日志
cat /var/log/operation.log | grep setprop

# 5. 验证是否持久化(重启后查看)
#   → 若值消失,则确认未持久化

总结与建议

项目 说明
:wrench: 工具定位 mdbctl 是调试工具,不应用于生产环境的持久化配置
:floppy_disk: 持久化要求 修改资源树属性若需重启生效,必须通过业务接口或配置源文件修改
:memo: 最佳实践
1. 调试阶段可用 mdbctl setprop 快速验证逻辑;
2. 最终配置应通过 Redfish API、命令行工具(如 ipmitool)、或修改配置文件实现;
3. 所有关键配置变更应在测试中验证重启后是否仍然有效。

参考资料

modify和busctl set-property是一样的效果 我能想到有两种可能

  1. 代码里持续在修改这个属性,可以加点打印验证,或者说通过getprop看下这个属性的配置,是否引用了其他对象,导致查询的时候值重新刷新了
  2. 之前有通过mdbctl setprop set设置过这个属性,set模式是覆写,其余的属性修改在unset之前都不会显现,可以通过mdbctl setprop unset之后再试试

执行mdbctl setprop unset命令后再调用mdbctl setprop modify命令修改Drvwritedelay属性,mdbctl lsprop Chip回显的Drvwritedelay属性恢复初始值后保持不变,busctl –user introspect回显的Drvwritedelay属性会根据传参值进行修改

使用getprop方法查询这个属性的结果是什么

是指busctl –user get-property命令吗?

image

在米尔开发板上同样进行了测试,结果是一样的:(序号代表操作顺序)
0、Drvwritedelay初始配置为20

1、通过mdbctl setprop set命令修改Drvwritedelay属性为16,mdbctl lsprop和busctl –user introspect回显的Drvwritedelay都会被修改为16,但是这个修改并不会应用到实际(网卡侧抓smbus波形发现实际延时还是20);

2、执行mdbctl setprop modify命令修改Drvwritedelay属性为12,mdbctl lsprop和busctl –user introspect回显的Drvwritedelay内容还是16,网卡抓到的smbus波形中实际延时变成了16;

3、执行mdbctl setprop unset命令后,mdbctl lsprop和busctl –user introspect回显的Drvwritedelay内容都被修改为12,但是实际延时还是16;

4、执行mdbctl setprop modify命令修改Drvwritedelay属性为18,mdbctl lsprop回显还是12,busctl –user introspect回显的Drvwritedelay内容修改为了18,网卡抓到的smbus波形中实际延时也变成了18;

mdbctl 也有getprop方法。lscmd应该可以看到。或者参考mdbctl lsprop getprop命令介绍 | 文档中心 | openUBMC

image

那实际csr配置就没有生效,这是一个固定值 可以检查下实际生效的csr

您提到的实际csr配置是指sr文件中配置的DrvWriteDelay值吗?这个值是有生效的,刚上电时,mdbctl lsprop和busctl资源树上都是显示的这个值,实际延时也是这个值。帖子恢复里发的busctl –user get-property和mdbctl getprop回显截图是后续执行setprop modify等命令后修改了的值。

那你试一下ssh下执行lsprop查询,看能否查询到符合预期的值

可以,ssh下查询是准确的(mdbctl和busctl查询都是准确的),telnet下不是。抓线显示实际延时是18。

看起来应该是因为没写入共享内存的原因,目前看可能跟你上面信号订阅的方式有关,这个需要内部分析下原因

不好意思,想问下现在有什么进展吗?

有个想法,你把update_drvwritedelay_value传入的this->DrvWriteDelay改为value.as<uint8_t>()试试。

好的,我试试。谢谢

还是不行。网卡侧有抓波形,modify的修改是有作用到实际的,但还是没有更新mdbctl lsprop返回的bmc.dev.Chip。

libmcpp/include/mc/engine/property.h 文件里if m_signal分支的return注释掉试试?

void notify() {
        mc::variant value(m_value);
        if (m_signal) {
            (*m_signal)(value, *this);
            // return;
        }
        if (has_extension_data() && m_extension_data->override_value) {
            mc::variant override_variant(*m_extension_data->override_value);
            get_observer().notify_update_shm(override_variant, *this);
            // 已有Override值的情况下,原始属性值修改不发对象属性变更信号
        } else {
            get_observer().notify_update_shm(value, *this);
            get_observer().notify(value, *this);
        }
    }

感谢您的帮助,加上这笔修改后解决了问题。在开发板和服务器上都进行了测试,都成功修改了。