use of com.emc.storageos.db.client.model.BlockConsistencyGroup in project coprhd-controller by CoprHD.
the class VolumeIngestionUtil method findOrCreateRPBlockConsistencyGroup.
/**
* Creates a block consistency group for the given protection set, or finds one first
* if it has already been created in another volume context within the scope of this
* ingestion request.
*
* @param requestContext the current IngestionRequestContext
* @param unManagedVolume the currently ingesting UnManagedVolume
* @param pset the ProtectionSet
* @param dbClient a reference to the database client
* @return a BlockConsistencyGroup for the volume context and ProtectionSet
*/
public static BlockConsistencyGroup findOrCreateRPBlockConsistencyGroup(IngestionRequestContext requestContext, UnManagedVolume unManagedVolume, ProtectionSet pset, DbClient dbClient) {
BlockConsistencyGroup cg = null;
Project project = dbClient.queryObject(Project.class, pset.getProject());
NamedURI projectNamedUri = new NamedURI(pset.getProject(), project.getLabel());
// if this is a recover point ingestion context, check for an existing CG in memory
RecoverPointVolumeIngestionContext rpContext = null;
if (requestContext instanceof RecoverPointVolumeIngestionContext) {
rpContext = (RecoverPointVolumeIngestionContext) requestContext;
} else if (requestContext.getVolumeContext(unManagedVolume.getNativeGuid()) instanceof RecoverPointVolumeIngestionContext) {
rpContext = (RecoverPointVolumeIngestionContext) requestContext.getVolumeContext(unManagedVolume.getNativeGuid());
}
if (rpContext != null) {
cg = rpContext.findExistingBlockConsistencyGroup(pset.getLabel(), projectNamedUri, project.getTenantOrg());
}
// Find the source volume in the protection set so we can set the virtual array in the consistency group
URI varrayId = null;
URI storageSystemId = null;
if (pset.getVolumes() != null) {
for (String volumeIdStr : pset.getVolumes()) {
Volume volume = requestContext.findDataObjectByType(Volume.class, URI.create(volumeIdStr), true);
if (volume != null) {
if (PersonalityTypes.SOURCE.name().equalsIgnoreCase(volume.getPersonality())) {
varrayId = volume.getVirtualArray();
if (volume.isVPlexVolume(dbClient)) {
storageSystemId = volume.getStorageController();
}
}
}
}
}
if (cg == null) {
cg = new BlockConsistencyGroup();
cg.setId(URIUtil.createId(BlockConsistencyGroup.class));
cg.setLabel(pset.getLabel());
cg.setProject(projectNamedUri);
cg.addConsistencyGroupTypes(Types.RP.name());
// By default, the array consistency is false. However later when we iterate over volumes in the BCG and we
// see any replicationGroupInstance information, we'll flip this bit to true. (See decorateRPVolumesCGInfo())
cg.setArrayConsistency(false);
cg.setTenant(project.getTenantOrg());
cg.setVirtualArray(varrayId);
cg.setStorageController(storageSystemId);
_logger.info("Created new block consistency group: " + cg.getId().toString());
}
cg.addSystemConsistencyGroup(pset.getProtectionSystem().toString(), pset.getLabel());
return cg;
}
use of com.emc.storageos.db.client.model.BlockConsistencyGroup in project coprhd-controller by CoprHD.
the class BlockDeviceController method addStepsForUpdateApplicationSingleStorage.
/**
* add step for update application
* adds volumes to replication groups on a single storage systems
*
* @param workflow
* @param storage
* @param rgName
* @param addVolumeList
* @param removeVolumeList
* @param waitForStep
* @param opId
* @return
* @throws ControllerException
*/
private String addStepsForUpdateApplicationSingleStorage(Workflow workflow, URI storage, String rgName, List<URI> addVolumeList, List<URI> removeVolumeList, String waitForStep, String opId) throws ControllerException {
String waitFor = waitForStep;
// Need to process remove list first
if (removeVolumeList != null && !removeVolumeList.isEmpty()) {
Volume vol = _dbClient.queryObject(Volume.class, removeVolumeList.get(0));
URI cgUri = vol.getConsistencyGroup();
String groupName = vol.getReplicationGroupInstance();
StorageSystem storageSystem = _dbClient.queryObject(StorageSystem.class, storage);
// call ReplicaDeviceController
waitFor = _replicaDeviceController.addStepsForRemovingVolumesFromCG(workflow, waitFor, cgUri, removeVolumeList, opId);
// Remove the volumes from the consistency group
waitFor = workflow.createStep(REMOVE_VOLUMES_FROM_CG_STEP_GROUP, String.format("Remove volumes from consistency group %s", cgUri.toString()), waitFor, storage, storageSystem.getSystemType(), this.getClass(), removeFromConsistencyGroupMethod(storage, cgUri, removeVolumeList, false), addToConsistencyGroupMethod(storage, cgUri, groupName, removeVolumeList), null);
// remove replication group if the CG will become empty
if (ControllerUtils.replicationGroupHasNoOtherVolume(_dbClient, groupName, removeVolumeList, storage)) {
waitFor = workflow.createStep(UPDATE_CONSISTENCY_GROUP_STEP_GROUP, String.format("Deleting replication group for consistency group %s", cgUri.toString()), waitFor, storage, storageSystem.getSystemType(), this.getClass(), deleteConsistencyGroupMethod(storage, cgUri, groupName, false, false, false), createConsistencyGroupMethod(storage, cgUri, groupName), null);
}
}
if (addVolumeList != null && !addVolumeList.isEmpty()) {
_log.info("Creating workflows for adding volumes to CG and application");
Volume vol = _dbClient.queryObject(Volume.class, addVolumeList.get(0));
URI cgUri = vol.getConsistencyGroup();
BlockConsistencyGroup cg = _dbClient.queryObject(BlockConsistencyGroup.class, cgUri);
StorageSystem storageSystem = _dbClient.queryObject(StorageSystem.class, storage);
// check if cg is created, if not create it
boolean isNewRG = false;
if (!cg.created(rgName, storage)) {
_log.info("Consistency group not created. Creating it");
isNewRG = true;
if (storageSystem.deviceIsType(Type.vnxblock)) {
// set arrayConsistency to false, so that no replication group will be created on array
cg.setArrayConsistency(false);
_dbClient.updateObject(cg);
}
waitFor = workflow.createStep(UPDATE_CONSISTENCY_GROUP_STEP_GROUP, String.format("Creating consistency group %s", rgName), waitFor, storage, storageSystem.getSystemType(), this.getClass(), createConsistencyGroupMethod(storage, cgUri, rgName), deleteConsistencyGroupMethod(storage, cgUri, rgName, false, false, false), null);
}
waitFor = workflow.createStep(UPDATE_CONSISTENCY_GROUP_STEP_GROUP, String.format("Adding volumes to consistency group %s", cgUri.toString()), waitFor, storage, storageSystem.getSystemType(), this.getClass(), addToConsistencyGroupMethod(storage, cgUri, rgName, addVolumeList), removeFromConsistencyGroupMethod(storage, cgUri, addVolumeList, false), null);
if (!isNewRG) {
// call ReplicaDeviceController
waitFor = _replicaDeviceController.addStepsForAddingVolumesToRG(workflow, waitFor, cgUri, addVolumeList, rgName, opId);
}
}
return waitFor;
}
use of com.emc.storageos.db.client.model.BlockConsistencyGroup in project coprhd-controller by CoprHD.
the class BlockDeviceController method updateConsistencyGroup.
@Override
public void updateConsistencyGroup(URI storage, URI consistencyGroup, List<URI> addVolumesList, List<URI> removeVolumesList, String task) {
TaskCompleter completer = new BlockConsistencyGroupUpdateCompleter(consistencyGroup, task);
try {
StorageSystem storageSystem = _dbClient.queryObject(StorageSystem.class, storage);
BlockConsistencyGroup cg = _dbClient.queryObject(BlockConsistencyGroup.class, consistencyGroup);
boolean srdfCG = false;
// check if SRDF
if (addVolumesList != null && !addVolumesList.isEmpty()) {
URI volumeURI = addVolumesList.get(0);
if (URIUtil.isType(volumeURI, Volume.class)) {
Volume volume = _dbClient.queryObject(Volume.class, volumeURI);
if (volume.isSRDFSource()) {
srdfCG = true;
cg.getRequestedTypes().add(Types.SRDF.name());
_dbClient.updateObject(cg);
}
}
}
// Generate the Workflow.
Workflow workflow = _workflowService.getNewWorkflow(this, UPDATE_CONSISTENCY_GROUP_WF_NAME, false, task);
String waitFor = null;
// check if cg is created, if not create it
if (!cg.created()) {
_log.info("Consistency group not created. Creating it");
String groupName = ControllerUtils.generateReplicationGroupName(storageSystem, cg, null, _dbClient);
waitFor = workflow.createStep(UPDATE_CONSISTENCY_GROUP_STEP_GROUP, String.format("Creating consistency group %s", consistencyGroup), waitFor, storage, storageSystem.getSystemType(), this.getClass(), createConsistencyGroupMethod(storage, consistencyGroup, groupName), deleteConsistencyGroupMethod(storage, consistencyGroup, groupName, false, false, true), null);
}
if (addVolumesList != null && !addVolumesList.isEmpty()) {
String groupName = ControllerUtils.generateReplicationGroupName(storageSystem, cg, null, _dbClient);
waitFor = workflow.createStep(UPDATE_CONSISTENCY_GROUP_STEP_GROUP, String.format("Adding volumes to consistency group %s", consistencyGroup), waitFor, storage, storageSystem.getSystemType(), this.getClass(), addToConsistencyGroupMethod(storage, consistencyGroup, groupName, addVolumesList), removeFromConsistencyGroupMethod(storage, consistencyGroup, addVolumesList, false), null);
// call ReplicaDeviceController
waitFor = _replicaDeviceController.addStepsForAddingSessionsToCG(workflow, waitFor, consistencyGroup, addVolumesList, groupName, task);
}
if (removeVolumesList != null && !removeVolumesList.isEmpty()) {
Volume volume = _dbClient.queryObject(Volume.class, removeVolumesList.get(0));
if (volume != null && !volume.getInactive()) {
String groupName = volume.getReplicationGroupInstance();
// call ReplicaDeviceController
waitFor = _replicaDeviceController.addStepsForRemovingVolumesFromCG(workflow, waitFor, consistencyGroup, removeVolumesList, task);
waitFor = workflow.createStep(UPDATE_CONSISTENCY_GROUP_STEP_GROUP, String.format("Removing volumes from consistency group %s", consistencyGroup), waitFor, storage, storageSystem.getSystemType(), this.getClass(), removeFromConsistencyGroupMethod(storage, consistencyGroup, removeVolumesList, false), addToConsistencyGroupMethod(storage, consistencyGroup, groupName, removeVolumesList), null);
// remove replication group if the CG will become empty
if ((addVolumesList == null || addVolumesList.isEmpty()) && ControllerUtils.cgHasNoOtherVolume(_dbClient, consistencyGroup, removeVolumesList)) {
waitFor = workflow.createStep(UPDATE_CONSISTENCY_GROUP_STEP_GROUP, String.format("Deleting replication group for consistency group %s", consistencyGroup), waitFor, storage, storageSystem.getSystemType(), this.getClass(), deleteConsistencyGroupMethod(storage, consistencyGroup, groupName, false, false, true), createConsistencyGroupMethod(storage, consistencyGroup, groupName), null);
}
}
}
// add target volumes to that target consistency group.
if (srdfCG) {
createTargetConsistencyGroup(cg, addVolumesList, workflow, waitFor, task);
}
// Finish up and execute the plan.
_log.info("Executing workflow plan {}", UPDATE_CONSISTENCY_GROUP_STEP_GROUP);
String successMessage = String.format("Update consistency group successful for %s", consistencyGroup);
workflow.executePlan(completer, successMessage);
} catch (Exception e) {
_log.error("Error updating consistency group: {}", consistencyGroup, e);
completer.error(_dbClient, DeviceControllerException.exceptions.failedToUpdateConsistencyGroup(e.getMessage()));
}
}
use of com.emc.storageos.db.client.model.BlockConsistencyGroup in project coprhd-controller by CoprHD.
the class BlockDeviceController method createConsistencyGroupStep.
public boolean createConsistencyGroupStep(URI storage, URI consistencyGroup, String replicationGroupName, String opId) throws ControllerException {
TaskCompleter taskCompleter = null;
try {
StorageSystem storageSystem = _dbClient.queryObject(StorageSystem.class, storage);
taskCompleter = new BlockConsistencyGroupCreateCompleter(consistencyGroup, opId);
String groupName = ControllerUtils.generateReplicationGroupName(storageSystem, consistencyGroup, replicationGroupName, _dbClient);
String lockKey = groupName;
boolean isVNX = storageSystem.deviceIsType(Type.vnxblock);
if (isVNX && lockKey == null) {
lockKey = replicationGroupName;
}
if (lockKey == null) {
BlockConsistencyGroup cgObj = _dbClient.queryObject(BlockConsistencyGroup.class, consistencyGroup);
lockKey = cgObj.getAlternateLabel() != null ? cgObj.getAlternateLabel() : cgObj.getLabel();
}
// Lock the CG for the step duration.
List<String> lockKeys = new ArrayList<>();
lockKeys.add(ControllerLockingUtil.getReplicationGroupStorageKey(_dbClient, lockKey, storage));
_workflowService.acquireWorkflowStepLocks(opId, lockKeys, LockTimeoutValue.get(LockType.ARRAY_CG));
if (isVNX) {
// replication group may have been just created by another thread, in that case,
// group name for VNX will be array generated name (if arrayConsistency is true), or
// replicationGroupName if arrayConsistency is false
// so get the group name again here to be used in ControllerUtils.replicationGroupExists call
groupName = ControllerUtils.generateReplicationGroupName(storageSystem, consistencyGroup, replicationGroupName, _dbClient);
}
// make sure this array consistency group was not just created by another thread that held the lock
if (groupName != null && ControllerUtils.replicationGroupExists(storage, groupName, _dbClient)) {
taskCompleter.ready(_dbClient);
return true;
}
getDevice(storageSystem.getSystemType()).doCreateConsistencyGroup(storageSystem, consistencyGroup, groupName, taskCompleter);
} catch (Exception e) {
_log.error("create consistency group job failed:", e);
ServiceError serviceError = DeviceControllerException.errors.jobFailed(e);
taskCompleter.error(_dbClient, serviceError);
WorkflowStepCompleter.stepFailed(opId, serviceError);
return false;
}
return true;
}
use of com.emc.storageos.db.client.model.BlockConsistencyGroup in project coprhd-controller by CoprHD.
the class BlockDeviceController method restoreSnapshotSession.
/**
* {@inheritDoc}
*/
@Override
public void restoreSnapshotSession(URI systemURI, URI snapSessionURI, Boolean updateStatus, String opId) {
BlockSnapshotSession snapshotSession = _dbClient.queryObject(BlockSnapshotSession.class, snapSessionURI);
TaskCompleter completer = new BlockSnapshotSessionRestoreWorkflowCompleter(snapshotSession.getId(), updateStatus, opId);
try {
// Get a new workflow to restore the snapshot session.
Workflow workflow = _workflowService.getNewWorkflow(this, RESTORE_SNAPSHOT_SESSION_WF_NAME, false, opId);
_log.info("Created new workflow to restore snapshot session {} with operation id {}", snapSessionURI, opId);
String waitFor = null;
// Check if we are dealing with a single volume or a group...
BlockObject sourceObj = null;
if (snapshotSession.hasConsistencyGroup() && NullColumnValueGetter.isNotNullValue(snapshotSession.getReplicationGroupInstance())) {
// We need a single source volume for the session.
BlockConsistencyGroup cg = _dbClient.queryObject(BlockConsistencyGroup.class, snapshotSession.getConsistencyGroup());
List<Volume> nativeVolumes = BlockConsistencyGroupUtils.getActiveNativeVolumesInCG(cg, _dbClient);
// get source group name from the session.
String sourceGroupName = snapshotSession.getReplicationGroupInstance();
for (Volume volume : nativeVolumes) {
if (sourceGroupName.equals(volume.getReplicationGroupInstance())) {
sourceObj = volume;
// get source volume which matches session's RG name
break;
}
}
} else {
sourceObj = BlockObject.fetch(_dbClient, snapshotSession.getParent().getURI());
}
if (sourceObj instanceof Volume && isNonSplitSRDFTargetVolume((Volume) sourceObj)) {
// PRIOR to Restoring R2 Device from its session, we need to
// a) SUSPEND the R1-R2 pair if the Copy Mode is ACTIVE Or
// b) SPLIT the R1-R2 pair if the Copy Mode is SYNC/ ASYNC
Volume sourceVolume = (Volume) sourceObj;
URI srdfSourceVolumeURI = sourceVolume.getSrdfParent().getURI();
Volume srdfSourceVolume = _dbClient.queryObject(Volume.class, srdfSourceVolumeURI);
URI srdfSourceStorageSystemURI = srdfSourceVolume.getStorageController();
if (Mode.ACTIVE.equals(Mode.valueOf(sourceVolume.getSrdfCopyMode()))) {
waitFor = suspendSRDFLinkWorkflowStep(waitFor, srdfSourceStorageSystemURI, srdfSourceVolumeURI, sourceObj.getId(), workflow);
} else {
// split all members the group
Workflow.Method splitMethod = srdfDeviceController.splitSRDFGroupLinkMethod(srdfSourceStorageSystemURI, srdfSourceVolumeURI, sourceObj.getId(), false);
Workflow.Method splitRollbackMethod = srdfDeviceController.resumeGroupPairsMethod(srdfSourceStorageSystemURI, srdfSourceVolumeURI, sourceObj.getId());
waitFor = workflow.createStep(SRDFDeviceController.SPLIT_SRDF_MIRRORS_STEP_GROUP, SRDFDeviceController.SPLIT_SRDF_MIRRORS_STEP_DESC, waitFor, srdfSourceStorageSystemURI, getDeviceType(srdfSourceStorageSystemURI), SRDFDeviceController.class, splitMethod, splitRollbackMethod, null);
}
} else if (sourceObj instanceof Volume && isNonSplitSRDFSourceVolume((Volume) sourceObj)) {
// PRIOR to Restoring R1 Device from its session, we need to SUSPEND the R1-R2 pair if the Copy Mode is
// ACTIVE
Volume srdfSourceVolume = (Volume) sourceObj;
URI srdfSourceStorageSystemURI = srdfSourceVolume.getStorageController();
StringSet targets = srdfSourceVolume.getSrdfTargets();
if (null != targets) {
for (String target : targets) {
if (NullColumnValueGetter.isNotNullValue(target)) {
Volume srdfTargetVolume = _dbClient.queryObject(Volume.class, URI.create(target));
if (null != srdfTargetVolume && Mode.ACTIVE.equals(Mode.valueOf(srdfTargetVolume.getSrdfCopyMode()))) {
waitFor = suspendSRDFLinkWorkflowStep(waitFor, srdfSourceStorageSystemURI, srdfSourceVolume.getId(), srdfTargetVolume.getId(), workflow);
}
break;
}
}
}
}
// Create the workflow step to restore the snapshot session.
waitFor = workflow.createStep(RESTORE_SNAPSHOT_SESSION_STEP_GROUP, String.format("Restore snapshot session %s", snapSessionURI), waitFor, systemURI, getDeviceType(systemURI), getClass(), restoreBlockSnapshotSessionMethod(systemURI, snapSessionURI), rollbackMethodNullMethod(), null);
// Execute the workflow.
workflow.executePlan(completer, "Restore block snapshot session successful");
} catch (Exception e) {
_log.error("Restore block snapshot session failed", e);
ServiceCoded serviceException = DeviceControllerException.exceptions.restoreBlockSnapshotSessionFailed(e);
completer.error(_dbClient, serviceException);
}
}
Aggregations