SPDK nvmf with rbd bdev 命名空间修改方案

**

本文主要介绍如何调整nvmf的命令空间

**

一、架构介绍

SPDK nvmf with rbd bdev 命名空间修改方案_第1张图片

                              图1 spdk nvme of target架构图

从图1 可以看出,整个架构分成两部分,一部分为SPDK提供的NVMe oF Target端,一部分是主机侧 NVME oF Initiator端。
SPDK端使用ceph rbd 组成Bdev设备,然后将Bdev设备作为subsystme中的命名空间。HOST端使用nvme cli 连接NVMe oF Target,呈现给主机的是nvme 设备,使用的是内核自带的nvme 驱动。通过virtio-blk、virtio-scsi驱动,nvme 设备被attach给虚拟机,虚拟机内部看到的是vdx,sdx设备。

二、 命令空间方案介绍

在第一部分的应用场景下,本文描述如何动态增加nvme磁盘的容量(对应主机侧)或者说nvme of target的一个命名空间容量。
容量调整涉及到几个方面:
(1)调整rbd 块设备大小
(2)调整bdev大小
(3)nvme of target的命名空间大小
(4)host侧 nvme of initiator端能感知到变化,调整nvme设备大小
(5)主机侧nvme块设备大小
(6)虚拟机及时识别设备容量变化
(7)调整虚拟机内部设备文件系统大小。
其中(7)很多文件系统支持扩容,及时不支持也可以重新格式化,不在本文讨论范围内。
(1)rbd本身支持动态调整大小,只需要在spdk代码中调用rbd_resize即可。

2.1 SPDK侧

SPDK 代码中已经有调整lvol的代码,我们参考其流程进行修改即可。
SPDKNVMe of target 侧修改方案:
(1)增加 RPC for resizing bdev with ceph rbd backend
(2)调用 spdk_bdev_notify_blockcnt_change 函数修改bdev结构体的blockcnt字段即可,该字段代表bdev 设备的块数。
(3)spdk 中nvme of target ns 大小即是bdev设备的大小,当主机侧发送nvme list后,SPDK会调用spdk_nvmf_bdev_ctrlr_identify_ns 重新获取命名空间容量的块数。所以nvme initiator端可以手动出发感知。

2.2 主机侧

按照第一节架构图所示,主机侧数据流架构如下
SPDK nvmf with rbd bdev 命名空间修改方案_第2张图片

nvme list 看到的只是nvme 驱动层设备大小,还需要触发VFS层和通用块设备大小变化,调用nvme ns-rescan即可触发从下到上的设备信息更新。
主机上块设备大小变化后,需要触发虚拟机内部重新识别新容量,libvirt和qemu提供了相应的机制。
调用:virsh blockresize domid vdb --size 800G
Qemu层逻辑包括两部分:
(1) 针对 raw格式的device 不对设备进行扩容,只检查扩容后的大小是否超过的设备大小,获取设备大小是通过 open+lseek的方式
(2) 通知虚拟机内部容量发生变化,该部分是virtio 负责的。
Qemu侧函数执行流程为:

virsh blockresize----》
qmp_block_resize----》
bdrv_truncate---》
drv->bdrv_truncate---》(修改qcow2,rbd或者raw 文件大小,.bdrv_truncate          = qemu_rbd_truncate,)
bdrv_parent_cb_resize---》
blk_root_resize—》
virtio_blk_resize---》
virtio_notify_config----发送中断给虚拟机

虚拟机侧:

vp_interrrupt-----》 	vp_config_changed---》 		virtio_config_change----》 			virtblk_config_changed----》
				virtblk_config_changed_work----》
					virtblk_update_capacity ---》获取新的大小
						revalidate_disk  ------》 更新内核栈中设备的大小

三、具体操作流程和原理介绍

3.1 3个nvme ssd 组成一个subsystem

(1)spdk侧 nvmef 配置文件

[Nvme]
  TransportID "trtype:PCIe traddr:0000:18:00.0" Nvme0
  TransportID "trtype:PCIe traddr:0000:19:00.0" Nvme1
  TransportID "trtype:PCIe traddr:0000:1a:00.0" Nvme2
[Subsystem1]
  NQN nqn.2016-06.io.spdk:cnode1
  Listen RDMA 10.1.1.54:4420
  AllowAnyHost yes
  Host nqn.2016-06.io.spdk:init
  SN SPDK00000000000001
  MaxNamespaces 20
  Namespace Nvme0n1 1
  Namespace Nvme1n1 2
  Namespace Nvme2n1 3

Nvme target 端:

[root@cvknode54 spdk]# ./scripts/rpc.py get_nvmf_subsystems

[
  {
    "allow_any_host": true,
    "subtype": "Discovery",
    "nqn": "nqn.2014-08.org.nvmexpress.discovery",
    "hosts": [],
    "listen_addresses": []
  },
  {
    "max_namespaces": 20,
    "subtype": "NVMe",
    "nqn": "nqn.2016-06.io.spdk:cnode1",
    "serial_number": "SPDK00000000000001",
    "hosts": [
      {
        "nqn": "nqn.2016-06.io.spdk:init"
      }
    ],
    "listen_addresses": [
      {
        "trtype": "RDMA",
        "adrfam": "IPv4",
        "trsvcid": "4420",
        "traddr": "10.1.1.54",
        "transport": "RDMA"
      }
    ],
    "allow_any_host": true,
    "namespaces": [
      {
        "bdev_name": "Nvme0n1",
        "name": "Nvme0n1",
        "nsid": 1
      },
      {
        "bdev_name": "Nvme1n1",
        "name": "Nvme1n1",
        "nsid": 2
      },
      {
        "bdev_name": "Nvme2n1",
        "name": "Nvme2n1",
        "nsid": 3
      }
    ]
  }
]

Nvme initiator 端 看到3个设备

[root@cvknode54 spdk]# nvme list
Node             SN                   Model                                    Namespace Usage                      Format           FW Rev  
---------------- -------------------- ---------------------------------------- --------- -------------------------- ---------------- --------
/dev/nvme0n1     SPDK00000000000001   SPDK bdev Controller                     1           1.00  TB /   1.00  TB    512   B +  0 B   19.01   
/dev/nvme0n2     SPDK00000000000001   SPDK bdev Controller                     2           1.00  TB /   1.00  TB    512   B +  0 B   19.01   
/dev/nvme0n3     SPDK00000000000001   SPDK bdev Controller                     3           1.00  TB /   1.00  TB    512   B +  0 B   19.01
[root@cvknode54 spdk]# ll /dev/nvme*
crw------- 1 root root 244,  0 Nov 22 17:29 /dev/nvme0
brw-rw---- 1 root disk 259,  0 Nov 22 17:29 /dev/nvme0n1
brw-rw---- 1 root disk 259,  1 Nov 22 17:29 /dev/nvme0n2
brw-rw---- 1 root disk 259,  2 Nov 22 17:29 /dev/nvme0n3

删除 命名空间:

[root@cvknode54 spdk]# ./scripts/rpc.py nvmf_subsystem_remove_ns  nqn.2016-06.io.spdk:cnode1  1
[root@cvknode54 spdk]# nvme list
Node             SN                   Model                                    Namespace Usage                      Format           FW Rev  
---------------- -------------------- ---------------------------------------- --------- -------------------------- ---------------- --------
/dev/nvme0n2     SPDK00000000000001   SPDK bdev Controller                     2           1.00  TB /   1.00  TB    512   B +  0 B   19.01   
/dev/nvme0n3     SPDK00000000000001   SPDK bdev Controller                     3           1.00  TB /   1.00  TB    512   B +  0 B   19.01

增加命名空间

[root@cvknode54 spdk]# ./scripts/rpc.py nvmf_subsystem_add_ns nqn.2016-06.io.spdk:cnode1  Nvme0n1---- 此处是bdev name 首先要保证bdev 存在。

[root@cvknode54 spdk]# nvme list
Node             SN                   Model                                    Namespace Usage                      Format           FW Rev  
---------------- -------------------- ---------------------------------------- --------- -------------------------- ---------------- --------
/dev/nvme0n1     SPDK00000000000001   SPDK bdev Controller                     1           1.00  TB /   1.00  TB    512   B +  0 B   19.01   
/dev/nvme0n2     SPDK00000000000001   SPDK bdev Controller                     2           1.00  TB /   1.00  TB    512   B +  0 B   19.01   
/dev/nvme0n3     SPDK00000000000001   SPDK bdev Controller                     3           1.00  TB /   1.00  TB    512   B +  0 B   19.01  

断开连接

nvme disconnect  -d /dev/nvme0

针对 nvme initiator 端执行 nvme create-ns delete-ns attach-ns detach-ns
spdk侧都不支持。

Spdk 侧添加删除 ns,initiator端会立即识别到。

目前 spdk支持 操作nvmf 接口

set_nvmf_target_options
    set_nvmf_target_max_subsystems
    set_nvmf_target_config
    nvmf_create_transport
    get_nvmf_transports
                        Display nvmf transports
    get_nvmf_subsystems
                        Display nvmf subsystems
    construct_nvmf_subsystem
                        Add a nvmf subsystem
    nvmf_subsystem_create
    delete_nvmf_subsystem
                        Delete a nvmf subsystem
    nvmf_subsystem_add_listener
    nvmf_subsystem_remove_listener
    nvmf_subsystem_add_ns
    nvmf_subsystem_remove_ns
    nvmf_subsystem_add_host
    nvmf_subsystem_remove_host
nvmf_subsystem_allow_any_host

创建 rbd blockdev设备

[root@cvknode54 spdk]# ./scripts/rpc.py  construct_rbd_bdev  pool-1 myvol-3  512
Ceph3

增加命令空间

[root@cvknode54 spdk]# ./scripts/rpc.py  nvmf_subsystem_add_ns nqn.2016-06.io.spdk:cnode1 Ceph3
[root@cvknode54 spdk]# nvme list
Node             SN                   Model                                    Namespace Usage                      Format           FW Rev  
---------------- -------------------- ---------------------------------------- --------- -------------------------- ---------------- --------
/dev/nvme0n1     SPDK00000000000001   SPDK bdev Controller                     1          64.42  GB /  64.42  GB    512   B +  0 B   19.01   
/dev/nvme0n2     SPDK00000000000001   SPDK bdev Controller                     2          85.90  GB /  85.90  GB    512   B +  0 B   19.01   
/dev/nvme0n3     SPDK00000000000001   SPDK bdev Controller                     3          42.95  GB /  42.95  GB    512   B +  0 B   19.01   
/dev/nvme0n4     SPDK00000000000001   SPDK bdev Controller                     4          53.69  GB /  53.69  GB    512   B +  0 B   19.01
[root@cvknode54 qemu]# ll /sys/class/nvme/*
lrwxrwxrwx 1 root root 0 Nov 23 15:28 /sys/class/nvme/nvme0 -> ../../devices/virtual/nvme-fabrics/ctl/nvme0
[root@cvknode54 qemu]# ll /dev/nvme*
crw------- 1 root root 244,  0 Nov 23 12:11 /dev/nvme0
brw-rw---- 1 root disk 259,  0 Nov 23 12:11 /dev/nvme0n1
brw-rw---- 1 root disk 259,  1 Nov 23 12:11 /dev/nvme0n2
brw-rw---- 1 root root 259,  2 Nov 23 14:55 /dev/nvme0n3
brw-rw---- 1 root disk 259,  3 Nov 23 15:00 /dev/nvme0n4
crw------- 1 root root  10, 56 Nov 22 17:28 /dev/nvme-fabrics

与真实的nvme ssd 有区别,没有pci地址。

Ceph 公共网络和集群网络都是使用的rdma,或者都不使用rdma。整个流程都是正常的。

[root@cvknode54 qemu]# virsh blockresize 4 vdb --size 50G
error: Failed to resize block device ‘vdb’
error: internal error: unable to execute QEMU command ‘block_resize’: Cannot grow device files

或者

[root@cvknode54 qemu]# grep “blk_root_resize” ./ -nr
Binary file ./qemu-img matches
./block/block-backend.c:127:static void blk_root_resize(BdrvChild *child);
./block/block-backend.c:292: .resize = blk_root_resize,
./block/block-backend.c:1060:static void blk_root_resize(BdrvChild *child)

static void bdrv_parent_cb_resize(BlockDriverState *bs)
{
BdrvChild *c;
QLIST_FOREACH(c, &bs->parents, next_parent) {
if (c->role->resize) {
c->role->resize©;
}
}
}

static void scsi_disk_resize_cb(void *opaque)
{
SCSIDiskState *s = opaque;

/* SPC lists this sense code as available only for
 * direct-access devices.
 */
if (s->qdev.type == TYPE_DISK) {
    scsi_device_report_change(&s->qdev, SENSE_CODE(CAPACITY_CHANGED));
}

}

static void blk_root_resize(BdrvChild *child)
{
BlockBackend *blk = child->opaque;

if (blk->dev_ops && blk->dev_ops->resize_cb) {
    blk->dev_ops->resize_cb(blk->dev_opaque);
}

}

static const BlockDevOps virtio_block_ops = {
.resize_cb = virtio_blk_resize,
};
virsh blockresize----》
qmp_block_resize----》
bdrv_truncate—》
drv->bdrv_truncate—》(修改qcow2,rbd或者raw 文件大小,.bdrv_truncate = qemu_rbd_truncate,)
bdrv_parent_cb_resize—》
blk_root_resize—》
virtio_blk_resize
—》virtio_notify_config

[root@cvknode54 spdk]# nvme list
Node SN Model Namespace Usage Format FW Rev


/dev/nvme1n1 SPDK00000000000001 SPDK bdev Controller 1 64.42 GB / 64.42 GB 512 B + 0 B 19.01
/dev/nvme1n3 SPDK00000000000001 SPDK bdev Controller 3 429.50 GB / 429.50 GB 512 B + 0 B 19.01
[root@cvknode54 spdk]# nvme disconnect -d /devb/nvme1n3
[root@cvknode54 spdk]# nvme disconnect -d /dev/nvme1n3
Failed to disconnect by device name: /dev/nvme1n3
[root@cvknode54 spdk]# nvme list
Node SN Model Namespace Usage Format FW Rev


[root@cvknode54 spdk]#

操作流程: spdk target端增加 rbd bdev设备的大小,目前会自动对rbd设备进行扩容。

/home/spdk/scripts/rpc.py resize_rbd_bdev Ceph2 819200—此处 ceph2 为 bdev的设备名称,不是rbd的名称,819200 单位是M,1024进制。

Spdk initiator 端,执行nvme ns-rescan /dev/nvme2 搜索nvme 设备,注意此处不是nvme的namespace。
对虚拟机磁盘进行扩容。
virsh blockresize domid vdb --size 800G blockresize 动作分两步,一是对设备扩容,二是通知虚拟机磁盘发生变化。 针对block设备,此处只有动作(二),没动作(一)。所以用户自己保证 扩容的容量大小保证一致。

另外:spdk initiator端 主机上显示的设备名,没有直接的命令查看对应的spdk target设备名。

Initiator 端,查看 sn和 namespace id。
[root@cvknode54 spdk]# nvme list
Node SN Model Namespace Usage Format FW Rev


/dev/nvme1n1 SPDK00000000000002 SPDK bdev Controller 1 64.42 GB / 64.42 GB 512 B + 0 B 19.01
/dev/nvme2n1 SPDK00000000000001 SPDK bdev Controller 1 64.42 GB / 64.42 GB 512 B + 0 B 19.01
/dev/nvme2n2 SPDK00000000000001 SPDK bdev Controller 2 85.90 GB / 85.90 GB 512 B + 0 B 19.01
/dev/nvme2n3 SPDK00000000000001 SPDK bdev Controller 3 858.99 GB / 858.99 GB 512 B + 0 B 19.01

Spdk target 端:

./scripts/rpc.py get_nvmf_subsystems

{
“listen_addresses”: [
{
“trsvcid”: “4421”,
“transport”: “RDMA”,
“traddr”: “10.1.1.54”,
“adrfam”: “IPv4”,
“trtype”: “RDMA”
}
],
“namespaces”: [
{
“name”: “Ceph4”,
“nsid”: 1,
“bdev_name”: “Ceph4”
}
],
“subtype”: “NVMe”,
“nqn”: “nqn.2016-06.io.spdk:cnode2”,
“hosts”: [],
“allow_any_host”: true,
“serial_number”: “SPDK00000000000002”
}

./scripts/rpc.py  get_bdevs
{
    "name": "Ceph4",
    "aliases": [],
    "driver_specific": {
      "rbd": {
        "pool_name": "pool-1",
        "rbd_name": "host-rbd-img-1"
      }
    },

spdk动态增加 bdev 、nvmf target

[root@cvknode54 spdk]# ./scripts/rpc.py construct_rbd_bdev pool-1 host-rbd-img-1 512 -b Ceph4
Ceph4

./scripts/rpc.py construct_nvmf_subsystem nqn.2016-06.io.spdk:cnode2 "trtype:RDMA traddr:10.1.1.54 trsvcid:4421" "" -a -s SPDK00000000000002

[root@cvknode54 spdk]# ./scripts/rpc.py  nvmf_subsystem_add_ns  nqn.2016-06.io.spdk:cnode2 Ceph4

你可能感兴趣的:(网络)