Merge "Huawei: Record and check LUN wwn"
This commit is contained in:
commit
69e8575dc8
@ -52,20 +52,22 @@ hypermetro_devices = """{
|
||||
}
|
||||
"""
|
||||
|
||||
test_volume = {'name': 'volume-21ec7341-9256-497b-97d9-ef48edcf0635',
|
||||
'size': 2,
|
||||
'volume_name': 'vol1',
|
||||
'id': '21ec7341-9256-497b-97d9-ef48edcf0635',
|
||||
'volume_id': '21ec7341-9256-497b-97d9-ef48edcf0635',
|
||||
'provider_auth': None,
|
||||
'project_id': 'project',
|
||||
'display_name': 'vol1',
|
||||
'display_description': 'test volume',
|
||||
'volume_type_id': None,
|
||||
'host': 'ubuntu001@backend001#OpenStack_Pool',
|
||||
'provider_location': '11',
|
||||
'status': 'available',
|
||||
}
|
||||
test_volume = {
|
||||
'name': 'volume-21ec7341-9256-497b-97d9-ef48edcf0635',
|
||||
'size': 2,
|
||||
'volume_name': 'vol1',
|
||||
'id': '21ec7341-9256-497b-97d9-ef48edcf0635',
|
||||
'volume_id': '21ec7341-9256-497b-97d9-ef48edcf0635',
|
||||
'provider_auth': None,
|
||||
'project_id': 'project',
|
||||
'display_name': 'vol1',
|
||||
'display_description': 'test volume',
|
||||
'volume_type_id': None,
|
||||
'host': 'ubuntu001@backend001#OpenStack_Pool',
|
||||
'provider_location': '11',
|
||||
'status': 'available',
|
||||
'admin_metadata': {'huawei_lun_wwn': '6643e8c1004c5f6723e9f454003'},
|
||||
}
|
||||
|
||||
fake_smartx_value = {'smarttier': 'true',
|
||||
'smartcache': 'true',
|
||||
@ -101,6 +103,7 @@ hyper_volume = {'name': 'volume-21ec7341-9256-497b-97d9-ef48edcf0635',
|
||||
'value': '1'},
|
||||
{'key': 'remote_lun_id',
|
||||
'value': '11'}],
|
||||
'admin_metadata': {},
|
||||
}
|
||||
|
||||
sync_replica_specs = {'replication_enabled': '<is> True',
|
||||
@ -122,26 +125,28 @@ replication_volume = {
|
||||
'volume_type_id': None,
|
||||
'host': 'ubuntu@huawei#OpenStack_Pool',
|
||||
'provider_location': '11',
|
||||
'metadata': {'lun_wwn': '6643e8c1004c5f6723e9f454003'},
|
||||
'admin_metadata': {'huawei_lun_wwn': '6643e8c1004c5f6723e9f454003'},
|
||||
'replication_status': 'disabled',
|
||||
'replication_driver_data':
|
||||
'{"pair_id": "%s", "rmt_lun_id": "1"}' % TEST_PAIR_ID,
|
||||
}
|
||||
|
||||
test_snap = {'name': 'volume-21ec7341-9256-497b-97d9-ef48edcf0635',
|
||||
'size': 1,
|
||||
'volume_name': 'vol1',
|
||||
'id': '21ec7341-9256-497b-97d9-ef48edcf0635',
|
||||
'volume_id': '21ec7341-9256-497b-97d9-ef48edcf0635',
|
||||
'provider_auth': None,
|
||||
'project_id': 'project',
|
||||
'display_name': 'vol1',
|
||||
'display_description': 'test volume',
|
||||
'volume_type_id': None,
|
||||
'provider_location': '11',
|
||||
'volume': {"volume_id": '21ec7341-9256-497b-97d9-ef48edcf0635',
|
||||
'provider_location': '12'},
|
||||
}
|
||||
test_snap = {
|
||||
'name': 'volume-21ec7341-9256-497b-97d9-ef48edcf0635',
|
||||
'size': 1,
|
||||
'volume_name': 'vol1',
|
||||
'id': '21ec7341-9256-497b-97d9-ef48edcf0635',
|
||||
'volume_id': '21ec7341-9256-497b-97d9-ef48edcf0635',
|
||||
'provider_auth': None,
|
||||
'project_id': 'project',
|
||||
'display_name': 'vol1',
|
||||
'display_description': 'test volume',
|
||||
'volume_type_id': None,
|
||||
'provider_location': '11',
|
||||
'volume': {'provider_location': '12',
|
||||
'admin_metadata': {
|
||||
'huawei_lun_wwn': '6643e8c1004c5f6723e9f454003'}},
|
||||
}
|
||||
|
||||
test_host = {'host': 'ubuntu001@backend001#OpenStack_Pool',
|
||||
'capabilities': {'smartcache': True,
|
||||
@ -219,7 +224,8 @@ FAKE_FIND_POOL_RESPONSE = {'CAPACITY': '985661440',
|
||||
'TOTALCAPACITY': '985661440'}
|
||||
|
||||
FAKE_CREATE_VOLUME_RESPONSE = {"ID": "1",
|
||||
"NAME": "5mFHcBv4RkCcD+JyrWc0SA"}
|
||||
"NAME": "5mFHcBv4RkCcD+JyrWc0SA",
|
||||
"WWN": '6643e8c1004c5f6723e9f454003'}
|
||||
|
||||
FakeConnector = {'initiator': 'iqn.1993-08.debian:01:ec2bff7ac3a3',
|
||||
'wwpns': ['10000090fa0d6754'],
|
||||
@ -1944,6 +1950,25 @@ class HuaweiISCSIDriverTestCase(test.TestCase):
|
||||
device_id = self.driver.client.login()
|
||||
self.assertEqual('210235G7J20000000000', device_id)
|
||||
|
||||
def test_check_volume_exist_on_array(self):
|
||||
test_volume = {'name': 'volume-21ec7341-9256-497b-97d9-ef48edcf0635',
|
||||
'size': 2,
|
||||
'volume_name': 'vol1',
|
||||
'id': '21ec7341-9256-497b-97d9-ef48edcf0635',
|
||||
'volume_id': '21ec7341-9256-497b-97d9-ef48edcf0635',
|
||||
'provider_auth': None,
|
||||
'project_id': 'project',
|
||||
'display_name': 'vol1',
|
||||
'display_description': 'test volume',
|
||||
'volume_type_id': None,
|
||||
'host': 'ubuntu001@backend001#OpenStack_Pool',
|
||||
'provider_location': None,
|
||||
}
|
||||
self.mock_object(rest_client.RestClient, 'get_lun_id_by_name',
|
||||
mock.Mock(return_value=None))
|
||||
self.driver._check_volume_exist_on_array(
|
||||
test_volume, constants.VOLUME_NOT_EXISTS_WARN)
|
||||
|
||||
def test_create_volume_success(self):
|
||||
# Have pool info in the volume.
|
||||
test_volume = {'name': 'volume-21ec7341-9256-497b-97d9-ef48edcf0635',
|
||||
@ -1958,6 +1983,7 @@ class HuaweiISCSIDriverTestCase(test.TestCase):
|
||||
'volume_type_id': None,
|
||||
'host': 'ubuntu001@backend001#OpenStack_Pool',
|
||||
'provider_location': '11',
|
||||
'admin_metadata': {},
|
||||
}
|
||||
lun_info = self.driver.create_volume(test_volume)
|
||||
self.assertEqual('1', lun_info['provider_location'])
|
||||
@ -1975,6 +2001,7 @@ class HuaweiISCSIDriverTestCase(test.TestCase):
|
||||
'volume_type_id': None,
|
||||
'host': 'ubuntu001@backend001',
|
||||
'provider_location': '11',
|
||||
'admin_metadata': {},
|
||||
}
|
||||
lun_info = self.driver.create_volume(test_volume)
|
||||
self.assertEqual('1', lun_info['provider_location'])
|
||||
@ -2066,7 +2093,7 @@ class HuaweiISCSIDriverTestCase(test.TestCase):
|
||||
|
||||
def test_delete_snapshot_fail(self):
|
||||
self.driver.client.test_fail = True
|
||||
self.driver.delete_volume(test_snap)
|
||||
self.driver.delete_snapshot(test_snap)
|
||||
|
||||
def test_delete_snapshot_with_snapshot_nonexistent(self):
|
||||
fake_snap = {
|
||||
@ -2503,7 +2530,8 @@ class HuaweiISCSIDriverTestCase(test.TestCase):
|
||||
return_value={'CAPACITY': 2097152,
|
||||
'ID': 'ID1',
|
||||
'PARENTNAME': 'StoragePool001',
|
||||
'HEALTHSTATUS': constants.STATUS_HEALTH})
|
||||
'HEALTHSTATUS': constants.STATUS_HEALTH,
|
||||
'WWN': '6643e8c1004c5f6723e9f454003'})
|
||||
@mock.patch.object(rest_client.RestClient, 'get_lun_id_by_name',
|
||||
return_value='ID1')
|
||||
def test_manage_existing_with_lower_version(self, mock_get_by_name,
|
||||
@ -2511,13 +2539,20 @@ class HuaweiISCSIDriverTestCase(test.TestCase):
|
||||
mock_get_hyper_pairs):
|
||||
test_volume = {'host': 'ubuntu-204@v3r3#StoragePool001',
|
||||
'id': '21ec7341-9256-497b-97d9-ef48edcf0635',
|
||||
'name': 'volume-21ec7341-9256-497b-97d9-ef48edcf'}
|
||||
'name': 'volume-21ec7341-9256-497b-97d9-ef48edcf',
|
||||
'admin_metadata': {
|
||||
'huawei_lun_wwn': '6643e8c1004c5f6723e9f454003'}}
|
||||
mock_get_hyper_pairs.side_effect = (
|
||||
exception.VolumeBackendAPIException(data='err'))
|
||||
external_ref = {'source-name': 'LUN1'}
|
||||
model_update = self.driver.manage_existing(test_volume,
|
||||
external_ref)
|
||||
self.assertEqual({'provider_location': 'ID1'}, model_update)
|
||||
expected_val = {
|
||||
'admin_metadata': {
|
||||
'huawei_lun_wwn': '6643e8c1004c5f6723e9f454003'
|
||||
},
|
||||
'provider_location': 'ID1'}
|
||||
self.assertEqual(expected_val, model_update)
|
||||
|
||||
@ddt.data([[{'PRILUNID': 'ID1'}], []],
|
||||
[[{'PRILUNID': 'ID2'}], ['ID1', 'ID2']])
|
||||
@ -2594,7 +2629,8 @@ class HuaweiISCSIDriverTestCase(test.TestCase):
|
||||
return_value={'PARENTNAME': 'StoragePool001',
|
||||
'SNAPSHOTIDS': [],
|
||||
'ID': 'ID1',
|
||||
'HEALTHSTATUS': constants.STATUS_HEALTH})
|
||||
'HEALTHSTATUS': constants.STATUS_HEALTH,
|
||||
'WWN': '6643e8c1004c5f6723e9f454003'})
|
||||
@mock.patch.object(rest_client.RestClient, 'get_lun_info',
|
||||
return_value={'CAPACITY': 2097152,
|
||||
'ALLOCTYPE': 1})
|
||||
@ -2603,19 +2639,30 @@ class HuaweiISCSIDriverTestCase(test.TestCase):
|
||||
def test_manage_existing_success(self, mock_get_by_name, mock_get_info,
|
||||
mock_check_lun, mock_rename,
|
||||
external_ref):
|
||||
test_volume = {'host': 'ubuntu-204@v3r3#StoragePool001',
|
||||
'id': '21ec7341-9256-497b-97d9-ef48edcf0635',
|
||||
'name': 'volume-21ec7341-9256-497b-97d9-ef48edcf'}
|
||||
test_volume = {
|
||||
'host': 'ubuntu-204@v3r3#StoragePool001',
|
||||
'id': '21ec7341-9256-497b-97d9-ef48edcf0635',
|
||||
'name': 'volume-21ec7341-9256-497b-97d9-ef48edcf',
|
||||
'admin_metadata': {
|
||||
'huawei_lun_wwn': '6643e8c1004c5f6723e9f454003'
|
||||
}
|
||||
}
|
||||
model_update = self.driver.manage_existing(test_volume,
|
||||
external_ref)
|
||||
self.assertEqual({'provider_location': 'ID1'}, model_update)
|
||||
expected_val = {
|
||||
'admin_metadata': {
|
||||
'huawei_lun_wwn': '6643e8c1004c5f6723e9f454003'
|
||||
},
|
||||
'provider_location': 'ID1'}
|
||||
self.assertEqual(expected_val, model_update)
|
||||
|
||||
@ddt.data([None, 0], ['ID1', 1])
|
||||
@mock.patch.object(rest_client.RestClient, 'rename_lun')
|
||||
def test_unmanage(self, ddt_data, mock_rename):
|
||||
test_volume = {'host': 'ubuntu-204@v3r3#StoragePool001',
|
||||
'id': '21ec7341-9256-497b-97d9-ef48edcf0635'}
|
||||
with mock.patch.object(rest_client.RestClient, 'get_lun_id_by_name',
|
||||
with mock.patch.object(huawei_driver.HuaweiBaseDriver,
|
||||
'_check_volume_exist_on_array',
|
||||
return_value=ddt_data[0]):
|
||||
self.driver.unmanage(test_volume)
|
||||
self.assertEqual(ddt_data[1], mock_rename.call_count)
|
||||
|
@ -103,3 +103,6 @@ REPLICA_DATA_SYNC_KEY = 'ISDATASYNC'
|
||||
REPLICA_DATA_STATUS_SYNCED = '1'
|
||||
REPLICA_DATA_STATUS_COMPLETE = '2'
|
||||
REPLICA_DATA_STATUS_INCOMPLETE = '3'
|
||||
|
||||
VOLUME_NOT_EXISTS_WARN = 'warning'
|
||||
VOLUME_NOT_EXISTS_RAISE = 'raise'
|
||||
|
@ -266,6 +266,9 @@ class HuaweiBaseDriver(driver.VolumeDriver):
|
||||
lun_info = self.client.create_lun(lun_params)
|
||||
model_update['provider_location'] = lun_info['ID']
|
||||
|
||||
admin_metadata = volume['admin_metadata']
|
||||
admin_metadata.update({'huawei_lun_wwn': lun_info['WWN']})
|
||||
model_update['admin_metadata'] = admin_metadata
|
||||
metadata = huawei_utils.get_volume_metadata(volume)
|
||||
model_update['metadata'] = metadata
|
||||
return lun_info, model_update
|
||||
@ -367,9 +370,9 @@ class HuaweiBaseDriver(driver.VolumeDriver):
|
||||
Secondly, remove associate from QoS policy.
|
||||
Thirdly, remove the lun.
|
||||
"""
|
||||
lun_id = volume.get('provider_location')
|
||||
if not lun_id or not self.client.check_lun_exist(lun_id):
|
||||
LOG.warning(_LW("Can't find lun %s on the array."), lun_id)
|
||||
lun_id = self._check_volume_exist_on_array(
|
||||
volume, constants.VOLUME_NOT_EXISTS_WARN)
|
||||
if not lun_id:
|
||||
return
|
||||
|
||||
qos_id = self.client.get_qosid_by_lunid(lun_id)
|
||||
@ -386,6 +389,8 @@ class HuaweiBaseDriver(driver.VolumeDriver):
|
||||
metro.delete_hypermetro(volume)
|
||||
except exception.VolumeBackendAPIException as err:
|
||||
LOG.error(_LE('Delete hypermetro error: %s.'), err)
|
||||
# We have checked the LUN WWN above,
|
||||
# no need to check again here.
|
||||
self._delete_volume(volume)
|
||||
raise
|
||||
|
||||
@ -401,11 +406,11 @@ class HuaweiBaseDriver(driver.VolumeDriver):
|
||||
|
||||
self._delete_volume(volume)
|
||||
|
||||
def _delete_lun_with_check(self, lun_id):
|
||||
def _delete_lun_with_check(self, lun_id, lun_wwn=None):
|
||||
if not lun_id:
|
||||
return
|
||||
|
||||
if self.client.check_lun_exist(lun_id):
|
||||
if self.client.check_lun_exist(lun_id, lun_wwn):
|
||||
qos_id = self.client.get_qosid_by_lunid(lun_id)
|
||||
if qos_id:
|
||||
smart_qos = smartx.SmartQos(self.client)
|
||||
@ -512,6 +517,8 @@ class HuaweiBaseDriver(driver.VolumeDriver):
|
||||
|
||||
def migrate_volume(self, ctxt, volume, host, new_type=None):
|
||||
"""Migrate a volume within the same array."""
|
||||
self._check_volume_exist_on_array(volume,
|
||||
constants.VOLUME_NOT_EXISTS_RAISE)
|
||||
|
||||
# NOTE(jlc): Replication volume can't migrate. But retype
|
||||
# can remove replication relationship first then do migrate.
|
||||
@ -681,11 +688,8 @@ class HuaweiBaseDriver(driver.VolumeDriver):
|
||||
|
||||
def create_cloned_volume(self, volume, src_vref):
|
||||
"""Clone a new volume from an existing volume."""
|
||||
if src_vref.get('provider_location') is None:
|
||||
msg = (_("Can't find lun id from db, volume: %(id)s") %
|
||||
{"id": volume['id']})
|
||||
LOG.error(msg)
|
||||
raise exception.VolumeBackendAPIException(data=msg)
|
||||
self._check_volume_exist_on_array(src_vref,
|
||||
constants.VOLUME_NOT_EXISTS_RAISE)
|
||||
|
||||
# Form the snapshot structure.
|
||||
snapshot = {'id': uuid.uuid4().__str__(),
|
||||
@ -711,6 +715,42 @@ class HuaweiBaseDriver(driver.VolumeDriver):
|
||||
|
||||
return model_update
|
||||
|
||||
def _check_volume_exist_on_array(self, volume, action):
|
||||
"""Check whether the volume exists on the array.
|
||||
|
||||
If the volume exists on the array, return the LUN ID.
|
||||
If not exists, raise or log warning.
|
||||
"""
|
||||
# Firstly, try to find LUN ID by volume['provider_location'].
|
||||
lun_id = volume.get('provider_location')
|
||||
# If LUN ID not recorded, find LUN ID by LUN NAME.
|
||||
if not lun_id:
|
||||
volume_name = huawei_utils.encode_name(volume['id'])
|
||||
lun_id = self.client.get_lun_id_by_name(volume_name)
|
||||
if not lun_id:
|
||||
msg = (_("Volume %s does not exist on the array.")
|
||||
% volume['id'])
|
||||
if action == constants.VOLUME_NOT_EXISTS_WARN:
|
||||
LOG.warning(msg)
|
||||
if action == constants.VOLUME_NOT_EXISTS_RAISE:
|
||||
raise exception.VolumeBackendAPIException(data=msg)
|
||||
return
|
||||
|
||||
metadata = volume['admin_metadata']
|
||||
lun_wwn = metadata.get('huawei_lun_wwn') if metadata else None
|
||||
if not lun_wwn:
|
||||
LOG.debug("No LUN WWN recorded for volume %s.", volume['id'])
|
||||
|
||||
if not self.client.check_lun_exist(lun_id, lun_wwn):
|
||||
msg = (_("Volume %s does not exist on the array.")
|
||||
% volume['id'])
|
||||
if action == constants.VOLUME_NOT_EXISTS_WARN:
|
||||
LOG.warning(msg)
|
||||
if action == constants.VOLUME_NOT_EXISTS_RAISE:
|
||||
raise exception.VolumeBackendAPIException(data=msg)
|
||||
return
|
||||
return lun_id
|
||||
|
||||
def extend_volume(self, volume, new_size):
|
||||
"""Extend a volume."""
|
||||
lun_id = volume.get('provider_location')
|
||||
@ -807,6 +847,8 @@ class HuaweiBaseDriver(driver.VolumeDriver):
|
||||
'new_type': new_type,
|
||||
'diff': diff,
|
||||
'host': host})
|
||||
self._check_volume_exist_on_array(
|
||||
volume, constants.VOLUME_NOT_EXISTS_RAISE)
|
||||
|
||||
# Check what changes are needed
|
||||
migration, change_opts, lun_id = self.determine_changes_when_retype(
|
||||
@ -1267,8 +1309,11 @@ class HuaweiBaseDriver(driver.VolumeDriver):
|
||||
{'old_name': lun_info.get('NAME'),
|
||||
'new_name': new_name})
|
||||
self.client.rename_lun(lun_id, new_name, description)
|
||||
metadata = volume['admin_metadata']
|
||||
metadata.update({'huawei_lun_wwn': lun_info['WWN']})
|
||||
|
||||
model_update = {}
|
||||
model_update.update({'admin_metadata': metadata})
|
||||
model_update.update({'provider_location': lun_id})
|
||||
|
||||
if new_opts and new_opts.get('replication_enabled'):
|
||||
@ -1305,14 +1350,14 @@ class HuaweiBaseDriver(driver.VolumeDriver):
|
||||
|
||||
def unmanage(self, volume):
|
||||
"""Export Huawei volume from Cinder."""
|
||||
volume_id = volume['id']
|
||||
LOG.debug("Unmanage volume: %s.", volume_id)
|
||||
lun_name = huawei_utils.encode_name(volume_id)
|
||||
lun_id = self.client.get_lun_id_by_name(lun_name)
|
||||
LOG.debug("Unmanage volume: %s.", volume['id'])
|
||||
|
||||
lun_id = self._check_volume_exist_on_array(
|
||||
volume, constants.VOLUME_NOT_EXISTS_WARN)
|
||||
if not lun_id:
|
||||
LOG.error(_LE("Can't find LUN on the array for volume: %s."),
|
||||
volume_id)
|
||||
return
|
||||
|
||||
lun_name = huawei_utils.encode_name(volume['id'])
|
||||
new_name = 'unmged_' + lun_name
|
||||
LOG.debug("Rename LUN %(lun_name)s to %(new_name)s.",
|
||||
{'lun_name': lun_name,
|
||||
@ -1574,15 +1619,15 @@ class HuaweiISCSIDriver(HuaweiBaseDriver, driver.ISCSIDriver):
|
||||
@utils.synchronized('huawei', external=True)
|
||||
def initialize_connection(self, volume, connector):
|
||||
"""Map a volume to a host and return target iSCSI information."""
|
||||
LOG.info(_LI('Enter initialize_connection.'))
|
||||
initiator_name = connector['initiator']
|
||||
volume_name = huawei_utils.encode_name(volume['id'])
|
||||
lun_id = self._check_volume_exist_on_array(
|
||||
volume, constants.VOLUME_NOT_EXISTS_RAISE)
|
||||
|
||||
initiator_name = connector['initiator']
|
||||
LOG.info(_LI(
|
||||
'initiator name: %(initiator_name)s, '
|
||||
'volume name: %(volume)s.'),
|
||||
'LUN ID: %(lun_id)s.'),
|
||||
{'initiator_name': initiator_name,
|
||||
'volume': volume_name})
|
||||
'lun_id': lun_id})
|
||||
|
||||
(iscsi_iqns,
|
||||
target_ips,
|
||||
@ -1605,8 +1650,6 @@ class HuaweiISCSIDriver(HuaweiBaseDriver, driver.ISCSIDriver):
|
||||
host_id)
|
||||
hostgroup_id = self.client.add_host_to_hostgroup(host_id)
|
||||
|
||||
lun_id = self.client.get_lun_id(volume, volume_name)
|
||||
|
||||
# Mapping lungroup and hostgroup to view.
|
||||
self.client.do_mapping(lun_id, hostgroup_id,
|
||||
host_id, portgroup_id)
|
||||
@ -1649,18 +1692,16 @@ class HuaweiISCSIDriver(HuaweiBaseDriver, driver.ISCSIDriver):
|
||||
@utils.synchronized('huawei', external=True)
|
||||
def terminate_connection(self, volume, connector, **kwargs):
|
||||
"""Delete map between a volume and a host."""
|
||||
lun_id = self._check_volume_exist_on_array(
|
||||
volume, constants.VOLUME_NOT_EXISTS_WARN)
|
||||
initiator_name = connector['initiator']
|
||||
volume_name = huawei_utils.encode_name(volume['id'])
|
||||
lun_id = volume.get('provider_location')
|
||||
host_name = connector['host']
|
||||
lungroup_id = None
|
||||
|
||||
LOG.info(_LI(
|
||||
'terminate_connection: volume name: %(volume)s, '
|
||||
'initiator name: %(ini)s, '
|
||||
'lun_id: %(lunid)s.'),
|
||||
{'volume': volume_name,
|
||||
'ini': initiator_name,
|
||||
'terminate_connection: initiator name: %(ini)s, '
|
||||
'LUN ID: %(lunid)s.'),
|
||||
{'ini': initiator_name,
|
||||
'lunid': lun_id},)
|
||||
|
||||
portgroup = None
|
||||
@ -1685,20 +1726,17 @@ class HuaweiISCSIDriver(HuaweiBaseDriver, driver.ISCSIDriver):
|
||||
lungroup_id = self.client.find_lungroup_from_map(view_id)
|
||||
|
||||
# Remove lun from lungroup.
|
||||
if lun_id and self.client.check_lun_exist(lun_id):
|
||||
if lungroup_id:
|
||||
lungroup_ids = self.client.get_lungroupids_by_lunid(lun_id)
|
||||
if lungroup_id in lungroup_ids:
|
||||
self.client.remove_lun_from_lungroup(lungroup_id,
|
||||
lun_id)
|
||||
else:
|
||||
LOG.warning(_LW("Lun is not in lungroup. "
|
||||
"Lun id: %(lun_id)s. "
|
||||
"lungroup id: %(lungroup_id)s."),
|
||||
{"lun_id": lun_id,
|
||||
"lungroup_id": lungroup_id})
|
||||
else:
|
||||
LOG.warning(_LW("Can't find lun on the array."))
|
||||
if lun_id and lungroup_id:
|
||||
lungroup_ids = self.client.get_lungroupids_by_lunid(lun_id)
|
||||
if lungroup_id in lungroup_ids:
|
||||
self.client.remove_lun_from_lungroup(lungroup_id,
|
||||
lun_id)
|
||||
else:
|
||||
LOG.warning(_LW("LUN is not in lungroup. "
|
||||
"LUN ID: %(lun_id)s. "
|
||||
"Lungroup id: %(lungroup_id)s."),
|
||||
{"lun_id": lun_id,
|
||||
"lungroup_id": lungroup_id})
|
||||
|
||||
# Remove portgroup from mapping view if no lun left in lungroup.
|
||||
if lungroup_id:
|
||||
@ -1771,15 +1809,16 @@ class HuaweiFCDriver(HuaweiBaseDriver, driver.FibreChannelDriver):
|
||||
@utils.synchronized('huawei', external=True)
|
||||
@fczm_utils.AddFCZone
|
||||
def initialize_connection(self, volume, connector):
|
||||
lun_id = self._check_volume_exist_on_array(
|
||||
volume, constants.VOLUME_NOT_EXISTS_RAISE)
|
||||
|
||||
wwns = connector['wwpns']
|
||||
volume_name = huawei_utils.encode_name(volume['id'])
|
||||
LOG.info(_LI(
|
||||
'initialize_connection, initiator: %(wwpns)s,'
|
||||
' volume name: %(volume)s.'),
|
||||
' LUN ID: %(lun_id)s.'),
|
||||
{'wwpns': wwns,
|
||||
'volume': volume_name},)
|
||||
'lun_id': lun_id},)
|
||||
|
||||
lun_id = self.client.get_lun_id(volume, volume_name)
|
||||
portg_id = None
|
||||
|
||||
original_host_name = connector['host']
|
||||
@ -1906,19 +1945,18 @@ class HuaweiFCDriver(HuaweiBaseDriver, driver.FibreChannelDriver):
|
||||
@fczm_utils.RemoveFCZone
|
||||
def terminate_connection(self, volume, connector, **kwargs):
|
||||
"""Delete map between a volume and a host."""
|
||||
lun_id = self._check_volume_exist_on_array(
|
||||
volume, constants.VOLUME_NOT_EXISTS_WARN)
|
||||
|
||||
wwns = connector['wwpns']
|
||||
volume_name = huawei_utils.encode_name(volume['id'])
|
||||
lun_id = volume.get('provider_location')
|
||||
|
||||
host_name = connector['host']
|
||||
left_lunnum = -1
|
||||
lungroup_id = None
|
||||
view_id = None
|
||||
LOG.info(_LI('terminate_connection: volume name: %(volume)s, '
|
||||
'wwpns: %(wwns)s, '
|
||||
'lun_id: %(lunid)s.'),
|
||||
{'volume': volume_name,
|
||||
'wwns': wwns,
|
||||
'lunid': lun_id},)
|
||||
LOG.info(_LI('terminate_connection: wwpns: %(wwns)s, '
|
||||
'LUN ID: %(lun_id)s.'),
|
||||
{'wwns': wwns, 'lun_id': lun_id})
|
||||
|
||||
host_name = huawei_utils.encode_host_name(host_name)
|
||||
host_id = self.client.get_host_id_by_name(host_name)
|
||||
@ -1928,19 +1966,17 @@ class HuaweiFCDriver(HuaweiBaseDriver, driver.FibreChannelDriver):
|
||||
if view_id:
|
||||
lungroup_id = self.client.find_lungroup_from_map(view_id)
|
||||
|
||||
if (lun_id is not None
|
||||
and self.client.check_lun_exist(lun_id)):
|
||||
if lungroup_id:
|
||||
lungroup_ids = self.client.get_lungroupids_by_lunid(lun_id)
|
||||
if lungroup_id in lungroup_ids:
|
||||
self.client.remove_lun_from_lungroup(lungroup_id,
|
||||
lun_id)
|
||||
else:
|
||||
LOG.warning(_LW("Lun is not in lungroup. "
|
||||
"Lun id: %(lun_id)s. "
|
||||
"Lungroup id: %(lungroup_id)s."),
|
||||
{"lun_id": lun_id,
|
||||
"lungroup_id": lungroup_id})
|
||||
if lun_id and lungroup_id:
|
||||
lungroup_ids = self.client.get_lungroupids_by_lunid(lun_id)
|
||||
if lungroup_id in lungroup_ids:
|
||||
self.client.remove_lun_from_lungroup(lungroup_id,
|
||||
lun_id)
|
||||
else:
|
||||
LOG.warning(_LW("LUN is not in lungroup. "
|
||||
"LUN ID: %(lun_id)s. "
|
||||
"Lungroup id: %(lungroup_id)s."),
|
||||
{"lun_id": lun_id,
|
||||
"lungroup_id": lungroup_id})
|
||||
|
||||
else:
|
||||
LOG.warning(_LW("Can't find lun on the array."))
|
||||
|
@ -583,16 +583,15 @@ class ReplicaPairManager(object):
|
||||
self.rmt_driver.enable(pair_id)
|
||||
|
||||
lun_info = self.rmt_client.get_lun_info(rmt_lun_id)
|
||||
lun_wwn = lun_info.get('WWN')
|
||||
metadata = huawei_utils.get_volume_metadata(v)
|
||||
metadata.update({'lun_wwn': lun_wwn})
|
||||
admin_metadata = v['admin_metadata']
|
||||
admin_metadata.update({'huawei_lun_wwn': lun_info['WWN']})
|
||||
new_drv_data = {'pair_id': pair_id,
|
||||
'rmt_lun_id': v['provider_location']}
|
||||
new_drv_data = to_string(new_drv_data)
|
||||
v_update['updates'] = {'provider_location': rmt_lun_id,
|
||||
'replication_status': 'available',
|
||||
'replication_driver_data': new_drv_data,
|
||||
'metadata': metadata}
|
||||
'admin_metadata': admin_metadata}
|
||||
volumes_update.append(v_update)
|
||||
|
||||
return volumes_update
|
||||
@ -624,16 +623,16 @@ class ReplicaPairManager(object):
|
||||
self.rmt_driver.failover(pair_id)
|
||||
|
||||
lun_info = self.rmt_client.get_lun_info(rmt_lun_id)
|
||||
lun_wwn = lun_info.get('WWN')
|
||||
metadata = huawei_utils.get_volume_metadata(v)
|
||||
metadata.update({'lun_wwn': lun_wwn})
|
||||
admin_metadata = v['admin_metadata']
|
||||
admin_metadata.update({'huawei_lun_wwn': lun_info['WWN']})
|
||||
|
||||
new_drv_data = {'pair_id': pair_id,
|
||||
'rmt_lun_id': v['provider_location']}
|
||||
new_drv_data = to_string(new_drv_data)
|
||||
v_update['updates'] = {'provider_location': rmt_lun_id,
|
||||
'replication_status': 'failed-over',
|
||||
'replication_driver_data': new_drv_data,
|
||||
'metadata': metadata}
|
||||
'admin_metadata': admin_metadata}
|
||||
volumes_update.append(v_update)
|
||||
|
||||
return volumes_update
|
||||
|
@ -206,13 +206,18 @@ class RestClient(object):
|
||||
|
||||
return result['data']
|
||||
|
||||
def check_lun_exist(self, lun_id):
|
||||
def check_lun_exist(self, lun_id, lun_wwn=None):
|
||||
url = "/lun/" + lun_id
|
||||
result = self.call(url, None, "GET")
|
||||
error_code = result['error']['code']
|
||||
if error_code != 0:
|
||||
return False
|
||||
|
||||
if lun_wwn and result['data']['WWN'] != lun_wwn:
|
||||
LOG.debug("LUN ID %(id)s with WWN %(wwn)s does not exist on "
|
||||
"the array.", {"id": lun_id, "wwn": lun_wwn})
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
def delete_lun(self, lun_id):
|
||||
|
Loading…
x
Reference in New Issue
Block a user