# Storage

[TOC]

## 功能简介
1. Storage模块是独立组件管理存储组件，对内提供资源树功能接口，目前storage的版本信息在manifest/hardware子系统中
2. 信息获取：支持从带外或通过BMA获取控制器、硬盘、超级电容、逻辑盘、RAID组信息
3. 对外功能：支持创建、删除、设置逻辑盘；支持设置控制器功能；支持点硬盘定位灯
4. 故障检测：支持控制器健康状态检测、硬盘健康状态检测、逻辑盘健康状态检测以及超级电容健康状态检测
5. 支持RAID卡：当前支持1880RAID卡、博通RAID卡和PMC RAID卡

### 目录结构

```
├── src
│   ├── lualib
│   │   ├── add_event.lua                         --事件上报功能
│   │   ├── array                                 --阵列功能相关
│   │   ├── battery                               --电容功能相关
│   │   ├── bma                                   --直通盘及bma相关功能
│   │   ├── bus_monitor_service.lua               --smbios功能
│   │   ├── common_def.lua                        --公共宏定义
│   │   ├── controller                            --raid卡功能相关
│   │   ├── ctrl_commu_loss_monitor.lua           --raid卡通信丢失检测功能
│   │   ├── drive                                 --硬盘功能相关
│   │   ├── drives                                --硬盘组功能相关
│   │   ├── diagnose                              --误码诊断功能
│   │   ├── error_engine.lua                      --错误引擎功能
│   │   ├── handler                               --配置导入导出功能
│   │   ├── ipmi_service.lua                      --ipmi服务
│   │   ├── link_volume_array_drive_service.lua   --逻辑盘、阵列、物理盘关联功能
│   │   ├── mctp                                  --mctp服务
│   │   ├── method_misc.lua                       --misc服务
│   │   ├── metric_collect.lua                    --硬盘数据采集功能
│   │   ├── nvme                                  --nvme盘功能
│   │   ├── object_manager                        --业务对象相关功能
│   │   ├── os_patition                           --os分区
│   │   ├── pd                                    --硬盘定位功能
│   │   ├── rpc_services                          --rpc方法
│   │   ├── sas_phy
│   │   ├── sml                                   --sml库相关
│   │   ├── storage_app.lua                       --组件服务相关功能
│   │   ├── storage_bus.lua
│   │   ├── storage_mdb_object.lua
│   │   ├── storageconfig
│   │   ├── sync_task.lua                         --基础任务功能
│   │   ├── tasks.lua                             --基础任务功能
│   │   ├── task_service.lua                      --通用任务服务
│   │   └── volume                                --逻辑盘功能
│   ├── lualib-src
│   │   ├── CMakeLists.txt
│   │   └── l_sml                                 --sml服务
│   ├── service
│   │   ├── main.lua
│   │   └── smld.lua
```

## 关键特性

### 博通Raid卡带外管理介绍

（1）介绍

对博通卡进行带外管理时，我们要使用卡的驱动通过I2C与RAID卡进行通讯。在这个过程中，我们需要将BMC的I2C读写函数传递给RAID卡的驱动，供RAID卡的驱动进行调用。由于当前BMC的I2C通道由hwproxy模块进行统一管理，因此我们需要使用插件的方式实现支持I2C的读写。

（2）实现机制

因为BMC的I2C通信实现方式，因此我们引入插件(plugin)的方式来让存储模块使用在hwproxy管理下的I2C总线，下图描述了其中的关系

![简要描述](http://image.huawei.com/tiny-lts/v1/images/8133c9d04eab3c12416d6c036d5c2d87_692x433.png)

- 控制器对象实现具体的功能时，调用注册好的i2c芯片的PluginRequest方法，并传入插件名、函数名和函数参数，插件名用来寻找是哪个插件
- 找到对应的插件后，调用插件的run_cmd函数，创建一个Worker虚拟机，后续的操作都在虚拟机中实现，所以Plugin的协程可以先睡觉
- 在虚拟机中调用实际的sml库中的函数
- sml库中的函数需要使用i2c通信时，将i2c命令打包后使用skynet_send函数将消息发送给plugin所在的skynet服务，并由skynet暂停hwproxy的i2c轮询线程，优先处理当前的i2c通信请求
- 当三方库函数处理结束后，Worker虚拟机会将处理结果发送给plugin，同时唤醒Plugin的协程，并由plugin将信息返回给函数调用方

下图是具体的信息流图：

![信息流图](http://image.huawei.com/tiny-lts/v1/images/95b272538323e27cb3328e6db0b3ea17_1124x530.png)

### 1880及PMC Raid卡代管理介绍
（1）介绍

1880和PMC的raid卡采用MCTP方式和RAID卡进行通信实现带外管理。首先需要正常建立起MCTP链路后才能正常进行数据更新。

（2）实现机制
MCTP组件提供相关服务，将收发信息的接口注册到Storage组件，需要收发信息会组件会调用回调函数进行处理。
- Storage注册的回调接口为：do_mctp_writeread
- 回调函数注册流程：CMD.register_controller

### 通用Raid卡更新流程
下图是Raid卡的一般更新流程：
![image.png](http://image.huawei.com/tiny-lts/v1/images/hi3ms/af215f14f57ffc5b058eddf9a5f24fce_736x963.png@900-0-90-f.png)

## 对外接口

### 资源树接口

#### 控制器对外接口

##### bmc.kepler.Systems.Storage.Controller

```
NAME                                  TYPE      SIGNATURE RESULT/VALUE    FLAGS  description
.ClearForeignConfig                   method    a{ss}     -               -      一键清除外部配置
.ImportForeignConfig                  method    a{ss}     -               -      一键导入外部配置
.RestoreDefaultSettings               method    a{ss}     -               -      恢复默认设置
.SetBootDevices                       method    a{ss}ss   -               -      设置启动盘
.SetCopybackState                     method    a{ss}y    -               -      设置回拷开关
.SetJBODState                         method    a{ss}y    -               -      设置JBOD开关
.SetSmarterCopyBackState              method    a{ss}y    -               -      设置smrat信息错误回拷开关
.SetWorkMode                          method    a{ss}yy   -               -      设置控制器的工作模式
.DumpLog                              method    a{ss}     u               -      收集RAID控制器信息
```

##### bmc.kepler.Systems.Storage.Controller.ConsistencyCheck

```
NAME                                                   TYPE      SIGNATURE RESULT/VALUE FLAGS  description
.Disable                                               method    a{ss}     -            -      禁用
.Enable                                                method    a{ss}qyyu -            -      使能开关
.SetParameters                                         method    a{ss}qyy  -            -      设置参数
```

##### bmc.kepler.Systems.Storage.Controller.VolumeManage

```
NAME                                               TYPE      SIGNATURE            RESULT/VALUE                             FLAGS  description
.CreateCachecadeVolume                             method    a{ss}ayysyquyqy      u                                        -  创建cachecade逻辑盘
.CreateVolumeInExisingtArray                       method    a{ss}qyyysuyyyyyyyyy u                                        -  在现有阵列上创建逻辑盘
.CreateVolumeInNewArray                            method    a{ss}ayyysuyyyyyyyyy u                                        -  在新的阵列上创建逻辑盘
.DeleteVolume                                      method    a{ss}q               u                                        -  删除逻辑盘
```

#### 硬盘对外接口
##### bmc.kepler.Systems.Storage.Drives

```
NAME                                     TYPE      SIGNATURE RESULT/VALUE           FLAGS  description
.CollectIODeteriorationDiagInfo          method    a{ss}     u                      -      收集硬盘IO信息
.GetDrivesSubHealthDiagInfo              method    a{ss}y    aa{ua{ss}}             -      收集硬盘亚健康诊断信息
.SetDriveSubHealthDiagResult             method    a{ss}sq   -                      -      设置硬盘亚健康诊断结果
```

##### bmc.kepler.Systems.Storage.Drive

```
NAME                             TYPE      SIGNATURE RESULT/VALUE           FLAGS  description
.CryptoErase                     method    a{ss}     -                      -      加密擦除
.SetBootPriority                 method    a{ss}y    -                      -      设置启动优先级
.SetFaultIndicatorState          method    a{ss}y    -                      -      设置故障灯状态
.SetFirmwareStatus               method    a{ss}y    -                      -      设置固件状态
.SetHotspareType                 method    a{ss}yq   -                      -      设置热备盘
.SetLocationIndicatorState       method    a{ss}y    -                      -      设置定位灯状态
.SetPatrolState                  method    a{ss}y    -                      -      设置巡检状态
```

#### 逻辑盘对外接口

##### bmc.kepler.Systems.Storage.Volume

```
NAME                              TYPE      SIGNATURE RESULT/VALUE       FLAGS  description
.CancelForegroundInit             method    a{ss}     u                  -      取消前台初始化
.SetAccelerator                   method    a{ss}y    -                  -      设置加速方法
.SetAccessPolicy                  method    a{ss}y    -                  -      设置获取策略
.SetBGIEnable                     method    a{ss}y    -                  -      设置bgi使能
.SetBootable                      method    a{ss}y    -                  -      设置启动优先级
.SetCachecadeEnable               method    a{ss}y    -                  -      设置cache使能
.SetDiskCachePolicy               method    a{ss}y    -                  -      设置逻辑盘cache策略
.SetIOPolicy                      method    a{ss}y    -                  -      设置IO策略
.SetName                          method    a{ss}s    -                  -      设置名称
.SetReadPolicy                    method    a{ss}y    -                  -      设置读策略
.SetWritePolicy                   method    a{ss}y    -                  -      设置写策略
.SetCapacitySize                  method    a{ss}uy   -                  -      设置容量
.SetStripSize                     method    a{ss}y    -                  -      设置条带大小
```


### IPMI命令
- 具体详细请参考：mds/ipmi.json

```
└─/bmc
  └─/bmc/kepler
    ├─/bmc/kepler/IpmiCmds
    │ ├─/bmc/kepler/IpmiCmds/30
    │ │ ├─/bmc/kepler/IpmiCmds/30/92
    │ │ │ └─/bmc/kepler/IpmiCmds/30/92/SetRaidFaultStatus                 设置raid卡硬件故障
    │ │ └─/bmc/kepler/IpmiCmds/30/93
    │ │   ├─/bmc/kepler/IpmiCmds/30/93/CreateCachecadeLogicalDrive        创建CacheCade逻辑盘
    │ │   ├─/bmc/kepler/IpmiCmds/30/93/CreateLogicalDriveOnExistedArray   在已有的DiskArray上创建逻辑盘
    │ │   ├─/bmc/kepler/IpmiCmds/30/93/CreateLogicalDriveOnNewArray       在新的DiskArray上创建逻辑盘
    │ │   ├─/bmc/kepler/IpmiCmds/30/93/DeleteLogicalDrive                 删除指定的逻辑盘
    │ │   ├─/bmc/kepler/IpmiCmds/30/93/GetArrayInfo                       获取指定RAID控制器的Disk Array的信息
    │ │   ├─/bmc/kepler/IpmiCmds/30/93/GetArrayLds                        获取指定Array上的逻辑盘ID列表
    │ │   ├─/bmc/kepler/IpmiCmds/30/93/GetArrayLdsEx                      获取指定Array上的逻辑盘ID列表, ID是16bit数据
    │ │   ├─/bmc/kepler/IpmiCmds/30/93/GetArrayList                       查询指定RAID控制器下的DiskArray ID列表
    │ │   ├─/bmc/kepler/IpmiCmds/30/93/GetArrayPds                        获取指定Array的物理盘ID列表
    │ │   ├─/bmc/kepler/IpmiCmds/30/93/GetCachecadeAssociatedLds          查询CacheCade逻辑盘关联的普通逻辑盘ID列表
    │ │   ├─/bmc/kepler/IpmiCmds/30/93/GetCachecadeAssociatedLdsEx        查询CacheCade逻辑盘关联的普通逻辑盘ID列表(ID是16bit数据)
    │ │   ├─/bmc/kepler/IpmiCmds/30/93/GetControllerCapability            获取RAID带外管理能力
    │ │   ├─/bmc/kepler/IpmiCmds/30/93/GetControllerFwVersion             查询RAID控制器的Firmware版本信息
    │ │   ├─/bmc/kepler/IpmiCmds/30/93/GetControllerInfo                  查询RAID控制器的配置信息
    │ │   ├─/bmc/kepler/IpmiCmds/30/93/GetControllerList                  查询RAID控制器的ID列表
    │ │   ├─/bmc/kepler/IpmiCmds/30/93/GetControllerNvdataVersion         查询RAID控制器的NVDATA版本信息
    │ │   ├─/bmc/kepler/IpmiCmds/30/93/GetControllerPds                   查询指定RAID控制器管理的物理盘ID列表
    │ │   ├─/bmc/kepler/IpmiCmds/30/93/GetDiskManufacturer                查询指定物理盘厂商
    │ │   ├─/bmc/kepler/IpmiCmds/30/93/GetDiskSilk                        查询指定硬盘丝印信息
    │ │   ├─/bmc/kepler/IpmiCmds/30/93/GetHddPwrStatus                    查询硬盘的通电状态
    │ │   ├─/bmc/kepler/IpmiCmds/30/93/GetLogicalDriveList                查询RAID控制器下的逻辑盘ID列表
    │ │   ├─/bmc/kepler/IpmiCmds/30/93/GetLogicalDriveListEx              查询RAID控制器下的逻辑盘ID列表(ID为16bit数据)
    │ │   ├─/bmc/kepler/IpmiCmds/30/93/GetLogicalDrivePds                 查询指定逻辑盘的物理成员盘ID列表
    │ │   ├─/bmc/kepler/IpmiCmds/30/93/GetPhysicalDriveInfo               查询指定逻辑盘的基本信息
    │ │   ├─/bmc/kepler/IpmiCmds/30/93/GetPhysicalDriveLedStatus          查询硬盘灯状态
    │ │   ├─/bmc/kepler/IpmiCmds/30/93/GetPhysicalDriveLocation           查询指定物理盘的位置信息（丝印）
    │ │   ├─/bmc/kepler/IpmiCmds/30/93/GetRaidControllerTemp              查询raid控制器温度
    │ │   ├─/bmc/kepler/IpmiCmds/30/93/SetControllerCopyback              修改指定RAID控制器是否启用Copyback功能
    │ │   ├─/bmc/kepler/IpmiCmds/30/93/SetControllerJbod                  设置指定RAID控制器是否开启JBOD功能
    │ │   ├─/bmc/kepler/IpmiCmds/30/93/SetControllerOutofband             设置指定RIAD控制器是否支持带外管理
    │ │   ├─/bmc/kepler/IpmiCmds/30/93/SetControllerRestoreSettings       恢复指定RAID控制器到初始设置
    │ │   ├─/bmc/kepler/IpmiCmds/30/93/SetControllerSmarterCopyback       设置指定RAID控制器在检测到物理盘SMART错误之后是否自动进行Copyback
    │ │   ├─/bmc/kepler/IpmiCmds/30/93/SetFirmwareStatus                  设置固件状态
    │ │   ├─/bmc/kepler/IpmiCmds/30/93/SetHotspareType                    设置设备盘类型
    │ │   ├─/bmc/kepler/IpmiCmds/30/93/SetLocationIndicatorState          设置定位灯状态
    │ │   ├─/bmc/kepler/IpmiCmds/30/93/SetLogicDriveBootable              设置指定逻辑盘为启动盘
    │ │   ├─/bmc/kepler/IpmiCmds/30/93/SetLogicDriveRp                    设置指定逻辑盘的读策略
    │ │   ├─/bmc/kepler/IpmiCmds/30/93/SetLogicDriveWp                    设置指定逻辑盘的写策略
    │ │   ├─/bmc/kepler/IpmiCmds/30/93/SetLogicalDriveAP                  设置指定逻辑盘的访问策略
    │ │   ├─/bmc/kepler/IpmiCmds/30/93/SetLogicalDriveBGI                 设置指定逻辑盘的BGI使能状态
    │ │   ├─/bmc/kepler/IpmiCmds/30/93/SetLogicalDriveCachecade           设置指定逻辑盘是否关联CacheCade逻辑盘
    │ │   ├─/bmc/kepler/IpmiCmds/30/93/SetLogicalDriveDCP                 设置指定逻辑盘的Disk缓存策略
    │ │   ├─/bmc/kepler/IpmiCmds/30/93/SetLogicalDriveIOP                 设置指定逻辑盘的IO策略
    │ │   ├─/bmc/kepler/IpmiCmds/30/93/SetLogicalDriveName                设置逻辑盘名称
    │ │   └─/bmc/kepler/IpmiCmds/30/93/SetPdLogCollect                    主动触发硬盘日志收集
    │ └─/bmc/kepler/IpmiCmds/38
    │   └─/bmc/kepler/IpmiCmds/38/13
    │     ├─/bmc/kepler/IpmiCmds/38/13/GetNvmeInfo                        获取nvme盘信息
    │     └─/bmc/kepler/IpmiCmds/38/13/GetNvmeNum                         获取nvme盘数量
```

## 配置介绍

### 配置NVME盘
1.在硬盘背板上面配置"Connector_ComVPDConnect_x"对象，关键字段："Bom":"14140224", "Id":"VPD", "AuxId":"0"，固定配置。
2.跟据Bom+Id+AuxId组合找到对应的文件14140224_VPD_0.sr。
3.然后框架会进一步加载14140224_VPD_0.sr文件中定义2个对象：
- "Connector_ComVPD"对象，关键字段："Bom":"14140224","Id":"PROTOCOL","AuxId":"255"。
- "VirtualVPDConnect"对象，关键字段："RefVPDChip":"#/Chip_Virtual_SSD","RefConnector":"#/Connector_ComVPD"。

4.Storage组件会通过"VirtualVPDConnect"对象从NVME盘中读取协议信息并更新到"Connector_ComVPD"对象的"AuxId"上，用于表示NVME支持的具体协议。
- 支持协议有：NVME_VPD_PROTOCOL_NVME_MI = 0, NVME_VPD_PROTOCOL_SSD_FORM_FACTOR = 1, SAMSUNG_NVME_VPD_PROTOCOL_SSD_FORM_FACTOR = 2

5.更新之后，框架会进一步利用Bom+Id+AuxId组合来加载具体的协议文件，比如：14140224_PROTOCOL_0.sr，14140224_PROTOCOL_0_soft.sr
6.在14140224_PROTOCOL_0.sr中定义有具体的Nvme_1对象，也就是对应Storage的c_nvme对象。


