]> review.fuel-infra Code Review - openstack-build/cinder-build.git/commitdiff
Huawei: Check the QoS status before we use
authorWilson Liu <liuxinguo@huawei.com>
Sat, 23 Jan 2016 02:46:56 +0000 (10:46 +0800)
committerhuananhuawei <huanan@huawei.com>
Wed, 16 Mar 2016 01:35:46 +0000 (09:35 +0800)
Currently we use a existing QoS without check
whether the QoS is for block storage or NAS,
but one QoS on the array should be used for either
block storage or NAS, not both. Also, we add
check with QoS parameter.

Closes-Bug: #1537301
Change-Id: I9842044249cc59d9c29e887b68d48cf97595efcc

cinder/tests/unit/test_huawei_drivers.py
cinder/volume/drivers/huawei/constants.py
cinder/volume/drivers/huawei/huawei_driver.py
cinder/volume/drivers/huawei/rest_client.py
cinder/volume/drivers/huawei/smartx.py

index 68e428efe75fe18c697e3f2702eb294df08a7731..af7f098f15f95da92d11c5d66d6c9b73721ed9d2 100644 (file)
@@ -2184,7 +2184,11 @@ class HuaweiISCSIDriverTestCase(test.TestCase):
             "data": [{
                 "ID": "11",
                 "MAXIOPS": "100",
+                "LATENCY": "0",
                 "IOType": "2",
+                "FSLIST": u'[""]',
+                'RUNNINGSTATUS': "2",
+                "NAME": "OpenStack_57_20151225102851",
                 "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",\
@@ -2208,7 +2212,11 @@ class HuaweiISCSIDriverTestCase(test.TestCase):
             "data": [{
                 "ID": "11",
                 "MAXIOPS": "100",
+                "LATENCY": "0",
                 "IOType": "2",
+                "FSLIST": u'[""]',
+                'RUNNINGSTATUS': "2",
+                "NAME": "OpenStack_57_20151225102851",
                 "LUNLIST": u'["0", "1", "2"]'
             }]
         }
index 68e047ff21d966526539fd69bad09294f1e92510..1c441a527af1baad7bea58d344911a8012cd3026 100644 (file)
@@ -70,8 +70,10 @@ OS_TYPE = {'Linux': '0',
 
 HUAWEI_VALID_KEYS = ['maxIOPS', 'minIOPS', 'minBandWidth',
                      'maxBandWidth', 'latency', 'IOType']
-QOS_KEYS = ['MAXIOPS', 'MINIOPS', 'MINBANDWidth',
-            'MAXBANDWidth', 'LATENCY', 'IOTYPE']
+QOS_KEYS = [i.upper() for i in HUAWEI_VALID_KEYS]
+EXTRA_QOS_KEYS = ['MAXIOPS', 'MINIOPS', 'MINBANDWIDTH', 'MAXBANDWIDTH']
+LOWER_LIMIT_KEYS = ['MINIOPS', 'LATENCY', 'MINBANDWIDTH']
+UPPER_LIMIT_KEYS = ['MAXIOPS', 'MAXBANDWIDTH']
 MAX_LUN_NUM_IN_QOS = 64
 
 DEFAULT_REPLICA_WAIT_INTERVAL = 1
index b57a166ea29a5f0476b543dc3d974f5bac680f51..ec04587bacda67f59497fd9172b357fc1824be78 100644 (file)
@@ -1017,11 +1017,12 @@ class HuaweiBaseDriver(driver.VolumeDriver):
             qos_info = self.client.get_qos_info(qos_id)
 
         for key, value in qos_info.items():
-            if key.upper() in constants.QOS_KEYS:
-                if key.upper() == 'LATENCY' and value == '0':
+            key = key.upper()
+            if key in constants.QOS_KEYS:
+                if key == 'LATENCY' and value == '0':
                     continue
                 else:
-                    qos[key.upper()] = value
+                    qos[key] = value
         return qos
 
     def create_export(self, context, volume, connector):
index 3d6a1b4eb54f3a161df989a8f64784f5b0df5efa..d42686716eca4d6f1d734826eddb6bad87b3d35c 100644 (file)
@@ -1515,24 +1515,40 @@ class RestClient(object):
         """"Find available QoS on the array."""
         qos_id = None
         lun_list = []
+        extra_qos = [i for i in constants.EXTRA_QOS_KEYS if i not in qos]
         result = self.get_qos()
 
         if 'data' in result:
-            for item in result['data']:
+            for items in result['data']:
                 qos_flag = 0
+                extra_flag = False
+                if 'LATENCY' not in qos and items['LATENCY'] != '0':
+                        extra_flag = True
+                else:
+                    for item in items:
+                        if item in extra_qos:
+                            extra_flag = True
+                            break
                 for key in qos:
-                    if key not in item:
+                    if key not in items:
                         break
-                    elif qos[key] != item[key]:
+                    elif qos[key] != items[key]:
                         break
                     qos_flag = qos_flag + 1
-                lun_num = len(item['LUNLIST'].split(","))
+                lun_num = len(items['LUNLIST'].split(","))
+                qos_name = items['NAME']
+                qos_status = items['RUNNINGSTATUS']
                 # We use this QoS only if the LUNs in it is less than 64,
+                # created by OpenStack and does not contain filesystem,
                 # 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']
+                        and not extra_flag
+                        and lun_num < constants.MAX_LUN_NUM_IN_QOS
+                        and qos_name.startswith(constants.QOS_NAME_PREFIX)
+                        and qos_status == constants.STATUS_QOS_ACTIVE
+                        and items['FSLIST'] == '[""]'):
+                    qos_id = items['ID']
+                    lun_list = items['LUNLIST']
                     break
 
         return (qos_id, lun_list)
index 37c0cb149ab9638cbbd7c429b87b298d482848c0..2569e57073efe9e98d0645326865fb6d96109e09 100644 (file)
@@ -42,24 +42,50 @@ class SmartQos(object):
             return {}
 
         qos = {}
+        io_type_flag = None
         ctxt = context.get_admin_context()
         kvs = qos_specs.get_qos_specs(ctxt, qos_specs_id)['specs']
         LOG.info(_LI('The QoS sepcs is: %s.'), kvs)
         for k, v in kvs.items():
             if k not in constants.HUAWEI_VALID_KEYS:
                 continue
-
-            if k.upper() != 'IOTYPE' and int(v) <= 0:
+            if k != 'IOType' and int(v) <= 0:
                 msg = _('QoS config is wrong. %s must > 0.') % k
                 LOG.error(msg)
                 raise exception.InvalidInput(reason=msg)
-            elif k.upper() == 'IOTYPE' and v not in ['0', '1', '2']:
-                msg = _('Illegal value specified for IOTYPE: 0, 1, or 2.')
-                LOG.error(msg)
-                raise exception.InvalidInput(reason=msg)
+            if k == 'IOType':
+                if v not in ['0', '1', '2']:
+                    msg = _('Illegal value specified for IOTYPE: 0, 1, or 2.')
+                    LOG.error(msg)
+                    raise exception.InvalidInput(reason=msg)
+                io_type_flag = 1
+                qos[k.upper()] = v
             else:
                 qos[k.upper()] = v
 
+        if not io_type_flag:
+            msg = (_('QoS policy must specify for IOTYPE: 0, 1, or 2, '
+                     'QoS policy: %(qos_policy)s ') % {'qos_policy': qos})
+            LOG.error(msg)
+            raise exception.InvalidInput(reason=msg)
+
+        # QoS policy must specify for IOTYPE and another qos_specs.
+        if len(qos) < 2:
+            msg = (_('QoS policy must specify for IOTYPE and another '
+                     'qos_specs, QoS policy: %(qos_policy)s.')
+                   % {'qos_policy': qos})
+            LOG.error(msg)
+            raise exception.InvalidInput(reason=msg)
+
+        for upper_limit in constants.UPPER_LIMIT_KEYS:
+            for lower_limit in constants.LOWER_LIMIT_KEYS:
+                if upper_limit in qos and lower_limit in qos:
+                    msg = (_('QoS policy upper_limit and lower_limit '
+                             'conflict, QoS policy: %(qos_policy)s.')
+                           % {'qos_policy': qos})
+                    LOG.error(msg)
+                    raise exception.InvalidInput(reason=msg)
+
         return qos
 
     def _is_high_priority(self, qos):