Merge "FlashSystem: Add CMMVC6045E CLI error for multi-host mapping" into stable/ocata

This commit is contained in:
Zuul
2018-04-27 16:15:05 +00:00
committed by Gerrit Code Review
2 changed files with 72 additions and 13 deletions

View File

@@ -51,8 +51,15 @@ class FlashSystemManagementSimulator(object):
# CMMVC50000 is a fake error which indicates that command has not
# got expected results. This error represents kinds of CLI errors.
'CMMVC50000': ('', 'CMMVC50000 The command can not be executed '
'successfully.')
'successfully.'),
'CMMVC6045E': ('', 'CMMVC6045E The action failed, as the '
'-force flag was not entered.'),
'CMMVC6071E': ('', 'CMMVC6071E The VDisk-to-host mapping '
'was not created because the VDisk is '
'already mapped to a host.')
}
self._multi_host_map_error = None
self._multi_host_map_errors = ['CMMVC6045E', 'CMMVC6071E']
@staticmethod
def _find_unused_id(d):
@@ -94,10 +101,9 @@ class FlashSystemManagementSimulator(object):
if arg_list[0] not in ('svcinfo', 'svctask') or len(arg_list) < 2:
raise exception.InvalidInput(reason=six.text_type(arg_list))
ret = {'cmd': arg_list[1]}
arg_list.pop(0)
skip = False
for i in range(1, len(arg_list)):
for i in range(2, len(arg_list)):
if skip:
skip = False
continue
@@ -612,15 +618,14 @@ class FlashSystemManagementSimulator(object):
if mapping_info['host'] not in self._hosts_list:
return self._errors['CMMVC50000']
if mapping_info['vol'] in self._mappings_list:
return self._errors['CMMVC50000']
for v in self._mappings_list.values():
if (v['vol'] == mapping_info['vol']) and ('force' not in kwargs):
return self._errors[self._multi_host_map_error or 'CMMVC50000']
if ((v['host'] == mapping_info['host']) and
(v['lun'] == mapping_info['lun'])):
return self._errors['CMMVC50000']
for v in self._mappings_list.values():
if (v['lun'] == mapping_info['lun']) and ('force' not in kwargs):
return self._errors['CMMVC50000']
@@ -748,6 +753,13 @@ class FlashSystemDriverTestCase(test.TestCase):
'wwpns': ['abcd000000000001', 'abcd000000000002'],
'initiator': 'iqn.123456'}
self.alt_connector = {
'host': 'other',
'wwnns': ['0123456789fedcba', '0123456789badcfe'],
'wwpns': ['dcba000000000001', 'dcba000000000002'],
'initiator': 'iqn.654321'
}
self.sim = FlashSystemManagementSimulator()
self.driver = FlashSystemFakeDriver(
configuration=conf.Configuration(None))
@@ -1282,6 +1294,25 @@ class FlashSystemDriverTestCase(test.TestCase):
1,
self.driver._map_vdisk_to_host(vol1['name'], self.connector))
# case 4: multi-host mapping, good path
for error in self.sim._multi_host_map_errors:
self.sim._multi_host_map_error = error
self.assertEqual(
1,
self.driver._map_vdisk_to_host(
vol1['name'], self.alt_connector
)
)
self.driver._unmap_vdisk_from_host(
vol1['name'], self.alt_connector
)
self.sim._multi_host_map_error = None
# case 5: multi-host mapping, bad path
self.assertRaises(
exception.VolumeBackendAPIException,
self.driver._map_vdisk_to_host, vol1['name'], self.alt_connector)
# clean environment
self.driver._unmap_vdisk_from_host(vol1['name'], self.connector)
self.driver._unmap_vdisk_from_host(vol2['name'], self.connector)

View File

@@ -96,6 +96,8 @@ class FlashSystemDriver(san.SanDriver,
VERSION = "1.0.12"
MULTI_HOST_MAP_ERRORS = ['CMMVC6045E', 'CMMVC6071E']
def __init__(self, *args, **kwargs):
super(FlashSystemDriver, self).__init__(*args, **kwargs)
self.configuration.append_config_values(flashsystem_opts)
@@ -726,6 +728,27 @@ class FlashSystemDriver(san.SanDriver,
existing_ref=existing_ref, reason=reason)
return vdisk
def _cli_except(self, fun, cmd, out, err, exc_list):
"""Raise if stderr contains an unexpected error code"""
if not err:
return None
if not isinstance(exc_list, (tuple, list)):
exc_list = [exc_list]
try:
err_type = [e for e in exc_list
if err.startswith(e)].pop()
except IndexError:
msg = _(
'%(fun)s: encountered unexpected CLI error, '
'expected one of: %(errors)s'
) % {'fun': fun,
'errors': ', '.join(exc_list)}
LOG.error(msg)
raise exception.VolumeBackendAPIException(data=msg)
return {'code': err_type, 'message': err.strip(err_type).strip()}
@utils.synchronized('flashsystem-map', external=True)
def _map_vdisk_to_host(self, vdisk_name, connector):
"""Create a mapping between a vdisk to a host."""
@@ -752,13 +775,18 @@ class FlashSystemDriver(san.SanDriver,
ssh_cmd = ['svctask', 'mkvdiskhostmap', '-host', host_name,
'-scsi', six.text_type(result_lun), vdisk_name]
out, err = self._ssh(ssh_cmd, check_exit_code=False)
if err and err.startswith('CMMVC6071E'):
map_error = self._cli_except('_map_vdisk_to_host',
ssh_cmd,
out,
err,
self.MULTI_HOST_MAP_ERRORS)
if map_error:
if not self.configuration.flashsystem_multihostmap_enabled:
msg = _('flashsystem_multihostmap_enabled is set '
'to False, not allow multi host mapping. '
'CMMVC6071E The VDisk-to-host mapping '
'was not created because the VDisk is '
'already mapped to a host.')
msg = _(
'flashsystem_multihostmap_enabled is set '
'to False, failing requested multi-host map. '
'(%(code)s %(message)s)'
) % map_error
LOG.error(msg)
raise exception.VolumeBackendAPIException(data=msg)