【学习笔记】SPDK(二):SPDK NVMe over RDMA 部署
记录 SPDK NVMe over RDMA 的部署过程。
环境准备
Ubuntu 22.04 虚拟机 x2
dev1,作为 Host 端,ip:192.168.246.129
dev2,作为 Target 端,ip:192.168.246.130
dev2 可以在 dev1 环境准备完成后进行 clone
2 块虚拟硬盘:
SATA:用于安装 Ubuntu
NVMe:用于绑定 spdk
NVMe 硬盘不需要挂载和格式化 ,lsblk
结果如下: 1 2 3 4 5 6 7 8 sda 8:0 0 60G 0 disk ├─sda1 8:1 0 1M 0 part ├─sda2 8:2 0 513M 0 part /boot/efi └─sda3 8:3 0 59.5G 0 part /var/snap/firefox common/ host-hunspell / nvme0n1 259:0 0 20G 0 disk
文件准备
需要下载的文件:(严格控制版本,不同版本可能会导致很多错误)
安装与构建
clone 项目源码
1 2 3 4 5 6 git clone -b v24.05.x git@github.com:spdk/spdk.git
更新子模块
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 git submodule update --init
安装依赖
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 sudo ./scripts/pkgdep.sh -r pip3 install ninja -i https://pypi.doubanio.com/simple pip3 install meson -i https://pypi.doubanio.com/simple pip3 install pyelftools -i https://pypi.doubanio.com/simple pip3 install ijson -i https://pypi.doubanio.com/simple pip3 install python-magic -i https://pypi.doubanio.com/simple pip3 install grpcio -i https://pypi.doubanio.com/simple pip3 install grpcio-tools -i https://pypi.doubanio.com/simple pip3 install pyyaml -i https://pypi.doubanio.com/simple pip3 install Jinja2 -i https://pypi.doubanio.com/simple pip3 install tabulate -i https://pypi.doubanio.com/simple
打上 patch、修改代码
开发者说明 master
分支已经整合该 patch
,v24.05.x
还未整合。
位于 lib/log/log.c
。添加和修改以下代码(共 3 处):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 void spdk_vlog (enum spdk_log_level level, const char *file, const int line, const char *func, const char *format, va_list ap) { int severity = LOG_INFO; char *buf, _buf[MAX_TMPBUF], *ext_buf = NULL ; char timestamp[64 ]; va_list ap_copy; int rc; if (g_log) { g_log(level, file, line, func, format, ap); return ; } if (level > g_spdk_log_print_level && level > g_spdk_log_level) { return ; } severity = spdk_log_to_syslog_level(level); if (severity < 0 ) { return ; } buf = _buf; va_copy(ap_copy, ap); rc = vsnprintf(_buf, sizeof (_buf), format, ap); if (rc > MAX_TMPBUF) { rc = vasprintf(&ext_buf, format, ap_copy); if (rc < 0 ) { } else { buf = ext_buf; } } if (level <= g_spdk_log_print_level) { get_timestamp_prefix(timestamp, sizeof (timestamp)); if (file) {
构建项目
1 2 3 ./configure --with-rdma --enable-debug make
执行单元测试
1 2 3 4 5 6 7 8 ./test/unit/unittest.sh
绑定 NVMe 设备
绑定 NVMe 设备:
1 2 3 4 5 6 7 8 9 10 11 ./scripts/setup.sh ./scripts/setup.sh status
则绑定成功。lsblk
中看不到 NVMe 设备。
若输出结果为:
1 0000:03:00.0 (15ad 07f0): Active devices: mount@nvme0n1:nvme0n1, so not binding PCI dev
且运行 build/examples/hello_world
,若出现以下结果:
1 2 3 4 5 ./build/examples/hello_world
说明没有 NVMe 设备或者 NVMe 设备处于挂载状态,无法解除内核驱动,此时需要将该设备初始化或者其他的方法。
添加 NVMe 设备后,NVMe 设备不能处于挂载状态,lsblk
结果:
1 2 3 4 5 6 7 8 sda 8:0 0 60G 0 disk ├─sda1 8:1 0 1M 0 part ├─sda2 8:2 0 513M 0 part /boot/efi └─sda3 8:3 0 59.5G 0 part /var/snap/firefox common/host-hunspell / nvme0n1 259:0 0 50G 0 disk
再次绑定后测试,出现正确结果则成功。
取消绑定
1 ./scripts/setup.sh reset
部署 RDMA Soft-RoCE
参考 【学习笔记】NVMeoF(二):NVMe over RDMA 环境部署 部署 RDMA 部分,部署好 RDMA Soft RoCE 软件栈。
仅部署 RDMA 部分,sh 脚本中从 # 1. config nvme subsystem
后的代码全部注释掉。
重启后需要重新部署一遍 RDMA 软件栈。
这部分结束可以对 dev1 进行克隆。
配置 SPDK NVMe over RDMA Target 端
Target 端 ip:192.168.246.130
。
运行 nvmeof-setup.sh 脚本部署 RDMA Soft-RoCE
绑定 NVMe SSD 设备
1 2 3 4 5 6 7 8 9 10 11 ./scripts/setup.sh ./scripts/setup.sh status
这个 BDF 0000:0b:00.0
可能会变化,需要记住。
给 SPDK 分配大页(非必须)
1 2 3 4 5 echo 32768 | tee /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepagesmkdir /dev/hugepages_2mbmount -t hugetlbfs none /dev/hugepages_2mb -o pagesize=2MB
启动 tgt 并监听
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 build/bin/nvmf_tgt & scripts/rpc.py nvmf_create_transport -t RDMA -u 8192 -i 131072 -c 8192 ./scripts/rpc.py bdev_nvme_attach_controller -b NVMe1 -t PCIe -a 0000:0b:00.0 ./scripts/rpc.py nvmf_create_subsystem nqn.2016-06.io.spdk:cnode1 -a -s SPDK00000000000001 -d SPDK_Controller1 ./scripts/rpc.py nvmf_subsystem_add_ns nqn.2016-06.io.spdk:cnode1 NVMe1n1 ./scripts/rpc.py nvmf_subsystem_add_listener nqn.2016-06.io.spdk:cnode1 -t rdma -a 192.168.246.130 -s 4420 再加一个ns ./scripts/rpc.py bdev_nvme_attach_controller -b NVMe2 -t PCIe -a 0000:0b:00.0 ./scripts/rpc.py nvmf_subsystem_add_ns nqn.2016-06.io.spdk:cnode1 NVMe2n1 ./scripts/rpc.py nvmf_get_subsystems ./scripts/rpc.py nvmf_delete_subsystem nqn.2016-06.io.spdk:cnode1 ./scripts/rpc.py nvmf_remove_ns <nsid> ./scripts/rpc.py nvmf_subsystem_remove_listener nqn.2016-06.io.spdk:cnode1 -t rdma -a 192.168.246.130 -s 4420
配置 SPDK NVMe over RDMA Host 端
Host 端 ip:192.168.246.129
。
运行 nvmeof-setup.sh 脚本部署 RDMA Soft-RoCE
SPDK 初始化
发现 Target 并连接(与 SPDK 无关)
这一步执行的是 nvme-cli
的命令,需要经过 kernel 驱动,而 SPDK 是用户态驱动。可以直接跳过这一步直接运行 SPDK 的应用程序。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 nvme discover -t rdma -a 192.168.246.130 -s 4420 nvme connect -t rdma -n "nqn.2016-06.io.spdk:cnode1" -a 192.168.246.130 -s 4420 nvme list lsblk
简单测试
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 ./build/bin/spdk_nvme_perf -r 'trtype:rdma adrfam:IPv4 traddr:192.168.246.130 trsvcid:4420' -q 256 -o 4096 -w randread -t 100
测试结果图:
这里测试结果的值较低,可能是因为虚拟机的缘故?
取消连接(与 SPDK 无关)
如果执行了前面的 nvme connect
命令连接设备,则这里执行 nvme disconnect
命令取消连接。
1 nvme disconnect -n "nqn.2016-06.io.spdk:cnode1"
恢复内核态驱动
1 ./scripts/setup.sh reset