summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRawan Herzallah <rawanh@mellanox.com>2017-07-11 20:18:07 +0300
committerHamdy Khader <hamdyk@mellanox.com>2018-05-29 11:26:01 +0000
commita833bcd05f811325f40cb3c8cce7f94c93cd6b6e (patch)
treeb665b9537f0c09ee0ba45895777184adf43b37b2
parent5bf9aa7fd455e93b73dc13aba66ccb7ec00f23a5 (diff)
downloadnova-a833bcd05f811325f40cb3c8cce7f94c93cd6b6e.tar.gz
Adding NVMEoF for libvirt driver
Adding NVMEoF libvirt driver for supporting NVMEoF initiator CLI. Libvirt NVMe volume driver is added to handle required calls for attaching and detaching volume from instaces through calling os-brick's NVMe Connector. Implements: blueprint nvme-over-fabirc-nova Co-Authored-By: Ivan Kolodyazhny <e0ne@e0ne.info> Change-Id: I67a72c4226e54c18b3a6e4a13b5055fa6e85af09
-rw-r--r--lower-constraints.txt2
-rw-r--r--nova/conf/libvirt.py13
-rw-r--r--nova/tests/unit/virt/libvirt/volume/test_nvme.py66
-rw-r--r--nova/virt/libvirt/driver.py1
-rw-r--r--nova/virt/libvirt/volume/nvme.py63
-rw-r--r--releasenotes/notes/bp-nvme-over-fabric-nova-ae1ef46fb5a7fc02.yaml4
-rw-r--r--requirements.txt2
7 files changed, 149 insertions, 2 deletions
diff --git a/lower-constraints.txt b/lower-constraints.txt
index 2d464e0afe..99b46bfaae 100644
--- a/lower-constraints.txt
+++ b/lower-constraints.txt
@@ -66,7 +66,7 @@ netifaces==0.10.4
networkx==1.11
numpy==1.14.2
openstacksdk==0.12.0
-os-brick==2.4.0
+os-brick==2.5.0
os-client-config==1.29.0
os-service-types==1.2.0
os-traits==0.4.0
diff --git a/nova/conf/libvirt.py b/nova/conf/libvirt.py
index 8349455d06..af96840db9 100644
--- a/nova/conf/libvirt.py
+++ b/nova/conf/libvirt.py
@@ -1190,6 +1190,18 @@ v2.10."""),
]
+libvirt_volume_nvmeof_opts = [
+ cfg.IntOpt('num_nvme_discover_tries',
+ default=3,
+ help="""
+Number of times to rediscover NVMe target to find volume
+
+Nova provides support for block storage attaching to hosts via NVMe
+(Non-Volatile Memory Express). This option allows the user to specify the
+maximum number of retry attempts that can be made to discover the NVMe device.
+"""),
+]
+
ALL_OPTS = list(itertools.chain(
libvirt_general_opts,
libvirt_imagebackend_opts,
@@ -1208,6 +1220,7 @@ ALL_OPTS = list(itertools.chain(
libvirt_remotefs_opts,
libvirt_volume_vzstorage_opts,
libvirt_virtio_queue_sizes,
+ libvirt_volume_nvmeof_opts,
))
diff --git a/nova/tests/unit/virt/libvirt/volume/test_nvme.py b/nova/tests/unit/virt/libvirt/volume/test_nvme.py
new file mode 100644
index 0000000000..997c914927
--- /dev/null
+++ b/nova/tests/unit/virt/libvirt/volume/test_nvme.py
@@ -0,0 +1,66 @@
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+import mock
+
+from nova.tests.unit.virt.libvirt.volume import test_volume
+from nova.virt.libvirt.volume import nvme
+
+from os_brick.initiator import connector
+
+
+class LibvirtNVMEVolumeDriverTestCase(test_volume.LibvirtVolumeBaseTestCase):
+
+ @mock.patch('os.path.exists', return_value=True)
+ def test_libvirt_nvme_driver(self, exists):
+ libvirt_driver = nvme.LibvirtNVMEVolumeDriver(self.fake_host)
+ self.assertIsInstance(libvirt_driver.connector,
+ connector.NVMeConnector)
+
+ def test_libvirt_nvme_driver_connect(self):
+ nvme_driver = nvme.LibvirtNVMEVolumeDriver(self.fake_host)
+ config = {'server_ip': '127.0.0.1', 'server_port': 9898}
+ disk_info = {
+ 'id': '1234567',
+ 'name': 'aNVMEVolume',
+ 'conf': config}
+ connection_info = {'data': disk_info}
+ with mock.patch.object(nvme_driver.connector,
+ 'connect_volume',
+ return_value={'path': '/dev/dms1234567'}):
+ nvme_driver.connect_volume(connection_info, None)
+ self.assertEqual('/dev/dms1234567',
+ connection_info['data']['device_path'])
+
+ def test_libvirt_nvme_driver_disconnect(self):
+ nvme_con = nvme.LibvirtNVMEVolumeDriver(self.connr)
+ nvme_con.connector.disconnect_volume = mock.MagicMock()
+ disk_info = {
+ 'path': '/dev/dms1234567', 'name': 'aNVMEVolume',
+ 'type': 'raw', 'dev': 'vda1', 'bus': 'pci0',
+ 'device_path': '/dev/dms123456'}
+ connection_info = {'data': disk_info}
+ nvme_con.disconnect_volume(connection_info, None)
+ nvme_con.connector.disconnect_volume.assert_called_once_with(
+ disk_info, None)
+
+ def test_libvirt_nvme_driver_get_config(self):
+ nvme_driver = nvme.LibvirtNVMEVolumeDriver(self.fake_host)
+ device_path = '/dev/fake-dev'
+ connection_info = {'data': {'device_path': device_path}}
+
+ conf = nvme_driver.get_config(connection_info, self.disk_info)
+ tree = conf.format_dom()
+
+ self.assertEqual('block', tree.get('type'))
+ self.assertEqual(device_path, tree.find('./source').get('dev'))
+ self.assertEqual('raw', tree.find('./driver').get('type'))
diff --git a/nova/virt/libvirt/driver.py b/nova/virt/libvirt/driver.py
index 4e3de84435..9d283db1b6 100644
--- a/nova/virt/libvirt/driver.py
+++ b/nova/virt/libvirt/driver.py
@@ -187,6 +187,7 @@ libvirt_volume_drivers = [
'nova.virt.libvirt.volume.vrtshyperscale.'
'LibvirtHyperScaleVolumeDriver',
'storpool=nova.virt.libvirt.volume.storpool.LibvirtStorPoolVolumeDriver',
+ 'nvmeof=nova.virt.libvirt.volume.nvme.LibvirtNVMEVolumeDriver',
]
diff --git a/nova/virt/libvirt/volume/nvme.py b/nova/virt/libvirt/volume/nvme.py
new file mode 100644
index 0000000000..8d20ab10d5
--- /dev/null
+++ b/nova/virt/libvirt/volume/nvme.py
@@ -0,0 +1,63 @@
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+import nova.conf
+from nova import utils
+from nova.virt.libvirt.volume import volume as libvirt_volume
+
+from os_brick import initiator
+from os_brick.initiator import connector
+
+from oslo_log import log as logging
+
+LOG = logging.getLogger(__name__)
+
+CONF = nova.conf.CONF
+
+
+class LibvirtNVMEVolumeDriver(libvirt_volume.LibvirtVolumeDriver):
+ """Driver to attach NVMe volumes to libvirt."""
+
+ def __init__(self, connection):
+ super(LibvirtNVMEVolumeDriver,
+ self).__init__(connection)
+
+ self.connector = connector.InitiatorConnector.factory(
+ initiator.NVME, utils.get_root_helper(),
+ device_scan_attempts=CONF.libvirt.num_nvme_discover_tries)
+
+ def connect_volume(self, connection_info, instance):
+
+ device_info = self.connector.connect_volume(
+ connection_info['data'])
+ LOG.debug(
+ "Connecting NVMe volume with device_info %s",
+ device_info)
+
+ connection_info['data']['device_path'] = device_info['path']
+
+ def disconnect_volume(self, connection_info, instance):
+ """Detach the volume from the instance."""
+ LOG.debug("Disconnecting NVMe disk")
+ self.connector.disconnect_volume(
+ connection_info['data'], None)
+ super(LibvirtNVMEVolumeDriver,
+ self).disconnect_volume(connection_info, instance)
+
+ def extend_volume(self, connection_info, instance):
+ """Extend the volume."""
+ LOG.debug("calling os-brick to extend NVMe Volume", instance=instance)
+ new_size = self.connector.extend_volume(connection_info['data'])
+ LOG.debug("Extend NVMe Volume %s; new_size=%s",
+ connection_info['data']['device_path'],
+ new_size, instance=instance)
+ return new_size
diff --git a/releasenotes/notes/bp-nvme-over-fabric-nova-ae1ef46fb5a7fc02.yaml b/releasenotes/notes/bp-nvme-over-fabric-nova-ae1ef46fb5a7fc02.yaml
new file mode 100644
index 0000000000..1ec6f33d0c
--- /dev/null
+++ b/releasenotes/notes/bp-nvme-over-fabric-nova-ae1ef46fb5a7fc02.yaml
@@ -0,0 +1,4 @@
+---
+features:
+ - |
+ Added support for ``nvmeof`` type volumes to the libvirt driver.
diff --git a/requirements.txt b/requirements.txt
index 1b7631771e..43b82f6cfb 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -52,7 +52,7 @@ rfc3986>=0.3.1 # Apache-2.0
oslo.middleware>=3.31.0 # Apache-2.0
psutil>=3.2.2 # BSD
oslo.versionedobjects>=1.31.2 # Apache-2.0
-os-brick>=2.4.0 # Apache-2.0
+os-brick>=2.5.0 # Apache-2.0
os-traits>=0.4.0 # Apache-2.0
os-vif!=1.8.0,>=1.7.0 # Apache-2.0
os-win>=3.0.0 # Apache-2.0