From 32099d547a2bb9c5f21de4592c5bf08272fcb14c Mon Sep 17 00:00:00 2001 From: Wilson Liu Date: Wed, 23 Sep 2015 15:04:33 +0800 Subject: [PATCH] Huawei driver add check before use a QoS One QoS in Huawei storage array can contain at most 64 LUNs. Do a check before adding LUN to QoS, if the number of the LUNs in the QoS is already equal or larger than 64, then this QoS should not be used. Closed-Bug: #1498773 Change-Id: I9dd78cc1378051ded135a885cfc9347d42977311 --- cinder/tests/unit/test_huawei_drivers.py | 53 +++++++++++++++++---- cinder/volume/drivers/huawei/constants.py | 1 + cinder/volume/drivers/huawei/rest_client.py | 16 +++++-- 3 files changed, 56 insertions(+), 14 deletions(-) diff --git a/cinder/tests/unit/test_huawei_drivers.py b/cinder/tests/unit/test_huawei_drivers.py index a86257a6f..4356e6e47 100644 --- a/cinder/tests/unit/test_huawei_drivers.py +++ b/cinder/tests/unit/test_huawei_drivers.py @@ -1653,6 +1653,49 @@ class Huawei18000ISCSIDriverTestCase(test.TestCase): lun_info = self.driver.create_volume(test_volume) self.assertEqual('1', lun_info['provider_location']) + def test_find_available_qos(self): + self.driver.restclient.login() + qos = {'MAXIOPS': '100', 'IOType': '2'} + fake_qos_info_response_equal = { + "error": { + "code": 0 + }, + "data": [{ + "ID": "11", + "MAXIOPS": "100", + "IOType": "2", + "LUNLIST": u'["1", "2", "3", "4", "5", "6", "7", "8", "9",\ + "10", ,"11", "12", "13", "14", "15", "16", "17", "18", "19",\ + "20", ,"21", "22", "23", "24", "25", "26", "27", "28", "29",\ + "30", ,"31", "32", "33", "34", "35", "36", "37", "38", "39",\ + "40", ,"41", "42", "43", "44", "45", "46", "47", "48", "49",\ + "50", ,"51", "52", "53", "54", "55", "56", "57", "58", "59",\ + "60", ,"61", "62", "63", "64"]' + }] + } + # Number of LUNs in QoS is equal to 64 + with mock.patch.object(rest_client.RestClient, 'get_qos', + return_value=fake_qos_info_response_equal): + (qos_id, lun_list) = self.driver.restclient.find_available_qos(qos) + self.assertEqual((None, []), (qos_id, lun_list)) + + # Number of LUNs in QoS is less than 64 + fake_qos_info_response_less = { + "error": { + "code": 0 + }, + "data": [{ + "ID": "11", + "MAXIOPS": "100", + "IOType": "2", + "LUNLIST": u'["0", "1", "2"]' + }] + } + with mock.patch.object(rest_client.RestClient, 'get_qos', + return_value=fake_qos_info_response_less): + (qos_id, lun_list) = self.driver.restclient.find_available_qos(qos) + self.assertEqual(("11", u'["0", "1", "2"]'), (qos_id, lun_list)) + def create_fake_conf_file(self): """Create a fake Config file. @@ -1689,11 +1732,6 @@ class Huawei18000ISCSIDriverTestCase(test.TestCase): url.appendChild(url_text) storage.appendChild(url) - storagepool = doc.createElement('StoragePool') - pool_text = doc.createTextNode('OpenStack_Pool') - storagepool.appendChild(pool_text) - storage.appendChild(storagepool) - lun = doc.createElement('LUN') config.appendChild(lun) storagepool = doc.createElement('StoragePool') @@ -2188,11 +2226,6 @@ class Huawei18000FCDriverTestCase(test.TestCase): url.appendChild(url_text) storage.appendChild(url) - storagepool = doc.createElement('StoragePool') - pool_text = doc.createTextNode('OpenStack_Pool') - storagepool.appendChild(pool_text) - storage.appendChild(storagepool) - lun = doc.createElement('LUN') config.appendChild(lun) storagepool = doc.createElement('StoragePool') diff --git a/cinder/volume/drivers/huawei/constants.py b/cinder/volume/drivers/huawei/constants.py index 7f4f9443b..f2174ba5f 100644 --- a/cinder/volume/drivers/huawei/constants.py +++ b/cinder/volume/drivers/huawei/constants.py @@ -60,3 +60,4 @@ HUAWEI_VALID_KEYS = ['maxIOPS', 'minIOPS', 'minBandWidth', 'maxBandWidth', 'latency', 'IOType'] QOS_KEYS = ['MAXIOPS', 'MINIOPS', 'MINBANDWidth', 'MAXBANDWidth', 'LATENCY', 'IOTYPE'] +MAX_LUN_NUM_IN_QOS = 64 diff --git a/cinder/volume/drivers/huawei/rest_client.py b/cinder/volume/drivers/huawei/rest_client.py index 3c90a9378..e2db78ead 100644 --- a/cinder/volume/drivers/huawei/rest_client.py +++ b/cinder/volume/drivers/huawei/rest_client.py @@ -1463,13 +1463,17 @@ class RestClient(object): result = self.call(url, data, "PUT") self._assert_rest_result(result, _('Remove lun from cache error.')) + def get_qos(self): + url = "/ioclass" + result = self.call(url, None, "GET") + self._assert_rest_result(result, _('Get QoS information error.')) + return result + def find_available_qos(self, qos): """"Find available QoS on the array.""" qos_id = None lun_list = [] - url = "/ioclass" - result = self.call(url, None, "GET") - self._assert_rest_result(result, _('Get QoS information error.')) + result = self.get_qos() if 'data' in result: for item in result['data']: @@ -1480,7 +1484,11 @@ class RestClient(object): elif qos[key] != item[key]: break qos_flag = qos_flag + 1 - if qos_flag == len(qos): + lun_num = len(item['LUNLIST'].split(",")) + # We use this QoS only if the LUNs in it is less than 64, + # else we cannot add LUN to this QoS any more. + if (qos_flag == len(qos) + and lun_num < constants.MAX_LUN_NUM_IN_QOS): qos_id = item['ID'] lun_list = item['LUNLIST'] break -- 2.45.2