Merge "FlashSystem: Add CMMVC6045E CLI error for multi-host mapping" into stable/ocata
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user