Merge "EMC VMAX - locking SG for concurrent threads"

This commit is contained in:
Jenkins 2016-07-06 07:38:52 +00:00 committed by Gerrit Code Review
commit a0a96a8e55
3 changed files with 383 additions and 153 deletions

View File

@ -241,6 +241,10 @@ class EMCVMAXCommonData(object):
default_storage_group = (
u'//10.10.10.10/root/emc: SE_DeviceMaskingGroup.InstanceID='
'"SYMMETRIX+000198700440+OS_default_GOLD1_SG"')
default_sg_instance_name = {
'CreationClassName': 'CIM_DeviceMaskingGroup',
'ElementName': 'OS_default_GOLD1_SG',
'SystemName': 'SYMMETRIX+000195900551'}
storage_system = 'SYMMETRIX+000195900551'
storage_system_v3 = 'SYMMETRIX-+-000197200056'
port_group = 'OS-portgroup-PG'
@ -3139,7 +3143,7 @@ class EMCVMAXISCSIDriverNoFastTestCase(test.TestCase):
@mock.patch.object(
emc_vmax_utils.EMCVMAXUtils,
'find_storage_masking_group',
return_value='value')
return_value=EMCVMAXCommonData.default_sg_instance_name)
@mock.patch.object(
emc_vmax_masking.EMCVMAXMasking,
'_wrap_get_storage_group_from_volume',
@ -3167,7 +3171,7 @@ class EMCVMAXISCSIDriverNoFastTestCase(test.TestCase):
@mock.patch.object(
emc_vmax_utils.EMCVMAXUtils,
'find_storage_masking_group',
return_value='value')
return_value=EMCVMAXCommonData.default_sg_instance_name)
@mock.patch.object(
emc_vmax_common.EMCVMAXCommon,
'find_device_number',
@ -3242,7 +3246,7 @@ class EMCVMAXISCSIDriverNoFastTestCase(test.TestCase):
@mock.patch.object(
emc_vmax_utils.EMCVMAXUtils,
'find_storage_masking_group',
return_value=EMCVMAXCommonData.storagegroupname)
return_value=EMCVMAXCommonData.default_sg_instance_name)
@mock.patch.object(
volume_types,
'get_volume_type_extra_specs',
@ -4141,7 +4145,7 @@ class EMCVMAXISCSIDriverFastTestCase(test.TestCase):
@mock.patch.object(
emc_vmax_utils.EMCVMAXUtils,
'find_storage_masking_group',
return_value=EMCVMAXCommonData.storagegroupname)
return_value=EMCVMAXCommonData.default_sg_instance_name)
@mock.patch.object(
volume_types,
'get_volume_type_extra_specs',
@ -5920,6 +5924,8 @@ class EMCV3DriverTestCase(test.TestCase):
self.data.test_volume_v3['host'] = self.data.fake_host_v3
self.driver.common._initial_setup = mock.Mock(
return_value=self.default_extraspec())
self.driver.common._get_or_create_storage_group_v3 = mock.Mock(
return_value = self.data.default_sg_instance_name)
self.driver.create_volume(self.data.test_volume_v3)
@mock.patch.object(
@ -5949,6 +5955,8 @@ class EMCV3DriverTestCase(test.TestCase):
'portgroupname': 'OS-portgroup-PG'}
self.driver.common._initial_setup = mock.Mock(
return_value=extraSpecs)
self.driver.common._get_or_create_storage_group_v3 = mock.Mock(
return_value = self.data.default_sg_instance_name)
self.driver.create_volume(v3_vol)
@ -5988,6 +5996,8 @@ class EMCV3DriverTestCase(test.TestCase):
self, _mock_volume_type, mock_storage_system):
self.driver.common._initial_setup = mock.Mock(
return_value=self.default_extraspec())
self.driver.common._get_or_create_storage_group_v3 = mock.Mock(
return_value = self.data.default_sg_instance_name)
self.driver.create_volume(self.data.test_volume_CG_v3)
@mock.patch.object(
@ -6014,7 +6024,10 @@ class EMCV3DriverTestCase(test.TestCase):
def test_create_snapshot_v3_success(
self, mock_volume_db, mock_type, moke_pool):
self.data.test_volume_v3['volume_name'] = "vmax-1234567"
self.driver.common._initial_setup = mock.Mock(
common = self.driver.common
common.provisionv3.utils.get_v3_default_sg_instance_name = mock.Mock(
return_value=(None, None, self.data.default_sg_instance_name))
common._initial_setup = mock.Mock(
return_value=self.default_extraspec())
self.driver.create_snapshot(self.data.test_volume_v3)
@ -6059,8 +6072,13 @@ class EMCV3DriverTestCase(test.TestCase):
cloneVol['NumberOfBlocks'] = 100
cloneVol['BlockSize'] = self.data.block_size
cloneVol['host'] = self.data.fake_host_v3
self.driver.common._initial_setup = mock.Mock(
common = self.driver.common
common._initial_setup = mock.Mock(
return_value=self.default_extraspec())
common._get_or_create_storage_group_v3 = mock.Mock(
return_value = self.data.default_sg_instance_name)
common.provisionv3.utils.get_v3_default_sg_instance_name = mock.Mock(
return_value=(None, None, self.data.default_sg_instance_name))
self.driver.create_cloned_volume(cloneVol, self.data.test_volume_v3)
@mock.patch.object(
@ -6124,7 +6142,7 @@ class EMCV3DriverTestCase(test.TestCase):
@mock.patch.object(
emc_vmax_provision_v3.EMCVMAXProvisionV3,
'_find_new_storage_group',
return_value='Any')
return_value=EMCVMAXCommonData.default_sg_instance_name)
@mock.patch.object(
emc_vmax_utils.EMCVMAXUtils,
'wrap_get_storage_group_from_volume',
@ -6954,6 +6972,8 @@ class EMCV3MultiSloDriverTestCase(test.TestCase):
self.vol_v3['provider_location'] = None
self.driver.common._initial_setup = mock.Mock(
return_value=self.default_extraspec())
self.driver.common._get_or_create_storage_group_v3 = mock.Mock(
return_value = self.data.default_sg_instance_name)
self.driver.create_volume(self.vol_v3)
@mock.patch.object(
@ -6983,12 +7003,14 @@ class EMCV3MultiSloDriverTestCase(test.TestCase):
self.data.test_volume_CG_v3['provider_location'] = None
self.driver.common._initial_setup = mock.Mock(
return_value=self.default_extraspec())
self.driver.common._get_or_create_storage_group_v3 = mock.Mock(
return_value = self.data.default_sg_instance_name)
self.driver.create_volume(self.data.test_volume_CG_v3)
@mock.patch.object(
emc_vmax_provision_v3.EMCVMAXProvisionV3,
'_find_new_storage_group',
return_value='Any')
return_value=EMCVMAXCommonData.default_sg_instance_name)
@mock.patch.object(
emc_vmax_utils.EMCVMAXUtils,
'wrap_get_storage_group_from_volume',
@ -7468,6 +7490,65 @@ class EMCVMAXProvisionV3Test(test.TestCase):
theVolumeInstanceName, inVolumeInstanceName, volumeSize,
extraSpecs)
def test_create_volume_from_sg(self):
provisionv3 = self.driver.common.provisionv3
conn = FakeEcomConnection()
storageConfigService = {
'CreationClassName': 'EMC_StorageConfigurationService',
'SystemName': 'SYMMETRIX+000195900551'}
extraSpecs = {'volume_backend_name': 'GOLD_BE',
'isV3': True}
volumeName = 'v3_vol'
volumeSize = 3
volumeDict, rc = (
provisionv3.create_volume_from_sg(
conn, storageConfigService, volumeName,
self.data.default_sg_instance_name, volumeSize, extraSpecs))
keybindings = volumeDict['keybindings']
self.assertEqual('1', keybindings['DeviceID'])
self.assertEqual(0, rc)
def test_create_storage_group_v3(self):
provisionv3 = self.driver.common.provisionv3
conn = FakeEcomConnection()
controllerConfigService = {
'CreationClassName': 'EMC_ControllerConfigurationService',
'SystemName': 'SYMMETRIX+000195900551'}
extraSpecs = {'volume_backend_name': 'GOLD_BE',
'isV3': True}
groupName = self.data.storagegroupname
srp = 'SRP_1'
slo = 'Bronze'
workload = 'DSS'
provisionv3._find_new_storage_group = mock.Mock(
return_value=self.data.default_sg_instance_name)
newstoragegroup = provisionv3.create_storage_group_v3(
conn, controllerConfigService, groupName, srp, slo, workload,
extraSpecs)
self.assertEqual(self.data.default_sg_instance_name, newstoragegroup)
def test_create_element_replica(self):
provisionv3 = self.driver.common.provisionv3
conn = FakeEcomConnection()
repServiceInstanceName = {
'CreationClassName': 'repServiceInstanceName',
'SystemName': 'SYMMETRIX+000195900551'}
extraSpecs = {'volume_backend_name': 'GOLD_BE',
'isV3': True,
'storagetype:pool': 'SRP_1',
'storagetype:slo': 'SRP_1',
'storagetype:workload': 'SRP_1'}
sourceInstance = (
conn.EnumerateInstanceNames("EMC_StorageVolume")[0])
syncType = 7
cloneName = 'new_ss'
provisionv3.utils.get_v3_default_sg_instance_name = mock.Mock(
return_value=(None, None, self.data.default_sg_instance_name))
rc, job = provisionv3.create_element_replica(
conn, repServiceInstanceName, cloneName, syncType, sourceInstance,
extraSpecs)
self.assertEqual(0, rc)
class EMCVMAXMaskingTest(test.TestCase):
def setUp(self):
@ -7838,6 +7919,8 @@ class EMCVMAXCommonTest(test.TestCase):
targetInstance = common.conn.GetInstance(volumeInstanceName)
common.utils.find_volume_instance = mock.Mock(
return_value=targetInstance)
self.driver.common._get_or_create_storage_group_v3 = mock.Mock(
return_value = self.data.default_sg_instance_name)
duplicateVolumeInstance = self.driver.common._create_duplicate_volume(
sourceInstance, cloneName, extraSpecs)
self.assertIsNotNone(duplicateVolumeInstance)
@ -7861,3 +7944,76 @@ class EMCVMAXCommonTest(test.TestCase):
self.driver.common._cleanup_target(
repServiceInstanceName, targetInstance, extraSpecs)
class EMCVMAXProvisionTest(test.TestCase):
def setUp(self):
self.data = EMCVMAXCommonData()
super(EMCVMAXProvisionTest, self).setUp()
configuration = mock.Mock()
configuration.safe_get.return_value = 'ProvisionTests'
configuration.config_group = 'ProvisionTests'
emc_vmax_common.EMCVMAXCommon._gather_info = mock.Mock()
driver = emc_vmax_iscsi.EMCVMAXISCSIDriver(
configuration=configuration)
driver.db = FakeDB()
self.driver = driver
self.driver.utils = emc_vmax_utils.EMCVMAXUtils(object)
def test_remove_device_from_storage_group(self):
conn = FakeEcomConnection()
controllerConfigService = (
self.driver.utils.find_controller_configuration_service(
conn, self.data.storage_system))
volumeInstanceName = (
conn.EnumerateInstanceNames("EMC_StorageVolume")[0])
volumeName = 'vol1'
extraSpecs = {'volume_backend_name': 'V3_BE',
'isV3': True,
'storagetype:pool': 'SRP_1',
'storagetype:workload': 'DSS',
'storagetype:slo': 'Bronze'}
masking = self.driver.common.masking
masking.provision.remove_device_from_storage_group = mock.Mock()
masking = self.driver.common.masking
volumeInstance = conn.GetInstance(volumeInstanceName)
storageGroupName = self.data.storagegroupname
storageGroupInstanceName = (
self.driver.common.utils.find_storage_masking_group(
conn, controllerConfigService, storageGroupName))
numVolsInSG = 2
masking._multiple_vols_in_SG(
conn, controllerConfigService, storageGroupInstanceName,
volumeInstance, volumeName, numVolsInSG, extraSpecs)
masking.provision.remove_device_from_storage_group.assert_called_with(
conn, controllerConfigService, storageGroupInstanceName,
volumeInstanceName, volumeName, extraSpecs)
def test_add_members_to_masking_group(self):
conn = FakeEcomConnection()
controllerConfigService = (
self.driver.utils.find_controller_configuration_service(
conn, self.data.storage_system))
volumeInstanceName = (
conn.EnumerateInstanceNames("EMC_StorageVolume")[0])
volumeName = 'vol1'
extraSpecs = {'volume_backend_name': 'V3_BE',
'isV3': True,
'storagetype:pool': 'SRP_1',
'storagetype:workload': 'DSS',
'storagetype:slo': 'Bronze'}
volumeInstance = conn.GetInstance(volumeInstanceName)
storageGroupName = self.data.storagegroupname
storageGroupInstanceName = (
self.driver.common.utils.find_storage_masking_group(
conn, controllerConfigService, storageGroupName))
masking = self.driver.common.masking
masking.provision.add_members_to_masking_group = mock.Mock()
masking.add_volume_to_storage_group(
conn, controllerConfigService, storageGroupInstanceName,
volumeInstance, volumeName, storageGroupName, extraSpecs)
masking.provision.add_members_to_masking_group.assert_called_with(
conn, controllerConfigService, storageGroupInstanceName,
volumeInstanceName, volumeName, extraSpecs)

View File

@ -14,6 +14,7 @@
# under the License.
import time
from oslo_concurrency import lockutils
from oslo_log import log as logging
import six
@ -159,33 +160,38 @@ class EMCVMAXProvision(object):
"""
startTime = time.time()
rc, job = conn.InvokeMethod(
'CreateGroup', controllerConfigService, GroupName=storageGroupName,
Type=self.utils.get_num(STORAGEGROUPTYPE, '16'),
Members=[volumeInstanceName])
@lockutils.synchronized(storageGroupName,
"emc-sg-", True)
def do_create_storage_group():
rc, job = conn.InvokeMethod(
'CreateGroup', controllerConfigService,
GroupName=storageGroupName,
Type=self.utils.get_num(STORAGEGROUPTYPE, '16'),
Members=[volumeInstanceName])
if rc != 0:
rc, errordesc = self.utils.wait_for_job_complete(conn, job,
extraSpecs)
if rc != 0:
exceptionMessage = (_(
"Error Create Group: %(groupName)s. "
"Return code: %(rc)lu. Error: %(error)s.")
% {'groupName': storageGroupName,
'rc': rc,
'error': errordesc})
LOG.error(exceptionMessage)
raise exception.VolumeBackendAPIException(
data=exceptionMessage)
rc, errordesc = self.utils.wait_for_job_complete(conn, job,
extraSpecs)
if rc != 0:
exceptionMessage = (_(
"Error Create Group: %(groupName)s. "
"Return code: %(rc)lu. Error: %(error)s.")
% {'groupName': storageGroupName,
'rc': rc,
'error': errordesc})
LOG.error(exceptionMessage)
raise exception.VolumeBackendAPIException(
data=exceptionMessage)
LOG.debug("InvokeMethod CreateGroup "
"took: %(delta)s H:MM:SS.",
{'delta': self.utils.get_time_delta(startTime,
time.time())})
foundStorageGroupInstanceName = self._find_new_storage_group(
conn, job, storageGroupName)
LOG.debug("InvokeMethod CreateGroup "
"took: %(delta)s H:MM:SS.",
{'delta': self.utils.get_time_delta(startTime,
time.time())})
foundStorageGroupInstanceName = self._find_new_storage_group(
conn, job, storageGroupName)
return foundStorageGroupInstanceName
return foundStorageGroupInstanceName
return do_create_storage_group()
def create_storage_group_no_members(
self, conn, controllerConfigService, groupName, extraSpecs):
@ -267,42 +273,57 @@ class EMCVMAXProvision(object):
return volumeDict
def remove_device_from_storage_group(
self, conn, controllerConfigService, storageGroupInstanceName,
self, conn, controllerConfigService, sgInstanceName,
volumeInstanceName, volumeName, extraSpecs):
"""Remove a volume from a storage group.
:param conn: the connection to the ecom server
:param controllerConfigService: the controller configuration service
:param storageGroupInstanceName: the instance name of the storage group
:param sgInstanceName: the instance name of the storage group
:param volumeInstanceName: the instance name of the volume
:param volumeName: the volume name (String)
:param extraSpecs: additional info
:returns: int -- the return code of the job
:raises: VolumeBackendAPIException
"""
startTime = time.time()
rc, jobDict = conn.InvokeMethod('RemoveMembers',
controllerConfigService,
MaskingGroup=storageGroupInstanceName,
Members=[volumeInstanceName])
if rc != 0:
rc, errorDesc = self.utils.wait_for_job_complete(conn, jobDict,
extraSpecs)
try:
storageGroupInstance = conn.GetInstance(sgInstanceName)
except Exception:
exceptionMessage = (_(
"Unable to get the name of the storage group."))
LOG.error(exceptionMessage)
raise exception.VolumeBackendAPIException(
data=exceptionMessage)
@lockutils.synchronized(storageGroupInstance['ElementName'],
"emc-sg-", True)
def do_remove_volume_from_sg():
startTime = time.time()
rc, jobDict = conn.InvokeMethod('RemoveMembers',
controllerConfigService,
MaskingGroup=sgInstanceName,
Members=[volumeInstanceName])
if rc != 0:
exceptionMessage = (_(
"Error removing volume %(vol)s. %(error)s.")
% {'vol': volumeName, 'error': errorDesc})
LOG.error(exceptionMessage)
raise exception.VolumeBackendAPIException(
data=exceptionMessage)
rc, errorDesc = self.utils.wait_for_job_complete(conn, jobDict,
extraSpecs)
if rc != 0:
exceptionMessage = (_(
"Error removing volume %(vol)s from %(sg). %(error)s.")
% {'vol': volumeName,
'sg': storageGroupInstance['ElementName'],
'error': errorDesc})
LOG.error(exceptionMessage)
raise exception.VolumeBackendAPIException(
data=exceptionMessage)
LOG.debug("InvokeMethod RemoveMembers "
"took: %(delta)s H:MM:SS.",
{'delta': self.utils.get_time_delta(startTime,
time.time())})
LOG.debug("InvokeMethod RemoveMembers "
"took: %(delta)s H:MM:SS.",
{'delta': self.utils.get_time_delta(startTime,
time.time())})
return rc
return rc
return do_remove_volume_from_sg()
def add_members_to_masking_group(
self, conn, controllerConfigService, storageGroupInstanceName,
@ -317,28 +338,43 @@ class EMCVMAXProvision(object):
:param extraSpecs: additional info
:raises: VolumeBackendAPIException
"""
startTime = time.time()
try:
storageGroupInstance = conn.GetInstance(storageGroupInstanceName)
except Exception:
exceptionMessage = (_(
"Unable to get the name of the storage group."))
LOG.error(exceptionMessage)
raise exception.VolumeBackendAPIException(
data=exceptionMessage)
rc, job = conn.InvokeMethod(
'AddMembers', controllerConfigService,
MaskingGroup=storageGroupInstanceName,
Members=[volumeInstanceName])
@lockutils.synchronized(storageGroupInstance['ElementName'],
"emc-sg-", True)
def do_add_volume_to_sg():
startTime = time.time()
rc, job = conn.InvokeMethod(
'AddMembers', controllerConfigService,
MaskingGroup=storageGroupInstanceName,
Members=[volumeInstanceName])
if rc != 0:
rc, errordesc = self.utils.wait_for_job_complete(conn, job,
extraSpecs)
if rc != 0:
exceptionMessage = (_(
"Error mapping volume %(vol)s. %(error)s.")
% {'vol': volumeName, 'error': errordesc})
LOG.error(exceptionMessage)
raise exception.VolumeBackendAPIException(
data=exceptionMessage)
rc, errordesc = self.utils.wait_for_job_complete(conn, job,
extraSpecs)
if rc != 0:
exceptionMessage = (_(
"Error adding volume %(vol)s to %(sg). %(error)s.")
% {'vol': volumeName,
'sg': storageGroupInstance['ElementName'],
'error': errordesc})
LOG.error(exceptionMessage)
raise exception.VolumeBackendAPIException(
data=exceptionMessage)
LOG.debug("InvokeMethod AddMembers "
"took: %(delta)s H:MM:SS.",
{'delta': self.utils.get_time_delta(startTime,
time.time())})
LOG.debug("InvokeMethod AddMembers "
"took: %(delta)s H:MM:SS.",
{'delta': self.utils.get_time_delta(startTime,
time.time())})
return rc
return do_add_volume_to_sg()
def unbind_volume_from_storage_pool(
self, conn, storageConfigService,

View File

@ -15,6 +15,7 @@
import time
from oslo_concurrency import lockutils
from oslo_log import log as logging
import six
@ -111,41 +112,55 @@ class EMCVMAXProvisionV3(object):
:returns: int -- return code
:raises: VolumeBackendAPIException
"""
startTime = time.time()
try:
storageGroupInstance = conn.GetInstance(sgInstanceName)
except Exception:
exceptionMessage = (_(
"Unable to get the name of the storage group"))
LOG.error(exceptionMessage)
raise exception.VolumeBackendAPIException(
data=exceptionMessage)
rc, job = conn.InvokeMethod(
'CreateOrModifyElementFromStoragePool',
storageConfigService, ElementName=volumeName,
EMCCollections=[sgInstanceName],
ElementType=self.utils.get_num(THINPROVISIONING, '16'),
Size=self.utils.get_num(volumeSize, '64'))
@lockutils.synchronized(storageGroupInstance['ElementName'],
"emc-sg-", True)
def do_create_volume_from_sg():
startTime = time.time()
LOG.debug("Create Volume: %(volumename)s. Return code: %(rc)lu.",
{'volumename': volumeName,
'rc': rc})
rc, job = conn.InvokeMethod(
'CreateOrModifyElementFromStoragePool',
storageConfigService, ElementName=volumeName,
EMCCollections=[sgInstanceName],
ElementType=self.utils.get_num(THINPROVISIONING, '16'),
Size=self.utils.get_num(volumeSize, '64'))
LOG.debug("Create Volume: %(volumename)s. Return code: %(rc)lu.",
{'volumename': volumeName,
'rc': rc})
if rc != 0:
rc, errordesc = self.utils.wait_for_job_complete(conn, job,
extraSpecs)
if rc != 0:
exceptionMessage = (_(
"Error Create Volume: %(volumeName)s. "
"Return code: %(rc)lu. Error: %(error)s.")
% {'volumeName': volumeName,
'rc': rc,
'error': errordesc})
LOG.error(exceptionMessage)
raise exception.VolumeBackendAPIException(
data=exceptionMessage)
rc, errordesc = self.utils.wait_for_job_complete(conn, job,
extraSpecs)
if rc != 0:
exceptionMessage = (_(
"Error Create Volume: %(volumeName)s. "
"Return code: %(rc)lu. Error: %(error)s.")
% {'volumeName': volumeName,
'rc': rc,
'error': errordesc})
LOG.error(exceptionMessage)
raise exception.VolumeBackendAPIException(
data=exceptionMessage)
LOG.debug("InvokeMethod CreateOrModifyElementFromStoragePool "
"took: %(delta)s H:MM:SS.",
{'delta': self.utils.get_time_delta(startTime,
time.time())})
LOG.debug("InvokeMethod CreateOrModifyElementFromStoragePool "
"took: %(delta)s H:MM:SS.",
{'delta': self.utils.get_time_delta(startTime,
time.time())})
# Find the newly created volume.
volumeDict = self.get_volume_dict_from_job(conn, job['Job'])
return volumeDict, rc
# Find the newly created volume.
volumeDict = self.get_volume_dict_from_job(conn, job['Job'])
return volumeDict, rc
return do_create_volume_from_sg()
def _find_new_storage_group(
self, conn, maskingGroupDict, storageGroupName):
@ -246,38 +261,51 @@ class EMCVMAXProvisionV3(object):
conn, extraSpecs[self.utils.POOL],
extraSpecs[self.utils.SLO],
extraSpecs[self.utils.WORKLOAD], storageSystemName))
if targetInstance is None and rsdInstance is None:
rc, job = conn.InvokeMethod(
'CreateElementReplica', repServiceInstanceName,
ElementName=cloneName,
SyncType=self.utils.get_num(syncType, '16'),
SourceElement=sourceInstance.path,
Collections=[sgInstanceName])
else:
rc, job = self._create_element_replica_extra_params(
conn, repServiceInstanceName, cloneName, syncType,
sourceInstance, targetInstance, rsdInstance,
sgInstanceName)
try:
storageGroupInstance = conn.GetInstance(sgInstanceName)
except Exception:
exceptionMessage = (_(
"Unable to get the name of the storage group"))
LOG.error(exceptionMessage)
raise exception.VolumeBackendAPIException(
data=exceptionMessage)
@lockutils.synchronized(storageGroupInstance['ElementName'],
"emc-sg-", True)
def do_create_element_replica():
if targetInstance is None and rsdInstance is None:
rc, job = conn.InvokeMethod(
'CreateElementReplica', repServiceInstanceName,
ElementName=cloneName,
SyncType=self.utils.get_num(syncType, '16'),
SourceElement=sourceInstance.path,
Collections=[sgInstanceName])
else:
rc, job = self._create_element_replica_extra_params(
conn, repServiceInstanceName, cloneName, syncType,
sourceInstance, targetInstance, rsdInstance,
sgInstanceName)
if rc != 0:
rc, errordesc = self.utils.wait_for_job_complete(conn, job,
extraSpecs)
if rc != 0:
exceptionMessage = (_(
"Error Create Cloned Volume: %(cloneName)s "
"Return code: %(rc)lu. Error: %(error)s.")
% {'cloneName': cloneName,
'rc': rc,
'error': errordesc})
LOG.error(exceptionMessage)
raise exception.VolumeBackendAPIException(
data=exceptionMessage)
rc, errordesc = self.utils.wait_for_job_complete(conn, job,
extraSpecs)
if rc != 0:
exceptionMessage = (_(
"Error Create Cloned Volume: %(cloneName)s "
"Return code: %(rc)lu. Error: %(error)s.")
% {'cloneName': cloneName,
'rc': rc,
'error': errordesc})
LOG.error(exceptionMessage)
raise exception.VolumeBackendAPIException(
data=exceptionMessage)
LOG.debug("InvokeMethod CreateElementReplica "
"took: %(delta)s H:MM:SS.",
{'delta': self.utils.get_time_delta(startTime,
time.time())})
return rc, job
LOG.debug("InvokeMethod CreateElementReplica "
"took: %(delta)s H:MM:SS.",
{'delta': self.utils.get_time_delta(startTime,
time.time())})
return rc, job
return do_create_element_replica()
def _create_element_replica_extra_params(
self, conn, repServiceInstanceName, cloneName, syncType,
@ -363,36 +391,46 @@ class EMCVMAXProvisionV3(object):
"""
startTime = time.time()
rc, job = conn.InvokeMethod(
'CreateGroup',
controllerConfigService,
GroupName=groupName,
Type=self.utils.get_num(4, '16'),
EMCSRP=srp,
EMCSLO=slo,
EMCWorkload=workload)
@lockutils.synchronized(groupName, "emc-sg-", True)
def do_create_storage_group_v3():
if slo and workload:
rc, job = conn.InvokeMethod(
'CreateGroup',
controllerConfigService,
GroupName=groupName,
Type=self.utils.get_num(4, '16'),
EMCSRP=srp,
EMCSLO=slo,
EMCWorkload=workload)
else:
rc, job = conn.InvokeMethod(
'CreateGroup',
controllerConfigService,
GroupName=groupName,
Type=self.utils.get_num(4, '16'))
if rc != 0:
rc, errordesc = self.utils.wait_for_job_complete(conn, job,
extraSpecs)
if rc != 0:
LOG.error(_LE(
"Error Create Group: %(groupName)s. "
"Return code: %(rc)lu. Error: %(error)s."),
{'groupName': groupName,
'rc': rc,
'error': errordesc})
raise
rc, errordesc = self.utils.wait_for_job_complete(
conn, job, extraSpecs)
if rc != 0:
LOG.error(_LE(
"Error Create Group: %(groupName)s. "
"Return code: %(rc)lu. Error: %(error)s."),
{'groupName': groupName,
'rc': rc,
'error': errordesc})
raise
LOG.debug("InvokeMethod CreateGroup "
"took: %(delta)s H:MM:SS.",
{'delta': self.utils.get_time_delta(startTime,
time.time())})
LOG.debug("InvokeMethod CreateGroup "
"took: %(delta)s H:MM:SS.",
{'delta': self.utils.get_time_delta(startTime,
time.time())})
foundStorageGroupInstanceName = self._find_new_storage_group(
conn, job, groupName)
foundStorageGroupInstanceName = self._find_new_storage_group(
conn, job, groupName)
return foundStorageGroupInstanceName
return foundStorageGroupInstanceName
return do_create_storage_group_v3()
def get_storage_pool_capability(self, conn, poolInstanceName):
"""Get the pool capability.