use of com.emc.storageos.blockorchestrationcontroller.VolumeDescriptor in project coprhd-controller by CoprHD.
the class VPlexBlockServiceApiImpl method makeBackendVolumeDescriptors.
/**
* Takes a list of recommendations and makes the backend volumes and volume descriptors needed to
* provision. When possible (e.g. for SRDF and Block), All recommendations must be in single varray.
* calls the underlying storage routine createVolumesAndDescriptors().
*
* @param recommendations -- a VPlex recommendation list
* @param project - Project containing the Vplex volumes
* @param vplexProject -- private project of the Vplex
* @param rootVpool -- top level Virtual Pool (VpoolUse.ROOT)
* @param varrayCount -- instance count of the varray being provisioned
* @param size -- size of each volume
* @param backendCG -- the CG to be used on the backend Storage Systems
* @param vPoolCapabilities - a VirtualPoolCapabilityValuesWrapper containing provisioning arguments
* @param createTask -- boolean if true creates a task
* @param task -- Overall task id
* @return -- list of VolumeDescriptors to be provisioned
*/
private List<VolumeDescriptor> makeBackendVolumeDescriptors(List<VPlexRecommendation> recommendations, Project project, Project vplexProject, VirtualPool rootVpool, String volumeLabel, int varrayCount, long size, BlockConsistencyGroup backendCG, VirtualPoolCapabilityValuesWrapper vPoolCapabilities, boolean createTask, String task) {
VPlexRecommendation firstRecommendation = recommendations.get(0);
List<VolumeDescriptor> descriptors = new ArrayList<VolumeDescriptor>();
URI varrayId = firstRecommendation.getVirtualArray();
VirtualPool vpool = firstRecommendation.getVirtualPool();
s_logger.info("Generated backend descriptors for {} recommendations varray {}", recommendations.size(), varrayCount);
vPoolCapabilities.put(VirtualPoolCapabilityValuesWrapper.AUTO_TIER__POLICY_NAME, vpool.getAutoTierPolicyName());
if (firstRecommendation.getRecommendation() != null) {
// If these recommendations have lower level recommendation, process them.
// This path is used for the source side of Distributed Volumes and for Local volumes
// where we support building on top of SRDF or the BlockStorage as appropriate.
List<Recommendation> childRecommendations = new ArrayList<Recommendation>();
Recommendation childRecommendation = null;
for (VPlexRecommendation recommendation : recommendations) {
childRecommendation = recommendation.getRecommendation();
childRecommendations.add(childRecommendation);
}
VirtualArray varray = _dbClient.queryObject(VirtualArray.class, varrayId);
String newVolumeLabel = generateVolumeLabel(volumeLabel, varrayCount, 0, 0);
boolean srdfTarget = (childRecommendation instanceof SRDFCopyRecommendation);
boolean srdfSource = (childRecommendation instanceof SRDFRecommendation);
if (srdfTarget) {
newVolumeLabel = newVolumeLabel + "-target";
} else if (srdfSource) {
} else {
// nothing special about these volumes, hide them in the vplex project
// We can't use the vplexProject for SRDF volumes as they determine their RDF group
// grom the project.
project = vplexProject;
}
TaskList taskList = new TaskList();
descriptors = super.createVolumesAndDescriptors(descriptors, newVolumeLabel, size, project, varray, vpool, childRecommendations, taskList, task, vPoolCapabilities);
VolumeDescriptor.Type[] types;
if (srdfTarget) {
types = new VolumeDescriptor.Type[] { VolumeDescriptor.Type.SRDF_TARGET };
} else {
types = new VolumeDescriptor.Type[] { VolumeDescriptor.Type.BLOCK_DATA, VolumeDescriptor.Type.SRDF_SOURCE, VolumeDescriptor.Type.SRDF_EXISTING_SOURCE };
}
descriptors = VolumeDescriptor.filterByType(descriptors, types);
for (VolumeDescriptor descriptor : descriptors) {
Volume volume = _dbClient.queryObject(Volume.class, descriptor.getVolumeURI());
s_logger.info(String.format("Received prepared volume %s (%s, args) type %s", volume.getLabel(), volume.getId(), descriptor.getType().name()));
volume.addInternalFlags(DataObject.Flag.INTERNAL_OBJECT);
configureCGAndReplicationGroup(rootVpool, vPoolCapabilities, backendCG, volume);
_dbClient.updateObject(volume);
}
return descriptors;
}
// Sum resourceCount across all recommendations
int totalResourceCount = 0;
for (VPlexRecommendation recommendation : recommendations) {
totalResourceCount += recommendation.getResourceCount();
}
// The code below is used for the HA side of distributed volumes.
// The HA side does not currently call the lower level schedulers to get descriptors.
s_logger.info("Processing recommendations for Virtual Array {}", varrayId);
int volumeCounter = 0;
for (VPlexRecommendation recommendation : recommendations) {
for (int i = 0; i < recommendation.getResourceCount(); i++) {
vpool = recommendation.getVirtualPool();
URI storageDeviceURI = recommendation.getSourceStorageSystem();
URI storagePoolURI = recommendation.getSourceStoragePool();
String newVolumeLabel = generateVolumeLabel(volumeLabel, varrayCount, volumeCounter, totalResourceCount);
validateVolumeLabel(newVolumeLabel, project);
s_logger.info("Volume label is {}", newVolumeLabel);
VirtualArray varray = _dbClient.queryObject(VirtualArray.class, varrayId);
// This is also handled in StorageScheduler.prepareRecomendedVolumes
long thinVolumePreAllocationSize = 0;
if (null != vpool.getThinVolumePreAllocationPercentage()) {
thinVolumePreAllocationSize = VirtualPoolUtil.getThinVolumePreAllocationSize(vpool.getThinVolumePreAllocationPercentage(), size);
}
Volume volume = prepareVolume(VolumeType.BLOCK_VOLUME, null, size, thinVolumePreAllocationSize, vplexProject, varray, vpool, storageDeviceURI, storagePoolURI, newVolumeLabel, backendCG, vPoolCapabilities);
configureCGAndReplicationGroup(rootVpool, vPoolCapabilities, backendCG, volume);
volume.addInternalFlags(Flag.INTERNAL_OBJECT);
_dbClient.persistObject(volume);
if (createTask) {
_dbClient.createTaskOpStatus(Volume.class, volume.getId(), task, ResourceOperationTypeEnum.CREATE_BLOCK_VOLUME);
}
s_logger.info("Prepared volume {} ({}) ", volume.getLabel(), volume.getId());
VolumeDescriptor descriptor = new VolumeDescriptor(VolumeDescriptor.Type.BLOCK_DATA, storageDeviceURI, volume.getId(), storagePoolURI, backendCG == null ? null : backendCG.getId(), vPoolCapabilities, size);
descriptors.add(descriptor);
volumeCounter++;
}
}
return descriptors;
}
use of com.emc.storageos.blockorchestrationcontroller.VolumeDescriptor in project coprhd-controller by CoprHD.
the class VMAX3BlockSnapshotSessionApiImpl method createSnapshotSession.
/**
* {@inheritDoc}
*/
@Override
public void createSnapshotSession(BlockObject sourceObj, URI snapSessionURI, List<List<URI>> snapSessionSnapshotURIs, String copyMode, String taskId) {
// Invoke the BlockDeviceController to create the array snapshot session and create and link
// target volumes as necessary.
StorageSystem storageSystem = _dbClient.queryObject(StorageSystem.class, sourceObj.getStorageController());
VirtualPoolCapabilityValuesWrapper capabilities = new VirtualPoolCapabilityValuesWrapper();
capabilities.put(VirtualPoolCapabilityValuesWrapper.SNAPSHOT_SESSION_COPY_MODE, copyMode);
VolumeDescriptor sessionDescriptor = new VolumeDescriptor(VolumeDescriptor.Type.BLOCK_SNAPSHOT_SESSION, storageSystem.getId(), snapSessionURI, null, sourceObj.getConsistencyGroup(), capabilities, snapSessionSnapshotURIs);
List<VolumeDescriptor> volumeDescriptors = new ArrayList<VolumeDescriptor>();
volumeDescriptors.add(sessionDescriptor);
BlockOrchestrationController controller = getController(BlockOrchestrationController.class, BlockOrchestrationController.BLOCK_ORCHESTRATION_DEVICE);
controller.createSnapshotSession(volumeDescriptors, taskId);
}
use of com.emc.storageos.blockorchestrationcontroller.VolumeDescriptor in project coprhd-controller by CoprHD.
the class DefaultBlockFullCopyApiImpl method prepareVolumeDescriptorsForFullCopy.
/**
* creates volume descriptors based on the recommendations from placement
*
* @param volumes volume list that came from the placement algorithm
* @param createInactive flag to determine if the clone should be activated or not
* @return a list of volume descriptors
*/
private List<VolumeDescriptor> prepareVolumeDescriptorsForFullCopy(List<Volume> volumes, boolean createInactive) {
// Build up a list of VolumeDescriptors based on the volumes
final List<VolumeDescriptor> volumeDescriptors = new ArrayList<VolumeDescriptor>();
VirtualPoolCapabilityValuesWrapper vpoolCapabilities = new VirtualPoolCapabilityValuesWrapper();
vpoolCapabilities.put(VirtualPoolCapabilityValuesWrapper.REPLICA_CREATE_INACTIVE, new Boolean(createInactive).toString());
for (Volume volume : volumes) {
VolumeDescriptor desc = new VolumeDescriptor(VolumeDescriptor.Type.BLOCK_DATA, volume.getStorageController(), volume.getId(), volume.getPool(), volume.getConsistencyGroup(), vpoolCapabilities);
volumeDescriptors.add(desc);
}
return volumeDescriptors;
}
use of com.emc.storageos.blockorchestrationcontroller.VolumeDescriptor in project coprhd-controller by CoprHD.
the class DefaultBlockFullCopyApiImpl method create.
/**
* {@inheritDoc}
*/
@Override
public TaskList create(List<BlockObject> fcSourceObjList, VirtualArray varray, String name, boolean createInactive, int count, String taskId) {
// Get the placement recommendations for the full copies and
// prepare the ViPR volumes to represent the full copies.
// TBD We are getting recommendations one at a time instead
// of for all full copies at the same time as was done
// previously. However, now we are allowing for creating
// full copies for multiple volume form a CG. These volumes
// could have different vpools and sizes. Therefore, I don't
// see how we can get them at the same time for all volumes
// as the capabilities could be different. I guess the
// possible result is that if the volumes are the same, they
// could be placed in the same storage pool and if the pool
// is approaching capacity, there may not actually be enough
// space in the recommended pool.
int sourceCounter = 0;
List<Volume> volumesList = new ArrayList<Volume>();
BlockObject aFCSource = null;
Map<URI, VirtualArray> vArrayCache = new HashMap<URI, VirtualArray>();
List<BlockObject> sortedSourceObjectList = sortFullCopySourceList(fcSourceObjList);
try {
for (BlockObject fcSourceObj : sortedSourceObjectList) {
// Make sure when there are multiple source objects,
// each full copy has a unique name.
aFCSource = fcSourceObj;
// volumes in VolumeGroup can be from different vArrays
varray = getVarrayFromCache(vArrayCache, fcSourceObj.getVirtualArray());
String copyName = null;
boolean inApplication = false;
if (aFCSource instanceof Volume && ((Volume) aFCSource).getApplication(_dbClient) != null) {
inApplication = true;
}
if (NullColumnValueGetter.isNotNullValue(fcSourceObj.getReplicationGroupInstance()) && inApplication) {
copyName = name + "-" + fcSourceObj.getReplicationGroupInstance() + (sortedSourceObjectList.size() > 1 ? "-" + ++sourceCounter : "");
} else {
copyName = name + (sortedSourceObjectList.size() > 1 ? "-" + ++sourceCounter : "");
}
VirtualPool vpool = BlockFullCopyUtils.queryFullCopySourceVPool(fcSourceObj, _dbClient);
VirtualPoolCapabilityValuesWrapper capabilities = getCapabilitiesForFullCopyCreate(fcSourceObj, vpool, count);
List<VolumeRecommendation> placementRecommendations = getPlacementRecommendations(fcSourceObj, capabilities, varray, vpool.getId());
volumesList.addAll(prepareClonesForEachRecommendation(copyName, name, fcSourceObj, capabilities, createInactive, placementRecommendations));
}
} catch (Exception ex) {
handlePlacementFailure(volumesList);
throw ex;
}
// get volume descriptors
List<VolumeDescriptor> volumeDescriptors = prepareVolumeDescriptorsForFullCopy(volumesList, createInactive);
// get all tasks
TaskList tasks = getTasksForCreateFullCopy(aFCSource, volumesList, taskId);
try {
BlockOrchestrationController controller = getController(BlockOrchestrationController.class, BlockOrchestrationController.BLOCK_ORCHESTRATION_DEVICE);
controller.createFullCopy(volumeDescriptors, taskId);
} catch (InternalException ie) {
handleFailedRequest(taskId, tasks, volumesList, ie, true);
}
return tasks;
}
use of com.emc.storageos.blockorchestrationcontroller.VolumeDescriptor in project coprhd-controller by CoprHD.
the class VPlexBlockFullCopyApiImpl method prepareFullCopyPrimaryVolumes.
/**
* Places and prepares the primary copy volumes when copying a VPLEX virtual
* volume.
*
* @param name The base name for the volume.
* @param copyCount The number of copies to be made.
* @param srcBlockObject The primary volume of the VPLEX volume or snapshot being copied.
* @param srcCapabilities The capabilities of the primary volume.
* @param volumeDescriptors The list of descriptors.
* @param vPool The vPool to which the source object belongs to.
*
* @return A list of the prepared primary volumes for the VPLEX volume copy.
*/
private List<Volume> prepareFullCopyPrimaryVolumes(String name, int copyCount, BlockObject srcBlockObject, VirtualPoolCapabilityValuesWrapper srcCapabilities, List<VolumeDescriptor> volumeDescriptors, VirtualPool vPool) {
List<Volume> copyPrimaryVolumes = new ArrayList<>();
// Get the placement recommendations for the primary volume copies.
// Use the same method as is done for native volume copy.
VirtualArray vArray = _dbClient.queryObject(VirtualArray.class, srcBlockObject.getVirtualArray());
List<VolumeRecommendation> recommendations = ((VPlexScheduler) _scheduler).getBlockScheduler().getRecommendationsForVolumeClones(vArray, vPool, srcBlockObject, srcCapabilities);
if (recommendations.isEmpty()) {
throw APIException.badRequests.noStorageForPrimaryVolumesForVplexVolumeCopies();
}
// Prepare the copy volumes for each recommendation. Again,
// use the same manner as is done for native volume copy.
StringBuilder nameBuilder = new StringBuilder(name);
nameBuilder.append("-0");
int copyIndex = (copyCount > 1) ? 1 : 0;
for (VolumeRecommendation recommendation : recommendations) {
Volume volume = StorageScheduler.prepareFullCopyVolume(_dbClient, nameBuilder.toString(), srcBlockObject, recommendation, copyIndex++, srcCapabilities);
volume.addInternalFlags(Flag.INTERNAL_OBJECT);
_dbClient.persistObject(volume);
copyPrimaryVolumes.add(volume);
// Create the volume descriptor and add it to the passed list.
VolumeDescriptor volumeDescriptor = new VolumeDescriptor(VolumeDescriptor.Type.VPLEX_IMPORT_VOLUME, volume.getStorageController(), volume.getId(), volume.getPool(), srcCapabilities);
volumeDescriptors.add(volumeDescriptor);
}
return copyPrimaryVolumes;
}
Aggregations