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
|
# CMMVC50000 is a fake error which indicates that command has not
|
||||||
# got expected results. This error represents kinds of CLI errors.
|
# got expected results. This error represents kinds of CLI errors.
|
||||||
'CMMVC50000': ('', 'CMMVC50000 The command can not be executed '
|
'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
|
@staticmethod
|
||||||
def _find_unused_id(d):
|
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:
|
if arg_list[0] not in ('svcinfo', 'svctask') or len(arg_list) < 2:
|
||||||
raise exception.InvalidInput(reason=six.text_type(arg_list))
|
raise exception.InvalidInput(reason=six.text_type(arg_list))
|
||||||
ret = {'cmd': arg_list[1]}
|
ret = {'cmd': arg_list[1]}
|
||||||
arg_list.pop(0)
|
|
||||||
|
|
||||||
skip = False
|
skip = False
|
||||||
for i in range(1, len(arg_list)):
|
for i in range(2, len(arg_list)):
|
||||||
if skip:
|
if skip:
|
||||||
skip = False
|
skip = False
|
||||||
continue
|
continue
|
||||||
@@ -612,15 +618,14 @@ class FlashSystemManagementSimulator(object):
|
|||||||
if mapping_info['host'] not in self._hosts_list:
|
if mapping_info['host'] not in self._hosts_list:
|
||||||
return self._errors['CMMVC50000']
|
return self._errors['CMMVC50000']
|
||||||
|
|
||||||
if mapping_info['vol'] in self._mappings_list:
|
|
||||||
return self._errors['CMMVC50000']
|
|
||||||
|
|
||||||
for v in self._mappings_list.values():
|
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
|
if ((v['host'] == mapping_info['host']) and
|
||||||
(v['lun'] == mapping_info['lun'])):
|
(v['lun'] == mapping_info['lun'])):
|
||||||
return self._errors['CMMVC50000']
|
return self._errors['CMMVC50000']
|
||||||
|
|
||||||
for v in self._mappings_list.values():
|
|
||||||
if (v['lun'] == mapping_info['lun']) and ('force' not in kwargs):
|
if (v['lun'] == mapping_info['lun']) and ('force' not in kwargs):
|
||||||
return self._errors['CMMVC50000']
|
return self._errors['CMMVC50000']
|
||||||
|
|
||||||
@@ -748,6 +753,13 @@ class FlashSystemDriverTestCase(test.TestCase):
|
|||||||
'wwpns': ['abcd000000000001', 'abcd000000000002'],
|
'wwpns': ['abcd000000000001', 'abcd000000000002'],
|
||||||
'initiator': 'iqn.123456'}
|
'initiator': 'iqn.123456'}
|
||||||
|
|
||||||
|
self.alt_connector = {
|
||||||
|
'host': 'other',
|
||||||
|
'wwnns': ['0123456789fedcba', '0123456789badcfe'],
|
||||||
|
'wwpns': ['dcba000000000001', 'dcba000000000002'],
|
||||||
|
'initiator': 'iqn.654321'
|
||||||
|
}
|
||||||
|
|
||||||
self.sim = FlashSystemManagementSimulator()
|
self.sim = FlashSystemManagementSimulator()
|
||||||
self.driver = FlashSystemFakeDriver(
|
self.driver = FlashSystemFakeDriver(
|
||||||
configuration=conf.Configuration(None))
|
configuration=conf.Configuration(None))
|
||||||
@@ -1282,6 +1294,25 @@ class FlashSystemDriverTestCase(test.TestCase):
|
|||||||
1,
|
1,
|
||||||
self.driver._map_vdisk_to_host(vol1['name'], self.connector))
|
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
|
# clean environment
|
||||||
self.driver._unmap_vdisk_from_host(vol1['name'], self.connector)
|
self.driver._unmap_vdisk_from_host(vol1['name'], self.connector)
|
||||||
self.driver._unmap_vdisk_from_host(vol2['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"
|
VERSION = "1.0.12"
|
||||||
|
|
||||||
|
MULTI_HOST_MAP_ERRORS = ['CMMVC6045E', 'CMMVC6071E']
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super(FlashSystemDriver, self).__init__(*args, **kwargs)
|
super(FlashSystemDriver, self).__init__(*args, **kwargs)
|
||||||
self.configuration.append_config_values(flashsystem_opts)
|
self.configuration.append_config_values(flashsystem_opts)
|
||||||
@@ -726,6 +728,27 @@ class FlashSystemDriver(san.SanDriver,
|
|||||||
existing_ref=existing_ref, reason=reason)
|
existing_ref=existing_ref, reason=reason)
|
||||||
return vdisk
|
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)
|
@utils.synchronized('flashsystem-map', external=True)
|
||||||
def _map_vdisk_to_host(self, vdisk_name, connector):
|
def _map_vdisk_to_host(self, vdisk_name, connector):
|
||||||
"""Create a mapping between a vdisk to a host."""
|
"""Create a mapping between a vdisk to a host."""
|
||||||
@@ -752,13 +775,18 @@ class FlashSystemDriver(san.SanDriver,
|
|||||||
ssh_cmd = ['svctask', 'mkvdiskhostmap', '-host', host_name,
|
ssh_cmd = ['svctask', 'mkvdiskhostmap', '-host', host_name,
|
||||||
'-scsi', six.text_type(result_lun), vdisk_name]
|
'-scsi', six.text_type(result_lun), vdisk_name]
|
||||||
out, err = self._ssh(ssh_cmd, check_exit_code=False)
|
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:
|
if not self.configuration.flashsystem_multihostmap_enabled:
|
||||||
msg = _('flashsystem_multihostmap_enabled is set '
|
msg = _(
|
||||||
'to False, not allow multi host mapping. '
|
'flashsystem_multihostmap_enabled is set '
|
||||||
'CMMVC6071E The VDisk-to-host mapping '
|
'to False, failing requested multi-host map. '
|
||||||
'was not created because the VDisk is '
|
'(%(code)s %(message)s)'
|
||||||
'already mapped to a host.')
|
) % map_error
|
||||||
LOG.error(msg)
|
LOG.error(msg)
|
||||||
raise exception.VolumeBackendAPIException(data=msg)
|
raise exception.VolumeBackendAPIException(data=msg)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user