Huawei: Check the QoS status before we use

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
This commit is contained in:
Wilson Liu 2016-01-23 10:46:56 +08:00 committed by huananhuawei
parent fc282f1ca0
commit d3f2f0b0e9
5 changed files with 71 additions and 18 deletions

View 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"]'
}]
}

View 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

View 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):

View 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)

View 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):