]> review.fuel-infra Code Review - openstack-build/cinder-build.git/commitdiff
Verify the instance's existance in the VMAX driver
authorXing Yang <xing.yang@emc.com>
Wed, 17 Dec 2014 05:53:01 +0000 (00:53 -0500)
committerXing Yang <xing.yang@emc.com>
Fri, 16 Jan 2015 04:14:17 +0000 (23:14 -0500)
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

cinder/tests/test_emc_vmax.py
cinder/volume/drivers/emc/emc_vmax_common.py
cinder/volume/drivers/emc/emc_vmax_fast.py
cinder/volume/drivers/emc/emc_vmax_masking.py
cinder/volume/drivers/emc/emc_vmax_utils.py

index b37cf423e9ac473ed2d0738f881237a99ab1b54a..b4c3cb08fb9872b3580a93a5b2845428a89b01aa 100644 (file)
@@ -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,
index 1ff012015eb856212892c55a1095cb4ccbc6c9fd..592cfef326626d24d9cd6120832dc034a90be807 100644 (file)
@@ -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.
index d3512f7f021ec8429121923c1cd1ddc57ecfd28e..700d302ceb98fc8564d814847404491191460c13 100644 (file)
@@ -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"
index 96518296d6468ad03b6f37ca02dbfe0b31054ffd..4dca2a324fe8c5b33040300137b0e9a22e99a230 100644 (file)
@@ -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
 
index 82fc6b07fb73e69ce123e82f03f274997a4a34e1..56773fd22111700f40322956527f754ae1bbd1ce 100644 (file)
@@ -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