use of com.emc.storageos.db.client.model.Initiator in project coprhd-controller by CoprHD.
the class VplexXtremIOMaskingOrchestrator method configureZoning.
@Override
public StringSetMap configureZoning(Map<URI, List<List<StoragePort>>> portGroup, Map<String, Map<URI, Set<Initiator>>> initiatorGroup, Map<URI, NetworkLite> networkMap, StoragePortsAssigner assigner, Map<URI, String> initiatorSwitchMap, Map<URI, Map<String, List<StoragePort>>> switchStoragePortsMap, Map<URI, String> portSwitchMap) {
StringSetMap zoningMap = new StringSetMap();
// Set up a map to track port usage so that we can use all ports more or less equally.
Map<StoragePort, Integer> portUsage = new HashMap<StoragePort, Integer>();
// Iterate through each of the directors, matching each of its initiators
// with one port. This will ensure not to violate four paths per director.
// select number of paths per VPLEX director
// if X-bricks count is less than director count, choose only 2 initiators from each director
// leaving other initiators for future scale of X-bricks
// default 4 initiators in director
int pathsPerDirector = DEFAULT_NUMBER_OF_PATHS_PER_VPLEX_DIRECTOR;
if (xtremIOXbricksCount < vplexDirectorCount) {
pathsPerDirector = MINIMUM_NUMBER_OF_PATHS_PER_VPLEX_DIRECTOR;
}
_log.info(String.format("VPLEX Directors: %s, X-bricks: %s, Number of paths per VPLEX Director: %s", vplexDirectorCount, xtremIOXbricksCount, pathsPerDirector));
boolean isSwitchAffinity = false;
if (initiatorSwitchMap != null && !initiatorSwitchMap.isEmpty() && switchStoragePortsMap != null && !switchStoragePortsMap.isEmpty()) {
isSwitchAffinity = true;
}
int directorNumber = 1;
for (String director : initiatorGroup.keySet()) {
// split initiators across networks depending on number of paths per director
int numberOfNetworksForDirector = initiatorGroup.get(director).keySet().size();
int initiatorsPerNetworkForDirector = pathsPerDirector / numberOfNetworksForDirector;
_log.info("Number of Initiators that must be chosen per network for a director: {}", initiatorsPerNetworkForDirector);
for (URI networkURI : initiatorGroup.get(director).keySet()) {
int numberOfInitiatorsPerNetwork = 0;
NetworkLite net = networkMap.get(networkURI);
for (Initiator initiator : initiatorGroup.get(director).get(networkURI)) {
// If there are no ports on the initiators network, too bad...
if (portGroup.get(networkURI) == null) {
_log.info(String.format("%s -> no ports in network", initiator.getInitiatorPort()));
continue;
}
// if desired number of initiator paths chosen for network
if (numberOfInitiatorsPerNetwork >= initiatorsPerNetworkForDirector) {
_log.info(String.format("Maximum paths per network %s (%d) reached for Director %s", net.getLabel(), numberOfInitiatorsPerNetwork, director));
break;
}
List<StoragePort> assignablePorts = null;
if (isSwitchAffinity) {
// find the ports with the same switch as the initiator
String switchName = initiatorSwitchMap.get(initiator.getId());
if (!switchName.equals(NullColumnValueGetter.getNullStr())) {
Map<String, List<StoragePort>> switchMap = switchStoragePortsMap.get(networkURI);
if (switchMap != null) {
List<StoragePort> switchPorts = switchMap.get(switchName);
if (switchPorts != null && !switchPorts.isEmpty()) {
_log.info(String.format("Found the same switch ports, switch is %s", switchName));
assignablePorts = switchPorts;
}
}
}
}
List<StoragePort> portList = getStoragePortSetForDirector(portGroup.get(networkURI), directorNumber);
if (assignablePorts != null) {
assignablePorts.retainAll(portList);
}
if (assignablePorts == null || assignablePorts.isEmpty()) {
assignablePorts = portList;
}
// find a port for the initiator
StoragePort storagePort = VPlexBackEndOrchestratorUtil.assignPortToInitiator(assigner, assignablePorts, net, initiator, portUsage, null);
if (storagePort != null) {
_log.info(String.format("%s %s %s %s -> %s %s %s", director, net.getLabel(), initiator.getInitiatorPort(), initiatorSwitchMap.get(initiator.getId()), storagePort.getPortNetworkId(), storagePort.getPortName(), portSwitchMap.get(storagePort.getId())));
StringSet ports = new StringSet();
ports.add(storagePort.getId().toString());
zoningMap.put(initiator.getId().toString(), ports);
numberOfInitiatorsPerNetwork++;
} else {
_log.info(String.format("A port could not be assigned for %s %s %s", director, net.getLabel(), initiator.getInitiatorPort()));
}
}
}
directorNumber++;
}
return zoningMap;
}
use of com.emc.storageos.db.client.model.Initiator in project coprhd-controller by CoprHD.
the class XIVMaskingOrchestrator method exportGroupAddVolumes.
@Override
public void exportGroupAddVolumes(URI storageURI, URI exportGroupURI, Map<URI, Integer> volumeMap, String token) throws Exception {
ExportOrchestrationTask taskCompleter = null;
try {
BlockStorageDevice device = getDevice();
taskCompleter = new ExportOrchestrationTask(exportGroupURI, token);
StorageSystem storage = _dbClient.queryObject(StorageSystem.class, storageURI);
ExportGroup exportGroup = _dbClient.queryObject(ExportGroup.class, exportGroupURI);
boolean anyVolumesAdded = false;
boolean createdNewMask = false;
if (exportGroup != null && exportGroup.getExportMasks() != null) {
// Set up workflow steps.
Workflow workflow = _workflowService.getNewWorkflow(MaskingWorkflowEntryPoints.getInstance(), "exportGroupAddVolumes", true, token);
List<ExportMask> exportMasksToZoneAddVolumes = new ArrayList<ExportMask>();
List<URI> volumesToZoneAddVolumes = new ArrayList<URI>();
// Add the volume to all the ExportMasks that are contained in the
// ExportGroup. The volumes should be added only if they don't
// already exist for the ExportMask.
Collection<URI> initiatorURIs = Collections2.transform(exportGroup.getInitiators(), CommonTransformerFunctions.FCTN_STRING_TO_URI);
List<URI> hostURIs = new ArrayList<URI>();
Map<String, URI> portNameToInitiatorURI = new HashMap<String, URI>();
List<String> portNames = new ArrayList<String>();
processInitiators(exportGroup, initiatorURIs, portNames, portNameToInitiatorURI, hostURIs);
// We always want to have the full list of initiators for the hosts involved in
// this export. This will allow the export operation to always find any
// existing exports for a given host.
queryHostInitiatorsAndAddToList(portNames, portNameToInitiatorURI, initiatorURIs, hostURIs);
Map<String, Set<URI>> foundMatches = device.findExportMasks(storage, portNames, false);
// Need to maintain separate Export mask for Cluster and Host.
// So remove off the Export mask not matching to the Export Group.
filterExportMaskForGroup(exportGroup, foundMatches);
Set<String> checkMasks = mergeWithExportGroupMaskURIs(exportGroup, foundMatches.values());
for (String maskURIStr : checkMasks) {
ExportMask exportMask = _dbClient.queryObject(ExportMask.class, URI.create(maskURIStr));
_log.info(String.format("Checking mask %s", exportMask.getMaskName()));
// Check for NO_VIPR. If found, avoid this mask.
if (exportMask.getMaskName() != null && exportMask.getMaskName().toUpperCase().contains(ExportUtils.NO_VIPR)) {
_log.info(String.format("ExportMask %s disqualified because the name contains %s (in upper or lower case) to exclude it", exportMask.getMaskName(), ExportUtils.NO_VIPR));
continue;
}
if (!exportMask.getInactive() && exportMask.getStorageDevice().equals(storageURI)) {
exportMask = device.refreshExportMask(storage, exportMask);
// BlockStorageDevice level, so that it has up-to-date
// info from
// the array
Map<URI, Integer> volumesToAdd = new HashMap<URI, Integer>();
for (URI boURI : volumeMap.keySet()) {
BlockObject bo = Volume.fetchExportMaskBlockObject(_dbClient, boURI);
if (bo != null && !exportMask.hasExistingVolume(bo.getWWN()) && !exportMask.hasUserAddedVolume(bo.getWWN())) {
URI thisVol = bo.getId();
Integer hlu = volumeMap.get(boURI);
volumesToAdd.put(thisVol, hlu);
}
// Check if the requested HLU for the volume is
// already taken by a pre-existing volume.
Integer requestedHLU = volumeMap.get(boURI);
StringMap existingVolumesInMask = exportMask.getExistingVolumes();
if (existingVolumesInMask != null && requestedHLU.intValue() != ExportGroup.LUN_UNASSIGNED && !ExportGroup.LUN_UNASSIGNED_DECIMAL_STR.equals(requestedHLU.toString()) && existingVolumesInMask.containsValue(requestedHLU.toString())) {
ExportOrchestrationTask completer = new ExportOrchestrationTask(exportGroup.getId(), token);
ServiceError serviceError = DeviceControllerException.errors.exportHasExistingVolumeWithRequestedHLU(boURI.toString(), requestedHLU.toString());
completer.error(_dbClient, serviceError);
return;
}
}
_log.info(String.format("Mask %s, adding volumes %s", exportMask.getMaskName(), Joiner.on(',').join(volumesToAdd.entrySet())));
if (volumesToAdd.size() > 0) {
List<URI> volumeURIs = new ArrayList<URI>();
volumeURIs.addAll(volumesToAdd.keySet());
exportMasksToZoneAddVolumes.add(exportMask);
volumesToZoneAddVolumes.addAll(volumeURIs);
// Make sure the zoning map is getting updated for user-created masks
updateZoningMap(exportGroup, exportMask, true);
// Update volumeMap to find the next HLU here.
updateVolumeHLU(storage, initiatorURIs, volumesToAdd);
generateExportMaskAddVolumesWorkflow(workflow, EXPORT_GROUP_ZONING_TASK, storage, exportGroup, exportMask, volumesToAdd, null);
anyVolumesAdded = true;
// associated it with the ExportGroup.
if (!exportGroup.hasMask(exportMask.getId())) {
exportGroup.addExportMask(exportMask.getId());
_dbClient.updateAndReindexObject(exportGroup);
}
}
}
}
if (!anyVolumesAdded) {
String attachGroupSnapshot;
// masks and if there are initiators for the export.
if (!ExportMaskUtils.hasExportMaskForStorage(_dbClient, exportGroup, storageURI) && exportGroup.hasInitiators()) {
_log.info("No existing masks to which the requested volumes can be added. Creating a new mask");
List<URI> initiators = StringSetUtil.stringSetToUriList(exportGroup.getInitiators());
attachGroupSnapshot = checkForSnapshotsToCopyToTarget(workflow, storage, null, volumeMap, null);
Map<URI, List<URI>> hostInitiatorMap = new HashMap<URI, List<URI>>();
for (URI newExportMaskInitiator : initiators) {
Initiator initiator = _dbClient.queryObject(Initiator.class, newExportMaskInitiator);
// Not all initiators have hosts, be sure to handle either case.
URI hostURI = initiator.getHost();
if (hostURI == null) {
hostURI = NullColumnValueGetter.getNullURI();
}
List<URI> initiatorSet = hostInitiatorMap.get(hostURI);
if (initiatorSet == null) {
initiatorSet = new ArrayList<URI>();
hostInitiatorMap.put(hostURI, initiatorSet);
}
initiatorSet.add(initiator.getId());
_log.info(String.format("host = %s, " + "initiators to add: %d, ", hostURI, hostInitiatorMap.get(hostURI).size()));
}
if (!hostInitiatorMap.isEmpty()) {
for (URI hostID : hostInitiatorMap.keySet()) {
_log.info(String.format("new export masks %s", Joiner.on(",").join(hostInitiatorMap.get(hostID))));
String zoningStep = workflow.createStepId();
GenExportMaskCreateWorkflowResult result = generateExportMaskCreateWorkflow(workflow, zoningStep, storage, exportGroup, hostInitiatorMap.get(hostID), volumeMap, token);
List<URI> masks = new ArrayList<URI>();
masks.add(result.getMaskURI());
generateZoningCreateWorkflow(workflow, attachGroupSnapshot, exportGroup, masks, volumeMap, zoningStep);
}
createdNewMask = true;
}
}
}
if (!exportMasksToZoneAddVolumes.isEmpty()) {
generateZoningAddVolumesWorkflow(workflow, null, exportGroup, exportMasksToZoneAddVolumes, volumesToZoneAddVolumes);
}
String successMessage = String.format("Successfully added volumes to export on StorageArray %s", storage.getLabel());
workflow.executePlan(taskCompleter, successMessage);
} else {
if (exportGroup.hasInitiators()) {
_log.info("There are no masks for this export. Need to create anew.");
List<URI> initiatorURIs = new ArrayList<URI>();
for (String initiatorURIStr : exportGroup.getInitiators()) {
initiatorURIs.add(URI.create(initiatorURIStr));
}
// Invoke the export group create operation,
// which should in turn create a workflow operations to
// create the export for the newly added volume(s).
exportGroupCreate(storageURI, exportGroupURI, initiatorURIs, volumeMap, token);
anyVolumesAdded = true;
} else {
_log.warn("There are no initiator for export group: " + exportGroup.getLabel());
}
}
if (!anyVolumesAdded && !createdNewMask) {
taskCompleter.ready(_dbClient);
_log.info("No volumes pushed to array because either they already exist " + "or there were no initiators added to the export yet.");
}
} catch (Exception ex) {
_log.error("ExportGroup Orchestration failed.", ex);
// TODO add service code here
if (taskCompleter != null) {
ServiceError serviceError = DeviceControllerException.errors.jobFailedMsg(ex.getMessage(), ex);
taskCompleter.error(_dbClient, serviceError);
}
}
}
use of com.emc.storageos.db.client.model.Initiator in project coprhd-controller by CoprHD.
the class XIVMaskingOrchestrator method determineExportGroupCreateSteps.
/**
* Routine contains logic to create an export mask on the array
*
* @param workflow - Workflow object to create steps against
* @param previousStep - [optional] Identifier of workflow step to wait for
* @param device - BlockStorageDevice implementation
* @param storage - StorageSystem object representing the underlying array
* @param exportGroup - ExportGroup object representing Bourne-level masking
* @param initiatorURIs - List of Initiator URIs
* @param volumeMap - Map of Volume URIs to requested Integer HLUs
* @param zoningStepNeeded - Not required for XIV
* @param token - Identifier for the operation
* @throws Exception
*/
@Override
public boolean determineExportGroupCreateSteps(Workflow workflow, String previousStep, BlockStorageDevice device, StorageSystem storage, ExportGroup exportGroup, List<URI> initiatorURIs, Map<URI, Integer> volumeMap, boolean zoningStepNeeded, String token) throws Exception {
Map<String, URI> portNameToInitiatorURI = new HashMap<String, URI>();
List<URI> volumeURIs = new ArrayList<URI>();
volumeURIs.addAll(volumeMap.keySet());
Map<URI, URI> hostToExistingExportMaskMap = new HashMap<URI, URI>();
List<URI> hostURIs = new ArrayList<URI>();
List<String> portNames = new ArrayList<String>();
// Populate the port WWN/IQNs (portNames) and the
// mapping of the WWN/IQNs to Initiator URIs
processInitiators(exportGroup, initiatorURIs, portNames, portNameToInitiatorURI, hostURIs);
// We always want to have the full list of initiators for the hosts involved in
// this export. This will allow the export operation to always find any
// existing exports for a given host.
queryHostInitiatorsAndAddToList(portNames, portNameToInitiatorURI, initiatorURIs, hostURIs);
// Update volumeMap to find the next HLU here.
updateVolumeHLU(storage, initiatorURIs, volumeMap);
// Find the export masks that are associated with any or all the ports in
// portNames. We will have to do processing differently based on whether
// or there is an existing ExportMasks.
Map<String, Set<URI>> matchingExportMaskURIs = device.findExportMasks(storage, portNames, false);
// Need to maintain separate Export mask for Cluster and Host.
// So remove off the Export mask not matching to the Export Group.
filterExportMaskForGroup(exportGroup, matchingExportMaskURIs);
if (matchingExportMaskURIs.isEmpty()) {
String attachGroupSnapshot = checkForSnapshotsToCopyToTarget(workflow, storage, previousStep, volumeMap, null);
_log.info(String.format("No existing mask found w/ initiators { %s }", Joiner.on(",").join(portNames)));
createNewExportMaskWorkflowForInitiators(initiatorURIs, exportGroup, workflow, volumeMap, storage, token, attachGroupSnapshot);
} else {
_log.info(String.format("Mask(s) found w/ initiators {%s}. " + "MatchingExportMaskURIs {%s}, portNameToInitiators {%s}", Joiner.on(",").join(portNames), Joiner.on(",").join(matchingExportMaskURIs.keySet()), Joiner.on(",").join(portNameToInitiatorURI.entrySet())));
// There are some initiators that already exist. We need to create a
// workflow that create new masking containers or updates masking
// containers as necessary.
// These data structures will be used to track new initiators - ones
// that don't already exist on the array
List<URI> initiatorURIsCopy = new ArrayList<URI>();
initiatorURIsCopy.addAll(initiatorURIs);
// This loop will determine a list of volumes to update per export mask
Map<URI, Map<URI, Integer>> existingMasksToUpdateWithNewVolumes = new HashMap<URI, Map<URI, Integer>>();
Map<URI, Set<Initiator>> existingMasksToUpdateWithNewInitiators = new HashMap<URI, Set<Initiator>>();
for (Map.Entry<String, Set<URI>> entry : matchingExportMaskURIs.entrySet()) {
URI initiatorURI = portNameToInitiatorURI.get(entry.getKey());
Initiator initiator = _dbClient.queryObject(Initiator.class, initiatorURI);
// Keep track of those initiators that have been found to exist already
// in some export mask on the array
initiatorURIsCopy.remove(initiatorURI);
// Get a list of the ExportMasks that were matched to the initiator
List<URI> exportMaskURIs = new ArrayList<URI>();
exportMaskURIs.addAll(entry.getValue());
List<ExportMask> masks = _dbClient.queryObject(ExportMask.class, exportMaskURIs);
_log.info(String.format("initiator %s masks {%s}", initiator.getInitiatorPort(), Joiner.on(',').join(exportMaskURIs)));
for (ExportMask mask : masks) {
_log.info(String.format("mask %s has initiator %s", mask.getMaskName(), initiator.getInitiatorPort()));
// Check for NO_VIPR. If found, avoid this mask.
if (mask.getMaskName() != null && mask.getMaskName().toUpperCase().contains(ExportUtils.NO_VIPR)) {
_log.info(String.format("ExportMask %s disqualified because the name contains %s (in upper or lower case) to exclude it", mask.getMaskName(), ExportUtils.NO_VIPR));
continue;
}
if (mask.getCreatedBySystem()) {
_log.info(String.format("initiator %s is in persisted mask %s", initiator.getInitiatorPort(), mask.getMaskName()));
// in our export group, because we would simply add to them.
if (mask.getInitiators() != null) {
for (String existingMaskInitiatorStr : mask.getInitiators()) {
// Now look at it from a different angle. Which one of our export group initiators
// are NOT in the current mask? And if so, if it belongs to the same host as an existing one,
// we should add it to this mask.
Iterator<URI> initiatorIter = initiatorURIsCopy.iterator();
while (initiatorIter.hasNext()) {
Initiator initiatorCopy = _dbClient.queryObject(Initiator.class, initiatorIter.next());
if (initiatorCopy != null && initiatorCopy.getId() != null && !mask.hasInitiator(initiatorCopy.getId().toString())) {
Initiator existingMaskInitiator = _dbClient.queryObject(Initiator.class, URI.create(existingMaskInitiatorStr));
if (existingMaskInitiator != null && initiatorCopy.getHost() != null && initiatorCopy.getHost().equals(existingMaskInitiator.getHost())) {
// Add to the list of initiators we need to add to this mask
Set<Initiator> existingMaskInitiators = existingMasksToUpdateWithNewInitiators.get(mask.getId());
if (existingMaskInitiators == null) {
existingMaskInitiators = new HashSet<Initiator>();
existingMasksToUpdateWithNewInitiators.put(mask.getId(), existingMaskInitiators);
}
existingMaskInitiators.add(initiatorCopy);
// remove this from the list of initiators we'll make a new mask from
initiatorIter.remove();
}
}
}
}
}
} else {
// Insert this initiator into the mask's list of initiators managed by the system.
// This will get persisted below.
mask.addInitiator(initiator);
if (!NullColumnValueGetter.isNullURI(initiator.getHost())) {
hostToExistingExportMaskMap.put(initiator.getHost(), mask.getId());
}
}
// if it doesn't then we'll add it to the list of volumes to add.
for (URI boURI : volumeURIs) {
BlockObject bo = Volume.fetchExportMaskBlockObject(_dbClient, boURI);
if (bo != null && !mask.hasExistingVolume(bo) && !mask.hasUserAddedVolume(bo.getWWN())) {
_log.info(String.format("volume %s is not in mask %s", bo.getWWN(), mask.getMaskName()));
// The volume doesn't exist, so we have to add it to
// the masking container.
Map<URI, Integer> newVolumes = existingMasksToUpdateWithNewVolumes.get(mask.getId());
if (newVolumes == null) {
newVolumes = new HashMap<URI, Integer>();
existingMasksToUpdateWithNewVolumes.put(mask.getId(), newVolumes);
}
// Check if the requested HLU for the volume is
// already taken by a pre-existing volume.
Integer requestedHLU = volumeMap.get(boURI);
StringMap existingVolumesInMask = mask.getExistingVolumes();
if (existingVolumesInMask != null && requestedHLU.intValue() != ExportGroup.LUN_UNASSIGNED && !ExportGroup.LUN_UNASSIGNED_DECIMAL_STR.equals(requestedHLU.toString()) && existingVolumesInMask.containsValue(requestedHLU.toString())) {
ExportOrchestrationTask completer = new ExportOrchestrationTask(exportGroup.getId(), token);
ServiceError serviceError = DeviceControllerException.errors.exportHasExistingVolumeWithRequestedHLU(boURI.toString(), requestedHLU.toString());
completer.error(_dbClient, serviceError);
return false;
}
newVolumes.put(bo.getId(), requestedHLU);
mask.addToUserCreatedVolumes(bo);
}
}
// Update the list of volumes and initiators for the mask
Map<URI, Integer> volumeMapForExistingMask = existingMasksToUpdateWithNewVolumes.get(mask.getId());
if (volumeMapForExistingMask != null && !volumeMapForExistingMask.isEmpty()) {
mask.addVolumes(volumeMapForExistingMask);
}
Set<Initiator> initiatorSetForExistingMask = existingMasksToUpdateWithNewInitiators.get(mask.getId());
if (initiatorSetForExistingMask != null && initiatorSetForExistingMask.isEmpty()) {
mask.addInitiators(initiatorSetForExistingMask);
}
updateZoningMap(exportGroup, mask);
_dbClient.updateAndReindexObject(mask);
// TODO: All export group modifications should be moved to completers
exportGroup.addExportMask(mask.getId());
_dbClient.updateAndReindexObject(exportGroup);
}
}
// The initiatorURIsCopy was used in the foreach initiator loop to see
// which initiators already exist in a mask. If it is non-empty,
// then it means there are initiators that are new,
// so let's add them to the main tracker
Map<URI, List<URI>> hostInitiatorMap = new HashMap<URI, List<URI>>();
if (!initiatorURIsCopy.isEmpty()) {
for (URI newExportMaskInitiator : initiatorURIsCopy) {
Initiator initiator = _dbClient.queryObject(Initiator.class, newExportMaskInitiator);
List<URI> initiatorSet = hostInitiatorMap.get(initiator.getHost());
if (initiatorSet == null) {
initiatorSet = new ArrayList<URI>();
hostInitiatorMap.put(initiator.getHost(), initiatorSet);
}
initiatorSet.add(initiator.getId());
_log.info(String.format("host = %s, " + "initiators to add: %d, " + "existingMasksToUpdateWithNewVolumes.size = %d", initiator.getHost(), hostInitiatorMap.get(initiator.getHost()).size(), existingMasksToUpdateWithNewVolumes.size()));
}
}
_log.info(String.format("existingMasksToUpdateWithNewVolumes.size = %d", existingMasksToUpdateWithNewVolumes.size()));
String attachGroupSnapshot = checkForSnapshotsToCopyToTarget(workflow, storage, previousStep, volumeMap, existingMasksToUpdateWithNewVolumes.values());
// and/or add volumes to existing masks.
if (!hostInitiatorMap.isEmpty()) {
for (URI hostID : hostInitiatorMap.keySet()) {
// associated with that host to the list
if (hostToExistingExportMaskMap.containsKey(hostID)) {
URI existingExportMaskURI = hostToExistingExportMaskMap.get(hostID);
Set<Initiator> toAddInits = new HashSet<Initiator>();
List<URI> hostInitaitorList = hostInitiatorMap.get(hostID);
for (URI initURI : hostInitaitorList) {
Initiator initiator = _dbClient.queryObject(Initiator.class, initURI);
if (!initiator.getInactive()) {
toAddInits.add(initiator);
}
}
_log.info(String.format("Need to add new initiators to existing mask %s, %s", existingExportMaskURI.toString(), Joiner.on(',').join(hostInitaitorList)));
existingMasksToUpdateWithNewInitiators.put(existingExportMaskURI, toAddInits);
continue;
}
// We have some brand new initiators, let's add them to new masks
_log.info(String.format("new export masks %s", Joiner.on(",").join(hostInitiatorMap.get(hostID))));
generateExportMaskCreateWorkflow(workflow, attachGroupSnapshot, storage, exportGroup, hostInitiatorMap.get(hostID), volumeMap, token);
}
}
Map<URI, String> stepMap = new HashMap<URI, String>();
for (Map.Entry<URI, Map<URI, Integer>> entry : existingMasksToUpdateWithNewVolumes.entrySet()) {
ExportMask mask = _dbClient.queryObject(ExportMask.class, entry.getKey());
Map<URI, Integer> volumesToAdd = entry.getValue();
_log.info(String.format("adding these volumes %s to mask %s", Joiner.on(",").join(volumesToAdd.keySet()), mask.getMaskName()));
stepMap.put(entry.getKey(), generateExportMaskAddVolumesWorkflow(workflow, attachGroupSnapshot, storage, exportGroup, mask, volumesToAdd, null));
}
for (Entry<URI, Set<Initiator>> entry : existingMasksToUpdateWithNewInitiators.entrySet()) {
ExportMask mask = _dbClient.queryObject(ExportMask.class, entry.getKey());
Set<Initiator> initiatorsToAdd = entry.getValue();
List<URI> initiatorsURIs = new ArrayList<URI>();
for (Initiator initiator : initiatorsToAdd) {
initiatorsURIs.add(initiator.getId());
}
_log.info(String.format("adding these initiators %s to mask %s", Joiner.on(",").join(initiatorsURIs), mask.getMaskName()));
previousStep = stepMap.get(entry.getKey()) == null ? attachGroupSnapshot : stepMap.get(entry.getKey());
generateExportMaskAddInitiatorsWorkflow(workflow, previousStep, storage, exportGroup, mask, initiatorsURIs, null, token);
}
}
return true;
}
use of com.emc.storageos.db.client.model.Initiator in project coprhd-controller by CoprHD.
the class HDSExportOperations method updateHSDInfoInExportMask.
/**
* Updates the HSD information in the ExportMask.
*
* @param exportMask
* @param hostInitiators
* @param matchedHSDs
*/
private void updateHSDInfoInExportMask(ExportMask exportMask, Set<URI> hostInitiators, Set<HostStorageDomain> matchedHSDs, StorageSystem storage, Map<String, Set<URI>> matchingMasks) {
StringBuilder builder = new StringBuilder();
if (null != matchedHSDs && !matchedHSDs.isEmpty()) {
StringSetMap deviceDataMapEntries = new StringSetMap();
for (HostStorageDomain matchedHSD : matchedHSDs) {
List<String> initiatorsExistsOnHSD = getInitiatorsExistsOnHSD(matchedHSD.getWwnList(), matchedHSD.getIscsiList());
// volume Map['volume Id'] = lun
Map<String, Integer> volumesExistsOnHSD = getExportedVolumes(matchedHSD.getPathList(), storage);
log.info("Current list of Volumes exists on this HSD: {}", volumesExistsOnHSD);
builder.append(String.format("XM:%s I:{%s} V:{%s}%n", matchedHSD.getObjectID(), Joiner.on(',').join(initiatorsExistsOnHSD), Joiner.on(',').join(volumesExistsOnHSD.keySet())));
// Update deviceDataMap in ExportMask with HSD information.
updateDeviceDataMapInExportMask(exportMask, matchedHSD, storage, deviceDataMapEntries);
List<String> storagePorts = Arrays.asList(matchedHSD.getPortID());
List<String> storagePortURIs = getStoragePortURIs(storagePorts, storage);
if (null != exportMask.getStoragePorts() && !exportMask.getStoragePorts().isEmpty()) {
// Add the storage ports if they already exist on
// exportmask.
exportMask.getStoragePorts().addAll(storagePortURIs);
} else {
exportMask.setStoragePorts(storagePortURIs);
}
String maskName = (null == matchedHSD.getName()) ? matchedHSD.getNickname() : matchedHSD.getName();
exportMask.setMaskName(maskName);
exportMask.addToExistingVolumesIfAbsent(volumesExistsOnHSD);
exportMask.addToExistingInitiatorsIfAbsent(initiatorsExistsOnHSD);
List<Initiator> initiatorList = new ArrayList<>();
if (!CollectionUtils.isEmpty(initiatorsExistsOnHSD)) {
for (String port : initiatorsExistsOnHSD) {
Initiator existingInitiator = ExportUtils.getInitiator(Initiator.toPortNetworkId(port), dbClient);
if (existingInitiator != null && !existingInitiator.getInactive()) {
initiatorList.add(existingInitiator);
}
}
}
exportMask.addInitiators(initiatorList);
String strExistingInitiators = "";
String strExistingVolumes = "";
if (exportMask.getExistingInitiators() != null) {
strExistingInitiators = Joiner.on(',').join(exportMask.getExistingInitiators());
}
if (exportMask.getExistingVolumes() != null) {
strExistingVolumes = Joiner.on(',').join(exportMask.getExistingVolumes().keySet());
}
builder.append(String.format("XM is matching. " + "EI: { %s }, EV: { %s }\n", strExistingInitiators, strExistingVolumes));
}
exportMask.addDeviceDataMap(deviceDataMapEntries);
}
log.info(builder.toString());
}
use of com.emc.storageos.db.client.model.Initiator in project coprhd-controller by CoprHD.
the class CephStorageDevice method mapVolumes.
/**
* Map volumes to hosts on the hosts themselves.
*
* @param storage
* [in] - Storage System object
* @param volumeMap
* [in] - Volume URI to Integer LUN map
* @param initiators
* [in] - Collection of Initiator objects
* @param completer
* [in] - TaskCompleter
*/
private void mapVolumes(StorageSystem storage, Map<URI, Integer> volumeMap, Collection<Initiator> initiators, TaskCompleter completer) {
_log.info("mapVolumes: volumeMap: {}", volumeMap);
_log.info("mapVolumes: initiators: {}", initiators);
try {
for (Map.Entry<URI, Integer> volMapEntry : volumeMap.entrySet()) {
URI objectUri = volMapEntry.getKey();
BlockObject object = Volume.fetchExportMaskBlockObject(_dbClient, objectUri);
String monitorAddress = storage.getSmisProviderIP();
String monitorUser = storage.getSmisUserName();
String monitorKey = storage.getSmisPassword();
RBDMappingOptions rbdOptions = new RBDMappingOptions(object);
for (Initiator initiator : initiators) {
Host host = _dbClient.queryObject(Host.class, initiator.getHost());
if (initiator.getProtocol().equalsIgnoreCase(HostInterface.Protocol.RBD.name())) {
_log.info(String.format("mapVolume: host %s pool %s volume %s", host.getHostName(), rbdOptions.poolName, rbdOptions.volumeName));
LinuxSystemCLI linuxClient = getLinuxClient(host);
linuxClient.mapRBD(monitorAddress, monitorUser, monitorKey, rbdOptions.poolName, rbdOptions.volumeName, rbdOptions.snapshotName);
} else {
String msg = String.format("Unexpected initiator protocol %s, port %s, pool %s, volume %s", initiator.getProtocol(), initiator.getInitiatorPort(), rbdOptions.poolName, rbdOptions.volumeName);
ServiceCoded code = DeviceControllerErrors.ceph.operationFailed("mapVolumes", msg);
completer.error(_dbClient, code);
return;
}
}
}
completer.ready(_dbClient);
} catch (Exception e) {
_log.error("Encountered an exception", e);
ServiceCoded code = DeviceControllerErrors.ceph.operationFailed("mapVolumes", e.getMessage());
completer.error(_dbClient, code);
}
}
Aggregations