use of com.emc.storageos.db.client.model.ExportPathParams in project coprhd-controller by CoprHD.
the class VPlexDeviceController method reuseExistingExportMask.
/**
* Handles re-using an existing ViPR ExportMask for a volume export process.
*
* @param blockObjectMap
* the map of URIs to block volumes for export
* @param vplexSystem
* a StorageSystem object representing the VPLEX system
* @param exportGroup
* the ViPR export group
* @param varrayUri
* -- NOTE the varrayUri may not be the same as the one in exportGroup
* @param exportMasksToUpdateOnDevice
* collection of ExportMasks to update
* @param exportMasksToUpdateOnDeviceWithStoragePorts
* a map of ExportMasks to storage ports
* @param inits
* the host initiators of the host in question
* @param allPortsFromMaskMatchForVarray
* a flag indicating the storage port networking status
* @param viprExportMask
* the ExportMask in the ViPR database to re-use
* @param opId
* the workflow step id
*/
private void reuseExistingExportMask(Map<URI, Integer> blockObjectMap, StorageSystem vplexSystem, ExportGroup exportGroup, URI varrayUri, List<ExportMask> exportMasksToUpdateOnDevice, Map<URI, List<URI>> exportMasksToUpdateOnDeviceWithStoragePorts, List<Initiator> inits, boolean allPortsFromMaskMatchForVarray, ExportMask viprExportMask, String opId) {
exportMasksToUpdateOnDevice.add(viprExportMask);
ExportPathParams pathParams = _blockScheduler.calculateExportPathParamForVolumes(blockObjectMap.keySet(), exportGroup.getNumPaths(), vplexSystem.getId(), exportGroup.getId());
if (exportGroup.getType() != null) {
pathParams.setExportGroupType(exportGroup.getType());
}
// in the passed in varray (varrayUri)
if (!allPortsFromMaskMatchForVarray) {
Map<URI, List<URI>> assignments = _blockScheduler.assignStoragePorts(vplexSystem, exportGroup, inits, viprExportMask.getZoningMap(), pathParams, null, _networkDeviceController, varrayUri, opId);
// Consolidate the prezoned ports with the new assignments to get the total ports needed in the mask
if (assignments != null && !assignments.isEmpty()) {
// Update zoning Map with these new assignments
viprExportMask = ExportUtils.updateZoningMap(_dbClient, viprExportMask, assignments, exportMasksToUpdateOnDeviceWithStoragePorts);
}
}
}
use of com.emc.storageos.db.client.model.ExportPathParams in project coprhd-controller by CoprHD.
the class VPlexDeviceController method increaseMaxPaths.
@Override
public void increaseMaxPaths(Workflow workflow, StorageSystem vplex, ExportGroup exportGroup, ExportMask exportMask, List<URI> newInitiators, String token) throws Exception {
// Allocate any new ports that are required for the initiators
// and update the zoning map in the exportMask.
List<Initiator> initiators = _dbClient.queryObject(Initiator.class, newInitiators);
Collection<URI> volumeURIs = (Collections2.transform(exportMask.getVolumes().keySet(), CommonTransformerFunctions.FCTN_STRING_TO_URI));
ExportPathParams pathParams = _blockScheduler.calculateExportPathParamForVolumes(volumeURIs, exportGroup.getNumPaths(), vplex.getId(), exportGroup.getId());
if (exportGroup.getType() != null) {
pathParams.setExportGroupType(exportGroup.getType());
}
// Determine the Varray for the targets. Default to ExportGroup.virtualArray
URI varrayURI = exportGroup.getVirtualArray();
if (exportGroup.hasAltVirtualArray(vplex.getId().toString())) {
URI altVarrayURI = URI.create(exportGroup.getAltVirtualArrays().get(vplex.getId().toString()));
if (ExportMaskUtils.exportMaskInVarray(_dbClient, exportMask, altVarrayURI)) {
// If the targets match the alternate varray, use that instead.
varrayURI = altVarrayURI;
}
}
// Assign additional storage port(s).
Map<URI, List<URI>> assignments = _blockScheduler.assignStoragePorts(vplex, exportGroup, initiators, exportMask.getZoningMap(), pathParams, volumeURIs, _networkDeviceController, varrayURI, token);
List<URI> newTargets = BlockStorageScheduler.getTargetURIsFromAssignments(assignments);
exportMask.addZoningMap(BlockStorageScheduler.getZoneMapFromAssignments(assignments));
_dbClient.updateObject(exportMask);
if (newTargets.isEmpty() == false) {
// Only include initiators that were assigned ports in the Storage View.
// If we include any inititators that are not assigned and zoned to ports,
// creation or update of the Storage View will fail because we won't be
// able to register those initiators.
List<URI> storageViewInitiators = newInitiators;
// Create a Step to add the initiator to the Storage View
String message = String.format("adding initiators %s to StorageView %s", storageViewInitiators.toString(), exportGroup.getGeneratedName());
ExportMask sharedExportMask = VPlexUtil.getSharedExportMaskInDb(exportGroup, vplex.getId(), _dbClient, varrayURI, null, null);
boolean shared = false;
if (null != sharedExportMask && sharedExportMask.getId().equals(exportMask.getId())) {
shared = true;
}
String addInitStep = workflow.createStepId();
ExportMaskAddInitiatorCompleter completer = new ExportMaskAddInitiatorCompleter(exportGroup.getId(), exportMask.getId(), storageViewInitiators, new ArrayList<URI>(), addInitStep);
Workflow.Method addToViewMethod = storageViewAddInitiatorsMethod(vplex.getId(), exportGroup.getId(), exportMask.getId(), storageViewInitiators, null, shared, completer);
Workflow.Method addToViewRollbackMethod = storageViewAddInitiatorsRollbackMethod(vplex.getId(), exportGroup.getId(), exportMask.getId(), storageViewInitiators, null, addInitStep);
workflow.createStep(STORAGE_VIEW_ADD_INITS_METHOD, message, null, vplex.getId(), vplex.getSystemType(), this.getClass(), addToViewMethod, addToViewRollbackMethod, addInitStep);
// Create a Step to add storage ports to the Storage View
String addPortStep = workflow.createStepId();
ExportMaskAddInitiatorCompleter portCompleter = new ExportMaskAddInitiatorCompleter(exportGroup.getId(), exportMask.getId(), new ArrayList<URI>(), newTargets, addPortStep);
Workflow.Method addPortsToViewMethod = storageViewAddStoragePortsMethod(vplex.getId(), exportGroup.getId(), exportMask.getId(), newTargets, portCompleter);
Workflow.Method addPortsToViewRollbackMethod = storageViewAddStoragePortsRollbackMethod(vplex.getId(), exportGroup.getId(), exportMask.getId(), newTargets, addPortStep);
workflow.createStep(STORAGE_VIEW_ADD_STORAGE_PORTS_METHOD, String.format("Adding storage ports %s to VPLEX storage View %s", Joiner.on(", ").join(newTargets), exportGroup.getGeneratedName()), addInitStep, vplex.getId(), vplex.getSystemType(), this.getClass(), addPortsToViewMethod, addPortsToViewRollbackMethod, addPortStep);
List<ExportMask> exportMasks = ExportMaskUtils.getExportMasks(_dbClient, exportGroup, vplex.getId());
Map<URI, List<URI>> maskToInitiatorsMap = new HashMap<URI, List<URI>>();
Set<URI> zoningInitiators = new HashSet<>();
for (ExportMask mask : exportMasks) {
boolean sharedMask = false;
if (sharedExportMask != null) {
if (sharedExportMask.getId().equals(mask.getId())) {
sharedMask = true;
}
}
maskToInitiatorsMap.put(mask.getId(), new ArrayList<URI>());
Set<URI> exportMaskHosts = VPlexUtil.getExportMaskHosts(_dbClient, mask, sharedMask);
// Only add initiators to this ExportMask that are on the host of the Export Mask
for (Initiator initiator : initiators) {
if (exportMaskHosts.contains(VPlexUtil.getInitiatorHost(initiator))) {
maskToInitiatorsMap.get(mask.getId()).add(initiator.getId());
zoningInitiators.add(initiator.getId());
}
}
}
// Create a Step to add the SAN Zone
String zoningStepId = workflow.createStepId();
Workflow.Method zoningMethod = _networkDeviceController.zoneExportAddInitiatorsMethod(exportGroup.getId(), maskToInitiatorsMap);
List<NetworkZoningParam> zoningParams = NetworkZoningParam.convertExportMaskInitiatorMapsToNetworkZoningParam(exportGroup.getId(), maskToInitiatorsMap, _dbClient);
Workflow.Method zoningRollbackMethod = _networkDeviceController.zoneExportRemoveInitiatorsMethod(zoningParams);
zoningStepId = workflow.createStep(ZONING_STEP, String.format("Zone initiator %s to ExportGroup %s(%s)", Joiner.on(", ").join(zoningInitiators), exportGroup.getLabel(), exportGroup.getId()), addPortStep, vplex.getId(), vplex.getSystemType(), _networkDeviceController.getClass(), zoningMethod, zoningRollbackMethod, zoningStepId);
}
}
use of com.emc.storageos.db.client.model.ExportPathParams in project coprhd-controller by CoprHD.
the class VPlexDeviceController method setupExistingExportMaskWithNewHost.
/**
* This method is used to setup exportMask for the two cases as below
* 1. When initiators to be added are already present on the StorageView on VPLEX
* 2. When there is a sharedStorageView on VPLEX for the hosts in the exportGroup then new host
* is added to the same ExportMask in database and same storage view on the VPLEX
*
* @param blockObjectMap
* the map of URIs to block volumes for export
* @param vplexSystem
* reference to VPLEX storage system
* @param exportGroup
* reference to EXportGroup object
* @param varrayUri
* -- NOTE: may not be same as ExportGroup varray
* @param exportMasksToUpdateOnDevice
* Out param to track exportMasks that needs to be updated
* @param exportMasksToUpdateOnDeviceWithInitiators
* Out Param to track exportMasks that needs to be updated with the initiators
* @param exportMasksToUpdateOnDeviceWithStoragePorts
* Out Param to track exportMasks that needs to be updated with the storageports
* @param inits
* List of initiators that needs to be added
* @param sharedVplexExportMask
* ExportMask which represents multiple host.
* @param opId
* the workflow step id used to find the workflow to locate the zoning map stored in ZK
* @throws Exception
*/
private void setupExistingExportMaskWithNewHost(Map<URI, Integer> blockObjectMap, StorageSystem vplexSystem, ExportGroup exportGroup, URI varrayUri, List<ExportMask> exportMasksToUpdateOnDevice, Map<URI, List<Initiator>> exportMasksToUpdateOnDeviceWithInitiators, Map<URI, List<URI>> exportMasksToUpdateOnDeviceWithStoragePorts, List<Initiator> inits, ExportMask sharedVplexExportMask, String opId) throws Exception {
ExportPathParams pathParams = _blockScheduler.calculateExportPathParamForVolumes(blockObjectMap.keySet(), exportGroup.getNumPaths(), vplexSystem.getId(), exportGroup.getId());
// Try to assign new ports by passing in existingMap
Map<URI, List<URI>> assignments = _blockScheduler.assignStoragePorts(vplexSystem, exportGroup, inits, sharedVplexExportMask.getZoningMap(), pathParams, null, _networkDeviceController, varrayUri, opId);
if (assignments != null && !assignments.isEmpty()) {
// Update zoningMap if there are new assignments
sharedVplexExportMask = ExportUtils.updateZoningMap(_dbClient, sharedVplexExportMask, assignments, exportMasksToUpdateOnDeviceWithStoragePorts);
}
List<Initiator> initsToAddOnVplexDevice = new ArrayList<Initiator>();
for (Initiator init : inits) {
if (!sharedVplexExportMask.hasExistingInitiator(init)) {
initsToAddOnVplexDevice.add(init);
}
}
// already in the storage view as to create steps to add those initiators
if (!initsToAddOnVplexDevice.isEmpty()) {
if (exportMasksToUpdateOnDeviceWithInitiators.get(sharedVplexExportMask.getId()) == null) {
exportMasksToUpdateOnDeviceWithInitiators.put(sharedVplexExportMask.getId(), new ArrayList<Initiator>());
}
exportMasksToUpdateOnDeviceWithInitiators.get(sharedVplexExportMask.getId()).addAll(initsToAddOnVplexDevice);
}
// Storage ports that needs to be added will be calculated in the
// add storage ports method from the zoning Map.
exportMasksToUpdateOnDeviceWithStoragePorts.put(sharedVplexExportMask.getId(), new ArrayList<URI>());
exportMasksToUpdateOnDevice.add(sharedVplexExportMask);
}
use of com.emc.storageos.db.client.model.ExportPathParams in project coprhd-controller by CoprHD.
the class ExportChangePortGroupCompleter method updateVolumeExportPathParam.
/**
* Update export group pathParameters for the impacted volumes
*
* @param dbClient
*/
private void updateVolumeExportPathParam(DbClient dbClient) {
log.info("updating path param map.");
if (affectedExportGroups == null || affectedExportGroups.isEmpty()) {
// not export group is affected, return
return;
}
for (URI egURI : affectedExportGroups) {
ExportGroup exportGroup = dbClient.queryObject(ExportGroup.class, egURI);
log.info(String.format("Updating export group %s", exportGroup.getId().toString()));
StringMap volumes = exportGroup.getVolumes();
StringMap existingPathMap = exportGroup.getPathParameters();
List<URI> impactedVolumes = new ArrayList<URI>();
Map<URI, List<URI>> volumePath = new HashMap<URI, List<URI>>();
if (volumes == null || volumes.isEmpty()) {
continue;
}
Set<String> volSet = volumes.keySet();
for (String volId : volSet) {
URI volURI = URI.create(volId);
Volume volume = dbClient.queryObject(Volume.class, volURI);
if (volume == null || !volume.getStorageController().equals(systemURI)) {
continue;
}
log.info(String.format("Checking for the volume %s", volume.getLabel()));
// Check if the volume is in the pathMap
String pathParm = existingPathMap.get(volId);
if (pathParm != null) {
URI pathId = URI.create(pathParm);
List<URI> vols = volumePath.get(pathId);
if (vols == null) {
vols = new ArrayList<URI>();
}
vols.add(volURI);
volumePath.put(pathId, vols);
} else {
// No path param associated with the volume yet
impactedVolumes.add(volURI);
}
}
if (!volumePath.isEmpty()) {
for (Map.Entry<URI, List<URI>> entry : volumePath.entrySet()) {
URI pathParamURI = entry.getKey();
ExportPathParams pathParam = dbClient.queryObject(ExportPathParams.class, pathParamURI);
if (pathParam != null) {
pathParam.setPortGroup(newPortGroup);
dbClient.updateObject(pathParam);
}
}
}
if (!impactedVolumes.isEmpty()) {
ExportPathParams pathParam = new ExportPathParams();
pathParam.setLabel(exportGroup.getLabel());
pathParam.setExplicitlyCreated(false);
pathParam.setId(URIUtil.createId(ExportPathParams.class));
pathParam.setPortGroup(newPortGroup);
pathParam.setInactive(false);
dbClient.createObject(pathParam);
for (URI volId : impactedVolumes) {
exportGroup.addToPathParameters(volId, pathParam.getId());
}
}
dbClient.updateObject(exportGroup);
}
}
use of com.emc.storageos.db.client.model.ExportPathParams in project coprhd-controller by CoprHD.
the class ExportPortRebalanceCompleter method createExportPathParams.
/**
* Create an ExportPathParams based on the newPathParam
*
* @param dbClient - DbClient
* @param exportGroup - Export group
* @param portGroupURI - Port group URI
* @return - The created ExportPathParams instance
*/
private ExportPathParams createExportPathParams(DbClient dbClient, ExportGroup exportGroup, URI portGroupURI) {
ExportPathParams pathParam = new ExportPathParams();
pathParam.setMaxPaths(newPathParam.getMaxPaths());
pathParam.setMinPaths(newPathParam.getMinPaths());
pathParam.setPathsPerInitiator(newPathParam.getPathsPerInitiator());
pathParam.setExportGroupType(exportGroup.getType());
pathParam.setLabel(exportGroup.getLabel());
if (newPathParam.getStoragePorts() != null) {
pathParam.setStoragePorts(newPathParam.getStoragePorts());
}
pathParam.setExplicitlyCreated(false);
pathParam.setId(URIUtil.createId(ExportPathParams.class));
pathParam.setInactive(false);
pathParam.setPortGroup(portGroupURI);
dbClient.createObject(pathParam);
return pathParam;
}
Aggregations