Merge "Fix a problem with FAST support in VMAX driver"
This commit is contained in:
commit
0acf257464
@ -24,6 +24,7 @@ from oslo_log import log as logging
|
|||||||
import six
|
import six
|
||||||
|
|
||||||
from cinder import exception
|
from cinder import exception
|
||||||
|
from cinder.i18n import _
|
||||||
from cinder.openstack.common import loopingcall
|
from cinder.openstack.common import loopingcall
|
||||||
from cinder import test
|
from cinder import test
|
||||||
from cinder.volume.drivers.emc import emc_vmax_common
|
from cinder.volume.drivers.emc import emc_vmax_common
|
||||||
@ -263,7 +264,8 @@ class EMCVMAXCommonData(object):
|
|||||||
hardwareid_creationclass = 'EMC_StorageHardwareID'
|
hardwareid_creationclass = 'EMC_StorageHardwareID'
|
||||||
replicationgroup_creationclass = 'CIM_ReplicationGroup'
|
replicationgroup_creationclass = 'CIM_ReplicationGroup'
|
||||||
storagepoolid = 'SYMMETRIX+000195900551+U+gold'
|
storagepoolid = 'SYMMETRIX+000195900551+U+gold'
|
||||||
storagegroupname = 'OS_default_GOLD1_SG'
|
storagegroupname = 'OS-fakehost-gold-I-SG'
|
||||||
|
defaultstoragegroupname = 'OS_default_GOLD1_SG'
|
||||||
storagevolume_creationclass = 'EMC_StorageVolume'
|
storagevolume_creationclass = 'EMC_StorageVolume'
|
||||||
policyrule = 'gold'
|
policyrule = 'gold'
|
||||||
poolname = 'gold'
|
poolname = 'gold'
|
||||||
@ -783,12 +785,18 @@ class FakeEcomConnection(object):
|
|||||||
|
|
||||||
def _assoc_storagegroup(self):
|
def _assoc_storagegroup(self):
|
||||||
assocs = []
|
assocs = []
|
||||||
assoc = CIM_DeviceMaskingGroup()
|
assoc1 = CIM_DeviceMaskingGroup()
|
||||||
assoc['ElementName'] = 'OS_default_GOLD1_SG'
|
assoc1['ElementName'] = self.data.storagegroupname
|
||||||
assoc['SystemName'] = self.data.storage_system
|
assoc1['SystemName'] = self.data.storage_system
|
||||||
assoc['CreationClassName'] = 'CIM_DeviceMaskingGroup'
|
assoc1['CreationClassName'] = 'CIM_DeviceMaskingGroup'
|
||||||
assoc.path = assoc
|
assoc1.path = assoc1
|
||||||
assocs.append(assoc)
|
assocs.append(assoc1)
|
||||||
|
assoc2 = CIM_DeviceMaskingGroup()
|
||||||
|
assoc2['ElementName'] = self.data.defaultstoragegroupname
|
||||||
|
assoc2['SystemName'] = self.data.storage_system
|
||||||
|
assoc2['CreationClassName'] = 'CIM_DeviceMaskingGroup'
|
||||||
|
assoc2.path = assoc2
|
||||||
|
assocs.append(assoc2)
|
||||||
return assocs
|
return assocs
|
||||||
|
|
||||||
def _assoc_portgroup(self):
|
def _assoc_portgroup(self):
|
||||||
@ -981,8 +989,17 @@ class FakeEcomConnection(object):
|
|||||||
|
|
||||||
def _getinstance_devicemaskinggroup(self, objectpath):
|
def _getinstance_devicemaskinggroup(self, objectpath):
|
||||||
targetmaskinggroup = {}
|
targetmaskinggroup = {}
|
||||||
targetmaskinggroup['CreationClassName'] = 'CIM_DeviceMaskingGroup'
|
if 'CreationClassName' in objectpath:
|
||||||
targetmaskinggroup['ElementName'] = 'OS_default_GOLD1_SG'
|
targetmaskinggroup['CreationClassName'] = (
|
||||||
|
objectpath['CreationClassName'])
|
||||||
|
else:
|
||||||
|
targetmaskinggroup['CreationClassName'] = (
|
||||||
|
'CIM_DeviceMaskingGroup')
|
||||||
|
if 'ElementName' in objectpath:
|
||||||
|
targetmaskinggroup['ElementName'] = objectpath['ElementName']
|
||||||
|
else:
|
||||||
|
targetmaskinggroup['ElementName'] = (
|
||||||
|
self.data.storagegroupname)
|
||||||
return targetmaskinggroup
|
return targetmaskinggroup
|
||||||
|
|
||||||
def _getinstance_unit(self, objectpath):
|
def _getinstance_unit(self, objectpath):
|
||||||
@ -1324,11 +1341,27 @@ class FakeEcomConnection(object):
|
|||||||
|
|
||||||
def _enum_storagegroup(self):
|
def _enum_storagegroup(self):
|
||||||
storagegroups = []
|
storagegroups = []
|
||||||
storagegroup = {}
|
storagegroup1 = {}
|
||||||
storagegroup['CreationClassName'] = (
|
storagegroup1['CreationClassName'] = (
|
||||||
self.data.storagegroup_creationclass)
|
self.data.storagegroup_creationclass)
|
||||||
storagegroup['ElementName'] = self.data.storagegroupname
|
storagegroup1['ElementName'] = self.data.storagegroupname
|
||||||
storagegroups.append(storagegroup)
|
storagegroups.append(storagegroup1)
|
||||||
|
storagegroup2 = {}
|
||||||
|
storagegroup2['CreationClassName'] = (
|
||||||
|
self.data.storagegroup_creationclass)
|
||||||
|
storagegroup2['ElementName'] = self.data.defaultstoragegroupname
|
||||||
|
storagegroup2['SystemName'] = self.data.storage_system
|
||||||
|
storagegroups.append(storagegroup2)
|
||||||
|
storagegroup3 = {}
|
||||||
|
storagegroup3['CreationClassName'] = (
|
||||||
|
self.data.storagegroup_creationclass)
|
||||||
|
storagegroup3['ElementName'] = 'OS-fakehost-SRP_1-Bronze-DSS-SG'
|
||||||
|
storagegroups.append(storagegroup3)
|
||||||
|
storagegroup4 = {}
|
||||||
|
storagegroup4['CreationClassName'] = (
|
||||||
|
self.data.storagegroup_creationclass)
|
||||||
|
storagegroup4['ElementName'] = 'OS-SRP_1-Bronze-DSS-SG'
|
||||||
|
storagegroups.append(storagegroup4)
|
||||||
return storagegroups
|
return storagegroups
|
||||||
|
|
||||||
def _enum_storagevolume(self):
|
def _enum_storagevolume(self):
|
||||||
@ -1659,6 +1692,90 @@ class EMCVMAXISCSIDriverNoFastTestCase(test.TestCase):
|
|||||||
self.driver.utils._get_hardware_type(bogus_initiator))
|
self.driver.utils._get_hardware_type(bogus_initiator))
|
||||||
self.assertEqual(0, hardwaretypeid)
|
self.assertEqual(0, hardwaretypeid)
|
||||||
|
|
||||||
|
def test_check_if_rollback_action_for_masking_required(self):
|
||||||
|
conn = self.fake_ecom_connection()
|
||||||
|
controllerConfigService = (
|
||||||
|
self.driver.utils.find_controller_configuration_service(
|
||||||
|
conn, self.data.storage_system))
|
||||||
|
extraSpecs = {'volume_backend_name': 'GOLD_BE',
|
||||||
|
'isV3': False,
|
||||||
|
'storagetype:fastpolicy': 'GOLD1'}
|
||||||
|
|
||||||
|
vol = EMC_StorageVolume()
|
||||||
|
vol['name'] = self.data.test_volume['name']
|
||||||
|
vol['CreationClassName'] = 'Symm_StorageVolume'
|
||||||
|
vol['ElementName'] = self.data.test_volume['id']
|
||||||
|
vol['DeviceID'] = self.data.test_volume['device_id']
|
||||||
|
vol['Id'] = self.data.test_volume['id']
|
||||||
|
vol['SystemName'] = self.data.storage_system
|
||||||
|
vol['NumberOfBlocks'] = self.data.test_volume['NumberOfBlocks']
|
||||||
|
vol['BlockSize'] = self.data.test_volume['BlockSize']
|
||||||
|
|
||||||
|
# Added vol to vol.path
|
||||||
|
vol['SystemCreationClassName'] = 'Symm_StorageSystem'
|
||||||
|
vol.path = vol
|
||||||
|
vol.path.classname = vol['CreationClassName']
|
||||||
|
|
||||||
|
rollbackDict = {}
|
||||||
|
rollbackDict['isV3'] = False
|
||||||
|
rollbackDict['defaultStorageGroupInstanceName'] = (
|
||||||
|
self.data.default_storage_group)
|
||||||
|
rollbackDict['sgName'] = self.data.storagegroupname
|
||||||
|
rollbackDict['volumeName'] = 'vol1'
|
||||||
|
rollbackDict['fastPolicyName'] = 'GOLD1'
|
||||||
|
rollbackDict['volumeInstance'] = vol
|
||||||
|
rollbackDict['controllerConfigService'] = controllerConfigService
|
||||||
|
rollbackDict['extraSpecs'] = extraSpecs
|
||||||
|
# Path 1 - The volume is in another storage group that isn't the
|
||||||
|
# default storage group
|
||||||
|
expectedmessage = (_("V2 rollback - Volume in another storage "
|
||||||
|
"group besides default storage group."))
|
||||||
|
message = (
|
||||||
|
self.driver.common.masking.
|
||||||
|
_check_if_rollback_action_for_masking_required(
|
||||||
|
conn, rollbackDict))
|
||||||
|
self.assertEqual(expectedmessage, message)
|
||||||
|
# Path 2 - The volume is not in any storage group
|
||||||
|
rollbackDict['sgName'] = 'sq_not_exist'
|
||||||
|
expectedmessage = (_("V2 rollback, volume is not in any storage "
|
||||||
|
"group."))
|
||||||
|
message = (
|
||||||
|
self.driver.common.masking.
|
||||||
|
_check_if_rollback_action_for_masking_required(
|
||||||
|
conn, rollbackDict))
|
||||||
|
self.assertEqual(expectedmessage, message)
|
||||||
|
|
||||||
|
def test_migrate_cleanup(self):
|
||||||
|
conn = self.fake_ecom_connection()
|
||||||
|
extraSpecs = {'volume_backend_name': 'GOLD_BE',
|
||||||
|
'isV3': False,
|
||||||
|
'storagetype:fastpolicy': 'GOLD1'}
|
||||||
|
|
||||||
|
vol = EMC_StorageVolume()
|
||||||
|
vol['name'] = self.data.test_volume['name']
|
||||||
|
vol['CreationClassName'] = 'Symm_StorageVolume'
|
||||||
|
vol['ElementName'] = self.data.test_volume['id']
|
||||||
|
vol['DeviceID'] = self.data.test_volume['device_id']
|
||||||
|
vol['Id'] = self.data.test_volume['id']
|
||||||
|
vol['SystemName'] = self.data.storage_system
|
||||||
|
vol['NumberOfBlocks'] = self.data.test_volume['NumberOfBlocks']
|
||||||
|
vol['BlockSize'] = self.data.test_volume['BlockSize']
|
||||||
|
|
||||||
|
# Added vol to vol.path
|
||||||
|
vol['SystemCreationClassName'] = 'Symm_StorageSystem'
|
||||||
|
vol.path = vol
|
||||||
|
vol.path.classname = vol['CreationClassName']
|
||||||
|
# The volume is already belong to default storage group
|
||||||
|
return_to_default = self.driver.common._migrate_cleanup(
|
||||||
|
conn, vol, self.data.storage_system, 'GOLD1',
|
||||||
|
vol['name'], extraSpecs)
|
||||||
|
self.assertFalse(return_to_default)
|
||||||
|
# The volume does not belong to default storage group
|
||||||
|
return_to_default = self.driver.common._migrate_cleanup(
|
||||||
|
conn, vol, self.data.storage_system, 'BRONZE1',
|
||||||
|
vol['name'], extraSpecs)
|
||||||
|
self.assertTrue(return_to_default)
|
||||||
|
|
||||||
def test_wait_for_job_complete(self):
|
def test_wait_for_job_complete(self):
|
||||||
myjob = SE_ConcreteJob()
|
myjob = SE_ConcreteJob()
|
||||||
myjob.classname = 'SE_ConcreteJob'
|
myjob.classname = 'SE_ConcreteJob'
|
||||||
@ -3839,7 +3956,7 @@ class EMCVMAXFCDriverNoFastTestCase(test.TestCase):
|
|||||||
|
|
||||||
def test_get_port_group_parser(self):
|
def test_get_port_group_parser(self):
|
||||||
self.create_fake_config_file_parse_port_group()
|
self.create_fake_config_file_parse_port_group()
|
||||||
for _ in range(0, 10):
|
for _var in range(0, 10):
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
u'OS-PORTGROUP1-PG',
|
u'OS-PORTGROUP1-PG',
|
||||||
self.driver.utils.parse_file_to_get_port_group_name(
|
self.driver.utils.parse_file_to_get_port_group_name(
|
||||||
|
@ -803,42 +803,41 @@ class EMCVMAXCommon(object):
|
|||||||
:param sourceFastPolicyName: the source FAST policy name
|
:param sourceFastPolicyName: the source FAST policy name
|
||||||
:param volumeName: the volume Name
|
:param volumeName: the volume Name
|
||||||
:param extraSpecs: extra specifications
|
:param extraSpecs: extra specifications
|
||||||
|
:returns: boolean -- True/False
|
||||||
"""
|
"""
|
||||||
|
|
||||||
LOG.warning(_LW("_migrate_cleanup on : %(volumeName)s."),
|
LOG.warning(_LW("_migrate_cleanup on : %(volumeName)s."),
|
||||||
{'volumeName': volumeName})
|
{'volumeName': volumeName})
|
||||||
|
return_to_default = True
|
||||||
controllerConfigurationService = (
|
controllerConfigurationService = (
|
||||||
self.utils.find_controller_configuration_service(
|
self.utils.find_controller_configuration_service(
|
||||||
conn, storageSystemName))
|
conn, storageSystemName))
|
||||||
|
|
||||||
# Check to see what SG it is in.
|
# Check to see what SG it is in.
|
||||||
assocStorageGroupInstanceName = (
|
assocStorageGroupInstanceNames = (
|
||||||
self.utils.get_storage_group_from_volume(conn,
|
self.utils.get_storage_groups_from_volume(conn,
|
||||||
volumeInstance.path))
|
volumeInstance.path))
|
||||||
# This is the SG it should be in.
|
# This is the SG it should be in.
|
||||||
defaultStorageGroupInstanceName = (
|
defaultStorageGroupInstanceName = (
|
||||||
self.fast.get_policy_default_storage_group(
|
self.fast.get_policy_default_storage_group(
|
||||||
conn, controllerConfigurationService, sourceFastPolicyName))
|
conn, controllerConfigurationService, sourceFastPolicyName))
|
||||||
|
|
||||||
# It is not in any storage group. Must add it to default source.
|
for assocStorageGroupInstanceName in assocStorageGroupInstanceNames:
|
||||||
if assocStorageGroupInstanceName is None:
|
# It is in the incorrect storage group.
|
||||||
self.add_to_default_SG(conn, volumeInstance,
|
if (assocStorageGroupInstanceName !=
|
||||||
storageSystemName, sourceFastPolicyName,
|
defaultStorageGroupInstanceName):
|
||||||
volumeName, extraSpecs)
|
self.provision.remove_device_from_storage_group(
|
||||||
|
conn, controllerConfigurationService,
|
||||||
# It is in the incorrect storage group.
|
assocStorageGroupInstanceName,
|
||||||
if (assocStorageGroupInstanceName is not None and
|
volumeInstance.path, volumeName, extraSpecs)
|
||||||
(assocStorageGroupInstanceName !=
|
else:
|
||||||
defaultStorageGroupInstanceName)):
|
# The volume is already in the default.
|
||||||
self.provision.remove_device_from_storage_group(
|
return_to_default = False
|
||||||
conn, controllerConfigurationService,
|
if return_to_default:
|
||||||
assocStorageGroupInstanceName,
|
|
||||||
volumeInstance.path, volumeName, extraSpecs)
|
|
||||||
|
|
||||||
self.add_to_default_SG(
|
self.add_to_default_SG(
|
||||||
conn, volumeInstance, storageSystemName, sourceFastPolicyName,
|
conn, volumeInstance, storageSystemName, sourceFastPolicyName,
|
||||||
volumeName, extraSpecs)
|
volumeName, extraSpecs)
|
||||||
|
return return_to_default
|
||||||
|
|
||||||
def _migrate_volume_fast_target(
|
def _migrate_volume_fast_target(
|
||||||
self, volumeInstance, storageSystemName,
|
self, volumeInstance, storageSystemName,
|
||||||
@ -1041,7 +1040,7 @@ class EMCVMAXCommon(object):
|
|||||||
|
|
||||||
def _is_valid_for_storage_assisted_migration_v3(
|
def _is_valid_for_storage_assisted_migration_v3(
|
||||||
self, volumeInstanceName, host, sourceArraySerialNumber,
|
self, volumeInstanceName, host, sourceArraySerialNumber,
|
||||||
sourcePoolName, volumeName, volumeStatus):
|
sourcePoolName, volumeName, volumeStatus, sgName):
|
||||||
"""Check if volume is suitable for storage assisted (pool) migration.
|
"""Check if volume is suitable for storage assisted (pool) migration.
|
||||||
|
|
||||||
:param volumeInstanceName: the volume instance id
|
:param volumeInstanceName: the volume instance id
|
||||||
@ -1050,7 +1049,8 @@ class EMCVMAXCommon(object):
|
|||||||
the original volume
|
the original volume
|
||||||
:param sourcePoolName: the pool name of the original volume
|
:param sourcePoolName: the pool name of the original volume
|
||||||
:param volumeName: the name of the volume to be migrated
|
:param volumeName: the name of the volume to be migrated
|
||||||
:param volumeStatus: the status of the volume e.g
|
:param volumeStatus: the status of the volume
|
||||||
|
:param sgName: storage group name
|
||||||
:returns: boolean -- True/False
|
:returns: boolean -- True/False
|
||||||
:returns: string -- targetSlo
|
:returns: string -- targetSlo
|
||||||
:returns: string -- targetWorkload
|
:returns: string -- targetWorkload
|
||||||
@ -1094,7 +1094,7 @@ class EMCVMAXCommon(object):
|
|||||||
|
|
||||||
foundStorageGroupInstanceName = (
|
foundStorageGroupInstanceName = (
|
||||||
self.utils.get_storage_group_from_volume(
|
self.utils.get_storage_group_from_volume(
|
||||||
self.conn, volumeInstanceName))
|
self.conn, volumeInstanceName, sgName))
|
||||||
if foundStorageGroupInstanceName is None:
|
if foundStorageGroupInstanceName is None:
|
||||||
LOG.warning(_LW(
|
LOG.warning(_LW(
|
||||||
"Volume: %(volumeName)s is not currently "
|
"Volume: %(volumeName)s is not currently "
|
||||||
@ -1775,13 +1775,14 @@ class EMCVMAXCommon(object):
|
|||||||
controllerConfigurationService = (
|
controllerConfigurationService = (
|
||||||
self.utils.find_controller_configuration_service(
|
self.utils.find_controller_configuration_service(
|
||||||
self.conn, storageSystemName))
|
self.conn, storageSystemName))
|
||||||
|
defaultSgName = self.fast.format_default_sg_string(fastPolicyName)
|
||||||
|
|
||||||
self.fast.add_volume_to_default_storage_group_for_fast_policy(
|
self.fast.add_volume_to_default_storage_group_for_fast_policy(
|
||||||
self.conn, controllerConfigurationService, volumeInstance,
|
self.conn, controllerConfigurationService, volumeInstance,
|
||||||
volumeName, fastPolicyName, extraSpecs)
|
volumeName, fastPolicyName, extraSpecs)
|
||||||
foundStorageGroupInstanceName = (
|
foundStorageGroupInstanceName = (
|
||||||
self.utils.get_storage_group_from_volume(
|
self.utils.get_storage_group_from_volume(
|
||||||
self.conn, volumeInstance.path))
|
self.conn, volumeInstance.path, defaultSgName))
|
||||||
|
|
||||||
if foundStorageGroupInstanceName is None:
|
if foundStorageGroupInstanceName is None:
|
||||||
exceptionMessage = (_(
|
exceptionMessage = (_(
|
||||||
@ -2948,11 +2949,14 @@ class EMCVMAXCommon(object):
|
|||||||
:param extraSpecs: extra specifications
|
:param extraSpecs: extra specifications
|
||||||
:returns: boolean -- True if migration succeeded, False if error.
|
:returns: boolean -- True if migration succeeded, False if error.
|
||||||
"""
|
"""
|
||||||
|
storageGroupName = self.utils.get_v3_storage_group_name(
|
||||||
|
extraSpecs[POOL], extraSpecs[SLO], extraSpecs[WORKLOAD])
|
||||||
volumeInstanceName = volumeInstance.path
|
volumeInstanceName = volumeInstance.path
|
||||||
isValid, targetSlo, targetWorkload = (
|
isValid, targetSlo, targetWorkload = (
|
||||||
self._is_valid_for_storage_assisted_migration_v3(
|
self._is_valid_for_storage_assisted_migration_v3(
|
||||||
volumeInstanceName, host, extraSpecs[ARRAY],
|
volumeInstanceName, host, extraSpecs[ARRAY],
|
||||||
extraSpecs[POOL], volumeName, volumeStatus))
|
extraSpecs[POOL], volumeName, volumeStatus,
|
||||||
|
storageGroupName))
|
||||||
|
|
||||||
storageSystemName = volumeInstance['SystemName']
|
storageSystemName = volumeInstance['SystemName']
|
||||||
|
|
||||||
@ -2998,10 +3002,12 @@ class EMCVMAXCommon(object):
|
|||||||
controllerConfigService = (
|
controllerConfigService = (
|
||||||
self.utils.find_controller_configuration_service(
|
self.utils.find_controller_configuration_service(
|
||||||
self.conn, storageSystemName))
|
self.conn, storageSystemName))
|
||||||
|
defaultSgName = self.utils.get_v3_storage_group_name(
|
||||||
|
extraSpecs[POOL], extraSpecs[SLO], extraSpecs[WORKLOAD])
|
||||||
|
|
||||||
foundStorageGroupInstanceName = (
|
foundStorageGroupInstanceName = (
|
||||||
self.utils.get_storage_group_from_volume(
|
self.utils.get_storage_group_from_volume(
|
||||||
self.conn, volumeInstance.path))
|
self.conn, volumeInstance.path, defaultSgName))
|
||||||
if foundStorageGroupInstanceName is None:
|
if foundStorageGroupInstanceName is None:
|
||||||
LOG.warning(_LW(
|
LOG.warning(_LW(
|
||||||
"Volume : %(volumeName)s is not currently "
|
"Volume : %(volumeName)s is not currently "
|
||||||
@ -3017,7 +3023,7 @@ class EMCVMAXCommon(object):
|
|||||||
# Check that it has been removed.
|
# Check that it has been removed.
|
||||||
sgFromVolRemovedInstanceName = (
|
sgFromVolRemovedInstanceName = (
|
||||||
self.utils.wrap_get_storage_group_from_volume(
|
self.utils.wrap_get_storage_group_from_volume(
|
||||||
self.conn, volumeInstance.path))
|
self.conn, volumeInstance.path, defaultSgName))
|
||||||
if sgFromVolRemovedInstanceName is not None:
|
if sgFromVolRemovedInstanceName is not None:
|
||||||
LOG.error(_LE(
|
LOG.error(_LE(
|
||||||
"Volume : %(volumeName)s has not been "
|
"Volume : %(volumeName)s has not been "
|
||||||
@ -3044,7 +3050,7 @@ class EMCVMAXCommon(object):
|
|||||||
# Check that it has been added.
|
# Check that it has been added.
|
||||||
sgFromVolAddedInstanceName = (
|
sgFromVolAddedInstanceName = (
|
||||||
self.utils.get_storage_group_from_volume(
|
self.utils.get_storage_group_from_volume(
|
||||||
self.conn, volumeInstance.path))
|
self.conn, volumeInstance.path, storageGroupName))
|
||||||
if sgFromVolAddedInstanceName is None:
|
if sgFromVolAddedInstanceName is None:
|
||||||
LOG.error(_LE(
|
LOG.error(_LE(
|
||||||
"Volume : %(volumeName)s has not been "
|
"Volume : %(volumeName)s has not been "
|
||||||
|
@ -106,7 +106,7 @@ class EMCVMAXFast(object):
|
|||||||
:param volumeInstanceName: the volume instance name
|
:param volumeInstanceName: the volume instance name
|
||||||
:param volumeName: the volume name (String)
|
:param volumeName: the volume name (String)
|
||||||
:param fastPolicyName: the fast policy name (String)
|
:param fastPolicyName: the fast policy name (String)
|
||||||
:returns: foundDefaultStorageGroupInstanceName
|
:returns: foundDefaultStorageGroupInstanceName, defaultSgName
|
||||||
"""
|
"""
|
||||||
foundDefaultStorageGroupInstanceName = None
|
foundDefaultStorageGroupInstanceName = None
|
||||||
storageSystemInstanceName = self.utils.find_storage_system(
|
storageSystemInstanceName = self.utils.find_storage_system(
|
||||||
@ -117,9 +117,11 @@ class EMCVMAXFast(object):
|
|||||||
"FAST is not supported on this array."))
|
"FAST is not supported on this array."))
|
||||||
raise
|
raise
|
||||||
|
|
||||||
|
defaultSgName = self.format_default_sg_string(fastPolicyName)
|
||||||
assocStorageGroupInstanceName = (
|
assocStorageGroupInstanceName = (
|
||||||
self.utils.get_storage_group_from_volume(conn, volumeInstanceName))
|
self.utils.get_storage_group_from_volume(conn, volumeInstanceName,
|
||||||
defaultSgName = self._format_default_sg_string(fastPolicyName)
|
defaultSgName))
|
||||||
|
|
||||||
defaultStorageGroupInstanceName = (
|
defaultStorageGroupInstanceName = (
|
||||||
self.utils.find_storage_masking_group(conn,
|
self.utils.find_storage_masking_group(conn,
|
||||||
controllerConfigService,
|
controllerConfigService,
|
||||||
@ -137,12 +139,12 @@ class EMCVMAXFast(object):
|
|||||||
else:
|
else:
|
||||||
LOG.warning(_LW(
|
LOG.warning(_LW(
|
||||||
"Volume: %(volumeName)s Does not belong "
|
"Volume: %(volumeName)s Does not belong "
|
||||||
"to storage storage group %(defaultSgGroupName)s."),
|
"to storage group %(defaultSgName)s."),
|
||||||
{'volumeName': volumeName,
|
{'volumeName': volumeName,
|
||||||
'defaultSgGroupName': defaultSgName})
|
'defaultSgName': defaultSgName})
|
||||||
return foundDefaultStorageGroupInstanceName
|
return foundDefaultStorageGroupInstanceName, defaultSgName
|
||||||
|
|
||||||
def _format_default_sg_string(self, fastPolicyName):
|
def format_default_sg_string(self, fastPolicyName):
|
||||||
"""Format the default storage group name
|
"""Format the default storage group name
|
||||||
|
|
||||||
:param fastPolicyName: the fast policy name
|
:param fastPolicyName: the fast policy name
|
||||||
@ -171,14 +173,13 @@ class EMCVMAXFast(object):
|
|||||||
associated with the volume
|
associated with the volume
|
||||||
"""
|
"""
|
||||||
failedRet = None
|
failedRet = None
|
||||||
defaultSgName = self._format_default_sg_string(fastPolicyName)
|
defaultSgName = self.format_default_sg_string(fastPolicyName)
|
||||||
storageGroupInstanceName = self.utils.find_storage_masking_group(
|
storageGroupInstanceName = self.utils.find_storage_masking_group(
|
||||||
conn, controllerConfigService, defaultSgName)
|
conn, controllerConfigService, defaultSgName)
|
||||||
if storageGroupInstanceName is None:
|
if storageGroupInstanceName is None:
|
||||||
LOG.error(_LE(
|
LOG.error(_LE(
|
||||||
"Unable to create default storage group for "
|
"Unable to get default storage group %(defaultSgName)s."),
|
||||||
"FAST policy : %(fastPolicyName)s."),
|
{'defaultSgName': defaultSgName})
|
||||||
{'fastPolicyName': fastPolicyName})
|
|
||||||
return failedRet
|
return failedRet
|
||||||
|
|
||||||
self.provision.add_members_to_masking_group(
|
self.provision.add_members_to_masking_group(
|
||||||
@ -187,7 +188,8 @@ class EMCVMAXFast(object):
|
|||||||
# Check to see if the volume is in the storage group.
|
# Check to see if the volume is in the storage group.
|
||||||
assocStorageGroupInstanceName = (
|
assocStorageGroupInstanceName = (
|
||||||
self.utils.get_storage_group_from_volume(conn,
|
self.utils.get_storage_group_from_volume(conn,
|
||||||
volumeInstance.path))
|
volumeInstance.path,
|
||||||
|
defaultSgName))
|
||||||
return assocStorageGroupInstanceName
|
return assocStorageGroupInstanceName
|
||||||
|
|
||||||
def _create_default_storage_group(self, conn, controllerConfigService,
|
def _create_default_storage_group(self, conn, controllerConfigService,
|
||||||
@ -750,7 +752,7 @@ class EMCVMAXFast(object):
|
|||||||
:returns: defaultStorageGroupInstanceName - the default storage group
|
:returns: defaultStorageGroupInstanceName - the default storage group
|
||||||
instance name
|
instance name
|
||||||
"""
|
"""
|
||||||
defaultSgName = self._format_default_sg_string(fastPolicyName)
|
defaultSgName = self.format_default_sg_string(fastPolicyName)
|
||||||
defaultStorageGroupInstanceName = (
|
defaultStorageGroupInstanceName = (
|
||||||
self.utils.find_storage_masking_group(conn,
|
self.utils.find_storage_masking_group(conn,
|
||||||
controllerConfigService,
|
controllerConfigService,
|
||||||
|
@ -35,7 +35,8 @@ class EMCVMAXFCDriver(driver.FibreChannelDriver):
|
|||||||
2.0.0 - Add driver requirement functions
|
2.0.0 - Add driver requirement functions
|
||||||
2.1.0 - Add consistency group functions
|
2.1.0 - Add consistency group functions
|
||||||
2.1.1 - Fixed issue with mismatched config (bug #1442376)
|
2.1.1 - Fixed issue with mismatched config (bug #1442376)
|
||||||
2.1.3 - Clean up failed clones (bug #1440154)
|
2.1.2 - Clean up failed clones (bug #1440154)
|
||||||
|
2.1.3 - Fixed a problem with FAST support (bug #1435069)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
VERSION = "2.1.3"
|
VERSION = "2.1.3"
|
||||||
|
@ -43,7 +43,8 @@ class EMCVMAXISCSIDriver(driver.ISCSIDriver):
|
|||||||
2.0.0 - Add driver requirement functions
|
2.0.0 - Add driver requirement functions
|
||||||
2.1.0 - Add consistency group functions
|
2.1.0 - Add consistency group functions
|
||||||
2.1.1 - Fixed issue with mismatched config (bug #1442376)
|
2.1.1 - Fixed issue with mismatched config (bug #1442376)
|
||||||
2.1.3 - Clean up failed clones (bug #1440154)
|
2.1.2 - Clean up failed clones (bug #1440154)
|
||||||
|
2.1.3 - Fixed a problem with FAST support (bug #1435069)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
VERSION = "2.1.3"
|
VERSION = "2.1.3"
|
||||||
|
@ -93,7 +93,8 @@ class EMCVMAXMasking(object):
|
|||||||
if isV3:
|
if isV3:
|
||||||
assocStorageGroupInstanceName = (
|
assocStorageGroupInstanceName = (
|
||||||
self.utils.get_storage_group_from_volume(
|
self.utils.get_storage_group_from_volume(
|
||||||
conn, volumeInstance.path))
|
conn, volumeInstance.path,
|
||||||
|
maskingViewDict['sgGroupName']))
|
||||||
instance = conn.GetInstance(
|
instance = conn.GetInstance(
|
||||||
assocStorageGroupInstanceName, LocalOnly=False)
|
assocStorageGroupInstanceName, LocalOnly=False)
|
||||||
assocStorageGroupName = instance['ElementName']
|
assocStorageGroupName = instance['ElementName']
|
||||||
@ -125,14 +126,24 @@ class EMCVMAXMasking(object):
|
|||||||
volumeName, fastPolicyName,
|
volumeName, fastPolicyName,
|
||||||
extraSpecs))
|
extraSpecs))
|
||||||
|
|
||||||
maskingViewInstanceName, storageGroupInstanceName, errorMessage = (
|
# If anything has gone wrong with the masking view we rollback
|
||||||
self._validate_masking_view(conn, maskingViewDict,
|
try:
|
||||||
defaultStorageGroupInstanceName))
|
maskingViewInstanceName, storageGroupInstanceName, errorMessage = (
|
||||||
|
self._validate_masking_view(conn, maskingViewDict,
|
||||||
LOG.debug(
|
defaultStorageGroupInstanceName))
|
||||||
"The masking view in the attach operation is "
|
LOG.debug(
|
||||||
"%(maskingViewInstanceName)s.",
|
"The masking view in the attach operation is "
|
||||||
{'maskingViewInstanceName': maskingViewInstanceName})
|
"%(maskingViewInstanceName)s. The storage group "
|
||||||
|
"in the masking view is %(storageGroupInstanceName)s.",
|
||||||
|
{'maskingViewInstanceName': maskingViewInstanceName,
|
||||||
|
'storageGroupInstanceName': storageGroupInstanceName})
|
||||||
|
except Exception as e:
|
||||||
|
LOG.exception(_LE(
|
||||||
|
"Masking View creation or retrieval was not successful "
|
||||||
|
"for masking view %(maskingViewName)s. "
|
||||||
|
"Attempting rollback."),
|
||||||
|
{'maskingViewName': maskingViewDict['maskingViewName']})
|
||||||
|
errorMessage = e
|
||||||
|
|
||||||
if not errorMessage:
|
if not errorMessage:
|
||||||
# Only after the masking view has been validated, add the
|
# Only after the masking view has been validated, add the
|
||||||
@ -149,6 +160,7 @@ class EMCVMAXMasking(object):
|
|||||||
rollbackDict['fastPolicyName'] = fastPolicyName
|
rollbackDict['fastPolicyName'] = fastPolicyName
|
||||||
rollbackDict['isV3'] = isV3
|
rollbackDict['isV3'] = isV3
|
||||||
rollbackDict['extraSpecs'] = extraSpecs
|
rollbackDict['extraSpecs'] = extraSpecs
|
||||||
|
rollbackDict['sgName'] = maskingViewDict['sgGroupName']
|
||||||
|
|
||||||
if errorMessage:
|
if errorMessage:
|
||||||
# Rollback code if we cannot complete any of the steps above
|
# Rollback code if we cannot complete any of the steps above
|
||||||
@ -471,7 +483,7 @@ class EMCVMAXMasking(object):
|
|||||||
msg = None
|
msg = None
|
||||||
if self._is_volume_in_storage_group(
|
if self._is_volume_in_storage_group(
|
||||||
conn, storageGroupInstanceName,
|
conn, storageGroupInstanceName,
|
||||||
volumeInstance):
|
volumeInstance, sgGroupName):
|
||||||
LOG.warning(_LW(
|
LOG.warning(_LW(
|
||||||
"Volume: %(volumeName)s is already part "
|
"Volume: %(volumeName)s is already part "
|
||||||
"of storage group %(sgGroupName)s."),
|
"of storage group %(sgGroupName)s."),
|
||||||
@ -484,7 +496,7 @@ class EMCVMAXMasking(object):
|
|||||||
sgGroupName, maskingViewDict['extraSpecs'])
|
sgGroupName, maskingViewDict['extraSpecs'])
|
||||||
if not self._is_volume_in_storage_group(
|
if not self._is_volume_in_storage_group(
|
||||||
conn, storageGroupInstanceName,
|
conn, storageGroupInstanceName,
|
||||||
volumeInstance):
|
volumeInstance, sgGroupName):
|
||||||
# This may be used in exception hence _ instead of _LE.
|
# This may be used in exception hence _ instead of _LE.
|
||||||
msg = (_(
|
msg = (_(
|
||||||
"Volume: %(volumeName)s was not added "
|
"Volume: %(volumeName)s was not added "
|
||||||
@ -533,8 +545,7 @@ class EMCVMAXMasking(object):
|
|||||||
volumeName, fastPolicyName, extraSpecs))
|
volumeName, fastPolicyName, extraSpecs))
|
||||||
if retStorageGroupInstanceName is None:
|
if retStorageGroupInstanceName is None:
|
||||||
exceptionMessage = (_(
|
exceptionMessage = (_(
|
||||||
"Failed to remove volume %(volumeName)s from default SG: "
|
"Failed to remove volume %(volumeName)s from default SG.")
|
||||||
"%(volumeName)s.")
|
|
||||||
% {'volumeName': volumeName})
|
% {'volumeName': volumeName})
|
||||||
LOG.error(exceptionMessage)
|
LOG.error(exceptionMessage)
|
||||||
raise exception.VolumeBackendAPIException(
|
raise exception.VolumeBackendAPIException(
|
||||||
@ -577,7 +588,8 @@ class EMCVMAXMasking(object):
|
|||||||
|
|
||||||
# Required for unit tests.
|
# Required for unit tests.
|
||||||
emptyStorageGroupInstanceName = (
|
emptyStorageGroupInstanceName = (
|
||||||
self._wrap_get_storage_group_from_volume(conn, volumeInstanceName))
|
self._wrap_get_storage_group_from_volume(
|
||||||
|
conn, volumeInstanceName, maskingViewDict['sgGroupName']))
|
||||||
|
|
||||||
if emptyStorageGroupInstanceName is not None:
|
if emptyStorageGroupInstanceName is not None:
|
||||||
exceptionMessage = (_(
|
exceptionMessage = (_(
|
||||||
@ -589,7 +601,7 @@ class EMCVMAXMasking(object):
|
|||||||
data=exceptionMessage)
|
data=exceptionMessage)
|
||||||
|
|
||||||
def _is_volume_in_storage_group(
|
def _is_volume_in_storage_group(
|
||||||
self, conn, storageGroupInstanceName, volumeInstance):
|
self, conn, storageGroupInstanceName, volumeInstance, sgName):
|
||||||
"""Check if the volume is already part of the storage group.
|
"""Check if the volume is already part of the storage group.
|
||||||
|
|
||||||
Check if the volume is already part of the storage group,
|
Check if the volume is already part of the storage group,
|
||||||
@ -602,7 +614,7 @@ class EMCVMAXMasking(object):
|
|||||||
"""
|
"""
|
||||||
foundStorageGroupInstanceName = (
|
foundStorageGroupInstanceName = (
|
||||||
self.utils.get_storage_group_from_volume(
|
self.utils.get_storage_group_from_volume(
|
||||||
conn, volumeInstance.path))
|
conn, volumeInstance.path, sgName))
|
||||||
|
|
||||||
if foundStorageGroupInstanceName is not None:
|
if foundStorageGroupInstanceName is not None:
|
||||||
storageGroupInstance = conn.GetInstance(
|
storageGroupInstance = conn.GetInstance(
|
||||||
@ -1195,8 +1207,10 @@ class EMCVMAXMasking(object):
|
|||||||
|
|
||||||
:param conn: the connection to the ecom server
|
:param conn: the connection to the ecom server
|
||||||
:param rollbackDict: the rollback dictionary
|
:param rollbackDict: the rollback dictionary
|
||||||
|
:returns: message
|
||||||
:raises: VolumeBackendAPIException
|
:raises: VolumeBackendAPIException
|
||||||
"""
|
"""
|
||||||
|
message = None
|
||||||
try:
|
try:
|
||||||
if rollbackDict['isV3']:
|
if rollbackDict['isV3']:
|
||||||
errorMessage = self._check_adding_volume_to_storage_group(
|
errorMessage = self._check_adding_volume_to_storage_group(
|
||||||
@ -1204,14 +1218,16 @@ class EMCVMAXMasking(object):
|
|||||||
rollbackDict['defaultStorageGroupInstanceName'])
|
rollbackDict['defaultStorageGroupInstanceName'])
|
||||||
if errorMessage:
|
if errorMessage:
|
||||||
LOG.error(errorMessage)
|
LOG.error(errorMessage)
|
||||||
|
message = (_("V3 rollback"))
|
||||||
|
|
||||||
else:
|
else:
|
||||||
foundStorageGroupInstanceName = (
|
foundStorageGroupInstanceName = (
|
||||||
self.utils.get_storage_group_from_volume(
|
self.utils.get_storage_group_from_volume(
|
||||||
conn, rollbackDict['volumeInstance'].path))
|
conn, rollbackDict['volumeInstance'].path,
|
||||||
|
rollbackDict['sgName']))
|
||||||
# Volume is not associated with any storage group so add
|
# Volume is not associated with any storage group so add
|
||||||
# it back to the default.
|
# it back to the default.
|
||||||
if len(foundStorageGroupInstanceName) == 0:
|
if not foundStorageGroupInstanceName:
|
||||||
LOG.warning(_LW(
|
LOG.warning(_LW(
|
||||||
"No storage group found. "
|
"No storage group found. "
|
||||||
"Performing rollback on Volume: %(volumeName)s "
|
"Performing rollback on Volume: %(volumeName)s "
|
||||||
@ -1237,26 +1253,29 @@ class EMCVMAXMasking(object):
|
|||||||
"admin to get the volume re-added manually."),
|
"admin to get the volume re-added manually."),
|
||||||
{'volumeName': rollbackDict['volumeName'],
|
{'volumeName': rollbackDict['volumeName'],
|
||||||
'fastPolicyName': rollbackDict['fastPolicyName']})
|
'fastPolicyName': rollbackDict['fastPolicyName']})
|
||||||
if len(foundStorageGroupInstanceName) > 0:
|
message = (_("V2 rollback, volume is not in any storage "
|
||||||
|
"group."))
|
||||||
|
else:
|
||||||
LOG.info(_LI(
|
LOG.info(_LI(
|
||||||
"The storage group found is "
|
"The storage group found is "
|
||||||
"%(foundStorageGroupInstanceName)s."),
|
"%(foundStorageGroupInstanceName)s."),
|
||||||
{'foundStorageGroupInstanceName':
|
{'foundStorageGroupInstanceName':
|
||||||
foundStorageGroupInstanceName})
|
foundStorageGroupInstanceName})
|
||||||
|
|
||||||
# Check the name, see is it the default storage group
|
# Check the name, see is it the default storage group
|
||||||
# or another.
|
# or another.
|
||||||
if (foundStorageGroupInstanceName !=
|
if (foundStorageGroupInstanceName !=
|
||||||
rollbackDict['defaultStorageGroupInstanceName']):
|
rollbackDict['defaultStorageGroupInstanceName']):
|
||||||
# Remove it from its current masking view and return it
|
# Remove it from its current masking view and return it
|
||||||
# to its default masking view if fast is enabled.
|
# to its default masking view if fast is enabled.
|
||||||
self.remove_and_reset_members(
|
self.remove_and_reset_members(
|
||||||
conn,
|
conn,
|
||||||
rollbackDict['controllerConfigService'],
|
rollbackDict['controllerConfigService'],
|
||||||
rollbackDict['volumeInstance'],
|
rollbackDict['volumeInstance'],
|
||||||
rollbackDict['fastPolicyName'],
|
rollbackDict['volumeName'],
|
||||||
rollbackDict['volumeName'], rollbackDict['extraSpecs'],
|
rollbackDict['extraSpecs'])
|
||||||
False)
|
message = (_("V2 rollback - Volume in another storage "
|
||||||
|
"group besides default storage group."))
|
||||||
except Exception:
|
except Exception:
|
||||||
errorMessage = (_(
|
errorMessage = (_(
|
||||||
"Rollback for Volume: %(volumeName)s has failed. "
|
"Rollback for Volume: %(volumeName)s has failed. "
|
||||||
@ -1267,6 +1286,7 @@ class EMCVMAXMasking(object):
|
|||||||
'fastPolicyName': rollbackDict['fastPolicyName']})
|
'fastPolicyName': rollbackDict['fastPolicyName']})
|
||||||
LOG.exception(errorMessage)
|
LOG.exception(errorMessage)
|
||||||
raise exception.VolumeBackendAPIException(data=errorMessage)
|
raise exception.VolumeBackendAPIException(data=errorMessage)
|
||||||
|
return message
|
||||||
|
|
||||||
def _find_new_initiator_group(self, conn, maskingGroupDict):
|
def _find_new_initiator_group(self, conn, maskingGroupDict):
|
||||||
"""After creating an new initiator group find it and return it.
|
"""After creating an new initiator group find it and return it.
|
||||||
@ -1575,7 +1595,7 @@ class EMCVMAXMasking(object):
|
|||||||
:returns: instance name defaultStorageGroupInstanceName
|
:returns: instance name defaultStorageGroupInstanceName
|
||||||
"""
|
"""
|
||||||
failedRet = None
|
failedRet = None
|
||||||
defaultStorageGroupInstanceName = (
|
defaultStorageGroupInstanceName, defaultSgName = (
|
||||||
self.fast.get_and_verify_default_storage_group(
|
self.fast.get_and_verify_default_storage_group(
|
||||||
conn, controllerConfigService, volumeInstanceName,
|
conn, controllerConfigService, volumeInstanceName,
|
||||||
volumeName, fastPolicyName))
|
volumeName, fastPolicyName))
|
||||||
@ -1610,7 +1630,8 @@ class EMCVMAXMasking(object):
|
|||||||
|
|
||||||
# Required for unit tests.
|
# Required for unit tests.
|
||||||
emptyStorageGroupInstanceName = (
|
emptyStorageGroupInstanceName = (
|
||||||
self._wrap_get_storage_group_from_volume(conn, volumeInstanceName))
|
self._wrap_get_storage_group_from_volume(conn, volumeInstanceName,
|
||||||
|
defaultSgName))
|
||||||
|
|
||||||
if emptyStorageGroupInstanceName is not None:
|
if emptyStorageGroupInstanceName is not None:
|
||||||
LOG.error(_LE(
|
LOG.error(_LE(
|
||||||
@ -1621,18 +1642,20 @@ class EMCVMAXMasking(object):
|
|||||||
|
|
||||||
return defaultStorageGroupInstanceName
|
return defaultStorageGroupInstanceName
|
||||||
|
|
||||||
def _wrap_get_storage_group_from_volume(self, conn, volumeInstanceName):
|
def _wrap_get_storage_group_from_volume(self, conn, volumeInstanceName,
|
||||||
|
defaultSgName):
|
||||||
"""Wrapper for get_storage_group_from_volume.
|
"""Wrapper for get_storage_group_from_volume.
|
||||||
|
|
||||||
Needed for override in tests.
|
Needed for override in tests.
|
||||||
|
|
||||||
:param conn: the connection to the ecom server
|
:param conn: the connection to the ecom server
|
||||||
:param volumeInstanceName: the volume instance name
|
:param volumeInstanceName: the volume instance name
|
||||||
|
:param defaultSgName: the default storage group name
|
||||||
:returns: emptyStorageGroupInstanceName
|
:returns: emptyStorageGroupInstanceName
|
||||||
"""
|
"""
|
||||||
|
|
||||||
return self.utils.get_storage_group_from_volume(
|
return self.utils.get_storage_group_from_volume(
|
||||||
conn, volumeInstanceName)
|
conn, volumeInstanceName, defaultSgName)
|
||||||
|
|
||||||
def get_devices_from_storage_group(
|
def get_devices_from_storage_group(
|
||||||
self, conn, storageGroupInstanceName):
|
self, conn, storageGroupInstanceName):
|
||||||
|
@ -489,7 +489,7 @@ class EMCVMAXUtils(object):
|
|||||||
|
|
||||||
return foundStorageSystemInstanceName
|
return foundStorageSystemInstanceName
|
||||||
|
|
||||||
def get_storage_group_from_volume(self, conn, volumeInstanceName):
|
def get_storage_group_from_volume(self, conn, volumeInstanceName, sgName):
|
||||||
"""Returns the storage group for a particular volume.
|
"""Returns the storage group for a particular volume.
|
||||||
|
|
||||||
Given the volume instance name get the associated storage group if it
|
Given the volume instance name get the associated storage group if it
|
||||||
@ -505,14 +505,50 @@ class EMCVMAXUtils(object):
|
|||||||
volumeInstanceName,
|
volumeInstanceName,
|
||||||
ResultClass='CIM_DeviceMaskingGroup')
|
ResultClass='CIM_DeviceMaskingGroup')
|
||||||
|
|
||||||
if len(storageGroupInstanceNames) > 0:
|
if len(storageGroupInstanceNames) > 1:
|
||||||
foundStorageGroupInstanceName = storageGroupInstanceNames[0]
|
LOG.info(_LI(
|
||||||
|
"The volume belongs to more than one storage group. "
|
||||||
|
"Returning storage group %(sgName)s."),
|
||||||
|
{'sgName': sgName})
|
||||||
|
for storageGroupInstanceName in storageGroupInstanceNames:
|
||||||
|
instance = self.get_existing_instance(
|
||||||
|
conn, storageGroupInstanceName)
|
||||||
|
if instance and sgName == instance['ElementName']:
|
||||||
|
foundStorageGroupInstanceName = storageGroupInstanceName
|
||||||
|
break
|
||||||
|
|
||||||
return foundStorageGroupInstanceName
|
return foundStorageGroupInstanceName
|
||||||
|
|
||||||
def wrap_get_storage_group_from_volume(self, conn, volumeInstanceName):
|
def get_storage_groups_from_volume(self, conn, volumeInstanceName):
|
||||||
|
"""Returns all the storage group for a particular volume.
|
||||||
|
|
||||||
|
Given the volume instance name get all the associated storage groups.
|
||||||
|
|
||||||
|
:param conn: connection to the ecom server
|
||||||
|
:param volumeInstanceName: the volume instance name
|
||||||
|
:returns: foundStorageGroupInstanceName
|
||||||
|
"""
|
||||||
|
storageGroupInstanceNames = conn.AssociatorNames(
|
||||||
|
volumeInstanceName,
|
||||||
|
ResultClass='CIM_DeviceMaskingGroup')
|
||||||
|
|
||||||
|
if storageGroupInstanceNames:
|
||||||
|
LOG.debug("There are %(len)d storage groups associated "
|
||||||
|
"with volume %(volumeInstanceName)s.",
|
||||||
|
{'len': len(storageGroupInstanceNames),
|
||||||
|
'volumeInstanceName': volumeInstanceName})
|
||||||
|
else:
|
||||||
|
LOG.debug("There are no storage groups associated "
|
||||||
|
"with volume %(volumeInstanceName)s.",
|
||||||
|
{'volumeInstanceName': volumeInstanceName})
|
||||||
|
|
||||||
|
return storageGroupInstanceNames
|
||||||
|
|
||||||
|
def wrap_get_storage_group_from_volume(self, conn, volumeInstanceName,
|
||||||
|
sgName):
|
||||||
"""Unit test aid"""
|
"""Unit test aid"""
|
||||||
return self.get_storage_group_from_volume(conn, volumeInstanceName)
|
return self.get_storage_group_from_volume(conn, volumeInstanceName,
|
||||||
|
sgName)
|
||||||
|
|
||||||
def find_storage_masking_group(self, conn, controllerConfigService,
|
def find_storage_masking_group(self, conn, controllerConfigService,
|
||||||
storageGroupName):
|
storageGroupName):
|
||||||
|
Loading…
Reference in New Issue
Block a user