LVM: Added NVMe TCP support for the nvmet target

This patch adds NVMe TCP transport protocol support to the LVM driver's
nvmet target helper.

Configuration option is ``target_protocol = nvmet_tcp`` when using
``nvmet`` as the ``target_helper``.

NVMe TCP has been supported since:

- RHEL 8
- CentOS 8-Stream
- Fedora 28
- Ubuntu 19.04
- SUSE Linux Enterprise Server 15
- openSUSE 15.1/15.2

No changes to OS-Brick are necessary, since the transport type is not
hardcoded in the connector and uses the value from 'transport_type'
present in the connection info dictionary instead.

Change-Id: Icc0ad567d304bf3de1e34873ad8562650ada9383
This commit is contained in:
Gorka Eguileor 2021-05-17 18:39:32 +02:00
parent 1e4002aa8b
commit eb1b23dc6c
6 changed files with 28 additions and 13 deletions

View File

@ -12,6 +12,7 @@
from unittest import mock
import ddt
from oslo_utils import timeutils
from cinder import context
@ -20,12 +21,15 @@ from cinder import utils
from cinder.volume.targets import nvmet
@ddt.ddt
class TestNVMETDriver(tf.TargetDriverFixture):
def setUp(self):
super(TestNVMETDriver, self).setUp()
self.initialize('nvmet_rdma', 'rdma')
self.configuration.target_protocol = 'nvmet_rdma'
def initialize(self, target_protocol, transport_type):
self.configuration.target_protocol = target_protocol
self.target = nvmet.NVMET(root_helper=utils.get_root_helper(),
configuration=self.configuration)
@ -34,7 +38,7 @@ class TestNVMETDriver(tf.TargetDriverFixture):
self.nvmet_subsystem_name = self.configuration.target_prefix
self.nvmet_ns_id = self.configuration.nvmet_ns_id
self.nvmet_port_id = self.configuration.nvmet_port_id
self.nvme_transport_type = 'rdma'
self.nvme_transport_type = transport_type
self.fake_volume_id = 'c446b9a2-c968-4260-b95f-a18a7b41c004'
self.testvol_path = (
@ -56,12 +60,16 @@ class TestNVMETDriver(tf.TargetDriverFixture):
'created_at': timeutils.utcnow(),
'host': 'fake_host@lvm#lvm'})
@ddt.data(('nvmet_rdma', 'rdma'), ('nvmet_tcp', 'tcp'))
@ddt.unpack
@mock.patch.object(nvmet.NVMET, '_get_nvmf_subsystem')
@mock.patch.object(nvmet.NVMET, '_get_available_nvmf_subsystems')
@mock.patch.object(nvmet.NVMET, '_add_nvmf_subsystem')
def test_create_export(self, mock_add_nvmf_subsystem,
def test_create_export(self, target_protocol, transport_type,
mock_add_nvmf_subsystem,
mock_get_available_nvmf_subsystems,
mock_get_nvmf_subsystem):
self.initialize(target_protocol, transport_type)
mock_testvol = self.testvol
mock_testvol_path = self.testvol_path
@ -75,7 +83,7 @@ class TestNVMETDriver(tf.TargetDriverFixture):
"portid": 1,
"addr":
{"treq": "not specified",
"trtype": "rdma",
"trtype": self.nvme_transport_type,
"adrfam": "ipv4",
"trsvcid": self.target_port,
"traddr":
@ -126,7 +134,7 @@ class TestNVMETDriver(tf.TargetDriverFixture):
"portid": 1,
"addr":
{"treq": "not specified",
"trtype": "rdma",
"trtype": self.nvme_transport_type,
"adrfam": "ipv4",
"trsvcid": self.target_port,
"traddr":
@ -180,7 +188,7 @@ class TestNVMETDriver(tf.TargetDriverFixture):
"portid": self.nvmet_port_id,
"addr":
{"treq": "not specified",
"trtype": "rdma",
"trtype": self.nvme_transport_type,
"adrfam": "ipv4",
"trsvcid": self.target_port,
"traddr": self.target_ip}}
@ -249,7 +257,7 @@ class TestNVMETDriver(tf.TargetDriverFixture):
"portid": self.nvmet_port_id,
"addr":
{"treq": "not specified",
"trtype": "rdma",
"trtype": self.nvme_transport_type,
"adrfam": "ipv4",
"trsvcid": self.target_port,
"traddr": self.target_ip}}

View File

@ -136,13 +136,13 @@ volume_opts = [
'as is to the underlying tool.'),
cfg.StrOpt('target_protocol',
default='iscsi',
choices=['iscsi', 'iser', 'nvmet_rdma'],
choices=['iscsi', 'iser', 'nvmet_rdma', 'nvmet_tcp'],
help='Determines the target protocol for new volumes, '
'created with tgtadm, lioadm and nvmet target helpers. '
'In order to enable RDMA, this parameter should be set '
'with the value "iser". The supported iSCSI protocol '
'values are "iscsi" and "iser", in case of nvmet target '
'set to "nvmet_rdma".'),
'set to "nvmet_rdma" or "nvmet_tcp".'),
cfg.StrOpt('driver_client_cert_key',
help='The path to the client certificate key for verification, '
'if the driver supports it.'),

View File

@ -125,7 +125,7 @@ class LVMVolumeDriver(driver.VolumeDriver):
'target_port',
'iscsi_write_cache', 'iscsi_target_flags', # TGT
'iet_conf', 'iscsi_iotype', # IET
'nvmet_port_id', # NVMET
'nvmet_port_id', 'nvmet_ns_id', # NVMET
'scst_target_iqn_name', 'scst_target_driver', # SCST
'spdk_rpc_ip', 'spdk_rpc_port', 'spdk_rpc_username', # SPDKNVMF
'spdk_rpc_password', 'spdk_max_queue_depth', # SPDKNVMF

View File

@ -34,6 +34,7 @@ class NVMeOF(driver.Target):
protocol = 'nvmeof'
target_protocol_map = {
'nvmet_rdma': 'rdma',
'nvmet_tcp': 'tcp',
}
def __init__(self, *args, **kwargs):

View File

@ -62,7 +62,7 @@ class NVMET(nvmeof.NVMeOF):
target_port,
nvmet_port_id,
subsystem_name,
ns_id, volume_id, volume_path)
ns_id, volume_id, volume_path, transport_type)
if newly_added_subsystem is None:
LOG.error('Failed to add subsystem: %s', subsystem_name)
raise NVMETTargetAddError(subsystem=subsystem_name)
@ -93,7 +93,7 @@ class NVMET(nvmeof.NVMeOF):
def _add_nvmf_subsystem(self, nvmf_subsystems, target_ip, target_port,
nvmet_port_id, nvmet_subsystem_name, nvmet_ns_id,
volume_id, volume_path):
volume_id, volume_path, transport_type):
subsystem_name = self._get_target_info(nvmet_subsystem_name, volume_id)
# Create JSON sections for the new subsystem to be created
@ -104,7 +104,7 @@ class NVMET(nvmeof.NVMeOF):
"traddr": target_ip,
"treq": "not specified",
"trsvcid": target_port,
"trtype": "rdma"
"trtype": transport_type,
},
"portid": nvmet_port_id,
"referrals": [],

View File

@ -0,0 +1,6 @@
---
features:
- |
LVM driver: Added support for the NVMe TCP transport protocol.
Configuration option is ``target_protocol = nvmet_tcp`` when using
``nvmet`` as the ``target_helper``.