use of com.emc.storageos.db.client.model.BlockSnapshotSession in project coprhd-controller by CoprHD.
the class ReplicaDeviceController method getSnapSessionsForCGVolume.
/**
* Gets the snap sessions for a CG volume.
*
* @param volume the volume
* @return the snap sessions for cg volume
*/
private List<BlockSnapshotSession> getSnapSessionsForCGVolume(Volume volume) {
/**
* Get all snap sessions for Volume's CG
* filter the snap sessions which matches the Volume's Replication Group
*/
List<BlockSnapshotSession> cgVolumeSessions = new ArrayList<BlockSnapshotSession>();
String rgName = volume.getReplicationGroupInstance();
if (NullColumnValueGetter.isNotNullValue(rgName)) {
URI cgURI = volume.getConsistencyGroup();
List<BlockSnapshotSession> sessionsList = CustomQueryUtility.queryActiveResourcesByConstraint(_dbClient, BlockSnapshotSession.class, ContainmentConstraint.Factory.getBlockSnapshotSessionByConsistencyGroup(cgURI));
for (BlockSnapshotSession session : sessionsList) {
if (rgName.equals(session.getReplicationGroupInstance())) {
cgVolumeSessions.add(session);
}
}
}
return cgVolumeSessions;
}
use of com.emc.storageos.db.client.model.BlockSnapshotSession in project coprhd-controller by CoprHD.
the class ReplicaDeviceController method createSnapshotSessionAndLinkSessionStep.
public String createSnapshotSessionAndLinkSessionStep(final Workflow workflow, String waitFor, URI systemURI, List<Volume> existingVolumes, List<Volume> volumes, BlockSnapshotSession existingSession, URI cgURI) {
log.info("START create snapshot session and link session to targets step");
Volume existingVolume = existingVolumes.get(0);
// get existing snapshot groups
Set<String> snapGroupNames = ControllerUtils.getSnapshotReplicationGroupNamesForSnapSession(existingVolumes, existingSession, _dbClient);
for (Volume volume : volumes) {
// this may be the case if there is a snapshot on only one leg of a VPLEX volume (the backend storage device ids won't match)
if (volume != null && !URIUtil.identical(volume.getStorageController(), existingSession.getStorageController())) {
log.info("existing block snapshot session storage device id (%s) doesn't match volume storage device id (%s), skipping.", existingSession.getStorageController(), volume.getStorageController());
continue;
}
// delete the new session object at the end from DB
BlockSnapshotSession session = prepareSnapshotSessionFromSource(volume, existingSession);
log.info("adding snapshot session create step for volume {}", volume.getLabel());
waitFor = _blockDeviceController.addStepToCreateSnapshotSession(workflow, systemURI, session.getId(), existingSession.getReplicationGroupInstance(), waitFor);
// otherwise linking single target will fail when it sees the source in group
if (!snapGroupNames.isEmpty()) {
waitFor = _blockDeviceController.addStepToRemoveFromConsistencyGroup(workflow, systemURI, cgURI, Arrays.asList(volume.getId()), waitFor, false);
}
// snapshot targets
Map<String, List<URI>> snapGroupToSnapshots = new HashMap<String, List<URI>>();
for (String snapGroupName : snapGroupNames) {
String copyMode = ControllerUtils.getCopyModeFromSnapshotGroup(snapGroupName, systemURI, _dbClient);
log.info("Existing snap group {}, copy mode {}", snapGroupName, copyMode);
// prepare snapshot target
BlockSnapshot blockSnapshot = prepareSnapshot(volume, snapGroupName);
blockSnapshot.setCopyMode(copyMode);
_dbClient.updateObject(blockSnapshot);
// add this snapshot target to existing snap session
StringSet linkedTargets = existingSession.getLinkedTargets();
if (linkedTargets == null) {
linkedTargets = new StringSet();
}
linkedTargets.add(blockSnapshot.getId().toString());
_dbClient.updateObject(existingSession);
if (snapGroupToSnapshots.get(snapGroupName) == null) {
snapGroupToSnapshots.put(snapGroupName, new ArrayList<URI>());
}
snapGroupToSnapshots.get(snapGroupName).add(blockSnapshot.getId());
// Add steps to create new target and link them to the session
waitFor = _blockDeviceController.addStepToLinkBlockSnapshotSessionTarget(workflow, systemURI, session, blockSnapshot.getId(), copyMode, waitFor);
}
// add step to delete the newly created session object from DB
waitFor = workflow.createStep(MARK_SNAP_SESSIONS_INACTIVE_OR_REMOVE_TARGET_ID, String.format("marking snap session %s inactive", session.getLabel()), waitFor, systemURI, _blockDeviceController.getDeviceType(systemURI), this.getClass(), markSnapSessionInactiveOrRemoveTargetIdsMethod(session.getId(), null), _blockDeviceController.rollbackMethodNullMethod(), null);
// Add step to add back the source volume to its group which was removed before linking target
if (!snapGroupNames.isEmpty()) {
waitFor = _blockDeviceController.addStepToAddToConsistencyGroup(workflow, systemURI, cgURI, existingVolume.getReplicationGroupInstance(), Arrays.asList(volume.getId()), waitFor);
}
// Add steps to add new targets to their snap groups
for (Map.Entry<String, List<URI>> entry : snapGroupToSnapshots.entrySet()) {
waitFor = workflow.createStep(BlockDeviceController.UPDATE_CONSISTENCY_GROUP_STEP_GROUP, String.format("Updating consistency group %s", cgURI), waitFor, systemURI, _blockDeviceController.getDeviceType(systemURI), this.getClass(), addToReplicationGroupMethod(systemURI, cgURI, entry.getKey(), entry.getValue()), _blockDeviceController.rollbackMethodNullMethod(), null);
}
}
return waitFor;
}
use of com.emc.storageos.db.client.model.BlockSnapshotSession in project coprhd-controller by CoprHD.
the class ReplicaDeviceController method addStepsForAddingVolumesToRG.
/**
* Add steps to create clones/snapshots when add volumes to a replication group.
* @param workflow - The workflow that the steps would be added to
* @param waitFor - a waitFor key that can be used by subsequent controllers to wait on
* the Steps created by this controller.
* @param cgURI - CG URI
* @param volumeListToAdd - The volumes to be added.
* @param replicationGroup - replication group name
* @param taskId - top level operation's taskId
* @return - a waitFor key that can be used by subsequent controllers to wait on
* the Steps created by this controller.
* @throws InternalException
*/
public String addStepsForAddingVolumesToRG(Workflow workflow, String waitFor, URI cgURI, List<URI> volumeListToAdd, String replicationGroup, String taskId) throws InternalException {
log.info(String.format("addStepsForAddingVolumesToRG %s", replicationGroup));
List<Volume> volumesToAdd = ControllerUtils.queryVolumesByIterativeQuery(_dbClient, volumeListToAdd);
if (!volumesToAdd.isEmpty()) {
Volume firstVolume = volumesToAdd.get(0);
if (!ControllerUtils.isVmaxVolumeUsing803SMIS(firstVolume, _dbClient) && !ControllerUtils.isVnxVolume(firstVolume, _dbClient)) {
return waitFor;
}
URI storage = firstVolume.getStorageController();
StorageSystem storageSystem = _dbClient.queryObject(StorageSystem.class, storage);
// find member volumes in the group
List<Volume> existingRGVolumes = ControllerUtils.getVolumesPartOfRG(storage, replicationGroup, _dbClient);
if (existingRGVolumes.isEmpty()) {
return waitFor;
}
if (checkIfCGHasCloneReplica(existingRGVolumes)) {
log.info("Adding clone steps for adding volumes");
// create new clones for the newly added volumes
// add the created clones to clone groups
Set<String> repGroupNames = ControllerUtils.getCloneReplicationGroupNames(existingRGVolumes, _dbClient);
for (String repGroupName : repGroupNames) {
waitFor = addClonesToReplicationGroupStep(workflow, waitFor, storageSystem, volumesToAdd, repGroupName, cgURI);
}
}
if (checkIfCGHasMirrorReplica(existingRGVolumes)) {
log.info("Adding mirror steps for adding volumes");
// create new mirrors for the newly added volumes
// add the created mirrors to mirror groups
Set<String> repGroupNames = ControllerUtils.getMirrorReplicationGroupNames(existingRGVolumes, _dbClient);
for (String repGroupName : repGroupNames) {
waitFor = addMirrorToReplicationGroupStep(workflow, waitFor, storageSystem, volumesToAdd, repGroupName, cgURI);
}
}
List<BlockSnapshotSession> sessions = getSnapSessionsForCGVolume(existingRGVolumes.get(0));
boolean isExistingCGSnapShotAvailable = checkIfCGHasSnapshotReplica(existingRGVolumes);
boolean isExistingCGSnapSessionAvailable = sessions != null && !sessions.isEmpty();
boolean isVMAX3ExistingVolume = existingRGVolumes.get(0).isVmax3Volume(_dbClient);
if (isVMAX3ExistingVolume) {
if (isVMAX3VolumeHasSessionOnly(isExistingCGSnapSessionAvailable, isExistingCGSnapShotAvailable)) {
log.info("Existing CG only has Snap Session, adding snap session steps for adding volumes");
processSnapSessions(existingRGVolumes, workflow, waitFor, volumesToAdd);
} else if (isVMAX3VolumeHasSnapshotOnly(isExistingCGSnapSessionAvailable, isExistingCGSnapShotAvailable)) {
// create new snapshots for the newly added volumes
// add the created snapshots to snapshot groups
Set<String> snapGroupNames = ControllerUtils.getSnapshotReplicationGroupNames(existingRGVolumes, _dbClient);
for (String snapGroupName : snapGroupNames) {
// This method is invoked per RG, so need to get storage system separately
log.info("Existing CG only has Snapshots, adding snapshot steps for existing snap group {} adding volumes", snapGroupName);
waitFor = addSnapshotsToReplicationGroupStep(workflow, waitFor, storageSystem, volumesToAdd, snapGroupName, cgURI);
}
} else if (isVMAX3VolumeHasSessionAndSnapshot(isExistingCGSnapSessionAvailable, isExistingCGSnapShotAvailable)) {
log.info("Existing CG has both Sessions and linked targets, adding snapshot and session steps");
processSnapSessionsAndLinkedTargets(existingRGVolumes, workflow, waitFor, volumesToAdd, cgURI);
}
} else if (isExistingCGSnapShotAvailable) {
// non VMAX3 volume
log.info("Adding snapshot steps for adding volumes");
// create new snapshots for the newly added volumes
// add the created snapshots to snapshot groups
Set<String> snapGroupNames = ControllerUtils.getSnapshotReplicationGroupNames(existingRGVolumes, _dbClient);
for (String snapGroupName : snapGroupNames) {
waitFor = addSnapshotsToReplicationGroupStep(workflow, waitFor, storageSystem, volumesToAdd, snapGroupName, cgURI);
}
}
}
return waitFor;
}
use of com.emc.storageos.db.client.model.BlockSnapshotSession in project coprhd-controller by CoprHD.
the class SmisStorageDevice method fabricateSourceGroupAspects.
private void fabricateSourceGroupAspects(StorageSystem storage, BlockConsistencyGroup cg, Map<String, List<BlockSnapshotSession>> sessionLabelsMap) throws WBEMException {
/*
* Each key in the map represents the snapshot-session name, where a value represents a list
* of BlockSnapshotSession instances with this same name.
*/
for (Map.Entry<String, List<BlockSnapshotSession>> entry : sessionLabelsMap.entrySet()) {
String sessionLabel = entry.getKey();
List<BlockSnapshotSession> oldSessions = entry.getValue();
BlockSnapshotSession templateSession = oldSessions.get(0);
// get RG name from source (parent) volume
String groupName = null;
if (!NullColumnValueGetter.isNullNamedURI(templateSession.getParent())) {
BlockObject source = BlockObject.fetch(_dbClient, templateSession.getParent().getURI());
groupName = (source != null) ? source.getReplicationGroupInstance() : null;
}
// 1) Run Harsha's method to fab SourceGroup aspect
_log.info("Fabricating synchronization aspect for SourceGroup {}", cg.getLabel());
CIMObjectPath replicationSvc = _cimPath.getControllerReplicationSvcPath(storage);
CIMArgument[] iArgs = _helper.fabricateSourceGroupSynchronizationAspectInputArguments(storage, groupName, sessionLabel);
CIMArgument[] oArgs = new CIMArgument[5];
_helper.invokeMethod(storage, replicationSvc, "EMCRemoveSFSEntries", iArgs, oArgs);
// 2) Prepare to remove non-CG BlockSnapshotSession instances
StringSet consolidatedLinkedTargets = new StringSet();
for (BlockSnapshotSession oldSession : oldSessions) {
oldSession.setInactive(true);
StringSet linkedTargets = oldSession.getLinkedTargets();
if (linkedTargets != null && !linkedTargets.isEmpty()) {
consolidatedLinkedTargets.addAll(linkedTargets);
}
}
_dbClient.updateObject(oldSessions);
// 3) Create new BlockSnapshotSession instance, pointing to the new Source CG
BlockSnapshotSession newSession = new BlockSnapshotSession();
newSession.setId(URIUtil.createId(BlockSnapshotSession.class));
newSession.setConsistencyGroup(cg.getId());
newSession.setProject(new NamedURI(templateSession.getProject().getURI(), templateSession.getProject().getName()));
newSession.setStorageController(storage.getId());
newSession.setLabel(templateSession.getSessionLabel());
newSession.setSessionLabel(templateSession.getSessionLabel());
newSession.setReplicationGroupInstance(groupName);
newSession.setSessionSetName(groupName);
newSession.setLinkedTargets(consolidatedLinkedTargets);
_dbClient.createObject(newSession);
// Determine the session instance and update the BlockSnapshotSession
CIMObjectPath cgPath = _cimPath.getReplicationGroupPath(storage, groupName);
CloseableIterator<CIMObjectPath> associatorNames = null;
try {
_log.info("Finding associated source group aspects...");
associatorNames = _helper.getAssociatorNames(storage, cgPath, null, SYMM_SYNCHRONIZATION_ASPECT_FOR_SOURCE_GROUP, null, null);
while (associatorNames.hasNext()) {
CIMObjectPath aspectPath = associatorNames.next();
_log.info("Found {}", aspectPath);
String instanceId = aspectPath.getKeyValue(CP_INSTANCE_ID).toString();
if (instanceId.contains(newSession.getSessionLabel())) {
newSession.setSessionInstance(instanceId);
_dbClient.updateObject(newSession);
break;
}
}
} finally {
if (associatorNames != null) {
associatorNames.close();
}
}
}
}
use of com.emc.storageos.db.client.model.BlockSnapshotSession in project coprhd-controller by CoprHD.
the class SmisStorageDevice method doAddSnapshotSessionsToConsistencyGroup.
@Override
public void doAddSnapshotSessionsToConsistencyGroup(StorageSystem storageSystem, URI consistencyGroup, List<URI> volumes, TaskCompleter taskCompleter) {
List<? extends BlockObject> blockObjects = BlockObject.fetch(_dbClient, volumes);
BlockConsistencyGroup cg = _dbClient.queryObject(BlockConsistencyGroup.class, consistencyGroup);
Map<String, List<BlockSnapshotSession>> sessionLabelsMap = new HashMap<>();
for (BlockObject blockObject : blockObjects) {
List<BlockSnapshotSession> sessions = CustomQueryUtility.queryActiveResourcesByConstraint(_dbClient, BlockSnapshotSession.class, ContainmentConstraint.Factory.getParentSnapshotSessionConstraint(blockObject.getId()));
if (!sessions.isEmpty()) {
for (BlockSnapshotSession session : sessions) {
if (!sessionLabelsMap.containsKey(session.getSessionLabel())) {
sessionLabelsMap.put(session.getSessionLabel(), new ArrayList<BlockSnapshotSession>());
}
sessionLabelsMap.get(session.getSessionLabel()).add(session);
}
}
}
try {
fabricateSourceGroupAspects(storageSystem, cg, sessionLabelsMap);
taskCompleter.ready(_dbClient);
} catch (WBEMException e) {
_log.error("Problem in adding snapshot sessions to Consistency Group {}", consistencyGroup, e);
taskCompleter.error(_dbClient, DeviceControllerException.exceptions.failedToAddMembersToConsistencyGroup(cg.getLabel(), cg.getCgNameOnStorageSystem(storageSystem.getId()), e.getMessage()));
}
}
Aggregations