了解一下NVMe OF的initiator与target,搭建简单环境测试。 本文参考链接:https://www.cnblogs.com/JamesLi/p/11399054.html
NVMe OF分为initiator端与target端,由initiator端发起请求与target端NVM subsystem建立连接,进而实现initiator端远程访问target端NVM subsystem,常用访问协议有RDMA、TCP,本文讲解基于TCP传输协议的NVMe OF测试环境搭建。
想要简单了解RDMA的同学可以参考之前写的文章:https://blog.csdn.net/zz2633105/article/details/119519952?spm=1001.2014.3001.5501
准备工作
initiator端与target端一般为两个linux设备,但如果没有条件放一个设备也可以。这里所说的linux设备可以是真是的设备,也可以是虚拟机。
initiator端准备
1)安装nvme-cli:执行nvme list 命令,若提示未找到nvme 命令则自行安装,例如ubuntu系统执行apt install nvme-cli 。
2)加载nvme相关驱动:执行modprobe nvme_core 、modprobe nvme-fabrics 、modprobe nvme_tcp 命令,然后执行lsmod | grep nvme 命令,结果如下:
nvme_tcp 36864 0
nvme_fabrics 24576 1 nvme_tcp
nvme_core 126976 2 nvme_tcp,nvme_fabrics
执行ls /dev/nvme-fabrics 命令查看驱动是否加载成功,若存在节点,则驱动加载OK,常用的发行版linux系统都能支持,但如果嵌入式linux系统需要配置内核选项支持NVMe OF,配置如下:
CONFIG_NVME_CORE=y
CONFIG_BLK_DEV_NVME=y
CONFIG_NVME_FC=y
CONFIG_NVME_TCP=y
CONFIG_NVME_TARGET=y
target端准备
1)加载nvme相关驱动:modprobe nvmet 、modprobe nvme_tcp 命令,然后执行lsmod | grep nvme 命令,结果如下:
nvmet_tcp 28672 1
nvmet 126976 7 nvmet_tcp
nvme 49152 0
nvme_core 126976 2 nvmet,nvme
执行ls /sys/kernel/config/nvmet/ 命令查看驱动是否加载成功,若存在目录,则驱动加载OK,常用的发行版linux系统都能支持,但如果嵌入式linux系统需要配置内核选项支持NVMe OF,配置如下:
CONFIG_NVME_CORE=y
CONFIG_BLK_DEV_NVME=y
CONFIG_NVME_FC=y
CONFIG_NVME_TCP=y
CONFIG_NVME_TARGET=y
2)准备物理盘或虚拟盘
initiator端通过传输协议读写target端侧NVM子系统,而这个NVM子系统下可以挂真实NVMe盘,也可以STAT盘,甚至是虚拟盘,由于本文只是搭建测试环境,故采用虚拟盘形式。
随意找个目录,执行dd if=/dev/zero of=test.raw bs=1M count=0 seek=512 命令,再找个没有使用的loop号(可以执行ls /dev/loop* 查看,比如loop100),执行 losetup /dev/loop100 test.raw ,最后执行fdisk -l 命令查看是否加载设备成功,结果如下:
.......
Disk /dev/loop100: 512 MiB, 536870912 bytes, 1048576 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
若后续不使用了可以执行losetup -d /dev/loop100 移除设备。
target端操作
注意后续所有操作需要sudo权限
创建NVM subsystem
执行以下命令创建NVM subsystem
cd /sys/kernel/config/nvmet/subsystems
mkdir nqn.2014-08.org.nvmexpress.mytest
允许任何initiator访问NVM subsystem
执行以下命令
cd nqn.2014-08.org.nvmexpress.mytest
echo 1 > attr_allow_any_host
申请namespace id
任意选个NSID创建,比如
cd namespaces
mkdir 1
NSID绑定存储设备
绑定存储设备并使能,执行以下
cd 1
echo /dev/loop100 > device_path
echo 1 > enable
注意上面的loop100 就是上面创建的虚拟盘,如果有真实盘,则替换即可,比如echo /dev/nvme0n1 > device_path 或echo /dev/sda1 > device_path 。
创建NVMe over TCP的Transport层
cd /sys/kernel/config/nvmet/ports
mkdir 1234
cd 1234
echo tcp > addr_trtype
echo ipv4 > addr_adrfam
echo 192.168.11.49 > addr_traddr
echo 4420 > addr_trsvcid
即让target端监听192.168.11.49:4420 端口号,如果initiator与target都在同一设备上,则将ip 地址改为127.0.0.1 ,端口号不用变。
Transport层与NVM subsystem关联
cd subsystems
ln -s ../../../subsystems/nqn.2014-08.org.nvmexpress.mytest tcpsubsys
至此基于TCP传输协议的NVM subsystem已搭建好,等待initiator来连接即可。
initiator端操作
发现设备
Discovery Log Number of Records 1, Generation counter 2
=====Discovery Log Entry 0======
trtype: unrecognized
adrfam: ipv4
subtype: nvme subsystem
treq: unrecognized
portid: 1234
trsvcid: 4420
subnqn: nqn.2014-08.org.nvmexpress.mytest
traddr: 192.168.11.49
连接target
nvme connect -t tcp -a 192.168.11.49 -s 4420 -n nqn.2014-08.org.nvmexpress.mytest
然后执行nvme list命令查看结果
Node SN Model Namespace Usage Format FW Rev
---------------- -------------------- ---------------------------------------- --------- -------------------------- ---------------- --------
/dev/nvme0n1 CJH002000840 HUSMR7680BDP301 1 800.17 GB / 800.17 GB 4 KiB + 0 B KNGNP100
/dev/nvme1n1 ba63cc9987a6017b1980 Linux 1 536.87 MB / 536.87 MB 512 B + 0 B 5.15.59-
其中/dev/nvme1n1 是target在initiator端呈现的nvme设备。
测试
fio --name=global --direct=1 --norandommap --randrepeat=0 --ioengine=libaio --thread=1 --blocksize=4k --runtime=60 --time_based --rw=randread --numjobs=4 --iodepth=256 --group_reporting --size=100% --name=libaio_4_256_4k_randread --filename=/dev/nvme1n1
结果如下
libaio_4_256_4k_randread: (g=0): rw=randread, bs=(R) 4096B-4096B, (W) 4096B-4096B, (T) 4096B-4096B, ioengine=libaio, iodepth=256
...
fio-3.1
Starting 4 threads
Jobs: 4 (f=4): [r(4)][100.0%][r=107MiB/s,w=0KiB/s][r=27.4k,w=0 IOPS][eta 00m:00s]
libaio_4_256_4k_randread: (groupid=0, jobs=4): err= 0: pid=10160: Mon Oct 24 15:11:21 2022
read: IOPS=27.8k, BW=109MiB/s (114MB/s)(6525MiB/60019msec)
slat (nsec): min=684, max=269637k, avg=143300.55, stdev=874905.14
clat (usec): min=1223, max=576794, avg=36644.67, stdev=18842.86
lat (usec): min=1556, max=576795, avg=36787.99, stdev=18892.67
clat percentiles (msec):
| 1.00th=[ 13], 5.00th=[ 18], 10.00th=[ 21], 20.00th=[ 28],
| 30.00th=[ 33], 40.00th=[ 36], 50.00th=[ 36], 60.00th=[ 37],
| 70.00th=[ 37], 80.00th=[ 40], 90.00th=[ 52], 95.00th=[ 58],
| 99.00th=[ 94], 99.50th=[ 116], 99.90th=[ 292], 99.95th=[ 321],
| 99.99th=[ 355]
bw ( KiB/s): min= 2693, max=58664, per=25.00%, avg=27827.17, stdev=5516.23, samples=480
iops : min= 673, max=14666, avg=6956.75, stdev=1379.06, samples=480
lat (msec) : 2=0.01%, 4=0.01%, 10=0.42%, 20=8.77%, 50=80.30%
lat (msec) : 100=9.73%, 250=0.54%, 500=0.22%, 750=0.01%
cpu : usr=0.22%, sys=1.02%, ctx=468032, majf=0, minf=1028
IO depths : 1=0.1%, 2=0.1%, 4=0.1%, 8=0.1%, 16=0.1%, 32=0.1%, >=64=100.0%
submit : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
complete : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.1%
issued rwt: total=1670373,0,0, short=0,0,0, dropped=0,0,0
latency : target=0, window=0, percentile=100.00%, depth=256
Run status group 0 (all jobs):
READ: bw=109MiB/s (114MB/s), 109MiB/s-109MiB/s (114MB/s-114MB/s), io=6525MiB (6842MB), run=60019-60019msec
Disk stats (read/write):
nvme1n1: ios=0/0, merge=0/0, ticks=0/0, in_queue=0, util=0.00%
断开连接
NQN:nqn.2014-08.org.nvmexpress.mytest disconnected 1 controller(s)
卸载
initiator端不需要做什么,卸载工作都是target侧。注意,后续所有操作均需要sudo权限。
移除软连接
rm -rf /sys/kernel/config/nvmet/ports/1/subsystems/tcpsubsys
关闭使能解绑设备
echo 0 > /sys/kernel/config/nvmet/subsystems/nqn.2014-08.org.nvmexpress.mytest/namespaces/1/enable
echo -n 0 > /sys/kernel/config/nvmet/subsystems/nqn.2014-08.org.nvmexpress.mytest/namespaces/1/device_path
移除Transport层
rmdir --ignore-fail-on-non-empty /sys/kernel/config/nvmet/ports/1234
移除NVM subsystem
rmdir --ignore-fail-on-non-empty /sys/kernel/config/nvmet/subsystems/nqn.2014-08.org.nvmexpress.mytest/namespaces/1
rmdir --ignore-fail-on-non-empty /sys/kernel/config/nvmet/subsystems/nqn.2014-08.org.nvmexpress.mytest
注意:上面删除目录时使用的是rmdir 命令,而不是rm -rf 命令,这是为何?
细心的同学应该已经发现在我们之前执行mkdir 创建目录时,目录下面自动增加了很多属性和目录,这些新增的属性和目录是由内核驱动自动创建的并附有禁止删除权限!反过来,移除这些目录时候也必须触发内核驱动去移除新增的属性与目录!与mkdir 对应的命令时rmdir 而不是rm !
rm 与rmdir 差异可以看看这篇文章。
|