*openUBMC openUBMC 支持双主机场景对NVMe盘的带外管理详细设计说明书*

<table>
    <tr>
        <td>所属SIG组:</td>
        <td>hardware</td>
    </tr>
    <tr>
        <td>落入版本:</td>
        <td>25.12</td>
    </tr>
    <tr>
        <td>设计人员:</td>
        <td>黄明浩</td>
    </tr>
    <tr>
        <td>日期:</td>
        <td>2025/11/13</td>
    </tr>
</table>


**Copyright © 2025 openUBMC Community**

您对&quot;本文档&quot;的复制，使用，修改及分发受木兰宽松许可证, 第2版协议(以下简称&quot;MulanPSL2&quot;)的约束。
为了方便用户理解，您可以通过访问<https://license.coscl.org.cn/MulanPSL2>了解MulanPSL2的概要 (但不是替代)。
MulanPSL2的完整协议内容您可以访问如下网址获取：<https://license.coscl.org.cn/MulanPSL2>。

**改版记录**

<table>
    <tr>
        <th>日期</th>
        <th>修订版本</th>
        <th>修订描述</th>
        <th>作者</th>
        <th>审核</th>
    </tr>
    <tr>
        <td>xxx</td>
        <td>xxx</td>
        <td>xxx</td>
        <td>xxx</td>
        <td>xxx</td>
    </tr>
    <tr>
        <td>xxx</td>
        <td>xxx</td>
        <td>xxx</td>
        <td>xxx</td>
        <td>xxx</td>
    </tr>
</table>

**List of abbreviations**  **缩略语清单** ：

<table>
    <tr>
        <th>Abbreviations 缩略语</th>
        <th>Full spelling 英文全名</th>
        <th>Chinese explanation 中文解释</th>
    </tr>
    <tr>
        <td>NVMe</td>
        <td>NVM Express，Non-Volatile Memory Express</td>
        <td>非易失性内存标准，专为高速 SSD（尤其是通过 PCIe 接口连接的 SSD）设计的“超高速公路”协议</td>
    </tr>
    <tr>
        <td>PSR</td>
        <td>Product Description Record</td>
        <td>整机硬件配置</td>
    </tr>
</table>

[TOC]

# 1.功能分析
## 1.1 功能背景
<!-- 描述该需求的来源或背景，比如：支撑XXX功能、XXX优化等；以及该需求对用户（含组件）带来什么具体价值，如果没有该需求，对用户（含组件）带来什么损失； -->
该需求用来支持双主机场景下对NVMe盘的带外管理，BMC可以带外通过nvme-mi协议获取NVMe盘的信息用于展示和告警。

## 1.2 功能描述
<!-- 描述该需求交付的整体功能，主要实现XXX功能，解决XXX问题，明确方案如何实现 -->
实现双主机场景下对NVMe盘的带外管理，解决目前双主机场景下，归属第二个主机的NVMe盘无法通过mctp带外获取信息的问题
方案:
1.在platform.sr中配置一个对象NVMeConfig，配置跟随机型（硬件拓扑）变化，该配置表征各个槽位的NVMe盘的主机号（SystemId）。（若无该对象分发，SystemId默认为1）
放在PSR里面可能会在EEPROM故障时，无法加载PSR这时候会导致无法加载该对象，因此放在platform.sr中。
2.在原有流程--NVMe创建用于MCTP传输报文的EP时，将第一步中获取的SystemId传入该接口中
3.NVMe盘拿到各自的EP，通过EP进行带外访问获取NVMe-MI协议中规定的信息

## 1.3 功能场景
1) 场景触发条件及对象：网管、运维人员、开发人员可以通过web或其他接口查看获取NVMe盘的信息
2) 使用时间及频度：不频繁

## 1.4 功能列表
<!-- 描述该需求交付的功能列表，内容包括：列出功能详细描述，标题、描述。 -->
| 功能编号 | 功能标题 | 功能描述 |
| ------- | ------- | -------- |
| 1 | 支持双主机场景对NVMe盘的带外管理 | 支持双主机场景对NVMe盘的带外管理 |

# 2.功能设计
## 2.1 总体方案分析
<!-- 描述该方案的总体设计（注：相关输出方案可同步刷新到各组件仓） -->

1.在对应的platform.sr中增加NVMeConfig对象，配置各个槽位硬盘关联的主机号（SystemId）

2.storage仓model.json中增加NVMeConfig对象及相应的属性，示例如下所示：
```
"NVMeConfig": {
    "MultiHostMappings": [
        {
            "UID": "0000XXX",         // 硬盘背板UID
            "SlotId": [0, 1, 2, 3],   // 硬盘槽位Id
            "SystemId": [1, 1, 2, 2], // 对应的主机号
        }
    ]
}
```

3.在NVMe对象自发现时通过NVMeConfig对象更新对应的SystemId

4.在调用创建EP接口时，传入对应的SystemId，匹配对应主机的路由，返回对应的EP和tansport

4.通过原有的后续带外管理流程更新信息

5.不影响原有单主机场景NVMe带外管理

### 2.1.1 方案详细设计
#### 2.1.1.1 方案概述
<!-- 描述该方案的整体实现，内容包括：涉及的关键点，实现策略等 -->

1.在platform.sr整机配置中增加NVMeConfig对象--硬盘槽位归属哪个主机由硬件链路决定，属于整机硬件配置，跟随整机变化。

2.NVMeConfig配置在platform.sr中与root.sr同一层级，硬件自发现为广度优先遍历，因此保证先于NVMe对象添加。

3.单主机场景或者非双主机特定硬盘背板UID，NVMe盘的SystemId默认为1，不影响原有单主机NVMe带外管理

4.NVMe盘需要通过position获取所在的硬盘背板，拿到UID，找到对应的NVMeConfig中的UID,根据SlotId匹配到SystemId（暂不考虑M.2转接卡）

5.调用mctp提供的接口创建EP，使用该适配双主机场景的EP进行后续的带外管理

#### 2.1.1.2 开发视图
<!-- 开发视图面向系统开发及软件管理，描述系统代码结构，构建结构的视图，主要解决系统技术实现和开发的问题，它依托逻辑视图，描述代码、构建结构 -->
```mermaid
classDiagram
    class object {
        + on_add_object()
        + on_del_object()
    }

    class NVMe {
        + on_add_object()
        + init_nvme_mi_mctp()
        + get_nvme_smart_info()
    }

    class Drive {
        + on_add_object()
        + nvme_identified()
        + update_by_mctp()
    }

    class mctp {
        + get_endpoint_and_transport()
    }

    class NVMeConfig {
        -String UID
        -Array SlotId
        -Array SystemId
    }

    class DBUS {
        + GetBoardObjects()
    }

    object <|-- NVMe
    object <|-- Drive
    NVMe --> NVMeConfig : depends on
    Drive ..> NVMe : depends on
    NVMe --> mctp : depends on
    NVMe --> DBUS : depends on
```

#### 2.1.1.3 运行视图
<!-- 运行视图面向系统运行，描述系统启动过程、运行期交互的视图，主要解决系统运行期交互，描述各可执行交付件在运行期的交互关系 -->
```mermaid
sequenceDiagram
    participant User
    participant 北向接口
    participant hwdiscovery
    participant dbus资源树
    participant storage
    participant mctp
    storage->>storage:注册各类对象添加、删除的回调函数
    hwdiscovery->>dbus资源树:解析各类CSR并自发现对象数据
    storage->>dbus资源树:获取对象数据，NVMe对象初始化
    storage->>dbus资源树:获取HddbackPlane对象与VMeConfig对象匹配得到SystemId
    storage->>mctp:调用get_endpoint_and_transport接口获取EP
    storage->>protocol:调用device_spec_parser接口，传入配置文件获取封装好的用于通信的对象
    loop
        storage->>protocol:调用配置文件中配置好的命令，进行参数校验，NVME-MI协议头填充等操作
        protocol->>mctp:调用Request接口进行报文收发
        protocol->>storage:按照配置文件中的response函数进行报文解析并返回数据
    end
    storage->>dbus资源树:将带外获取的NVMe盘的信息更新到资源树上的Drive对象上
    User->>北向接口:用户调用北向接口
    北向接口->>dbus资源树:通过映射配置器获取dbus资源树上的信息
    dbus资源树->>北向接口:返回
    北向接口->>User:返回结果
```

### 2.1.2 内部依赖分析
<!-- 是否涉及与其他组件接口依赖，如果涉及需要确认当前是否已完成，是否匹配当前需求开发诉求 -->
依赖资源树接口GetBoardObjects获取NVMe盘所在的硬盘背板对象。

### 2.1.3 外部依赖分析
<!-- 是否涉及与平台SDK的依赖关系 -->
依赖mctp组件get_endpoint_and_transport接口支持双主机mctp通信。（已支持）

### 2.1.4 北向接口分析
<!-- 需要分析当前功能是否有以下接口影响，如果有影响，则需要具体的补充影响点。其中注意点如下：
（1）如果有新增IPMI接口，请排查代码中IPMI命令注册的过滤字段，是否完全和IPMI命令的定义一致？
（2）新增一个接口时，需要咨询SIG组是否还有其他的接口受影响 -->
| 特性 | SNMP | CLI | WEB | KVM_VMM | IPMI(RMCP/RMCP+) | HMM | Redfish |
| ---- | ---- | ---- | --- | ------ | ---------------- | --- | ------- |
| 支持双主机场景下对NVMe盘的带外管理 | 不涉及 | 不涉及 | 不涉及 | 不涉及 | 不涉及 | 不涉及 | 不涉及 |

### 2.1.5 兼容性分析
<!-- 当前的功能对现有在网的功能是否有影响，具体的影响点进行分析之后输出影响分析表格 -->
对于单主机场景，调用get_endpoint_and_transport接口的参数systemid不填或者填为1都不影响已有功能。
mctp_lib.get_endpoint_and_transport, bus, MODULE_NAME_STORAGE_MGNT,
    NVME_SMBUS_PHY_ADDR, mctp_lib.MCTP_MESSAGE_TYPE_NVME, position, system_id
### 2.1.6 定制化接口分析
不涉及
### 2.1.7 导入导出分析
<!-- 如果支持导入导出的配置，则需要分析导入导出的schema。 -->
不涉及
### 2.1.8 传感器分析
<!-- 如果需要新增传感器，则需要提前登记和评审新增的传感器要素。新增传感器评审需要上SIG-Interface进行评审 -->
不涉及
### 2.1.9 精准告警事件分析
<!-- 如果需要新增事件，则需要提前登记和评审新增的时间要素 -->
不涉及
### 2.1.10 系统锁定分析
<!-- 对外的接口或者命令是否支持系统锁定 -->
不涉及
### 2.1.11 用例场景分析
<!-- 以表格的形式输出该需求涉及的用例场景 -->

| 用例编号 | 用例描述 | 前置条件 |执行步骤 | 预期结果 |
| --- | --- | --- | --- | --- |
| 1 | 单主机场景NVMe盘带外信息正确获取 | 支持mctp的NVMe盘&OS上电 | 1.通过mdbctl查询盘的Smart信息；2.通过OS带内NVMe工具获取数据；3.对比数据是否一致 | 数据一致 |
| 2 | 双主机场景主机1的NVMe盘带外信息正确获取 | 支持mctp的NVMe盘&OS上电 | 1.通过mdbctl查询盘的Smart信息；2.通过OS带内NVMe工具获取数据；3.对比数据是否一致 | 数据一致 |
| 3 | 双主机场景主机2的NVMe盘带外信息正确获取 | 支持mctp的NVMe盘&OS上电 | 1.通过mdbctl查询盘的Smart信息；2.通过OS带内NVMe工具获取数据；3.对比数据是否一致 | 数据一致 |
| 4 | 双主机场景主机1和2的NVMe盘带外信息正确获取 | 支持mctp的NVMe盘&OS上电 | 1.通过mdbctl查询盘的Smart信息；2.通过OS带内NVMe工具获取数据；3.对比数据是否一致 | 数据一致 |
| 5 | 双主机场景AC后NVMe盘带外信息正确获取 | 支持mctp的NVMe盘&AC后 | 1.通过mdbctl查询盘的Smart信息；2.通过OS带内NVMe工具获取数据；3.对比数据是否一致 | 数据一致 |
| 6 | 双主机场景OS重启后NVMe盘带外信息正确获取 | 支持mctp的NVMe盘&OS重启 | 1.通过mdbctl查询盘的Smart信息；2.通过OS带内NVMe工具获取数据；3.对比数据是否一致 | 数据一致 |
| 7 | 双主机场景BMC复位后NVMe盘带外信息正确获取 | 支持mctp的NVMe盘&BMC复位 | 1.通过mdbctl查询盘的Smart信息；2.通过OS带内NVMe工具获取数据；3.对比数据是否一致 | 数据一致 |
| 8 | 双主机场景热拔插后NVMe盘带外信息正确获取 | 支持mctp的NVMe盘&BMC复位 | 1.通过mdbctl查询盘的Smart信息；2.通过OS带内NVMe工具获取数据；3.对比数据是否一致 | 数据一致 |


## 2.2 非功能质量属性设计
### 2.2.1 扩展性分析
<!-- 考虑后续新增类似功能可以很好地扩展 -->
如果新增硬盘背板或新增机型需要支持双主机场景NVMe盘带外管理，在对应机型的platform.sr中添加NVMeConfig对象或在NVMeConfig对象中添加相应硬盘背板UID即可，无需适配组件代码，只需新增配置。
### 2.2.2 重用性分析
<!-- 是否为通用处理方式、接口，如果是得考虑重用性 -->
不涉及

### 2.2.3 可测试性分析
<!-- 此需求如何验证，是否可直接验证，or通过XXX功能覆盖验证，or需要单独怎加测试接口验证 -->
在双主机环境，每个主机下都有支持mctp的NVMe盘
资源树上查看Drive对象bmc.kepler.Systems.Storage.Drive.NVMe.SMART接口下的AvailableSpare，CriticalWarning，UsedPercentage与带内通过命令smartctl -a /dev/nvmex 是否一致。

### 2.2.4 资料分析

<!-- 是否涉及资料修改 -->
不涉及

### 2.2.5 资源使用分析
<!-- 新增线程、内存分配、模型属性名长度是否合理，CPU占用率是否会激增，Flash中新增文件是否合理（频繁读写Flash会大幅缩短emmc寿命）；是否涉及消息队列，如果涉及请检查是否存在某些场景下消息队列会满导致消息丢失，例如大量消息发送到队列且处理消息需要耗费较长时间的场景。 -->
不涉及新增协程，新增对象NVMeConfig占用内容很小
### 2.2.6 可靠性分析
| 编号 | 场景 | 问题描述 | 可靠性影响 | 建议解决方案/需求 | 备注 |
| --- | --- | --- | --- | --- | --- |
| 1 | DC场景 | 创建EP或通信时DC | DC会触发清除EP和将相关属性恢复成无效值 | 无影响 | - |
| 2 | AC场景 | AC场景能否成功创建EP | 监听bios信号，postend后会触发一次创建EP，防止设备bdf还未上报的时序问题 | 无影响 | - |
| 3 | NVMeConfig配置错误或其他问题导致SystemId错误 | NVMe盘会拿到错误的SystemId | 可能没有对应路由无法创建EP带外管理或者将信息更新到错误的硬盘上 | 影响挺大，需要保证SystemId正确，或者需要有什么方式能校验SystemId是否正确 | - |
| 4 | 拔盘/换盘 | 拔盘资源是否释放，换盘是否能重新创建EP | 拔盘NVMe对象触发删除，相关资源会释放，插盘后会触发创建EP流程 | 无影响 | - |
| 5 | os下电时，BMC重启或硬盘插入 | mctp无对应路由，超时返回 | NVMe带外通信在单独的协程中进行，若是创建用于双主机场景下的EP失败，不影响其余属性更新。 | 不影响 | - |
### 2.2.7 安全性分析
| 安全合规项 | 是否涉及 | 现有的防护措施 |
| --- | --- | --- |
| 访问控制（通道、文件权限、用户权限、查询权限、配置权限、接口权限） | 不涉及 |  |
| 敏感数据 | 不涉及 |  |
| 日志（操作日志、维护日志、安全日志、运行日志） | 不涉及 |  |
| 文档 | 不涉及 |  |
| 加密及算法 | 不涉及 |                      |
| 新增关键资源（密钥、证书、关键配置）备份、恢复 | 不涉及 |  |
| 新增对外接口入参校验 | 不涉及 |  |
| 新增开源及三方软件引入 | 不涉及 |  |
# 3.功能实现
<!-- 通过表格、流程图、简明文字描述提供，力求容易看懂、容易实现，详细描述细节。 -->
## 3.支持双主机场景下对NVMe盘的带外管理
### 3.1.1 功能实现设计
见2.1 总体方案分析，不再赘述

### 3.1.2 功能详细设计
如 2.1 章节所示
### 3.1.3 开发者测试
<!--
增加模块接口：以活动图/流程图等形式明确模块内处理流程，针对模块处理流程中的分支进行覆盖
修改模块接口处理流程：覆盖修改影响流程分支
-->
#### 3.1.3.1 单元测试
<!-- UT，主要是功能单元测试，测试对象是功能单元接口。UT测试设计要从黑盒（功能）角度设计，从输入(I)、处理（B）、预期输出（O）的角度进行用例分析设计，测试覆盖率仅作为反馈，用于分析哪些功能场景没有覆盖到，从而指导测试设计优化并补充测试用例 -->

| 组件名  | 用例类型 | 测试用例描述                                 | 用例名称                                  | 预置条件   | 操作步骤                                                     | 预期结果  |
| ------- | -------- | -------------------------------------------- | ----------------------------------------- | ---------- | ------------------------------------------------------------ | --------- |
| Storage | UT       | 测试获取SystemId成功                 | test_nvme_get_systemid | 打桩position和对应的硬盘背板 | 1.创建NVMe对象<br> 2.调用nvme.update_systemid<br>  | systemid与配置一致  |
| Storage | UT       | 测试创建EP成功 | test_nvme_create_endpoint | nvme支持mctp | 1.创建NVMe对象<br>2.调用create_endpoint接口 | 返回true |



#### 3.1.3.2 集成测试
<!-- IT，主要是组件/模块内的集成测试，测试对象是模块/组件接口。IT测试设计将模块/组件当作黑盒测试，IT测试用例中禁止对组件/模块内部代码打桩，如果确实有少量场景难以构造，可以考虑在测试框架中统一打桩并提供接口供测试用例调用构造场景。
说明：API测试属于IT，其测试对象是微服务接口。
PCST，是指PC上的服务集成测试，测试对象是功能需求。PCST测试设计，要覆盖正常功能、异常功能和交叉功能，采用灰盒 -->
不涉及