*openUBMC 支持注册生效任务时携带固件版本号和固件匹配信息详细设计说明书*

<table>
    <tr>
        <td>所属SIG组:</td>
        <td>hardware</td>
    </tr>
    <tr>
        <td>落入版本:</td>
        <td>26.0</td>
    </tr>
    <tr>
        <td>设计人员:</td>
        <td>lisongwei</td>
    </tr>
    <tr>
        <td>日期:</td>
        <td>2026/02/02</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>2026/02/07</td>
        <td>1.0</td>
        <td>支持注册生效任务时携带固件版本号和固件匹配信息</td>
        <td>lisongwei</td>
        <td>/</td>
    </tr>
</table>

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

<table>
    <tr>
        <th>Abbreviations 缩略语</th>
        <th>Full spelling 英文全名</th>
        <th>Chinese explanation 中文解释</th>
    </tr>
    <tr>
        <td>CPLD</td>
        <td>Complex Programmable Logic Device</td>
        <td>复杂可编程逻辑器件</td>
    </tr>
    <tr>
        <td>VRD</td>
        <td>Voltage Regulator Device</td>
        <td>电压调节器器件</td>
    </tr>
    <tr>
        <td>MCU</td>
        <td>Microcontroller Unit</td>
        <td>微控制器</td>
    </tr>
</table>

[TOC]

# 1.功能分析
## 1.1 功能背景
<!-- 描述该需求的来源或背景，比如：支撑XXX功能、XXX优化等；以及该需求对用户（含组件）带来什么具体价值，如果没有该需求，对用户（含组件）带来什么损失； -->
基础服务子系统新增固件生效控制机制，允许用户完成固件升级后，在生效前查询待生效固件的信息，从而决定是否需要生效固件。通用硬件为支撑该需求，需要在固件升级完成后注册生效任务时，新增注册字段，向基础服务子系统注册本次升级固件包的版本号以及匹配信息。

## 1.2 功能描述
<!-- 描述该需求交付的整体功能，主要实现XXX功能，解决XXX问题，明确方案如何实现 -->
当本组件进行固件升级操作时，需要在固件升级的process阶段将本次升级的固件包版本号以及执行了升级动作的固件信息保存下来。在固件升级的finish阶段，如果判断需要注册生效任务，则取出process阶段保存的信息，在注册生效任务新增注册固件版本号和固件匹配信息，把这些信息提供给基础服务。

## 1.3 功能场景
<!-- 描述该需求的业务使用场景，内容包括：
1) 场景出发条件及对象：什么角色/工具/接口等在什么具体情况下使用该特性，使用对象技能如何？
2) 使用时间及频度
3) 描述该特性主要有哪些场景、子场景及关键任务操作 -->

### 1.3.1 场景触发条件及对象
使用角色：系统管理员。使用工具：BMC前台网页。使用技能：具备基本的BMC管理经验。

### 1.3.2 使用时间及频度
基础服务子系统下发固件升级请求时，在升级流程中触发该判断逻辑。

### 1.3.3 主要场景及子场景
固件升级场景。

## 1.4 功能列表
<!-- 描述该需求交付的功能列表，内容包括：列出功能详细描述，标题、描述。 -->
| 功能编号 | 功能标题 | 功能描述 |
| ------- | ------- | -------- |
| 1 | 新增保存固件版本号和固件匹配信息的模块 | 新增代码模块，用于在process阶段保存固件版本号和固件匹配信息，并能够在finish阶段取出 |
| 2 | 注册生效任务时携带固件版本号和固件匹配信息 | 注册生效任务时，获取本次升级的固件版本号和固件匹配信息，注册给基础服务 |

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


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


#### 2.1.1.2 开发视图
<!-- 开发视图面向系统开发及软件管理，描述系统代码结构，构建结构的视图，主要解决系统技术实现和开发的问题，它依托逻辑视图，描述代码、构建结构 -->
```mermaid
graph TB
    subgraph A[BMC前台]
        A1[固件升级界面]
    end
    
    subgraph B[基础服务]
        B1[固件升级管理模块]
    end

    subgraph C[general_hardware组件]
        C1[固件升级信号订阅模块]
        C2[固件升级流程]
        C3[固件升级信息保存模块]
    end

    A1 --> B1
    B1 --> C1
    C1 --> C2
    C2 --> C3
    C3 --> C2
    C2 --> C1
    C1 --> B1
```


#### 2.1.1.3 运行视图
<!-- 运行视图面向系统运行，描述系统启动过程、运行期交互的视图，主要解决系统运行期交互，描述各可执行交付件在运行期的交互关系 -->
```mermaid
sequenceDiagram
    participant general_hardware as general_hardware组件
    participant firmware_mgmt as 基础服务

    firmware_mgmt->>general_hardware: 固件升级prepare阶段
    Note over general_hardware: 保持当前逻辑
    general_hardware-->>firmware_mgmt: 返回结果
    firmware_mgmt->>general_hardware: 固件升级process阶段
    Note over general_hardware: 清空固件升级信息保存模块的数据，保存固件包版本号信息
    Note over general_hardware: 升级固件，保存每个升级固件的信息
    general_hardware-->>firmware_mgmt: 返回结果
    firmware_mgmt->>general_hardware: 固件升级finish阶段
    Note over general_hardware: 从固件升级信息保存模块中取出固件包版本号和固件信息，注册生效任务
    general_hardware-->>firmware_mgmt: 返回结果
    firmware_mgmt->>general_hardware: 固件升级active阶段
    Note over general_hardware: 保持当前逻辑
    general_hardware-->>firmware_mgmt: 返回结果
```

### 2.1.2 内部依赖分析
<!-- 是否涉及与其他组件接口依赖，如果涉及需要确认当前是否已完成，是否匹配当前需求开发诉求 -->
本组件代码开发依赖基础服务修改固件生效任务注册接口的入参处理，能够处理新增的字段。

### 2.1.3 外部依赖分析
<!-- 是否涉及与平台SDK的依赖关系 -->
依赖hpm包中update.cfg文件的Firmware域新增Version字段。

### 2.1.4 北向接口分析
<!-- 需要分析当前功能是否有以下接口影响，如果有影响，则需要具体的补充影响点。其中注意点如下：
（1）如果有新增IPMI接口，请排查代码中IPMI命令注册的过滤字段，是否完全和IPMI命令的定义一致？
（2）新增一个接口时，需要咨询SIG组是否还有其他的接口受影响 
（3）新增接口需要将对应接口属性名称和属性值列出，属性值若有单位、异常值处理、范围限制或格式规范也需要列出，对于标准接口需要列出标准接口文档中对应的属性名称和属性值相关规定-->
| 特性 | SNMP | CLI | WEB | KVM_VMM | IPMI(RMCP/RMCP+) | HMM | Redfish |
| ---- | ---- | ---- | --- | ------ | ---------------- | --- | ------- |
| 通用硬件子系统支持业务侧下电和重启生效的固件在注册固件清单时携带相关信息 | NA | NA | NA | NA | NA | NA | NA |

### 2.1.5 兼容性分析
<!-- 当前的功能对现有在网的功能是否有影响，具体的影响点进行分析之后输出影响分析表格 -->
不涉及

### 2.1.6 定制化接口分析
<!-- 如果支持定制化设置，则需要给出定制化时的默认值（空定制化项条件下的设置值），如果涉及到定制化接口变更或新增，注意定制化接口文档需配套修改。注意定制化默认值变更对白牌包的影响 -->
不涉及

### 2.1.7 导入导出分析
<!-- 如果支持导入导出的配置，则需要分析导入导出的schema。 -->
不涉及

### 2.1.8 传感器分析
<!-- 如果需要新增传感器，则需要提前登记和评审新增的传感器要素。新增传感器评审需要上SIG-Interface进行评审 -->
不涉及

### 2.1.9 精准告警事件分析
<!-- 如果需要新增事件，则需要提前登记和评审新增的时间要素 -->
不涉及

### 2.1.10 系统锁定分析
<!-- 对外的接口或者命令是否支持系统锁定 -->
不涉及

### 2.1.11 用例场景分析
<!-- 以表格的形式输出该需求涉及的用例场景 -->

| 用例编号 | 用例名称 | 前置条件 | 操作步骤 | 预期结果 |
| ---- | ---- | ---- | ---- | ---- |
| 1 | 升级CPLD固件，配置固件版本号 | 1. BMC正常运行<br> 2. 准备CPLD固件包，固件包配置有当前固件的版本号 | 1. 登录BMC前台，升级CPLD固件包，观察升级结果，预期有结果a<br>2. 查看后台日志，预期有结果b | a. 固件升级成功<br> b. 日志中记录有注册固件版本号和固件匹配信息的记录，其中固件版本号和固件包中的版本号一致，固件匹配信息（ComponentID、SubComponentID、TargetUIDs）和当前实际升级的固件一致
| 2 | 升级CPLD固件，未配置固件版本号 | 1. BMC正常运行<br> 2. 准备CPLD固件包，固件包无当前固件的版本号 | 1. 登录BMC前台，升级CPLD固件包，观察升级结果，预期有结果a<br>2. 查看后台日志，预期有结果b | a. 固件升级成功<br> b. 日志中记录有注册固件版本号和固件匹配信息的记录，其中固件版本号为空，固件匹配信息（ComponentID、SubComponentID、TargetUIDs）和当前实际升级的固件一致
| 3 | 升级VRD固件，配置固件版本号 | 1. BMC正常运行<br> 2. 准备VRD固件包，固件包配置有当前固件的版本号 | 1. 登录BMC前台，升级VRD固件包，观察升级结果，预期有结果a<br>2. 查看后台日志，预期有结果b | a. 固件升级成功<br> b. 日志中记录有注册固件版本号和固件匹配信息的记录，其中固件版本号和固件包中的版本号一致，固件匹配信息（ComponentID、SubComponentID、TargetUIDs）和当前实际升级的固件一致
| 4 | 升级VRD固件，未配置固件版本号 | 1. BMC正常运行<br> 2. 准备VRD固件包，固件包无当前固件的版本号 | 1. 登录BMC前台，升级VRD固件包，观察升级结果，预期有结果a<br>2. 查看后台日志，预期有结果b | a. 固件升级成功<br> b. 日志中记录有注册固件版本号和固件匹配信息的记录，其中固件版本号为空，固件匹配信息（ComponentID、SubComponentID、TargetUIDs）和当前实际升级的固件一致
| 5 | 升级MCU固件 | 1. BMC正常运行<br> 2. 准备MCU固件包 | 1. 登录BMC前台，升级MCU固件包，观察升级结果，预期有结果a<br>2. 查看后台日志，预期有结果b | a. 固件升级成功<br> b. 日志中无生效任务注册

### 2.1.12 装备能力差异分析
<!-- 当前功能是否在装备版本和Release版本中存在能力差异，若有差异需要进行说明 -->
不涉及

### 2.1.13 持久化分析
<!-- 当前的功能是否涉及持久化，尤其是持久化类型变更或某个属性新增了取值，是否兼容老版本 -->
不涉及

## 2.2 非功能质量属性设计
### 2.2.1 扩展性分析
<!-- 考虑后续新增类似功能可以很好地扩展 -->
不涉及

### 2.2.2 重用性分析
<!-- 是否为通用处理方式、接口，如果是得考虑重用性 -->
本方案开发的保存固件版本号和固件匹配信息模块是通用模块，该模块可为所有种类的固件使用，具有良好重用性。未来其他种类的固件需要适配类似需求时，无需重复开发代码，可以直接使用该模块实现保存信息的功能。

### 2.2.3 可测试性分析
<!-- 此需求如何验证，是否可直接验证，or通过XXX功能覆盖验证，or需要单独怎加测试接口验证 -->
本方案开发的代码可以通过前台上传驱动包进行升级，之后观察升级结果，并且在后台读取基础服务的日志进行验证。

### 2.2.4 资料分析
<!-- 是否涉及资料修改 -->
不涉及

### 2.2.5 资源使用分析
<!-- 新增线程、内存分配、模型属性名长度是否合理，CPU占用率是否会激增，Flash中新增文件是否合理（频繁读写Flash会大幅缩短emmc寿命）；是否涉及消息队列，如果涉及请检查是否存在某些场景下消息队列会满导致消息丢失，例如大量消息发送到队列且处理消息需要耗费较长时间的场景。 -->
不涉及

### 2.2.6 可靠性分析
| 编号 | 场景 | 问题描述 | 可靠性影响 | 问题级别 | 建议解决方案/需求 | 讨论结果 | 跟踪人 | 备注 |
| --- | --- | --- | --- | --- | --- | --- | --- | --- |
| 1 | 固件升级，固件包为旧版本，无Version字段 | 解析cfg文件时，无法获取Version属性 | 注册生效任务时，版本号字段为空 | 一般 | 代码中不区分该情况，将空值注册给基础服务，由基础服务对该情况进行处理。

### 2.2.7 安全性分析
| 安全合规项 | 是否涉及 | 现有的防护措施 |
| --- | --- | --- |
| 访问控制（通道、文件权限、用户权限、查询权限、配置权限、接口权限） | 不涉及 |  |
| 敏感数据 | 不涉及 |  |
| 日志（操作日志、维护日志、安全日志、运行日志） | 不涉及 |  |
| 文档 | 不涉及 |  |
| 加密及算法 | 不涉及 |  |
| 新增关键资源（密钥、证书、关键配置）备份、恢复 | 不涉及 |  |
| 新增对外接口入参校验 | 不涉及 |  |
| 新增开源及三方软件引入 | 不涉及 |  |
# 3.功能实现
<!-- 通过表格、流程图、简明文字描述提供，力求容易看懂、容易实现，详细描述细节。 -->
## 3.1 新增保存固件版本号和固件匹配信息的模块
### 3.1.1 功能实现设计
当前升级流程架构中，固件升级的各个阶段（prepare、process、finish、active）通过基础服务下发信号进行控制，本组件内部无法感知各个阶段之间的关联性。注册生效任务的流程在finish阶段发生，但是能够获取到固件版本和固件匹配信息的时机在process阶段发生。因此需要新增一个功能模块`fw_info_collector`，该模块用于在process阶段保存本次升级的固件版本和固件匹配信息，并提供读取接口，在finish阶段获取保存的信息。
### 3.1.2 功能详细设计
`fw_info_collector`设计是能够为所有种类的固件提供服务的。例如当CPLD和VRD固件同时升级时，这两种固件的升级流程均会使用该模块保存信息，需要保证两种固件各自保存的信息互不影响。为此，`fw_info_collector`所提供的各种读写接口需要带有入参`firmware_type`，以固件类型作为区分，分别保存各种固件升级时的信息，以防出现某种固件覆盖了其他固件保存信息的情况。同时，每次升级流程开始时，都需要清空上一次升级过程中保存的信息，防止遗留的信息被下一次升级流程中误读出。基于以上功能分析和可靠性分析，该模块需要提供的接口如下：

| 接口名 | 入参 | 功能 |
| ---- | ---- | ---- |
| clean | firmware_type | 清空`firmware_type`对应固件种类的保存信息 |
| insert_fw_info | firmware_type, fw_info | 向`firmware_type`对应固件种类中保存一个固件对象`fw_info` |
| insert_hpm_version | firmware_type, hpm_version | 向`firmware_type`对应固件种类中保存固件包版本号信息`hpm_version` |
| get_register_info_from_fw_info_list | firmware_type | 从`firmware_type`对应固件种类中取出固件列表，从中获取固件匹配信息并返回 |
| get_hpm_version | firmware_type | 从`firmware_type`对应固件种类中取出固件包版本号信息并返回 |
### 3.1.3 开发者测试
<!--
增加模块接口：以活动图/流程图等形式明确模块内处理流程，针对模块处理流程中的分支进行覆盖
修改模块接口处理流程：覆盖修改影响流程分支
-->
#### 3.1.3.1 单元测试
<!-- UT，主要是功能单元测试，测试对象是功能单元接口。UT测试设计要从黑盒（功能）角度设计，从输入(I)、处理（B）、预期输出（O）的角度进行用例分析设计，测试覆盖率仅作为反馈，用于分析哪些功能场景没有覆盖到，从而指导测试设计优化并补充测试用例 -->
`fw_info_collector`模块新增单元测试，用于测试各个接口功能的正确性：

| 组件名 | 用例类型 | 测试用例描述 | 用例名称 | 预置条件 | 操作步骤 | 预期结果 |
| ---- | ---- | ---- | ---- | ---- | ---- | ---- |
| general_hardware | UT | 向fw_info_collector模块中新增固件对象 | test_insert_fw_info | 无 | 调用insert_fw_info接口向fw_info_collector模块中新增固件对象 | 预期新增成功，存入的component_id/component_id_ex/uid属性值正确 |
| general_hardware | UT | 向fw_info_collector模块中新增固件版本号 | test_insert_hpm_version | 无 | 调用insert_hpm_version接口向fw_info_collector模块中新增固件版本号 | 预期新增成功，存入的hpm_version属性值正确 |
| general_hardware | UT | 向fw_info_collector模块中新增多个固件信息，之后读取 | test_get_all_value_from_fw_info_list | 无 | 1. 调用insert_fw_info接口向fw_info_collector模块中新增多个固件对象，其中包含多种固件类型，每种固件类型下有多个对象<br>2. 调用get_register_info_from_fw_info_list接口取出固件信息，检查取出的结果 | 预期取出的结果正确，多种固件之间component_id/component_id_ex/uid属性值没有互相影响 |
| general_hardware | UT | 向fw_info_collector模块中新增固件版本号，之后读取 | test_get_hpm_version | 无 | 1. 调用insert_hpm_version接口向fw_info_collector模块中新增固件版本号<br>2. 调用get_hpm_version接口取出版本号，检查取出的结果 | 预期取出的版本号和存入的版本号一致 |
#### 3.1.3.2 集成测试
<!-- IT，主要是组件/模块内的集成测试，测试对象是模块/组件接口。IT测试设计将模块/组件当作黑盒测试，IT测试用例中禁止对组件/模块内部代码打桩，如果确实有少量场景难以构造，可以考虑在测试框架中统一打桩并提供接口供测试用例调用构造场景。
说明：API测试属于IT，其测试对象是微服务接口。
PCST，是指PC上的服务集成测试，测试对象是功能需求。PCST测试设计，要覆盖正常功能、异常功能和交叉功能，采用灰盒 -->
不涉及

## 3.2 注册生效任务时携带固件版本号和固件匹配信息
### 3.2.1 功能实现设计
基于以上`fw_info_collector`模块，固件升级的具体流程可以调用该模块，在process阶段中使用保存接口存储本次升级的版本号和固件信息，在finish阶段使用获取接口取出保存的信息。根据需求需要，当前需要CPLD和VRD固件支持新增注册这些属性的功能，因此这两种固件的升级流程中需要新增调用`fw_info_collector`的保存与读取流程。
### 3.2.2 功能详细设计
分别修改CPLD和VRD固件升级的process阶段和finish阶段。在process阶段中，固件升级开始前首先调用`clean`接口，清除`fw_info_collector`之前保存的固件升级信息，之后调用`insert_hpm_version`接口，并从基础服务下发的入参中获取当前固件包的版本号，存入`fw_info_collector`。在process阶段的后期流程，代码会遍历单板上的固件对象，并用对象的uid属性和固件包中的uid属性进行对比，判断哪些固件需要升级。当一个固件对象的uid和固件包中的属性一致时，此处需要新增流程，调用`insert_fw_info`接口，将当前遍历到的固件信息保存下来，之后再进行升级的其他动作。

在finish阶段中，如果判断当前固件不能立刻生效，需要注册生效任务，则在注册生效任务的流程中调用`get_all_value_from_fw_info_list`和`get_hpm_version`接口，获取固件的component_id、component_id_ex、uid属性，以及固件包的Version属性，分别作为ComponentID、SubComponentID、TargetUIDs、TargetVersion属性注册给基础服务。此外，无论finish阶段是否需要执行注册流程，均无需清除`fw_info_collector`中的内容。该模块中的内容会在固件下一次升级时由进入流程的`clean`接口调用清除。

### 3.2.3 开发者测试
<!--
增加模块接口：以活动图/流程图等形式明确模块内处理流程，针对模块处理流程中的分支进行覆盖
修改模块接口处理流程：覆盖修改影响流程分支
-->
#### 3.2.3.1 单元测试
<!-- UT，主要是功能单元测试，测试对象是功能单元接口。UT测试设计要从黑盒（功能）角度设计，从输入(I)、处理（B）、预期输出（O）的角度进行用例分析设计，测试覆盖率仅作为反馈，用于分析哪些功能场景没有覆盖到，从而指导测试设计优化并补充测试用例 -->
测试调用`fw_info_collector`的接口进行写入或读取操作时，写入/读取的值符合预期：
| 组件名 | 用例类型 | 测试用例描述 | 用例名称 | 预置条件 | 操作步骤 | 预期结果 |
| ---- | ---- | ---- | ---- | ---- | ---- | ---- |
| general_hardware | UT | 调用CPLD升级流程，检查取出的固件信息正确 | test_upgrade_finish_callback_register | 无 | 1. 调用CPLD升级的upgrade_process_callback接口写入信息<br>2. 调用CPLD升级的upgrade_finfish_callback接口<br>3. 检查向基础服务注册的固件信息 | 预期注册的固件信息与升级的固件一致 |
| general_hardware | UT | 调用VRD升级流程，检查取出的固件信息正确 | test_upgrade_vrd | 无 | 1. 调用VRD升级的on_upgrade_process接口写入信息<br>2. 调用VRD升级的on_upgrade_finish接口<br>3. 检查向基础服务注册的固件信息 | 预期注册的固件信息与升级的固件一致 |
#### 3.2.3.2 集成测试
<!-- IT，主要是组件/模块内的集成测试，测试对象是模块/组件接口。IT测试设计将模块/组件当作黑盒测试，IT测试用例中禁止对组件/模块内部代码打桩，如果确实有少量场景难以构造，可以考虑在测试框架中统一打桩并提供接口供测试用例调用构造场景。
说明：API测试属于IT，其测试对象是微服务接口。
PCST，是指PC上的服务集成测试，测试对象是功能需求。PCST测试设计，要覆盖正常功能、异常功能和交叉功能，采用灰盒 -->
不涉及