From: Wilson Liu Date: Wed, 23 Sep 2015 07:04:33 +0000 (+0800) Subject: Huawei driver add check before use a QoS X-Git-Url: https://review.fuel-infra.org/gitweb?a=commitdiff_plain;h=4d42d496abf25630d1e6bd3ccf8c43ea1b754afb;p=openstack-build%2Fcinder-build.git 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 (cherry picked from commit 32099d547a2bb9c5f21de4592c5bf08272fcb14c) --- diff --git a/cinder/tests/unit/test_huawei_drivers.py b/cinder/tests/unit/test_huawei_drivers.py index 17e919690..70d3f2bf4 100644 --- a/cinder/tests/unit/test_huawei_drivers.py +++ b/cinder/tests/unit/test_huawei_drivers.py @@ -1651,6 +1651,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. @@ -1687,11 +1730,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') @@ -2158,11 +2196,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 f04814806..03ce11075 100644 --- a/cinder/volume/drivers/huawei/rest_client.py +++ b/cinder/volume/drivers/huawei/rest_client.py @@ -1479,13 +1479,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']: @@ -1496,7 +1500,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