From 9b088ca82a2612f0cf73cfa6bc670c6e5b5f64b6 Mon Sep 17 00:00:00 2001 From: Tzur Eliyahu Date: Tue, 25 Apr 2017 14:10:22 +0300 Subject: [PATCH] Ibm storage: added new option for qos type Added independent and shared types for qos classes. Shared type enables to share bandwidth and IO rates between volumes of the same class. Independent type gives each volume the same bandwidth and IO rates without being affected by other volumes in the same qos class. DocImpact Change-Id: I3f5e602a0554b852da0dceffbe100cc735e0876b --- .../unit/volume/drivers/ibm/test_xiv_proxy.py | 61 +++++++++++++++++++ .../drivers/ibm/ibm_storage/xiv_proxy.py | 29 +++++++-- ...qos-independent-type-58885c77efe24798.yaml | 7 +++ 3 files changed, 93 insertions(+), 4 deletions(-) create mode 100644 releasenotes/notes/xiv-new-qos-independent-type-58885c77efe24798.yaml diff --git a/cinder/tests/unit/volume/drivers/ibm/test_xiv_proxy.py b/cinder/tests/unit/volume/drivers/ibm/test_xiv_proxy.py index 18d40acdcf8..515672f8ba0 100644 --- a/cinder/tests/unit/volume/drivers/ibm/test_xiv_proxy.py +++ b/cinder/tests/unit/volume/drivers/ibm/test_xiv_proxy.py @@ -600,6 +600,67 @@ class XIVProxyTest(test.TestCase): perf_name = p._check_perf_class_on_backend({}) self.assertEqual('', perf_name) + def test_qos_class_name_contains_qos_type(self): + """Test backend naming + + Test if the naming convention is correct + when getting the right specs with qos type + """ + driver = mock.MagicMock() + driver.VERSION = "VERSION" + + p = self.proxy( + self.default_storage_info, + mock.MagicMock(), + test_mock.cinder.exception, + driver) + + p.ibm_storage_cli = mock.MagicMock() + p.ibm_storage_cli.cmd.perf_class_list.return_value.as_list = [] + perf_name = p._check_perf_class_on_backend({'bw': '100', + 'type': 'independent'}) + + self.assertEqual('cinder-qos_bw_100_type_independent', perf_name) + + def test_qos_called_with_type_parameter(self): + """Test xcli call for qos creation with type""" + driver = mock.MagicMock() + driver.VERSION = "VERSION" + + p = self.proxy( + self.default_storage_info, + mock.MagicMock(), + test_mock.cinder.exception, + driver) + + p.ibm_storage_cli = mock.MagicMock() + p.ibm_storage_cli.cmd.perf_class_list.return_value.as_list = [] + perf_name = p._check_perf_class_on_backend({'bw': '100', + 'type': 'independent'}) + p.ibm_storage_cli.cmd.perf_class_create.assert_called_once_with( + perf_class=perf_name, + type='independent') + + def test_qos_called_with_wrong_type_parameter(self): + """Test xcli call for qos creation with wrong type""" + driver = mock.MagicMock() + driver.VERSION = "VERSION" + + p = self.proxy( + self.default_storage_info, + mock.MagicMock(), + test_mock.cinder.exception, + driver) + + p.ibm_storage_cli = mock.MagicMock() + p.ibm_storage_cli.cmd.perf_class_list.return_value.as_list = [] + p.ibm_storage_cli.cmd.perf_class_create.side_effect = ( + errors.XCLIError('llegal value')) + + ex = getattr(p, "_get_exception")() + self.assertRaises(ex, p._check_perf_class_on_backend, + {'bw': '100', 'type': 'BAD'}) + def test_qos_class_on_backend_name_correct(self): """Test backend naming diff --git a/cinder/volume/drivers/ibm/ibm_storage/xiv_proxy.py b/cinder/volume/drivers/ibm/ibm_storage/xiv_proxy.py index 3e758a940c6..90f7f5cb413 100644 --- a/cinder/volume/drivers/ibm/ibm_storage/xiv_proxy.py +++ b/cinder/volume/drivers/ibm/ibm_storage/xiv_proxy.py @@ -111,6 +111,13 @@ class XIVProxy(proxy.IBMStorageProxy): """Proxy between the Cinder Volume and Spectrum Accelerate Storage. Supports IBM XIV, Spectrum Accelerate, A9000, A9000R + Version: 2.1.0 + Required pyxcli version: 1.1.2 + + 2.0 - First open source driver version + 2.1.0 - Support Consistency groups through Generic volume groups + - Support XIV\A9000 Volume independent QoS + """ async_rates = ( Rate(rpo=120, schedule='00:01:00'), @@ -172,6 +179,10 @@ class XIVProxy(proxy.IBMStorageProxy): self.ibm_storage_remote_cli = self._init_xcli(remote_id) self._event_service_start() self._update_stats() + LOG.info("IBM Storage %(common_ver)s " + "xiv_proxy %(proxy_ver)s. ", + {'common_ver': self.full_version, + 'proxy_ver': self.full_version}) self._update_system_id() if remote_id: self._update_active_schedule_objects() @@ -355,8 +366,10 @@ class XIVProxy(proxy.IBMStorageProxy): # list is not empty, check if class has the right values for perf_class in classes_list: - if (not perf_class.max_iops == specs.get('iops', '0') or - not perf_class.max_bw == specs.get('bw', '0')): + if (not perf_class.get('max_iops', + None) == specs.get('iops', '0') or + not perf_class.get('max_bw', + None) == specs.get('bw', '0')): raise self.meta['exception'].VolumeBackendAPIException( data=PERF_CLASS_VALUES_ERROR % {'details': perf_class_name}) @@ -374,8 +387,16 @@ class XIVProxy(proxy.IBMStorageProxy): def _create_qos_class(self, perf_class_name, specs): """Create the qos class on the backend.""" try: - self._call_xiv_xcli("perf_class_create", - perf_class=perf_class_name) + # check if we have a shared (default) perf class + # or an independent perf class + if 'type_' in perf_class_name: + _type = perf_class_name.split('type_')[1] + self._call_xiv_xcli("perf_class_create", + perf_class=perf_class_name, + type=_type) + else: + self._call_xiv_xcli("perf_class_create", + perf_class=perf_class_name) except errors.XCLIError as e: details = self._get_code_and_status_or_message(e) diff --git a/releasenotes/notes/xiv-new-qos-independent-type-58885c77efe24798.yaml b/releasenotes/notes/xiv-new-qos-independent-type-58885c77efe24798.yaml new file mode 100644 index 00000000000..31b84528045 --- /dev/null +++ b/releasenotes/notes/xiv-new-qos-independent-type-58885c77efe24798.yaml @@ -0,0 +1,7 @@ +--- +features: + - Added independent and shared types for qos classes in XIV & A9000. + Shared type enables to share bandwidth and IO rates between volumes + of the same class. Independent type gives each volume the same + bandwidth and IO rates without being affected by other volumes in + the same qos class.