Storwize: remove SCSI LUN ID for volume attaching
The VDisk-to-host mapping may fail due to the SCSI LUN id is already used by other VDisk mapping to this host, which is caused by serveral cinder volume nodes run parallelly and serveral volumes attaching parallelly. storwize volume driver does not need to calculate SCSI LUN ID locally for volume attaching. The SCSI LUN ID can be decided by storage backend correctly. Closes-Bug: 1603282 Change-Id: Ic8d229b539f1b2b79f530f966eb09154e5f13a2c
This commit is contained in:
parent
ca9038628e
commit
f3d1be2319
|
@ -1084,14 +1084,14 @@ port_speed!N/A
|
|||
def _cmd_mkvdiskhostmap(self, **kwargs):
|
||||
mapping_info = {}
|
||||
mapping_info['id'] = self._find_unused_id(self._mappings_list)
|
||||
|
||||
if 'host' not in kwargs:
|
||||
return self._errors['CMMVC5707E']
|
||||
mapping_info['host'] = kwargs['host'].strip('\'\"')
|
||||
|
||||
if 'scsi' not in kwargs:
|
||||
return self._errors['CMMVC5707E']
|
||||
mapping_info['lun'] = kwargs['scsi'].strip('\'\"')
|
||||
if 'scsi' in kwargs:
|
||||
mapping_info['lun'] = kwargs['scsi'].strip('\'\"')
|
||||
else:
|
||||
mapping_info['lun'] = mapping_info['id']
|
||||
|
||||
if 'obj' not in kwargs:
|
||||
return self._errors['CMMVC5707E']
|
||||
|
@ -1112,7 +1112,7 @@ port_speed!N/A
|
|||
return self._errors['CMMVC5879E']
|
||||
|
||||
for v in self._mappings_list.values():
|
||||
if (v['lun'] == mapping_info['lun']) and ('force' not in kwargs):
|
||||
if (v['vol'] == mapping_info['vol']) and ('force' not in kwargs):
|
||||
return self._errors['CMMVC6071E']
|
||||
|
||||
self._mappings_list[mapping_info['id']] = mapping_info
|
||||
|
@ -1169,7 +1169,7 @@ port_speed!N/A
|
|||
# List information about vdisk->host mappings
|
||||
def _cmd_lsvdiskhostmap(self, **kwargs):
|
||||
mappings_found = 0
|
||||
vdisk_name = kwargs['obj']
|
||||
vdisk_name = kwargs['obj'].strip('\'\"')
|
||||
|
||||
if vdisk_name not in self._volumes_list:
|
||||
return self._errors['CMMVC5753E']
|
||||
|
@ -1183,7 +1183,7 @@ port_speed!N/A
|
|||
mappings_found += 1
|
||||
volume = self._volumes_list[mapping['vol']]
|
||||
host = self._hosts_list[mapping['host']]
|
||||
rows.append([volume['id'], volume['name'], host['id'],
|
||||
rows.append([volume['id'], mapping['lun'], host['id'],
|
||||
host['host_name'], volume['uid'],
|
||||
volume['IO_group_id'], volume['IO_group_name']])
|
||||
|
||||
|
@ -5187,23 +5187,42 @@ class StorwizeHelpersTestCase(test.TestCase):
|
|||
class StorwizeSSHTestCase(test.TestCase):
|
||||
def setUp(self):
|
||||
super(StorwizeSSHTestCase, self).setUp()
|
||||
self.storwize_ssh = storwize_svc_common.StorwizeSSH(None)
|
||||
self.fake_driver = StorwizeSVCISCSIFakeDriver(
|
||||
configuration=conf.Configuration(None))
|
||||
sim = StorwizeSVCManagementSimulator(['openstack'])
|
||||
self.fake_driver.set_fake_storage(sim)
|
||||
self.storwize_ssh = storwize_svc_common.StorwizeSSH(
|
||||
self.fake_driver._run_ssh)
|
||||
|
||||
def test_mkvdiskhostmap(self):
|
||||
# mkvdiskhostmap should not be returning anything
|
||||
self.fake_driver.fake_storage._volumes_list['9999'] = {
|
||||
'name': ' 9999', 'id': '0', 'uid': '0',
|
||||
'IO_group_id': '0', 'IO_group_name': 'fakepool'}
|
||||
self.fake_driver.fake_storage._hosts_list['HOST1'] = {
|
||||
'name': 'HOST1', 'id': '0', 'host_name': 'HOST1'}
|
||||
self.fake_driver.fake_storage._hosts_list['HOST2'] = {
|
||||
'name': 'HOST2', 'id': '1', 'host_name': 'HOST2'}
|
||||
self.fake_driver.fake_storage._hosts_list['HOST3'] = {
|
||||
'name': 'HOST3', 'id': '2', 'host_name': 'HOST3'}
|
||||
|
||||
ret = self.storwize_ssh.mkvdiskhostmap('HOST1', '9999', '511', False)
|
||||
self.assertEqual('511', ret)
|
||||
|
||||
ret = self.storwize_ssh.mkvdiskhostmap('HOST2', '9999', '512', True)
|
||||
self.assertEqual('512', ret)
|
||||
|
||||
ret = self.storwize_ssh.mkvdiskhostmap('HOST3', '9999', None, True)
|
||||
self.assertIsNotNone(ret)
|
||||
|
||||
with mock.patch.object(
|
||||
storwize_svc_common.StorwizeSSH,
|
||||
'run_ssh_check_created') as run_ssh_check_created:
|
||||
run_ssh_check_created.return_value = None
|
||||
ret = self.storwize_ssh.mkvdiskhostmap('HOST1', 9999, 511, False)
|
||||
self.assertIsNone(ret)
|
||||
ret = self.storwize_ssh.mkvdiskhostmap('HOST2', 9999, 511, True)
|
||||
self.assertIsNone(ret)
|
||||
ex = exception.VolumeBackendAPIException(data='CMMVC6071E')
|
||||
run_ssh_check_created.side_effect = ex
|
||||
self.assertRaises(exception.VolumeBackendAPIException,
|
||||
self.storwize_ssh.mkvdiskhostmap,
|
||||
'HOST3', 9999, 511, True)
|
||||
'HOST3', '9999', 511, True)
|
||||
|
||||
|
||||
class StorwizeSVCReplicationMirrorTestCase(test.TestCase):
|
||||
|
|
|
@ -254,12 +254,26 @@ class StorwizeSSH(object):
|
|||
|
||||
If vdisk already mapped and multihostmap is True, use the force flag.
|
||||
"""
|
||||
ssh_cmd = ['svctask', 'mkvdiskhostmap', '-host', '"%s"' % host,
|
||||
'-scsi', lun, '"%s"' % vdisk]
|
||||
ssh_cmd = ['svctask', 'mkvdiskhostmap', '-host', '"%s"' % host, vdisk]
|
||||
|
||||
if lun:
|
||||
ssh_cmd.insert(ssh_cmd.index(vdisk), '-scsi')
|
||||
ssh_cmd.insert(ssh_cmd.index(vdisk), lun)
|
||||
|
||||
if multihostmap:
|
||||
ssh_cmd.insert(ssh_cmd.index('mkvdiskhostmap') + 1, '-force')
|
||||
try:
|
||||
self.run_ssh_check_created(ssh_cmd)
|
||||
result_lun = self.get_vdiskhostmapid(vdisk, host)
|
||||
if result_lun is None or (lun and lun != result_lun):
|
||||
msg = (_('mkvdiskhostmap error:\n command: %(cmd)s\n '
|
||||
'lun: %(lun)s\n result_lun: %(result_lun)s') %
|
||||
{'cmd': ssh_cmd,
|
||||
'lun': lun,
|
||||
'result_lun': result_lun})
|
||||
LOG.error(msg)
|
||||
raise exception.VolumeDriverException(message=msg)
|
||||
return result_lun
|
||||
except Exception as ex:
|
||||
if (not multihostmap and hasattr(ex, 'message') and
|
||||
'CMMVC6071E' in ex.message):
|
||||
|
@ -347,6 +361,14 @@ class StorwizeSSH(object):
|
|||
ssh_cmd = ['svcinfo', 'lshostvdiskmap', '-delim', '!', '"%s"' % host]
|
||||
return self.run_ssh_info(ssh_cmd, with_header=True)
|
||||
|
||||
def get_vdiskhostmapid(self, vdisk, host):
|
||||
resp = self.lsvdiskhostmap(vdisk)
|
||||
for mapping_info in resp:
|
||||
if mapping_info['host_name'] == host:
|
||||
lun_id = mapping_info['SCSI_id']
|
||||
return lun_id
|
||||
return None
|
||||
|
||||
def rmhost(self, host):
|
||||
ssh_cmd = ['svctask', 'rmhost', '"%s"' % host]
|
||||
self.run_ssh_assert_no_output(ssh_cmd)
|
||||
|
@ -852,26 +874,10 @@ class StorwizeHelpers(object):
|
|||
{'volume_name': volume_name, 'host_name': host_name})
|
||||
|
||||
# Check if this volume is already mapped to this host
|
||||
mapped = False
|
||||
luns_used = []
|
||||
result_lun = '-1'
|
||||
resp = self.ssh.lshostvdiskmap(host_name)
|
||||
for mapping_info in resp:
|
||||
luns_used.append(int(mapping_info['SCSI_id']))
|
||||
if mapping_info['vdisk_name'] == volume_name:
|
||||
mapped = True
|
||||
result_lun = mapping_info['SCSI_id']
|
||||
|
||||
if not mapped:
|
||||
# Find unused lun
|
||||
luns_used.sort()
|
||||
result_lun = str(len(luns_used))
|
||||
for index, n in enumerate(luns_used):
|
||||
if n > index:
|
||||
result_lun = str(index)
|
||||
break
|
||||
self.ssh.mkvdiskhostmap(host_name, volume_name, result_lun,
|
||||
multihostmap)
|
||||
result_lun = self.ssh.get_vdiskhostmapid(volume_name, host_name)
|
||||
if result_lun is None:
|
||||
result_lun = self.ssh.mkvdiskhostmap(host_name, volume_name, None,
|
||||
multihostmap)
|
||||
|
||||
LOG.debug('Leave: map_vol_to_host: LUN %(result_lun)s, volume '
|
||||
'%(volume_name)s, host %(host_name)s.',
|
||||
|
|
Loading…
Reference in New Issue