From: Xing Yang Date: Wed, 17 Dec 2014 05:53:01 +0000 (-0500) Subject: Verify the instance's existance in the VMAX driver X-Git-Url: https://review.fuel-infra.org/gitweb?a=commitdiff_plain;h=f4343a9c495b29372feb5b0a395fba7fc54ad2ce;p=openstack-build%2Fcinder-build.git Verify the instance's existance in the VMAX driver There are a few functions in the VMAX driver that are referencing an instance that may have been already deleted. This patch addressed this issue by verifying the instance's existance. Closes-Bug: #1393555 Change-Id: Id2aa0e892189d565d092c1c18c2e6dadc580f765 --- diff --git a/cinder/tests/test_emc_vmax.py b/cinder/tests/test_emc_vmax.py index b37cf423e..b4c3cb08f 100644 --- a/cinder/tests/test_emc_vmax.py +++ b/cinder/tests/test_emc_vmax.py @@ -62,6 +62,22 @@ class SYMM_LunMasking(dict): pass +class CIM_DeviceMaskingGroup(dict): + pass + + +class EMC_LunMaskingSCSIProtocolController(dict): + pass + + +class CIM_TargetMaskingGroup(dict): + pass + + +class EMC_StorageHardwareID(dict): + pass + + class Fake_CIMProperty(): def fake_getCIMProperty(self): @@ -166,6 +182,7 @@ class EMCVMAXCommonData(): u'//10.10.10.10/root/emc: SE_DeviceMaskingGroup.InstanceID=' '"SYMMETRIX+000198700440+OS_default_GOLD1_SG"') storage_system = 'SYMMETRIX+000195900551' + port_group = 'OS-portgroup-PG' lunmaskctrl_id =\ 'SYMMETRIX+000195900551+OS-fakehost-gold-MV' lunmaskctrl_name =\ @@ -194,12 +211,16 @@ class EMCVMAXCommonData(): assoctierpolicy_creationclass = 'CIM_StorageTier' storagepool_creationclass = 'Symm_VirtualProvisioningPool' storagegroup_creationclass = 'CIM_DeviceMaskingGroup' - hardwareid_creationclass = 'SE_StorageHardwareID' + hardwareid_creationclass = 'EMC_StorageHardwareID' storagepoolid = 'SYMMETRIX+000195900551+U+gold' storagegroupname = 'OS_default_GOLD1_SG' storagevolume_creationclass = 'EMC_StorageVolume' policyrule = 'gold' poolname = 'gold' + totalmanagedspace_bits = '1000000000000' + subscribedcapacity_bits = '500000000000' + totalmanagedspace_gbs = 931 + subscribedcapacity_gbs = 466 unit_creationclass = 'CIM_ProtocolControllerForUnit' storage_type = 'gold' @@ -289,6 +310,8 @@ class EMCVMAXCommonData(): 'storage_protocol': 'ISCSI'} test_host = {'capabilities': location_info, 'host': 'fake_host'} + + initiatorNames = ["123456789012345", "123456789054321"] test_ctxt = {} new_type = {} diff = {} @@ -397,6 +420,10 @@ class FakeEcomConnection(): result = self._enum_hdwidmgmts() elif name == 'SE_StorageHardwareID': result = self._enum_storhdwids() + elif name == 'EMC_StorageSystem': + result = self._enum_storage_system() + elif name == 'Symm_TierPolicyRule': + result = self._enum_policyrules() else: result = self._default_enum() return result @@ -434,6 +461,10 @@ class FakeEcomConnection(): result = self._getinstance_initiatormaskinggroup(objectpath) elif name == 'SE_StorageHardwareID': result = self._getinstance_storagehardwareid(objectpath) + elif name == 'EMC_StorageHardwareID': + result = self._getinstance_storagehardwareid(objectpath) + elif name == 'Symm_VirtualProvisioningPool': + result = self._getinstance_pool(objectpath) else: result = self._default_getinstance(objectpath) @@ -450,6 +481,14 @@ class FakeEcomConnection(): result = self._assoc_endpoint() elif ResultClass == 'EMC_StorageVolume': result = self._assoc_storagevolume(objectpath) + elif ResultClass == 'CIM_DeviceMaskingGroup': + result = self._assoc_storagegroup() + elif ResultClass == 'CIM_StorageExtent': + result = self._enum_storage_extent() + elif ResultClass == 'EMC_LunMaskingSCSIProtocolController': + result = self._assoc_lunmaskctrls() + elif ResultClass == 'CIM_TargetMaskingGroup': + result = self._assoc_portgroup() else: result = self._default_assoc(objectpath) return result @@ -480,12 +519,16 @@ class FakeEcomConnection(): result = self._enum_storagevolumes() elif ResultClass == 'SE_InitiatorMaskingGroup': result = self._enum_initiatorMaskingGroup() + elif ResultClass == 'CIM_InitiatorMaskingGroup': + result = self._enum_initiatorMaskingGroup() elif ResultClass == 'CIM_StorageExtent': result = self._enum_storage_extent() elif ResultClass == 'SE_StorageHardwareID': result = self._enum_storhdwids() elif ResultClass == 'Symm_FCSCSIProtocolEndpoint': result = self._enum_fcscsiendpoint() + elif ResultClass == 'CIM_TargetMaskingGroup': + result = self._assocnames_portgroup() else: result = self._default_assocnames(objectpath) @@ -553,13 +596,20 @@ class FakeEcomConnection(): def _assoc_hdwid(self): assocs = [] - assoc = {} + assoc = EMC_StorageHardwareID() assoc['StorageID'] = self.data.connector['initiator'] + assoc['SystemName'] = self.data.storage_system + assoc['CreationClassName'] = 'EMC_StorageHardwareID' + assoc.path = assoc assocs.append(assoc) for wwpn in self.data.connector['wwpns']: - assoc2 = {} + assoc2 = EMC_StorageHardwareID() assoc2['StorageID'] = wwpn + assoc2['SystemName'] = self.data.storage_system + assoc2['CreationClassName'] = 'EMC_StorageHardwareID' + assoc2.path = assoc2 assocs.append(assoc2) + assocs.append(assoc) return assocs def _assoc_endpoint(self): @@ -570,6 +620,37 @@ class FakeEcomConnection(): assocs.append(assoc) return assocs + def _assoc_storagegroup(self): + assocs = [] + assoc = CIM_DeviceMaskingGroup() + assoc['ElementName'] = 'OS_default_GOLD1_SG' + assoc['SystemName'] = self.data.storage_system + assoc['CreationClassName'] = 'CIM_DeviceMaskingGroup' + assoc.path = assoc + assocs.append(assoc) + return assocs + + def _assoc_portgroup(self): + assocs = [] + assoc = CIM_TargetMaskingGroup() + assoc['ElementName'] = self.data.port_group + assoc['SystemName'] = self.data.storage_system + assoc['CreationClassName'] = 'CIM_TargetMaskingGroup' + assoc.path = assoc + assocs.append(assoc) + return assocs + + def _assoc_lunmaskctrls(self): + ctrls = [] + ctrl = EMC_LunMaskingSCSIProtocolController() + ctrl['CreationClassName'] = self.data.lunmask_creationclass + ctrl['DeviceID'] = self.data.lunmaskctrl_id + ctrl['SystemName'] = self.data.storage_system + ctrl['ElementName'] = self.data.lunmaskctrl_name + ctrl.path = ctrl + ctrls.append(ctrl) + return ctrls + # Added test for EMC_StorageVolume associators def _assoc_storagevolume(self, objectpath): assocs = [] @@ -620,6 +701,9 @@ class FakeEcomConnection(): def _assocnames_storagevolume(self): return self._enum_storagevolume() + def _assocnames_portgroup(self): + return self._enum_portgroup() + def _default_assocnames(self, objectpath): return objectpath @@ -652,6 +736,7 @@ class FakeEcomConnection(): self.data.initiatorgroup_creationclass) initiatorgroup['DeviceID'] = self.data.initiatorgroup_id initiatorgroup['SystemName'] = self.data.storage_system + initiatorgroup['ElementName'] = self.data.initiatorgroup_name initiatorgroup.path = initiatorgroup return initiatorgroup @@ -663,6 +748,15 @@ class FakeEcomConnection(): hardwareid.path = hardwareid return hardwareid + def _getinstance_pool(self, objectpath): + pool = {} + pool['CreationClassName'] = 'Symm_VirtualProvisioningPool' + pool['ElementName'] = 'gold' + pool['SystemName'] = self.data.storage_system + pool['TotalManagedSpace'] = self.data.totalmanagedspace_bits + pool['EMCSubscribedCapacity'] = self.data.subscribedcapacity_bits + return pool + def _getinstance_unit(self, objectpath): unit = {} @@ -867,6 +961,14 @@ class FakeEcomConnection(): initatorgroups.append(initatorgroup) return initatorgroups + def _enum_storage_system(self): + storagesystems = [] + storagesystem = {} + storagesystem['SystemName'] = self.data.storage_system + storagesystem['Name'] = self.data.storage_system + storagesystems.append(storagesystem) + return storagesystems + def _enum_storage_extent(self): storageExtents = [] storageExtent = CIM_StorageExtent() @@ -985,6 +1087,15 @@ class FakeEcomConnection(): wwns.append(wwn) return wwns + def _enum_portgroup(self): + portgroups = [] + portgroup = {} + portgroup['CreationClassName'] = ( + 'CIM_TargetMaskingGroup') + portgroup['ElementName'] = self.data.port_group + portgroups.append(portgroup) + return portgroups + def _default_enum(self): names = [] name = {} @@ -1235,6 +1346,263 @@ class EMCVMAXISCSIDriverNoFastTestCase(test.TestCase): self.driver.common.utils.process_exception_args, arg, instancename3) + # Bug 1393555 - masking view has been deleted by another process. + def test_find_maskingview(self): + conn = self.fake_ecom_connection() + foundMaskingViewInstanceName = ( + self.driver.common.masking._find_masking_view( + conn, self.data.lunmaskctrl_name, self.data.storage_system)) + # The masking view has been found. + self.assertEqual( + self.data.lunmaskctrl_name, + conn.GetInstance(foundMaskingViewInstanceName)['ElementName']) + + self.driver.common.masking.utils.get_existing_instance = mock.Mock( + return_value=None) + foundMaskingViewInstanceName2 = ( + self.driver.common.masking._find_masking_view( + conn, self.data.lunmaskctrl_name, self.data.storage_system)) + # The masking view has not been found. + self.assertIsNone(foundMaskingViewInstanceName2) + + # Bug 1393555 - port group has been deleted by another process. + def test_find_portgroup(self): + conn = self.fake_ecom_connection() + controllerConfigService = ( + self.driver.utils.find_controller_configuration_service( + conn, self.data.storage_system)) + + foundPortGroupInstanceName = ( + self.driver.common.masking._find_port_group( + conn, controllerConfigService, self.data.port_group)) + # The port group has been found. + self.assertEqual( + self.data.port_group, + conn.GetInstance(foundPortGroupInstanceName)['ElementName']) + + self.driver.common.masking.utils.get_existing_instance = mock.Mock( + return_value=None) + foundPortGroupInstanceName2 = ( + self.driver.common.masking._find_port_group( + conn, controllerConfigService, self.data.port_group)) + # The port group has not been found as it has been deleted + # externally or by another thread. + self.assertIsNone(foundPortGroupInstanceName2) + + # Bug 1393555 - storage group has been deleted by another process. + def test_get_storage_group_from_masking_view(self): + conn = self.fake_ecom_connection() + foundStorageGroupInstanceName = ( + self.driver.common.masking._get_storage_group_from_masking_view( + conn, self.data.lunmaskctrl_name, self.data.storage_system)) + # The storage group has been found. + self.assertEqual( + self.data.storagegroupname, + conn.GetInstance(foundStorageGroupInstanceName)['ElementName']) + + self.driver.common.masking.utils.get_existing_instance = mock.Mock( + return_value=None) + foundStorageGroupInstanceName2 = ( + self.driver.common.masking._get_storage_group_from_masking_view( + conn, self.data.lunmaskctrl_name, self.data.storage_system)) + # The storage group has not been found as it has been deleted + # externally or by another thread. + self.assertIsNone(foundStorageGroupInstanceName2) + + # Bug 1393555 - initiator group has been deleted by another process. + def test_get_initiator_group_from_masking_view(self): + conn = self.fake_ecom_connection() + foundInitiatorGroupInstanceName = ( + self.driver.common.masking._get_initiator_group_from_masking_view( + conn, self.data.lunmaskctrl_name, self.data.storage_system)) + # The initiator group has been found. + self.assertEqual( + self.data.initiatorgroup_name, + conn.GetInstance(foundInitiatorGroupInstanceName)['ElementName']) + + self.driver.common.masking.utils.get_existing_instance = mock.Mock( + return_value=None) + foundInitiatorGroupInstanceName2 = ( + self.driver.common.masking._get_storage_group_from_masking_view( + conn, self.data.lunmaskctrl_name, self.data.storage_system)) + # The initiator group has not been found as it has been deleted + # externally or by another thread. + self.assertIsNone(foundInitiatorGroupInstanceName2) + + # Bug 1393555 - port group has been deleted by another process. + def test_get_port_group_from_masking_view(self): + conn = self.fake_ecom_connection() + foundPortGroupInstanceName = ( + self.driver.common.masking._get_port_group_from_masking_view( + conn, self.data.lunmaskctrl_name, self.data.storage_system)) + # The port group has been found. + self.assertEqual( + self.data.port_group, + conn.GetInstance(foundPortGroupInstanceName)['ElementName']) + + self.driver.common.masking.utils.get_existing_instance = mock.Mock( + return_value=None) + foundPortGroupInstanceName2 = ( + self.driver.common.masking._get_port_group_from_masking_view( + conn, self.data.lunmaskctrl_name, self.data.storage_system)) + # The port group has not been found as it has been deleted + # externally or by another thread. + self.assertIsNone(foundPortGroupInstanceName2) + + # Bug 1393555 - initiator group has been deleted by another process. + def test_find_initiator_group(self): + conn = self.fake_ecom_connection() + controllerConfigService = ( + self.driver.utils.find_controller_configuration_service( + conn, self.data.storage_system)) + + foundInitiatorGroupInstanceName = ( + self.driver.common.masking._find_initiator_masking_group( + conn, controllerConfigService, self.data.initiatorNames)) + # The initiator group has been found. + self.assertEqual( + self.data.initiatorgroup_name, + conn.GetInstance(foundInitiatorGroupInstanceName)['ElementName']) + + self.driver.common.masking.utils.get_existing_instance = mock.Mock( + return_value=None) + foundInitiatorGroupInstanceName2 = ( + self.driver.common.masking._find_initiator_masking_group( + conn, controllerConfigService, self.data.initiatorNames)) + # The initiator group has not been found as it has been deleted + # externally or by another thread. + self.assertIsNone(foundInitiatorGroupInstanceName2) + + # Bug 1393555 - hardware id has been deleted by another process. + def test_get_storage_hardware_id_instance_names(self): + conn = self.fake_ecom_connection() + foundHardwareIdInstanceNames = ( + self.driver.common.masking._get_storage_hardware_id_instance_names( + conn, self.data.initiatorNames, self.data.storage_system)) + # The hardware id list has been found. + self.assertEqual( + '123456789012345', + conn.GetInstance( + foundHardwareIdInstanceNames[0])['StorageID']) + + self.driver.common.masking.utils.get_existing_instance = mock.Mock( + return_value=None) + foundHardwareIdInstanceNames2 = ( + self.driver.common.masking._get_storage_hardware_id_instance_names( + conn, self.data.initiatorNames, self.data.storage_system)) + # The hardware id list has not been found as it has been removed + # externally. + self.assertTrue(len(foundHardwareIdInstanceNames2) == 0) + + # Bug 1393555 - controller has been deleted by another process. + def test_find_lunmasking_scsi_protocol_controller(self): + self.driver.common.conn = self.fake_ecom_connection() + foundControllerInstanceName = ( + self.driver.common._find_lunmasking_scsi_protocol_controller( + self.data.storage_system, self.data.connector)) + # The controller has been found. + self.assertEqual( + 'OS-fakehost-gold-MV', + self.driver.common.conn.GetInstance( + foundControllerInstanceName)['ElementName']) + + self.driver.common.utils.get_existing_instance = mock.Mock( + return_value=None) + foundControllerInstanceName2 = ( + self.driver.common._find_lunmasking_scsi_protocol_controller( + self.data.storage_system, self.data.connector)) + # The controller has not been found as it has been removed + # externally. + self.assertIsNone(foundControllerInstanceName2) + + # Bug 1393555 - storage group has been deleted by another process. + def test_get_policy_default_storage_group(self): + conn = self.fake_ecom_connection() + controllerConfigService = ( + self.driver.utils.find_controller_configuration_service( + conn, self.data.storage_system)) + + foundStorageMaskingGroupInstanceName = ( + self.driver.common.fast.get_policy_default_storage_group( + conn, controllerConfigService, 'OS_default')) + # The storage group has been found. + self.assertEqual( + 'OS_default_GOLD1_SG', + conn.GetInstance( + foundStorageMaskingGroupInstanceName)['ElementName']) + + self.driver.common.fast.utils.get_existing_instance = mock.Mock( + return_value=None) + foundStorageMaskingGroupInstanceName2 = ( + self.driver.common.fast.get_policy_default_storage_group( + conn, controllerConfigService, 'OS_default')) + # The storage group has not been found as it has been removed + # externally. + self.assertIsNone(foundStorageMaskingGroupInstanceName2) + + # Bug 1393555 - policy has been deleted by another process. + def test_get_capacities_associated_to_policy(self): + conn = self.fake_ecom_connection() + total_capacity_gb, free_capacity_gb = ( + self.driver.common.fast.get_capacities_associated_to_policy( + conn, self.data.storage_system, self.data.policyrule)) + # The capacities associated to the policy have been found. + self.assertEqual(self.data.totalmanagedspace_gbs, total_capacity_gb) + self.assertEqual(self.data.subscribedcapacity_gbs, free_capacity_gb) + + self.driver.common.fast.utils.get_existing_instance = mock.Mock( + return_value=None) + total_capacity_gb_2, free_capacity_gb_2 = ( + self.driver.common.fast.get_capacities_associated_to_policy( + conn, self.data.storage_system, self.data.policyrule)) + # The capacities have not been found as the policy has been + # removed externally. + self.assertEqual(0, total_capacity_gb_2) + self.assertEqual(0, free_capacity_gb_2) + + # Bug 1393555 - storage group has been deleted by another process. + def test_find_storage_masking_group(self): + conn = self.fake_ecom_connection() + controllerConfigService = ( + self.driver.utils.find_controller_configuration_service( + conn, self.data.storage_system)) + + foundStorageMaskingGroupInstanceName = ( + self.driver.common.utils.find_storage_masking_group( + conn, controllerConfigService, self.data.storagegroupname)) + # The storage group has been found. + self.assertEqual( + self.data.storagegroupname, + conn.GetInstance( + foundStorageMaskingGroupInstanceName)['ElementName']) + + self.driver.common.utils.get_existing_instance = mock.Mock( + return_value=None) + foundStorageMaskingGroupInstanceName2 = ( + self.driver.common.utils.find_storage_masking_group( + conn, controllerConfigService, self.data.storagegroupname)) + # The storage group has not been found as it has been removed + # externally. + self.assertIsNone(foundStorageMaskingGroupInstanceName2) + + # Bug 1393555 - pool has been deleted by another process. + def test_get_pool_by_name(self): + conn = self.fake_ecom_connection() + + foundPoolInstanceName = self.driver.common.utils.get_pool_by_name( + conn, self.data.poolname, self.data.storage_system) + # The pool has been found. + self.assertEqual( + self.data.poolname, + conn.GetInstance(foundPoolInstanceName)['ElementName']) + + self.driver.common.utils.get_existing_instance = mock.Mock( + return_value=None) + foundPoolInstanceName2 = self.driver.common.utils.get_pool_by_name( + conn, self.data.poolname, self.data.storage_system) + # The pool has not been found as it has been removed externally. + self.assertIsNone(foundPoolInstanceName2) + def test_get_volume_stats_1364232(self): self.create_fake_config_file_1364232() self.assertEqual('000198700439', @@ -1254,8 +1622,8 @@ class EMCVMAXISCSIDriverNoFastTestCase(test.TestCase): os.remove(self.config_file_1364232) @mock.patch.object( - EMCVMAXCommon, - '_find_storageSystem', + EMCVMAXUtils, + 'find_storageSystem', return_value=None) @mock.patch.object( EMCVMAXFast, @@ -1493,10 +1861,10 @@ class EMCVMAXISCSIDriverNoFastTestCase(test.TestCase): 'volume_backend_name': 'ISCSINoFAST'}) @mock.patch.object( EMCVMAXUtils, - 'check_if_volume_is_concatenated', + 'check_if_volume_is_extendable', return_value='False') def test_extend_volume_striped_no_fast_failed( - self, _mock_volume_type, _mock_is_concatenated): + self, _mock_volume_type, _mock_is_extendable): newSize = '2' self.assertRaises(exception.VolumeBackendAPIException, self.driver.extend_volume, @@ -1748,8 +2116,8 @@ class EMCVMAXISCSIDriverFastTestCase(test.TestCase): return @mock.patch.object( - EMCVMAXCommon, - '_find_storageSystem', + EMCVMAXUtils, + 'find_storageSystem', return_value=None) @mock.patch.object( EMCVMAXFast, @@ -1958,10 +2326,10 @@ class EMCVMAXISCSIDriverFastTestCase(test.TestCase): return_value={'volume_backend_name': 'ISCSIFAST'}) @mock.patch.object( EMCVMAXUtils, - 'check_if_volume_is_concatenated', + 'check_if_volume_is_extendable', return_value='False') def test_extend_volume_striped_fast_failed( - self, _mock_volume_type, _mock_is_concatenated): + self, _mock_volume_type, _mock_is_extendable): newSize = '2' self.assertRaises(exception.VolumeBackendAPIException, self.driver.extend_volume, @@ -2265,8 +2633,8 @@ class EMCVMAXFCDriverNoFastTestCase(test.TestCase): return @mock.patch.object( - EMCVMAXCommon, - '_find_storageSystem', + EMCVMAXUtils, + 'find_storageSystem', return_value=None) @mock.patch.object( EMCVMAXFast, @@ -2460,10 +2828,10 @@ class EMCVMAXFCDriverNoFastTestCase(test.TestCase): return_value={'volume_backend_name': 'FCNoFAST'}) @mock.patch.object( EMCVMAXUtils, - 'check_if_volume_is_concatenated', + 'check_if_volume_is_extendable', return_value='False') def test_extend_volume_striped_no_fast_failed( - self, _mock_volume_type, _mock_is_concatenated): + self, _mock_volume_type, _mock_is_extendable): newSize = '2' self.assertRaises(exception.VolumeBackendAPIException, self.driver.extend_volume, @@ -2600,8 +2968,8 @@ class EMCVMAXFCDriverFastTestCase(test.TestCase): return @mock.patch.object( - EMCVMAXCommon, - '_find_storageSystem', + EMCVMAXUtils, + 'find_storageSystem', return_value=None) @mock.patch.object( EMCVMAXFast, @@ -2805,10 +3173,10 @@ class EMCVMAXFCDriverFastTestCase(test.TestCase): return_value={'volume_backend_name': 'FCFAST'}) @mock.patch.object( EMCVMAXUtils, - 'check_if_volume_is_concatenated', + 'check_if_volume_is_extendable', return_value='False') def test_extend_volume_striped_fast_failed(self, _mock_volume_type, - _mock_is_concatenated): + _mock_is_extendable): newSize = '2' self.assertRaises(exception.VolumeBackendAPIException, self.driver.extend_volume, diff --git a/cinder/volume/drivers/emc/emc_vmax_common.py b/cinder/volume/drivers/emc/emc_vmax_common.py index 1ff012015..592cfef32 100644 --- a/cinder/volume/drivers/emc/emc_vmax_common.py +++ b/cinder/volume/drivers/emc/emc_vmax_common.py @@ -424,8 +424,8 @@ class EMCVMAXCommon(object): additionalVolumeSize = self.utils.convert_gb_to_bits( additionalVolumeSize) - # is the volume concatenated - isConcatenated = self.utils.check_if_volume_is_concatenated( + # Is the volume extendable. + isConcatenated = self.utils.check_if_volume_is_extendable( self.conn, volumeInstance) if 'True' not in isConcatenated: exceptionMessage = (_( @@ -564,7 +564,9 @@ class EMCVMAXCommon(object): if self.conn is None: self._set_ecom_credentials(emcConfigFileName) - storageSystemInstanceName = self._find_storageSystem(arrayName) + storageSystemInstanceName = ( + self.utils.find_storageSystem(self.conn, arrayName)) + isTieringPolicySupported = ( self.fast.is_tiering_policy_enabled_on_storage_system( self.conn, storageSystemInstanceName)) @@ -1154,32 +1156,6 @@ class EMCVMAXCommon(object): return conn - def _find_storageSystem(self, arrayStr): - """Find an array instance name given the array name. - - :param arrayStr: the array Serial number (String) - :returns: foundPoolInstanceName, the CIM Instance Name of the Pool - """ - foundStorageSystemInstanceName = None - storageSystemInstanceNames = self.conn.EnumerateInstanceNames( - 'EMC_StorageSystem') - for storageSystemInstanceName in storageSystemInstanceNames: - arrayName = storageSystemInstanceName['Name'] - index = arrayName.find(arrayStr) - if index > -1: - foundStorageSystemInstanceName = storageSystemInstanceName - - if foundStorageSystemInstanceName is None: - exceptionMessage = (_("StorageSystem %(array)s is not found.") - % {'storage_array': arrayStr}) - LOG.error(exceptionMessage) - raise exception.VolumeBackendAPIException(data=exceptionMessage) - - LOG.debug("Array Found: %(array)s.." - % {'array': arrayStr}) - - return foundStorageSystemInstanceName - def _find_pool_in_array(self, arrayStr, poolNameInStr): """Find a pool based on the pool name on a given array. @@ -1190,7 +1166,8 @@ class EMCVMAXCommon(object): foundPoolInstanceName = None systemNameStr = None - storageSystemInstanceName = self._find_storageSystem(arrayStr) + storageSystemInstanceName = self.utils.find_storageSystem(self.conn, + arrayStr) vpools = self.conn.AssociatorNames( storageSystemInstanceName, @@ -1440,26 +1417,32 @@ class EMCVMAXCommon(object): management service :returns: foundInstances, the list of storage hardware ID instances """ - foundInstances = [] + foundHardwareIdList = [] wwpns = self._find_initiator_names(connector) - hardwareIdInstanceNames = ( - self.utils.get_hardware_id_instance_names_from_array( + hardwareIdInstances = ( + self.utils.get_hardware_id_instances_from_array( self.conn, hardwareIdManagementService)) - for hardwareIdInstanceName in hardwareIdInstanceNames: - hardwareIdInstance = self.conn.GetInstance(hardwareIdInstanceName) + for hardwareIdInstance in hardwareIdInstances: storageId = hardwareIdInstance['StorageID'] for wwpn in wwpns: if wwpn.lower() == storageId.lower(): - foundInstances.append(hardwareIdInstance.path) + # Check that the found hardwareId has not been + # deleted. If it has, we don't want to add it to the list. + instance = self.utils.get_existing_instance( + self.conn, hardwareIdInstance.path) + if instance is None: + # hardwareId doesn't exist any more. Skip it. + break + foundHardwareIdList.append(hardwareIdInstance.path) break LOG.debug("Storage Hardware IDs for %(wwpns)s is " "%(foundInstances)s." % {'wwpns': wwpns, - 'foundInstances': foundInstances}) + 'foundInstances': foundHardwareIdList}) - return foundInstances + return foundHardwareIdList def _register_config_file_from_config_group(self, configGroupName): """Given the config group name register the file. @@ -2198,49 +2181,72 @@ class EMCVMAXCommon(object): def _find_lunmasking_scsi_protocol_controller(self, storageSystemName, connector): - """Find LunMaskingSCSIProtocolController for the local host + """Find LunMaskingSCSIProtocolController for the local host. Find out how many volumes are mapped to a host - associated to the LunMaskingSCSIProtocolController + associated to the LunMaskingSCSIProtocolController. - :param connector: volume object to be deleted :param storageSystemName: the storage system name - :returns: foundCtrl + :param connector: volume object to be deleted + :returns: foundControllerInstanceName """ - foundCtrl = None + foundControllerInstanceName = None initiators = self._find_initiator_names(connector) - controllers = self.conn.EnumerateInstanceNames( - 'EMC_LunMaskingSCSIProtocolController') - for ctrl in controllers: - if storageSystemName != ctrl['SystemName']: - continue - associators = self.conn.Associators( - ctrl, ResultClass='EMC_StorageHardwareID') - for assoc in associators: - # if EMC_StorageHardwareID matches the initiator, - # we found the existing EMC_LunMaskingSCSIProtocolController - # (Storage Group for VNX) - # we can use for masking a new LUN - hardwareid = assoc['StorageID'] - for initiator in initiators: - if hardwareid.lower() == initiator.lower(): - foundCtrl = ctrl - break - if foundCtrl is not None: - break + storageSystemInstanceName = self.utils.find_storageSystem( + self.conn, storageSystemName) + controllerInstanceNames = self.conn.AssociatorNames( + storageSystemInstanceName, + ResultClass='EMC_LunMaskingSCSIProtocolController') - if foundCtrl is not None: + for controllerInstanceName in controllerInstanceNames: + try: + # This is a check to see if the controller has + # been deleted. + self.conn.GetInstance(controllerInstanceName) + storageHardwareIdInstances = self.conn.Associators( + controllerInstanceName, + ResultClass='EMC_StorageHardwareID') + + for storageHardwareIdInstance in storageHardwareIdInstances: + # If EMC_StorageHardwareID matches the initiator, we + # found the existing EMC_LunMaskingSCSIProtocolController. + hardwareid = storageHardwareIdInstance['StorageID'] + for initiator in initiators: + if hardwareid.lower() == initiator.lower(): + # This is a check to see if the controller + # has been deleted. + instance = self.utils.get_existing_instance( + self.conn, controllerInstanceName) + if instance is None: + # Skip this controller as it doesn't exist + # any more + pass + else: + foundControllerInstanceName = ( + controllerInstanceName) + break + + if foundControllerInstanceName is not None: + break + except pywbem.cim_operations.CIMError as arg: + instance = self.utils.process_exception_args( + arg, controllerInstanceName) + if instance is None: + # Skip this controller as it doesn't exist any more. + pass + + if foundControllerInstanceName is not None: break LOG.debug("LunMaskingSCSIProtocolController for storage system " - "%(storage_system)s and initiator %(initiator)s is " + "%(storage_system)s and initiator %(initiator)s is " "%(ctrl)s." % {'storage_system': storageSystemName, 'initiator': initiators, - 'ctrl': foundCtrl}) - return foundCtrl + 'ctrl': foundControllerInstanceName}) + return foundControllerInstanceName def get_num_volumes_mapped(self, volume, connector): """Returns how many volumes are in the same zone as the connector. diff --git a/cinder/volume/drivers/emc/emc_vmax_fast.py b/cinder/volume/drivers/emc/emc_vmax_fast.py index d3512f7f0..700d302ce 100644 --- a/cinder/volume/drivers/emc/emc_vmax_fast.py +++ b/cinder/volume/drivers/emc/emc_vmax_fast.py @@ -420,18 +420,25 @@ class EMCVMAXFast(object): :returns: storageGroupInstanceName - instance name of the default storage group """ - storageMaskingGroupInstanceNames = conn.AssociatorNames( + foundStorageMaskingGroupInstanceName = None + storageMaskingGroupInstances = conn.Associators( controllerConfigService, ResultClass='CIM_DeviceMaskingGroup') - for storageMaskingGroupInstanceName in \ - storageMaskingGroupInstanceNames: - storageMaskingGroupInstance = conn.GetInstance( - storageMaskingGroupInstanceName) + for storageMaskingGroupInstance in \ + storageMaskingGroupInstances: + if ('_default_' in storageMaskingGroupInstance['ElementName'] and policyName in storageMaskingGroupInstance['ElementName']): - return storageMaskingGroupInstanceName + # Check that it has not been recently deleted. + instance = self.utils.get_existing_instance( + conn, storageMaskingGroupInstance.path) + if instance is None: + # Storage Group doesn't exist any more. + foundStorageMaskingGroupInstanceName = None + else: + foundStorageMaskingGroupInstanceName = instance.path - return None + return foundStorageMaskingGroupInstanceName def _get_associated_storage_groups_from_tier_policy( self, conn, tierPolicyInstanceName): @@ -694,15 +701,28 @@ class EMCVMAXFast(object): tierInstanceNames = self.get_associated_tier_from_tier_policy( conn, policyInstanceName) for tierInstanceName in tierInstanceNames: - poolInsttanceNames = self.get_associated_pools_from_tier( + # Check that tier hasn't suddenly been deleted. + instance = self.utils.get_existing_instance(conn, tierInstanceName) + if instance is None: + # Tier doesn't exist any more. + break + + poolInstanceNames = self.get_associated_pools_from_tier( conn, tierInstanceName) - for poolInstanceName in poolInsttanceNames: - storagePoolInstance = conn.GetInstance( - poolInstanceName, LocalOnly=False) + for poolInstanceName in poolInstanceNames: + # Check that pool hasn't suddenly been deleted. + storagePoolInstance = self.utils.get_existing_instance( + conn, poolInstanceName) + + if storagePoolInstance is None: + # Pool doesn't exist any more. + break + total_capacity_gb += self.utils.convert_bits_to_gbs( storagePoolInstance['TotalManagedSpace']) allocated_capacity_gb += self.utils.convert_bits_to_gbs( storagePoolInstance['EMCSubscribedCapacity']) + LOG.debug( "policyName:%(policyName)s, pool: %(poolInstanceName)s, " "allocated_capacity_gb = %(allocated_capacity_gb)lu" diff --git a/cinder/volume/drivers/emc/emc_vmax_masking.py b/cinder/volume/drivers/emc/emc_vmax_masking.py index 96518296d..4dca2a324 100644 --- a/cinder/volume/drivers/emc/emc_vmax_masking.py +++ b/cinder/volume/drivers/emc/emc_vmax_masking.py @@ -272,22 +272,33 @@ class EMCVMAXMasking(object): :returns: foundMaskingViewInstanceName masking view instance name """ foundMaskingViewInstanceName = None - maskingViewInstanceNames = conn.EnumerateInstanceNames( - 'EMC_LunMaskingSCSIProtocolController') - - for maskingViewInstanceName in maskingViewInstanceNames: - if storageSystemName == maskingViewInstanceName['SystemName']: - instance = conn.GetInstance( - maskingViewInstanceName, LocalOnly=False) - if maskingViewName == instance['ElementName']: - foundMaskingViewInstanceName = maskingViewInstanceName - break + + storageSystemInstanceName = self.utils.find_storageSystem( + conn, storageSystemName) + maskingViewInstances = conn.Associators( + storageSystemInstanceName, + ResultClass='EMC_LunMaskingSCSIProtocolController') + + for maskingViewInstance in maskingViewInstances: + if maskingViewName == maskingViewInstance['ElementName']: + foundMaskingViewInstanceName = maskingViewInstance.path + break if foundMaskingViewInstanceName is not None: - infoMessage = (_( - "Found existing masking view: %(maskingViewName)s ") - % {'maskingViewName': maskingViewName}) - LOG.info(infoMessage) + # now check that is has not been deleted + instance = self.utils.get_existing_instance( + conn, foundMaskingViewInstanceName) + if instance is None: + foundMaskingViewInstanceName = None + LOG.error(_LE( + "Looks like masking view: %(maskingViewName)s " + "has recently been deleted."), + {'maskingViewName': maskingViewName}) + else: + LOG.info(_LI( + "Found existing masking view: %(maskingViewName)s "), + {'maskingViewName': maskingViewName}) + return foundMaskingViewInstanceName def _create_storage_group( @@ -356,14 +367,18 @@ class EMCVMAXMasking(object): :returns: foundPortGroup storage group instance name """ foundPortGroupInstanceName = None - portMaskingGroupInstanceNames = conn.AssociatorNames( - controllerConfigService, resultClass='CIM_TargetMaskingGroup') - - for portMaskingGroupInstanceName in portMaskingGroupInstanceNames: - instance = conn.GetInstance( - portMaskingGroupInstanceName, LocalOnly=False) - if portGroupName == instance['ElementName']: - foundPortGroupInstanceName = portMaskingGroupInstanceName + portMaskingGroupInstances = conn.Associators( + controllerConfigService, ResultClass='CIM_TargetMaskingGroup') + + for portMaskingGroupInstance in portMaskingGroupInstances: + if portGroupName == portMaskingGroupInstance['ElementName']: + # Check to see if it has been recently deleted. + instance = self.utils.get_existing_instance( + conn, portMaskingGroupInstance.path) + if instance is None: + foundPortGroupInstanceName = None + else: + foundPortGroupInstanceName = instance.path break if foundPortGroupInstanceName is None: @@ -471,37 +486,41 @@ class EMCVMAXMasking(object): :param initiatorName: the list of initiator names :returns: foundInitiatorMaskingGroup """ - foundInitiatorMaskingGroupName = None + foundInitiatorMaskingGroupInstanceName = None - initiatorMaskingGroupNames = ( + initiatorMaskingGroupInstanceNames = ( conn.AssociatorNames(controllerConfigService, ResultClass='CIM_InitiatorMaskingGroup')) - for initiatorMaskingGroupName in initiatorMaskingGroupNames: - initiatorMaskingGroup = conn.GetInstance( - initiatorMaskingGroupName, LocalOnly=False) - associators = ( - conn.Associators(initiatorMaskingGroup.path, + for initiatorMaskingGroupInstanceName in \ + initiatorMaskingGroupInstanceNames: + # Check that it hasn't been deleted. If it has, continue + # to the next one in the loop. + instance = self.utils.get_existing_instance( + conn, initiatorMaskingGroupInstanceName) + if instance is None: + continue + + storageHardwareIdInstances = ( + conn.Associators(initiatorMaskingGroupInstanceName, ResultClass='EMC_StorageHardwareID')) - for assoc in associators: - # if EMC_StorageHardwareID matches the initiator, - # we found the existing EMC_LunMaskingSCSIProtocolController - # (Storage Group for VNX) - # we can use for masking a new LUN - hardwareid = assoc['StorageID'] + for storageHardwareIdInstance in storageHardwareIdInstances: + # If EMC_StorageHardwareID matches the initiator, + # we found the existing CIM_InitiatorMaskingGroup. + hardwareid = storageHardwareIdInstance['StorageID'] for initiator in initiatorNames: if six.text_type(hardwareid).lower() == \ six.text_type(initiator).lower(): - foundInitiatorMaskingGroupName = ( - initiatorMaskingGroupName) + foundInitiatorMaskingGroupInstanceName = ( + initiatorMaskingGroupInstanceName) break - if foundInitiatorMaskingGroupName is not None: + if foundInitiatorMaskingGroupInstanceName is not None: break - if foundInitiatorMaskingGroupName is not None: + if foundInitiatorMaskingGroupInstanceName is not None: break - return foundInitiatorMaskingGroupName + return foundInitiatorMaskingGroupInstanceName def _get_storage_hardware_id_instance_names( self, conn, initiatorNames, storageSystemName): @@ -518,21 +537,23 @@ class EMCVMAXMasking(object): self.utils.find_storage_hardwareid_service( conn, storageSystemName)) - hardwareIdInstanceNames = ( - self.utils.get_hardware_id_instance_names_from_array( + hardwareIdInstances = ( + self.utils.get_hardware_id_instances_from_array( conn, hardwareIdManagementService)) - - for hardwareIdInstanceName in hardwareIdInstanceNames: - hardwareIdInstance = conn.GetInstance(hardwareIdInstanceName) + for hardwareIdInstance in hardwareIdInstances: storageId = hardwareIdInstance['StorageID'] for initiatorName in initiatorNames: - LOG.debug("The storage Id is : %(storageId)s " - % {'storageId': storageId.lower()}) - LOG.debug("The initiatorName is : %(initiatorName)s " - % {'initiatorName': initiatorName.lower()}) if storageId.lower() == initiatorName.lower(): + # Check that the found hardwareId has been deleted. + # If it has, we don't want to add it to the list. + instance = self.utils.get_existing_instance( + conn, hardwareIdInstance.path) + if instance is None: + # HardwareId doesn't exist. Skip it. + break + foundHardwardIDsInstanceNames.append( - hardwareIdInstanceName) + hardwareIdInstance.path) break LOG.debug( @@ -630,25 +651,38 @@ class EMCVMAXMasking(object): :returns: instance name foundStorageGroupInstanceName """ foundStorageGroupInstanceName = None - maskingviews = conn.EnumerateInstanceNames( - 'EMC_LunMaskingSCSIProtocolController') - for view in maskingviews: - if storageSystemName == view['SystemName']: - instance = conn.GetInstance(view, LocalOnly=False) - if maskingViewName == instance['ElementName']: - foundView = view - break + foundView = self._find_masking_view( + conn, maskingViewName, storageSystemName) + if foundView is not None: + foundStorageGroupInstanceName = ( + self._get_storage_group_from_masking_view_instance( + conn, foundView)) + + LOG.debug("Masking view: %(view)s DeviceMaskingGroup: " + "%(masking)s.", + {'view': maskingViewName, + 'masking': foundStorageGroupInstanceName}) + else: + LOG.warn(_LW("Unable to find Masking view: %(view)s."), + {'view': maskingViewName}) + + return foundStorageGroupInstanceName + + def _get_storage_group_from_masking_view_instance( + self, conn, maskingViewInstance): + """Gets the Device Masking Group from masking view instance. + :param conn: the connection to the ecom server + :param maskingViewInstance + :returns: instance name foundStorageGroupInstanceName + """ + foundStorageGroupInstanceName = None groups = conn.AssociatorNames( - foundView, + maskingViewInstance, ResultClass='CIM_DeviceMaskingGroup') if groups[0] > 0: foundStorageGroupInstanceName = groups[0] - LOG.debug("Masking view: %(view)s DeviceMaskingGroup: %(masking)s." - % {'view': maskingViewName, - 'masking': foundStorageGroupInstanceName}) - return foundStorageGroupInstanceName def _get_storage_group_instance_name( @@ -812,7 +846,7 @@ class EMCVMAXMasking(object): infoMessage = (_( "Performing rollback on Volume: %(volumeName)s " "To return it to the default storage group for FAST policy" - " %(fastPolicyName)s. ") + " %(fastPolicyName)s.") % {'volumeName': volumeName, 'fastPolicyName': fastPolicyName}) LOG.warning(_LW("No storage group found. %s"), infoMessage) @@ -883,26 +917,22 @@ class EMCVMAXMasking(object): :returns: instance name foundInitiatorMaskingGroupInstanceName """ foundInitiatorMaskingGroupInstanceName = None + foundView = self._find_masking_view( + conn, maskingViewName, storageSystemName) + if foundView is not None: + groups = conn.AssociatorNames( + foundView, + ResultClass='CIM_InitiatorMaskingGroup') + if len(groups): + foundInitiatorMaskingGroupInstanceName = groups[0] - maskingviews = conn.EnumerateInstanceNames( - 'EMC_LunMaskingSCSIProtocolController') - for view in maskingviews: - if storageSystemName == view['SystemName']: - instance = conn.GetInstance(view, LocalOnly=False) - if maskingViewName == instance['ElementName']: - foundView = view - break - - groups = conn.AssociatorNames( - foundView, - ResultClass='CIM_InitiatorMaskingGroup') - if len(groups): - foundInitiatorMaskingGroupInstanceName = groups[0] - - LOG.debug( - "Masking view: %(view)s InitiatorMaskingGroup: %(masking)s." - % {'view': maskingViewName, - 'masking': foundInitiatorMaskingGroupInstanceName}) + LOG.debug( + "Masking view: %(view)s InitiatorMaskingGroup: %(masking)s." + % {'view': maskingViewName, + 'masking': foundInitiatorMaskingGroupInstanceName}) + else: + LOG.warn(_LW("Unable to find Masking view: %(view)s.") + % {'view': maskingViewName}) return foundInitiatorMaskingGroupInstanceName @@ -1052,26 +1082,20 @@ class EMCVMAXMasking(object): :returns: instance name foundPortMaskingGroupInstanceName """ foundPortMaskingGroupInstanceName = None + foundView = self._find_masking_view( + conn, maskingViewName, storageSystemName) - maskingviews = conn.EnumerateInstanceNames( - 'EMC_LunMaskingSCSIProtocolController') - for view in maskingviews: - if storageSystemName == view['SystemName']: - instance = conn.GetInstance(view, LocalOnly=False) - if maskingViewName == instance['ElementName']: - foundView = view - break - - groups = conn.AssociatorNames( - foundView, - ResultClass='CIM_TargetMaskingGroup') - if len(groups) > 0: - foundPortMaskingGroupInstanceName = groups[0] + if foundView is not None: + groups = conn.AssociatorNames( + foundView, + ResultClass='CIM_TargetMaskingGroup') + if len(groups) > 0: + foundPortMaskingGroupInstanceName = groups[0] - LOG.debug( - "Masking view: %(view)s InitiatorMaskingGroup: %(masking)s." - % {'view': maskingViewName, - 'masking': foundPortMaskingGroupInstanceName}) + LOG.debug( + "Masking view: %(view)s InitiatorMaskingGroup: %(masking)s." + % {'view': maskingViewName, + 'masking': foundPortMaskingGroupInstanceName}) return foundPortMaskingGroupInstanceName diff --git a/cinder/volume/drivers/emc/emc_vmax_utils.py b/cinder/volume/drivers/emc/emc_vmax_utils.py index 82fc6b07f..56773fd22 100644 --- a/cinder/volume/drivers/emc/emc_vmax_utils.py +++ b/cinder/volume/drivers/emc/emc_vmax_utils.py @@ -470,18 +470,23 @@ class EMCVMAXUtils(object): :param foundStorageGroup: storage group instance name """ foundStorageMaskingGroupInstanceName = None + storageMaskingGroupInstances = ( + conn.Associators(controllerConfigService, + ResultClass='CIM_DeviceMaskingGroup')) - storageMaskingGroupInstanceNames = ( - conn.AssociatorNames(controllerConfigService, - ResultClass='CIM_DeviceMaskingGroup')) + for storageMaskingGroupInstance in \ + storageMaskingGroupInstances: - for storageMaskingGroupInstanceName in \ - storageMaskingGroupInstanceNames: - storageMaskingGroupInstance = conn.GetInstance( - storageMaskingGroupInstanceName) if storageGroupName == storageMaskingGroupInstance['ElementName']: - foundStorageMaskingGroupInstanceName = ( - storageMaskingGroupInstanceName) + # Check that it has not been deleted recently. + instance = self.get_existing_instance( + conn, storageMaskingGroupInstance.path) + if instance is None: + # Storage group not found. + foundStorageMaskingGroupInstanceName = None + else: + foundStorageMaskingGroupInstanceName = ( + storageMaskingGroupInstance.path) break return foundStorageMaskingGroupInstanceName @@ -771,16 +776,17 @@ class EMCVMAXUtils(object): foundPoolInstanceName = foundPoolInstanceNames[0] return foundPoolInstanceName - def check_if_volume_is_concatenated(self, conn, volumeInstance): - """Checks if a volume is concatenated or not. + def check_if_volume_is_extendable(self, conn, volumeInstance): + """Checks if a volume is extendable or not. Check underlying CIM_StorageExtent to see if the volume is concatenated or not. - If isConcatenated is true then it is a composite + If isConcatenated is true then it is a concatenated and + extendable. If isConcatenated is False and isVolumeComposite is True then - it is a striped + it is striped and not extendable. If isConcatenated is False and isVolumeComposite is False then - it has no composite type and we can proceed. + it has one member only but is still extendable. :param conn: the connection information to the ecom server :param volumeInstance: the volume instance @@ -791,14 +797,12 @@ class EMCVMAXUtils(object): isVolumeComposite = self.check_if_volume_is_composite( conn, volumeInstance) - storageExtentInstanceNames = conn.AssociatorNames( + storageExtentInstances = conn.Associators( volumeInstance.path, ResultClass='CIM_StorageExtent') - if len(storageExtentInstanceNames) > 0: - storageExtentInstanceName = storageExtentInstanceNames[0] - storageExtentInstance = conn.GetInstance(storageExtentInstanceName) - + if len(storageExtentInstances) > 0: + storageExtentInstance = storageExtentInstances[0] propertiesList = storageExtentInstance.properties.items() for properties in propertiesList: if properties[0] == 'IsConcatenated': @@ -996,20 +1000,26 @@ class EMCVMAXUtils(object): :param storageSystemName: string value of array :returns: poolInstanceName - instance name of storage pool """ - poolInstanceName = None + foundPoolInstanceName = None LOG.debug("storagePoolName: %(poolName)s, storageSystemName: %(array)s" % {'poolName': storagePoolName, 'array': storageSystemName}) poolInstanceNames = conn.EnumerateInstanceNames( 'EMC_VirtualProvisioningPool') - for pool in poolInstanceNames: + for poolInstanceName in poolInstanceNames: poolName, systemName = ( - self.parse_pool_instance_id(pool['InstanceID'])) + self.parse_pool_instance_id(poolInstanceName['InstanceID'])) if (poolName == storagePoolName and storageSystemName in systemName): - poolInstanceName = pool + # Check that the pool hasn't been recently deleted. + instance = self.get_existing_instance(conn, poolInstanceName) + if instance is None: + foundPoolInstanceName = None + else: + foundPoolInstanceName = poolInstanceName + break - return poolInstanceName + return foundPoolInstanceName def convert_bits_to_gbs(self, strBitSize): """Convert Bits(string) to GB(string). @@ -1132,20 +1142,19 @@ class EMCVMAXUtils(object): else: return protocol - def get_hardware_id_instance_names_from_array( + def get_hardware_id_instances_from_array( self, conn, hardwareIdManagementService): """Get all the hardware ids from an array. :param conn: connection to the ecom server :param: hardwareIdManagementService - hardware id management service - :returns: hardwareIdInstanceNames - the list of hardware - id instance names + :returns: hardwareIdInstances - the list of hardware id instances """ - hardwareIdInstanceNames = ( - conn.AssociatorNames(hardwareIdManagementService, - ResultClass='SE_StorageHardwareID')) + hardwareIdInstances = ( + conn.Associators(hardwareIdManagementService, + ResultClass='EMC_StorageHardwareID')) - return hardwareIdInstanceNames + return hardwareIdInstances def find_ip_protocol_endpoint(self, conn, storageSystemName): '''Find the IP protocol endpoint for ISCSI. @@ -1266,3 +1275,29 @@ class EMCVMAXUtils(object): raise exception.VolumeBackendAPIException( data=exceptionMessage) return instance + + def find_storageSystem(self, conn, arrayStr): + """Find an array instance name given the array name. + + :param arrayStr: the array Serial number (string) + :returns: foundPoolInstanceName, the CIM Instance Name of the Pool + """ + foundStorageSystemInstanceName = None + storageSystemInstanceNames = conn.EnumerateInstanceNames( + 'EMC_StorageSystem') + for storageSystemInstanceName in storageSystemInstanceNames: + arrayName = storageSystemInstanceName['Name'] + index = arrayName.find(arrayStr) + if index > -1: + foundStorageSystemInstanceName = storageSystemInstanceName + + if foundStorageSystemInstanceName is None: + exceptionMessage = (_("StorageSystem %(array)s was not found.") + % {'array': arrayStr}) + LOG.error(exceptionMessage) + raise exception.VolumeBackendAPIException(data=exceptionMessage) + + LOG.debug("Array Found: %(array)s." + % {'array': arrayStr}) + + return foundStorageSystemInstanceName