1.用户态NVMe运维利器 -- SPDK NVMe 字符设备
用户态NVMe运维利器 -- SPDK NVMe 字符设备
刘孝冬 Intel 高级软件工程师 专注于开源存储SPDK及ISA-L软件的码分开发。
随着数据中心规模的码分不断扩大与延展,硬件设备的码分运行维护已成为信息技术企业与部门普遍重视的一环。随之而来,码分是码分庞大的IT运维工作量。实现硬件设备的码分中源溯源码可维护,需要灵活高效的码分监控与管理工具。
在Linux中,码分有诸多监控与管理工具助力设备运维,码分如hdparm、码分ethtool、码分SmartCTL等;也有很多简单易用的码分element官方源码系统工具,如lspci、码分lsblk、码分iostat。码分对于目前部署量越来越大的NVMe设备,最通用有效的工具莫过于Nvme-cli。
通过Nvme-cli,使用者可以获取NVMe设备记录的各种LOG;查询当前设备状态;获取设备本身以及内部Namespace的配置信息;设置设备的各项功能;以及对设备做重启与格式化。
Nvme-cli在监控管理NVMe设备的主要过程,即是组织相关命令信息,通过对NVMe设备文件(/dev/nvmeX,/dev/nvmeXnY)发起IOCTL系统调用,将命令传入内核继而发送请求到NVMe设备上;待NVMe设备响应命令请求,lcn源码解析发回响应后,再提取有效响应信息出来。因此,Nvme-cli众多命令的普遍格式是:
SPDK是一组用于编写高性能、可扩展的用户模式存储应用程序的工具和库。其基础是处在用户空间,轮询模式、异步、无锁的NVMe驱动程序。这为从用户空间应用程序直接访问NvmeSSD提供了零拷贝、高度并行的python共享源码访问。在此基础上,SPDK还提供了完整的块堆栈作为用户空间库,该库能够执行与操作系统中块存储软件栈相同的许多操作,以及最上层的NVMe-oF、iSCSI和Vhost-user应用服务。
伴随着SPDK日益广泛的应用,NVMe设备的监控管理成为一个必要的需求。即处在用户空间应用程序的NVMe设备,如何能被用户监控管理。尤其是要便捷、容易通用,beego路由源码那就要求Linux下常用的工具也能被SPDK所支持,尤其是Nvme-cli。
之前,SPDK社区在Nvme-cli源码基础上,加入对特定于SPDK下NVMe设备的修改(github.com/spdk/nvme-cli...),使得Nvme-cli用在该类设备上。但该实现方式如同在Nvme-cli进程内启动了一个SPDK实例(如图1所示),难以被合并到Nvme-cli的主分支上。
用户自己编译与使用的过程略显繁琐(spdk.io/doc/nvme-cli.html...):
由于类似SPDK版的Nvme-cli使用上的诸多不便,社区在寻找更佳的实现方式,来支持Linux上相关工具。
在SPDK v. Release (spdk.io/release//...)中增加的一个新功能叫做NVMe字符设备 (NVMe character device)。它基于CUSE实现,可以在Linux内核中为NvmeController和Nvme Namespace创建对应字符设备节点(即 /dev/spdk/nvmeX,/dev/spdk/nvmeXnY)。Nvme-cli等工具可以无修改,直接使用这些模拟出的字符设备来监控管理SPDK下的NVMe设备。
由于此功能目前被认为是实验性的功能,所以需要在configure的时候,显式指定使能nvme-cuse,即在编译SPDK NVMe 驱动时,加入基于CUSE字符设备的支持。
SPDK为NVMe字符设备功能加入了两个RPC命令bdev_nvme_cuse_register与bdev_nvme_cuse_unregister。它们分别用于指定为某NVMe设备创建CUSE字符设备,和注销CUSE字符设备。当使用bdev_nvme_cuse_register RPC命令后,SPDK会通过CUSE在路径/dev/spdk下,为NVMe controller创建 /dev/spdk/nvmeX,并为其下Namespace创建 /dev/spdk/nvmeXnY,如图2。
之后,可见路径/dev/spdk下出现SPDK创建的NVMe字符设备:
nvme-cli使用指定的SPDK NVMe字符设备。目前,大多数的nvme-cli命令可以通过这种方式执行。
nvme /dev/spdk/nvme0 []
SPDK社区期望能够无缝地将当前流行的监控管理工具应用在SPDK下的NVMe设备上。当前实现的SPDK NVMe字符设备朝着这个目标迈进了一大步——诸多采用对NVMe字符设备路径文件发起IOCTL调用的工具和命令可以直接运行操作。
但它的依旧存在诸多局限性:
通过CUSE创建的NVMeNamespace路径文件属性是字符设备。但从常理上,其文件属性应该为块设备,例如Linux内核驱动创建的NVMeNamespace路径文件属性是块设备。虽然与IO命令不同,监控与管理操作不需要区分设备类型,但在Nvme-cli中如果操作设备指定的是NVMeNamespace文件,代码是存在多处诸如S_ISBLK这样的设备类型检查。
以下两图分别是SPDK通过CUSE创建的NVMe设备文件,和内核驱动创建的NVMe设备文件,对比可见NVMeNamespace路径文件属性的不同。
/proc/diskstats信息的缺失。诸多性能监控工具采用定期查看/proc/diskstats文件来获取存储设备的IO流量和负载情况。SPDK目前还未实现一个通用的信息注入方法,来将SPDK块设备或NVMe设备的相关信息实时写入/proc/diskstats。
SPDK当前的获取设备IO流量和负载信息的方法,是通过SPDK RPC 方法bdev_get_iostat。
/sys/block/目录下相关文件的缺失。部分工具,如lsblk,是需要通过筛选读取/sys/block/目录下设备文件,来获取相关信息;对/sys/block/目录下设备相关的某些文件,写入内容,来操作设备。SPDK目前也没有实现简洁有效的方法,模拟导出自己的/sys/block/文件。