use of com.emc.storageos.db.client.model.BlockSnapshot in project coprhd-controller by CoprHD.
the class RPDeviceController method getStorageToBlockObjects.
/**
* Given a Map of snapshots (bookmarks) to HLUs, this method obtains all target copy volumes
* corresponding to the snapshot and groups them by storage system.
*
* @param snapshots
* the base mapping of snapshots to HLU
* @return a mapping of snapshot export BlockObjects by storage system
*/
private Map<URI, Map<URI, Integer>> getStorageToBlockObjects(Map<URI, Integer> snapshots) {
Map<URI, Map<URI, Integer>> storageToBlockObjects = new HashMap<URI, Map<URI, Integer>>();
for (Map.Entry<URI, Integer> entry : snapshots.entrySet()) {
BlockSnapshot snapshot = _dbClient.queryObject(BlockSnapshot.class, entry.getKey());
// Get the export objects corresponding to this snapshot
List<BlockObject> blockObjects = getExportObjectsForBookmark(snapshot);
for (BlockObject blockObject : blockObjects) {
URI storage = blockObject.getStorageController();
Map<URI, Integer> volumesForStorage = storageToBlockObjects.get(storage);
if (volumesForStorage == null) {
volumesForStorage = new HashMap<URI, Integer>();
storageToBlockObjects.put(storage, volumesForStorage);
}
// Add the BlockObject entry and set the HLU to the HLU corresponding to the snapshot
volumesForStorage.put(blockObject.getId(), entry.getValue());
}
}
return storageToBlockObjects;
}
use of com.emc.storageos.db.client.model.BlockSnapshot in project coprhd-controller by CoprHD.
the class RPDeviceController method constructSnapshotObjectFromBookmark.
/**
* Amend the BlockSnapshot object based on the results of the Bookmark creation operation
*
* @param result
* result from the snapshot creation command
* @param system
* protection system
* @param snapshotList
* snapshot list generated
* @param name
* emName
* @param opId
* operation ID for task completer
* @throws InternalException
* @throws FunctionalAPIInternalError_Exception
* @throws FunctionalAPIActionFailedException_Exception
*/
private void constructSnapshotObjectFromBookmark(CreateBookmarkResponse response, ProtectionSystem system, List<URI> snapshotList, String name, String opId) throws InternalException {
ProtectionSet protectionSet = null;
RecoverPointClient rp = RPHelper.getRecoverPointClient(system);
// Update each snapshot object with the respective information.
for (URI snapshotID : snapshotList) {
// Get the snapshot and the associated volume
BlockSnapshot snapshot = _dbClient.queryObject(BlockSnapshot.class, snapshotID);
Volume volume = _dbClient.queryObject(Volume.class, snapshot.getParent().getURI());
// Fetch the VPLEX volume that is created with this volume as the back-end volume.
if (Volume.checkForVplexBackEndVolume(_dbClient, volume)) {
volume = Volume.fetchVplexVolume(_dbClient, volume);
}
if (protectionSet == null || !protectionSet.getId().equals(volume.getProtectionSet().getURI())) {
protectionSet = _dbClient.queryObject(ProtectionSet.class, volume.getProtectionSet());
}
// Gather the bookmark date, which is different than the snapshot date
Date bookmarkDate = new Date();
if (response.getVolumeWWNBookmarkDateMap() != null) {
bookmarkDate = response.getVolumeWWNBookmarkDateMap().get(RPHelper.getRPWWn(volume.getId(), _dbClient));
} else {
_log.warn("Bookmark date was not filled-in. Will use current date/time.");
}
snapshot.setEmName(name);
snapshot.setInactive(false);
snapshot.setEmBookmarkTime("" + bookmarkDate.getTime());
snapshot.setCreationTime(Calendar.getInstance());
snapshot.setTechnologyType(TechnologyType.RP.toString());
Volume targetVolume = RPHelper.getRPTargetVolumeFromSource(_dbClient, volume, snapshot.getVirtualArray());
// This section will identify and store the COPY ID associated with the bookmarks created.
// It is critical to store this information so we can later determine which bookmarks have
// been deleted from the RPA.
//
// May be able to remove this if the protection set object is more detailed (for instance, if
// we store the copy id with the volume)
RecoverPointVolumeProtectionInfo protectionInfo = rp.getProtectionInfoForVolume(RPHelper.getRPWWn(targetVolume.getId(), _dbClient));
for (RPConsistencyGroup rpcg : response.getCgBookmarkMap().keySet()) {
if (rpcg.getCGUID().getId() == protectionInfo.getRpVolumeGroupID()) {
for (RPBookmark bookmark : response.getCgBookmarkMap().get(rpcg)) {
if (bookmark.getBookmarkName() != null && bookmark.getBookmarkName().equalsIgnoreCase(name) && bookmark.getCGGroupCopyUID().getGlobalCopyUID().getCopyUID() == protectionInfo.getRpVolumeGroupCopyID()) {
snapshot.setEmCGGroupCopyId(protectionInfo.getRpVolumeGroupCopyID());
break;
}
}
}
}
if (targetVolume.getId().equals(volume.getId())) {
_log.error("The source and the target volumes are the same");
throw DeviceControllerExceptions.recoverpoint.cannotActivateSnapshotNoTargetVolume();
}
snapshot.setDeviceLabel(targetVolume.getDeviceLabel());
snapshot.setStorageController(targetVolume.getStorageController());
snapshot.setSystemType(targetVolume.getSystemType());
snapshot.setVirtualArray(targetVolume.getVirtualArray());
snapshot.setNativeId(targetVolume.getNativeId());
snapshot.setAlternateName(targetVolume.getAlternateName());
snapshot.setNativeGuid(NativeGUIDGenerator.generateNativeGuid(system, snapshot));
snapshot.setIsSyncActive(false);
// Setting the WWN of the bookmark to the WWN of the volume, no functional reason for now.
snapshot.setWWN(RPHelper.getRPWWn(targetVolume.getId(), _dbClient));
snapshot.setProtectionController(system.getId());
snapshot.setProtectionSet(volume.getProtectionSet().getURI());
_log.info(String.format("Updated bookmark %1$s associated with block volume %2$s on site %3$s.", name, volume.getDeviceLabel(), snapshot.getEmInternalSiteName()));
_dbClient.updateObject(snapshot);
List<URI> taskSnapshotURIList = new ArrayList<URI>();
taskSnapshotURIList.add(snapshot.getId());
TaskCompleter completer = new BlockSnapshotCreateCompleter(taskSnapshotURIList, opId);
completer.ready(_dbClient);
}
// Get information about the bookmarks created so we can get to them later.
_log.info("Bookmark(s) created for snapshot operation");
return;
}
use of com.emc.storageos.db.client.model.BlockSnapshot in project coprhd-controller by CoprHD.
the class RPDeviceController method addExportRemoveVolumeSteps.
/**
* Add the export remove volume step to the workflow
*
* @param workflow
* workflow object
* @param rpSystem
* protection system
* @param exportGroupID
* export group
* @param boIDs
* volume/snapshot IDs
* @throws InternalException
*/
private void addExportRemoveVolumeSteps(Workflow workflow, ProtectionSystem rpSystem, URI exportGroupID, List<URI> boIDs) throws InternalException {
ExportGroup exportGroup = _dbClient.queryObject(ExportGroup.class, exportGroupID);
String exportStep = workflow.createStepId();
initTaskStatus(exportGroup, exportStep, Operation.Status.pending, "export remove volumes (that contain RP snapshots)");
Map<URI, List<URI>> deviceToBlockObjects = new HashMap<URI, List<URI>>();
for (URI snapshotID : boIDs) {
BlockSnapshot snapshot = _dbClient.queryObject(BlockSnapshot.class, snapshotID);
// Get the export objects corresponding to this snapshot
List<BlockObject> objectsToRemove = getExportObjectsForBookmark(snapshot);
for (BlockObject blockObject : objectsToRemove) {
List<URI> blockObjects = deviceToBlockObjects.get(blockObject.getStorageController());
if (blockObjects == null) {
blockObjects = new ArrayList<URI>();
deviceToBlockObjects.put(blockObject.getStorageController(), blockObjects);
}
blockObjects.add(blockObject.getId());
}
}
for (Map.Entry<URI, List<URI>> deviceEntry : deviceToBlockObjects.entrySet()) {
_log.info(String.format("Adding workflow step to remove RP bookmarks and associated target volumes from export. ExportGroup: %s, Storage System: %s, BlockObjects: %s", exportGroup.getId(), deviceEntry.getKey(), deviceEntry.getValue()));
_exportWfUtils.generateExportGroupRemoveVolumes(workflow, STEP_EXPORT_REMOVE_SNAPSHOT, STEP_EXPORT_GROUP_DISABLE, deviceEntry.getKey(), exportGroupID, deviceEntry.getValue());
}
_log.info(String.format("Created export group remove snapshot steps in workflow: %s", exportGroup.getId()));
}
use of com.emc.storageos.db.client.model.BlockSnapshot in project coprhd-controller by CoprHD.
the class RPDeviceController method addPreRestoreVolumeSteps.
/**
* Adds the necessary RecoverPoint controller steps that need to be executed prior
* to restoring a volume from snapshot. The pre-restore step is required if we
* are restoring a native array snapshot of the following parent volumes:
* <ul>
* <li>A BlockSnapshot parent volume that is a regular RP source/target residing on a VMAX.</li>
* <li>A BlockSnapshot parent volume that is a backing volume to a VPlex distributed volume.</li>
* </ul>
*
* @param workflow
* the Workflow being constructed
* @param storageSystemURI
* the URI of storage controller
* @param volumeURI
* the URI of volume to be restored
* @param snapshotURI
* the URI of snapshot used for restoration
* @param taskId
* the top level operation's taskId
* @return A waitFor key that can be used by subsequent controllers to wait on
*/
public String addPreRestoreVolumeSteps(Workflow workflow, URI storageSystemURI, URI volumeURI, URI snapshotURI, String taskId) {
String waitFor = null;
BlockSnapshot snapshot = _dbClient.queryObject(BlockSnapshot.class, snapshotURI);
// Only consider native snapshots
if (snapshot != null && NullColumnValueGetter.isNotNullValue(snapshot.getTechnologyType()) && snapshot.getTechnologyType().equals(TechnologyType.NATIVE.toString())) {
Volume volume = _dbClient.queryObject(Volume.class, volumeURI);
StorageSystem storageSystem = _dbClient.queryObject(StorageSystem.class, storageSystemURI);
if (volume != null && storageSystem != null) {
boolean vplexDistBackingVolume = false;
URI cgId = volume.getConsistencyGroup();
Volume associatedVPlexVolume = Volume.fetchVplexVolume(_dbClient, volume);
if (associatedVPlexVolume != null && associatedVPlexVolume.getAssociatedVolumes() != null && associatedVPlexVolume.getAssociatedVolumes().size() == 2) {
vplexDistBackingVolume = true;
}
if (vplexDistBackingVolume) {
volume = associatedVPlexVolume;
}
// before performing the native block restore.
if (!NullColumnValueGetter.isNullURI(volume.getProtectionController()) && (vplexDistBackingVolume || (storageSystem != null && NullColumnValueGetter.isNotNullValue(storageSystem.getSystemType()) && storageSystem.getSystemType().equals(SystemType.vmax.toString())))) {
ProtectionSystem rpSystem = null;
rpSystem = _dbClient.queryObject(ProtectionSystem.class, volume.getProtectionController());
if (rpSystem == null) {
// Verify non-null storage device returned from the database client.
throw DeviceControllerExceptions.recoverpoint.failedConnectingForMonitoring(volume.getProtectionController());
}
List<URI> volumeURIs = getVolumesForRestore(snapshot, volume);
// Validate the replication sets for all volumes to restore. Must ensure the source
// volume size is not greater than the target volume size
List<Volume> volumes = _dbClient.queryObject(Volume.class, volumeURIs);
RPHelper.validateRSetVolumeSizes(_dbClient, volumes);
Map<String, RecreateReplicationSetRequestParams> rsetParams = new HashMap<String, RecreateReplicationSetRequestParams>();
// Lock CG
List<String> locks = new ArrayList<String>();
String lockName = ControllerLockingUtil.getConsistencyGroupStorageKey(_dbClient, cgId, rpSystem.getId());
if (null != lockName) {
locks.add(lockName);
acquireWorkflowLockOrThrow(workflow, locks);
}
for (URI volumeId : volumeURIs) {
Volume vol = _dbClient.queryObject(Volume.class, volumeId);
RecreateReplicationSetRequestParams rsetParam = getReplicationSettings(rpSystem, vol.getId());
rsetParams.put(RPHelper.getRPWWn(vol.getId(), _dbClient), rsetParam);
}
String stepId = workflow.createStepId();
Workflow.Method deleteRsetExecuteMethod = new Workflow.Method(METHOD_DELETE_RSET_STEP, rpSystem.getId(), volumeURIs);
Workflow.Method recreateRSetExecuteMethod = new Workflow.Method(METHOD_RECREATE_RSET_STEP, rpSystem.getId(), volumeURIs, rsetParams);
waitFor = workflow.createStep(STEP_PRE_VOLUME_RESTORE, "Pre volume restore from snapshot, delete replication set step for RP: " + volumeURI.toString(), null, rpSystem.getId(), rpSystem.getSystemType(), this.getClass(), deleteRsetExecuteMethod, recreateRSetExecuteMethod, stepId);
_log.info(String.format("Created workflow step to delete replication set for volume %s.", volume.getId().toString()));
}
}
}
return waitFor;
}
use of com.emc.storageos.db.client.model.BlockSnapshot in project coprhd-controller by CoprHD.
the class RPDeviceController method getVolumesForRestore.
/**
* Gets a list of volume IDs to be restored. If the snapshot corresponds to
* a consistency group, we must get all the volumes associated to other
* BlockSnapshots that share the same snapset label. Secondly, if the snapshot's
* parent volume is a VPlex backing volume, we must lookup the associated
* VPlex volume and use that.
*
* @param snapshot
* the snapshot to restore.
* @param volume
* the volume to be restored.
* @return a list of volume IDs to be restored.
*/
private List<URI> getVolumesForRestore(BlockSnapshot snapshot, Volume volume) {
List<URI> volumeURIs = new ArrayList<URI>();
URI cgURI = snapshot.getConsistencyGroup();
if (NullColumnValueGetter.isNullURI(cgURI)) {
// If the snapshot is not in a CG, delete the replication set
// for only the requested volume.
volumeURIs.add(volume.getId());
} else {
// Otherwise, get all snapshots in the snapset, get the parent volume for each
// snapshot. If the parent is a VPlex backing volume, get the VLPEX volume
// using the snapshot parent.
List<BlockSnapshot> cgSnaps = ControllerUtils.getSnapshotsPartOfReplicationGroup(snapshot, _dbClient);
for (BlockSnapshot cgSnapshot : cgSnaps) {
URIQueryResultList queryResults = new URIQueryResultList();
_dbClient.queryByConstraint(AlternateIdConstraint.Factory.getVolumeByAssociatedVolumesConstraint(cgSnapshot.getParent().getURI().toString()), queryResults);
URI vplexVolumeURI = null;
if (queryResults.iterator().hasNext()) {
vplexVolumeURI = queryResults.iterator().next();
if (vplexVolumeURI != null) {
volumeURIs.add(vplexVolumeURI);
}
} else {
volumeURIs.add(cgSnapshot.getParent().getURI());
}
}
}
return volumeURIs;
}
Aggregations