共建开源生态——DapuStor对linux kernel问题的一次修复
“Linux Kernel 是 Linux 操作系统的核心部分,负责管理硬件资源并为软件提供底层服务。它充当操作系统与硬件之间的桥梁,确保各种应用程序能够有效地使用系统资源,如CPU、内存、存储设备、网络接口等。
在 Linux Kernel 中,NVMe 协议的 E2E(端到端)数据保护功能具有以下作用:它通过为数据块添加保护信息(通常是CRC和地址信息),如果检测到错误,系统可以修复或重新传输数据,确保数据的准确性和可靠性。这种保护机制对高性能、高可靠性的存储系统至关重要。”
日前,DapuStor在使用linux 6.2.0以及以上版本中进行测试,发现并解决的一个高版本linux kernel引入问题。此问题解决方案已经被开源团队评审并采纳,目前已经合入到linux kernel最新源码仓。
此次合入修复了该问题(https://github.com/torvalds/linux/commit/9570a48847e3acfa1a741cef431c923325ddc637)
01 在linux操作系统中测试嵘神6时发现问题
基于数据保护信息在IO路径中存放的位置,端到端数据保护功能分为dif及dix两种模式。在DapuStor使用新版本内核的linux操作系统进行测试的时候 ,发现dix模式下对设备进行读写的时候存在异常报错。
报错信息如下所示:
经过现场分析盘片日志中收到的问题IO命令发现,在DIX模式下,盘片收到的元数据(元数据中存放有数据保护信息)的长度为0。DIX模式下,设备需要meta_len获取到元数据的实际长度,在元数据长度为0的场景中,会导致获取元数据异常,导致命令失败。
02 DapuStor工程师的解决方案
因为这个问题在当前内核是必现问题,通过对不同内核比对测试,以及对正常和异常环境的nvme-cli工具交换测试发现,该缺陷非工具问题,而是一个在6.2.0内核版本引入的内核问题。
● 分析内核代码,内核通过ns->features字段标识此设备属于dix还是dif数据格式。其中dif格式为NVMe_NS_EXT_LBAS,dix格式为NVMe_NS_METADATA_SUPPORTED。
● 在使用nvme-cli工具对DIX格式的SSD下发nvme write命令时,我们发现驱动会将元数据长度(meta_len)修改为0,即驱动代码逻辑始终进入if分支(驱动将盘始终识别为DIF格式),最终导致驱动将错误的IO参数下发给SSD。
● 继续分析驱动为何将DIX/DIF格式的盘片全部标记为DIF格式。我们发现驱动在标记盘片feature时,使用如下枚举:
根据驱动逻辑:
● 因此,当盘片支持DEAC时,ns->features的bit0和bit1被置1,此后在处理DIX/DIF时,驱动逻辑优先校验盘片是否为DIF(NVME_NS_EXT_LBAS),即校验ns->features的bit0是否置1,因盘片支持DEAC,ns->features的bit0和bit1已经被置1,因此驱动标记盘片始终为DIF格式。
追溯内核代码,最终发现内核6.2.0中引入驱动对DEAC的支持,驱动对DEAC枚举赋值时覆盖了DIF和DIX的feature值。DapuStor工程师使用新的枚举值替换原值以修复此问题。
引入此问题的提交
● 此问题在6.2.0版本被引入,6.10.0版本被DapuStor修复。
DapuStor积极共建开源生态
DapuStor一直是开源技术的支持者,已加入阿里云 PolarDB、OCP、龙蜥、openKylin 等多个开源社区。开源的平台让我们受益于全球工程师们的成果分享和贡献,同时 DapuStor也作为开源生态的参与者和贡献者,希望未来继续以领先的技术和开放的姿态拥抱数字时代的新价值,与行业擦出更多创新的火花,构建繁荣的开放生态体系。