众所周知,在一个存储系统中,将设备管理与业务分离是一个良好的设计,比如在Nvme协议中就有一个Admin命令集,与IO命令分开。为了能够更规范合理得对NVMe SSD进行管理,NVMe-MI协议应运而生。
Nvme-MI(Management Interface),定义了一套完整的NVMe SSD管理方式,独立于NVMe协议且为NVMe服务。目前支持NVMe-MI协议的SSD比较少,支持产品见https://www.iol.unh.edu/registry/nvme-mi。在2015年10月,NVMe-MI 1.0版本正式发布,当前最新的为2019年4月发布的1.1版本,本文基于1.0版本对NVMe-MI协议进行阐述。
知道NVMe-MI的作用后,我们先从宏观角度看一下它是怎么实现的。与NVMe协议不同,NVMe-MI协议是通过MCTP协议进行传输,同时底层物理层支持PCIe或者SMBus/I2C,本文后续默认物理层都是SMBus/I2C。物理层使用I2C的好处就是和NVMe协议分离,即使SSD在NVMe看来是故障的,还能有另外一条路径查看SSD状态。
从整个协议栈我们可以想象出一次完整的MI命令执行过程:
- host将发送消息按照MI的协议规范组成MI报文;
- 将MI报文当作MCTP的数据封装为MCTP报文;
- 完整的MCTP报文通过I2C链路发给SSD;
- SSD收到MCTP报文后,解封MCTP报文得到MI报文;
- 解析MI报文后获取发送消息,然后将要回复的数据按照MI协议规范组成MI报文;
- 再将回复MI报文当作MCTP的数据封装为MCTP报文;
- 再将MCTP报文通过I2C链路发送给host;
- host解封MCTP报文,再解析MI报文获取回复消息。
在整个过程中,我们具体来看一下MI报文是怎么一回事,至于过程中涉及的MCTP协议,I2C协议可自行查看相关协议文档。
一个完整MI报文分为3部分,Header,Data和IC(Integrity Check)
Header:总共4个字节,主要指明该MI消息的类型;
Data:MI消息的具体数据,数据格式和大小因Header里面指明的类型不同而不同;
IC:总4个字节,Header和Data的CRC校验值,使用的是CRC-32C算法。
MI报文分类如下图所示,我们直接看到最下面的叶子节点,总共有6个,这也意味这MI报文有6种格式,这6种格式就具体体现在MI报文的Data里面。
我们再来看一下这6种MI报文格式,具体命令参考协议。
1)NVMe-MI Command:定义了获取NVMe SSD设备状态命令。
2)NVMe Admin Command:用MI协议规范模拟封装NVMe命令
3)PCIe Command:用MI协议规范模拟封装PCIe报文
4)Control Primitive:控制MI命令执行
5)Success Response:成功返回MI消息,通常带数据返回,每个命令的返回都不一样,详细见具体命令。
6)Error Response:失败返回MI消息,无数据,只有错误类型。
NVMe-MI协议整体就是这么一回事,并没有想象中的那么复杂。顺便值得一提的是,在协议的附录A这一章节,提到了NVMe Basic Management Command,这一方式是早期没有NVMe-MI协议时,通过I2C对SSD进行管理的方式,但该方式已经无法满足如今快速发展的NVMe SSD,因此协议强烈建议各SSD厂商转向使用NVMe-MI协议来对盘进行带外管理。