From de3c9db66a50f648148e366c60e82196698ccd7d Mon Sep 17 00:00:00 2001 From: Helen Walsh Date: Fri, 15 Jan 2016 15:27:11 +0000 Subject: [PATCH] EMC VMAX - necessary updates for CG changes Some of the stubs for the Consistency Group functionality have changed to remove the db object. As a consequence the VMAX implementation for these operations needs to be changed. Change-Id: I6c1e56c31e02f25d30689a272f92fafd59e17f70 Closes-Bug: #1534616 --- cinder/tests/unit/test_emc_vmax.py | 6 +- cinder/volume/drivers/emc/emc_vmax_common.py | 70 +++++++++----------- cinder/volume/drivers/emc/emc_vmax_fc.py | 8 ++- cinder/volume/drivers/emc/emc_vmax_iscsi.py | 8 ++- cinder/volume/drivers/emc/emc_vmax_utils.py | 27 +------- 5 files changed, 47 insertions(+), 72 deletions(-) diff --git a/cinder/tests/unit/test_emc_vmax.py b/cinder/tests/unit/test_emc_vmax.py index 6c2bd5488..0d059bf31 100644 --- a/cinder/tests/unit/test_emc_vmax.py +++ b/cinder/tests/unit/test_emc_vmax.py @@ -471,7 +471,8 @@ class EMCVMAXCommonData(object): 'id': '12345abcde', 'consistencygroup_id': '123456789', 'status': 'available', - 'snapshots': [] + 'snapshots': [], + 'consistencygroup': test_CG } location_info = {'location_info': '000195900551#silver#None', 'storage_protocol': 'ISCSI'} @@ -3627,7 +3628,8 @@ class EMCVMAXISCSIDriverNoFastTestCase(test.TestCase): utils = self.driver.common.utils status = 'status-string' volumes = utils.get_volume_model_updates( - None, self.driver.db, self.data.test_CG['id'], + None, self.driver.db.volume_get_all_by_group("", 5), + self.data.test_CG['id'], status) self.assertEqual(status, volumes[0]['status']) diff --git a/cinder/volume/drivers/emc/emc_vmax_common.py b/cinder/volume/drivers/emc/emc_vmax_common.py index d29406a78..0ba3cac19 100644 --- a/cinder/volume/drivers/emc/emc_vmax_common.py +++ b/cinder/volume/drivers/emc/emc_vmax_common.py @@ -2496,18 +2496,19 @@ class EMCVMAXCommon(object): modelUpdate['status'] = 'error_deleting' return volumes, modelUpdate - def create_cgsnapshot(self, context, cgsnapshot, db): + def create_cgsnapshot(self, context, cgsnapshot, snapshots): """Creates a cgsnapshot. :param context: the context :param cgsnapshot: the consistency group snapshot to be created - :param db: cinder database + :param snapshots: snapshots :returns: dict -- modelUpdate :returns: list -- list of snapshots :raises: VolumeBackendAPIException """ - consistencyGroup = db.consistencygroup_get( - context, cgsnapshot['consistencygroup_id']) + consistencyGroup = cgsnapshot.get('consistencygroup') + + snapshots_model_update = [] LOG.info(_LI( "Create snapshot for Consistency Group %(cgId)s " @@ -2518,8 +2519,6 @@ class EMCVMAXCommon(object): cgName = self.utils.truncate_string( cgsnapshot['consistencygroup_id'], 8) - modelUpdate = {'status': 'available'} - volumeTypeId = consistencyGroup['volume_type_id'].replace(",", "") extraSpecs = self._initial_setup(None, volumeTypeId) self.conn = self._get_ecom_connection() @@ -2621,41 +2620,39 @@ class EMCVMAXCommon(object): extraSpecs) except Exception: - modelUpdate['status'] = 'error' - self.utils.populate_cgsnapshot_status( - context, db, cgsnapshot['id'], modelUpdate['status']) exceptionMessage = (_("Failed to create snapshot for cg:" " %(cgName)s.") % {'cgName': cgName}) LOG.exception(exceptionMessage) raise exception.VolumeBackendAPIException(data=exceptionMessage) - snapshots = self.utils.populate_cgsnapshot_status( - context, db, cgsnapshot['id'], modelUpdate['status']) - return modelUpdate, snapshots + for snapshot in snapshots: + snapshots_model_update.append( + {'id': snapshot['id'], 'status': 'available'}) + modelUpdate = {'status': fields.ConsistencyGroupStatus.AVAILABLE} + + return modelUpdate, snapshots_model_update - def delete_cgsnapshot(self, context, cgsnapshot, db): + def delete_cgsnapshot(self, context, cgsnapshot, snapshots): """Delete a cgsnapshot. :param context: the context :param cgsnapshot: the consistency group snapshot to be created - :param db: cinder database + :param snapshots: snapshots :returns: dict -- modelUpdate :returns: list -- list of snapshots :raises: VolumeBackendAPIException """ - consistencyGroup = db.consistencygroup_get( - context, cgsnapshot['consistencygroup_id']) - snapshots = db.snapshot_get_all_for_cgsnapshot( - context, cgsnapshot['id']) - + consistencyGroup = cgsnapshot.get('consistencygroup') + model_update = {} + snapshots_model_update = [] LOG.info(_LI( "Delete snapshot for source CG %(cgId)s " "cgsnapshotID: %(cgsnapshot)s."), {'cgsnapshot': cgsnapshot['id'], 'cgId': cgsnapshot['consistencygroup_id']}) - modelUpdate = {'status': 'deleted'} + model_update['status'] = cgsnapshot['status'] volumeTypeId = consistencyGroup['volume_type_id'].replace(",", "") extraSpecs = self._initial_setup(None, volumeTypeId) self.conn = self._get_ecom_connection() @@ -2665,22 +2662,20 @@ class EMCVMAXCommon(object): try: targetCgName = self.utils.truncate_string(cgsnapshot['id'], 8) - modelUpdate, snapshots = self._delete_cg_and_members( - storageSystem, targetCgName, modelUpdate, + model_update, snapshots = self._delete_cg_and_members( + storageSystem, targetCgName, model_update, snapshots, extraSpecs) + for snapshot in snapshots: + snapshots_model_update.append( + {'id': snapshot['id'], 'status': 'deleted'}) except Exception: - modelUpdate['status'] = 'error_deleting' - self.utils.populate_cgsnapshot_status( - context, db, cgsnapshot['id'], modelUpdate['status']) exceptionMessage = (_("Failed to delete snapshot for cg: " "%(cgId)s.") % {'cgId': cgsnapshot['consistencygroup_id']}) LOG.exception(exceptionMessage) raise exception.VolumeBackendAPIException(data=exceptionMessage) - snapshots = self.utils.populate_cgsnapshot_status( - context, db, cgsnapshot['id'], modelUpdate['status']) - return modelUpdate, snapshots + return model_update, snapshots_model_update def _find_consistency_group(self, replicationService, cgName): """Finds a CG given its name. @@ -4219,7 +4214,8 @@ class EMCVMAXCommon(object): return volumeInstanceNames def create_consistencygroup_from_src(self, context, group, volumes, - cgsnapshot, snapshots, db): + cgsnapshot, snapshots, source_cg, + source_vols): """Creates the consistency group from source. Currently the source can only be a cgsnapshot. @@ -4229,7 +4225,8 @@ class EMCVMAXCommon(object): :param volumes: volumes in the consistency group :param cgsnapshot: the source consistency group snapshot :param snapshots: snapshots of the source volumes - :param db: database + :param source_cg: the source consistency group + :param source_vols: the source vols :returns: model_update, volumes_model_update model_update is a dictionary of cg status volumes_model_update is a list of dictionaries of volume @@ -4338,21 +4335,16 @@ class EMCVMAXCommon(object): self.provision.delete_clone_relationship( self.conn, replicationService, rgSyncInstanceName, extraSpecs) - except Exception as ex: - modelUpdate['status'] = 'error' + except Exception: cgSnapshotId = cgsnapshot['consistencygroup_id'] - volumes_model_update = self.utils.get_volume_model_updates( - context, db, group['id'], modelUpdate['status']) - LOG.error(_LE("Exception: %(ex)s."), {'ex': ex}) exceptionMessage = (_("Failed to create CG %(cgName)s " "from snapshot %(cgSnapshot)s.") % {'cgName': targetCgName, 'cgSnapshot': cgSnapshotId}) - LOG.error(exceptionMessage) - return modelUpdate, volumes_model_update - + LOG.exception(exceptionMessage) + raise exception.VolumeBackendAPIException(data=exceptionMessage) volumes_model_update = self.utils.get_volume_model_updates( - context, db, group['id'], modelUpdate['status']) + context, volumes, group['id'], modelUpdate['status']) return modelUpdate, volumes_model_update diff --git a/cinder/volume/drivers/emc/emc_vmax_fc.py b/cinder/volume/drivers/emc/emc_vmax_fc.py index 66e6244d4..c6c612593 100644 --- a/cinder/volume/drivers/emc/emc_vmax_fc.py +++ b/cinder/volume/drivers/emc/emc_vmax_fc.py @@ -56,6 +56,7 @@ class EMCVMAXFCDriver(driver.FibreChannelDriver): - Last volume in SG fix - _remove_last_vol_and_delete_sg is not being called for VMAX3 (bug #1520549) + - necessary updates for CG changes (#1534616) """ VERSION = "2.3.0" @@ -353,11 +354,11 @@ class EMCVMAXFCDriver(driver.FibreChannelDriver): def create_cgsnapshot(self, context, cgsnapshot, snapshots): """Creates a cgsnapshot.""" - return self.common.create_cgsnapshot(context, cgsnapshot, self.db) + return self.common.create_cgsnapshot(context, cgsnapshot, snapshots) def delete_cgsnapshot(self, context, cgsnapshot, snapshots): """Deletes a cgsnapshot.""" - return self.common.delete_cgsnapshot(context, cgsnapshot, self.db) + return self.common.delete_cgsnapshot(context, cgsnapshot, snapshots) def manage_existing(self, volume, external_ref): """Manages an existing VMAX Volume (import to Cinder). @@ -406,4 +407,5 @@ class EMCVMAXFCDriver(driver.FibreChannelDriver): :param source_vols: a list of volume dictionaries in the source_cg. """ return self.common.create_consistencygroup_from_src( - context, group, volumes, cgsnapshot, snapshots, self.db) + context, group, volumes, cgsnapshot, snapshots, source_cg, + source_vols) diff --git a/cinder/volume/drivers/emc/emc_vmax_iscsi.py b/cinder/volume/drivers/emc/emc_vmax_iscsi.py index 83c8b8553..e8edf4737 100644 --- a/cinder/volume/drivers/emc/emc_vmax_iscsi.py +++ b/cinder/volume/drivers/emc/emc_vmax_iscsi.py @@ -62,6 +62,7 @@ class EMCVMAXISCSIDriver(driver.ISCSIDriver): - Last volume in SG fix - _remove_last_vol_and_delete_sg is not being called for VMAX3 (bug #1520549) + - necessary updates for CG changes (#1534616) """ VERSION = "2.3.0" @@ -350,11 +351,11 @@ class EMCVMAXISCSIDriver(driver.ISCSIDriver): def create_cgsnapshot(self, context, cgsnapshot, snapshots): """Creates a cgsnapshot.""" - return self.common.create_cgsnapshot(context, cgsnapshot, self.db) + return self.common.create_cgsnapshot(context, cgsnapshot, snapshots) def delete_cgsnapshot(self, context, cgsnapshot, snapshots): """Deletes a cgsnapshot.""" - return self.common.delete_cgsnapshot(context, cgsnapshot, self.db) + return self.common.delete_cgsnapshot(context, cgsnapshot, snapshots) def _check_for_iscsi_ip_address(self): """Check to see if iscsi_ip_address is set in cinder.conf @@ -411,4 +412,5 @@ class EMCVMAXISCSIDriver(driver.ISCSIDriver): :param source_vols: a list of volume dictionaries in the source_cg. """ return self.common.create_consistencygroup_from_src( - context, group, volumes, cgsnapshot, snapshots, self.db) + context, group, volumes, cgsnapshot, snapshots, source_cg, + source_vols) diff --git a/cinder/volume/drivers/emc/emc_vmax_utils.py b/cinder/volume/drivers/emc/emc_vmax_utils.py index 217a1d448..7144d1d1b 100644 --- a/cinder/volume/drivers/emc/emc_vmax_utils.py +++ b/cinder/volume/drivers/emc/emc_vmax_utils.py @@ -1272,28 +1272,6 @@ class EMCVMAXUtils(object): return foundSyncInstanceName - def populate_cgsnapshot_status( - self, context, db, cgsnapshot_id, status='available'): - """Update cgsnapshot status in the cinder database. - - :param context: the context - :param db: cinder database - :param cgsnapshot_id: cgsnapshot id - :param status: string value reflects the status of the member snapshot - :returns: snapshots - updated snapshots - """ - snapshots = db.snapshot_get_all_for_cgsnapshot(context, cgsnapshot_id) - LOG.info(_LI( - "Populating status for cgsnapshot: %(id)s."), - {'id': cgsnapshot_id}) - if snapshots: - for snapshot in snapshots: - snapshot['status'] = status - else: - LOG.info(_LI("No snapshot found for %(cgsnapshot)s."), - {'cgsnapshot': cgsnapshot_id}) - return snapshots - def get_firmware_version(self, conn, arrayName): """Get the firmware version of array. @@ -2291,17 +2269,16 @@ class EMCVMAXUtils(object): return foundSyncInstanceName def get_volume_model_updates( - self, context, db, cgId, status='available'): + self, context, volumes, cgId, status='available'): """Update the volume model's status and return it. :param context: the context - :param db: cinder database + :param volumes: volumes object api :param cgId: cg id :param status: string value reflects the status of the member volume :returns: volume_model_updates - updated volumes """ volume_model_updates = [] - volumes = db.volume_get_all_by_group(context, cgId) LOG.info(_LI( "Updating status for CG: %(id)s."), {'id': cgId}) -- 2.45.2