NVMe over TCP

マシン2台で直結のテスト環境作ったので忘れないうちにメモしておく。

カーネル5.0からNVMe TCPがサポートされた。 f:id:mailstop:20191118023553p:plain

Ubuntu 18.04.03やFedora 31ではモジュール化されている。一応モジュールがあるか確認し、ロードする。モジュールになっていないディストリビューションの場合は構成を確認し、必要に応じてカーネルを再コンパイルする。

まずはターゲット側マシン。

# find /lib/modules/5.3.11-300.fc31.x86_64/kernel/drivers/nvme/ -name nvme*
/lib/modules/5.3.11-300.fc31.x86_64/kernel/drivers/nvme/
/lib/modules/5.3.11-300.fc31.x86_64/kernel/drivers/nvme/host/nvme-core.ko.xz
/lib/modules/5.3.11-300.fc31.x86_64/kernel/drivers/nvme/host/nvme-fabrics.ko.xz
/lib/modules/5.3.11-300.fc31.x86_64/kernel/drivers/nvme/host/nvme-fc.ko.xz
/lib/modules/5.3.11-300.fc31.x86_64/kernel/drivers/nvme/host/nvme-tcp.ko.xz
/lib/modules/5.3.11-300.fc31.x86_64/kernel/drivers/nvme/host/nvme.ko.xz
/lib/modules/5.3.11-300.fc31.x86_64/kernel/drivers/nvme/host/nvme-rdma.ko.xz
/lib/modules/5.3.11-300.fc31.x86_64/kernel/drivers/nvme/target/nvme-fcloop.ko.xz
/lib/modules/5.3.11-300.fc31.x86_64/kernel/drivers/nvme/target/nvme-loop.ko.xz
/lib/modules/5.3.11-300.fc31.x86_64/kernel/drivers/nvme/target/nvmet-fc.ko.xz
/lib/modules/5.3.11-300.fc31.x86_64/kernel/drivers/nvme/target/nvmet-tcp.ko.xz
/lib/modules/5.3.11-300.fc31.x86_64/kernel/drivers/nvme/target/nvmet.ko.xz
/lib/modules/5.3.11-300.fc31.x86_64/kernel/drivers/nvme/target/nvmet-rdma.ko.xz
# 
# modprobe nvmet
# modprobe nvmet-tcp
#
# lsmod | grep nvme
nvmet_tcp              28672  1
nvmet                 102400  7 nvmet_tcp
nvme                   49152  0
nvme_core             102400  1 nvme
# 

nvme用のターゲットツールをインストールする。やることの考え方はtargetcliと同じで、サブシステムでストレージの設定を行い、ポートでネットワークの設定を行い、両者を結びつける。

まずはサブシステムを今回はtcp-test1という名前で作成し、ネームスペースは単純に1として作成。 そのネームスペース1にバッキングデバイスとして今回は実物のNVMe SSDではなくnullデバイスを指定する。接続を許すホストとして全てOKにしてしまい、最後に有効化する。

# dnf install nvmetcli
#
# mkdir /sys/kernel/config/nvmet/subsystems/tcp-test1
# mkdir -p /sys/kernel/config/nvmet/subsystems/tcp-test1/namespaces/1
# echo /dev/nullb0 > /sys/kernel/config/nvmet/subsystems/tcp-test1/namespaces/1/device_path
# echo 1 > /sys/kernel/config/nvmet/subsystems/tcp-test1/attr_allow_any_host 
# echo 1 > /sys/kernel/config/nvmet/subsystems/tcp-test1/namespaces/1/enable 
#

ポートはまず1番ポートを作成し、接続方式としてIPv4とTCPを指定し、使用するIPアドレスとポートを設定する。ファイアウォールが稼働中であればポートの追加を忘れずに。

# mkdir /sys/kernel/config/nvmet/ports/1
# echo ipv4 > /sys/kernel/config/nvmet/ports/1/addr_adrfam 
# echo tcp > /sys/kernel/config/nvmet/ports/1/addr_trtype 
# echo 4420 > /sys/kernel/config/nvmet/ports/1/addr_trsvcid
# echo 192.168.1.1 >  /sys/kernel/config/nvmet/ports/1/addr_traddr 
#
# firewall-cmd --zone=FedoraServer --add-port=4420/tcp --permanent
# firewall-cmd --reload

ターゲット側の最後に今作成したサブシステムとポート間でリンクを張る。dmesgでNVMe over TCPが無事設定できたことが確認できる。

# ln -s /sys/kernel/config/nvmet/subsystems/tcp-test1/ /sys/kernel/config/nvmet/ports/1/subsystems/tcp-test1
#
# dmesg | grep nvmet_tcp
[ 3071.444329] nvmet_tcp: enabling port 1 (192.168.1.1:4420)

イニシエータ側マシンでの作業は、NVMe over TCPのクライアント用ドライバをロードして、ディスカバリし、接続という流れ。最終的にはターゲット側の250GBのnullb0がイニシエータ側マシンではnvme1n1として接続できている。

# firewall-cmd --zone=FedoraServer --add-port=4420/tcp --permanent
# firewall-cmd --reload
#
# modprobe nvme-tcp
# lsmod | grep nvme
nvme_tcp               36864  0
nvme_fabrics           28672  1 nvme_tcp
nvme                   49152  0
nvme_core             102400  3 nvme_tcp,nvme,nvme_fabrics
#
# nvme discover -t tcp -a 192.168.1.1 -s 4420

Discovery Log Number of Records 1, Generation counter 2
=====Discovery Log Entry 0======
trtype:  tcp
adrfam:  ipv4
subtype: nvme subsystem
treq:    not specified, sq flow control disable supported
portid:  1
trsvcid: 4420
subnqn:  tcp-test1
traddr:  192.168.1.1
sectype: none
#
# nvme connect -t tcp -n tcp-test1 -a 192.168.1.1 -s 4420
#
# lsblk 
NAME          MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
sda             8:0    0 447.1G  0 disk 
├─sda1          8:1    0   600M  0 part /boot/efi
├─sda2          8:2    0     1G  0 part /boot
└─sda3          8:3    0 445.6G  0 part 
  ├─fc31-root 253:0    0    15G  0 lvm  /
  └─fc31-swap 253:1    0  31.4G  0 lvm  [SWAP]
sdb             8:16   0   1.5T  0 disk 
sdc             8:32   0   1.5T  0 disk 
sdd             8:48   1  14.6G  0 disk 
└─sdd1          8:49   1  14.6G  0 part 
sr0            11:0    1     2G  0 rom  
nvme0n1       259:0    0   477G  0 disk 
├─nvme0n1p1   259:1    0   512M  0 part 
└─nvme0n1p2   259:2    0 476.4G  0 part 
nvme1n1       259:4    0   250G  0 disk