use of com.emc.storageos.db.client.model.ExportMask in project coprhd-controller by CoprHD.
the class VnxExportOperations method removeVolumes.
/*
* (non-Javadoc)
*
* @see
* com.emc.storageos.volumecontroller.impl.smis.ExportMaskOperations#removeVolume(com.emc.storageos.db.client.model.
* StorageSystem, java.net.URI, java.util.List, com.emc.storageos.volumecontroller.TaskCompleter)
*
*/
@Override
public void removeVolumes(StorageSystem storage, URI exportMaskURI, List<URI> volumeURIList, List<Initiator> initiatorList, TaskCompleter taskCompleter) throws DeviceControllerException {
_log.info("{} removeVolumes START...", storage.getSerialNumber());
try {
_log.info("removeVolumes: Export mask id: {}", exportMaskURI);
_log.info("removeVolumes: volumes: {}", Joiner.on(',').join(volumeURIList));
if (initiatorList != null) {
_log.info("removeVolumes: impacted initiators: {}", Joiner.on(",").join(initiatorList));
}
boolean isRollback = WorkflowService.getInstance().isStepInRollbackState(taskCompleter.getOpId());
if (isRollback) {
_log.info("Handling removeVolumes as a result of rollback");
List<URI> addedVolumes = new ArrayList<URI>();
// Get the context from the task completer as this is a rollback.
ExportOperationContext context = (ExportOperationContext) WorkflowService.getInstance().loadStepData(taskCompleter.getOpId());
if (context != null && context.getOperations() != null) {
ListIterator li = context.getOperations().listIterator(context.getOperations().size());
while (li.hasPrevious()) {
ExportOperationContextOperation operation = (ExportOperationContextOperation) li.previous();
if (operation != null && VnxExportOperationContext.OPERATION_ADD_VOLUMES_TO_STORAGE_GROUP.equals(operation.getOperation())) {
addedVolumes = (List<URI>) operation.getArgs().get(0);
_log.info("Removing volumes {} as part of rollback", Joiner.on(',').join(addedVolumes));
}
}
}
volumeURIList = addedVolumes;
if (volumeURIList == null || volumeURIList.isEmpty()) {
_log.info("There was no context found for add volumes. So there is nothing to rollback.");
taskCompleter.ready(_dbClient);
return;
}
}
if (null == volumeURIList || volumeURIList.isEmpty()) {
taskCompleter.ready(_dbClient);
_log.warn("{} removeVolumes invoked with zero volumes, resulting in no-op....", storage.getSerialNumber());
return;
}
ExportMask exportMask = _dbClient.queryObject(ExportMask.class, exportMaskURI);
ExportMaskValidationContext ctx = new ExportMaskValidationContext();
ctx.setStorage(storage);
ctx.setExportMask(exportMask);
ctx.setInitiators(initiatorList);
ctx.setAllowExceptions(!isRollback);
validator.removeVolumes(ctx).validate();
String[] volumeNames = null;
volumeNames = _helper.getBlockObjectAlternateNames(volumeURIList);
/**
* This extra condition makes sure ViPR do not pass null as volume name while invoking HidePaths.
* If we pass null into HidePaths call, SMI will remove the entire storage group and that will give DU.
*/
if (volumeNames == null || volumeNames.length == 0) {
_log.error("Volume's {} alternate name can not be null", volumeURIList);
ServiceError error = DeviceControllerException.errors.removeVolumeFromMaskFailed(volumeURIList.toString());
taskCompleter.error(_dbClient, error);
} else {
deleteOrShrinkStorageGroup(storage, exportMaskURI, volumeURIList, null);
taskCompleter.ready(_dbClient);
}
} catch (Exception e) {
_log.error("Unexpected error: removeVolumes failed.", e);
ServiceError error = DeviceControllerErrors.smis.methodFailed("removeVolumes", e.getMessage());
taskCompleter.error(_dbClient, error);
}
_log.info("{} removeVolumes END...", storage.getSerialNumber());
}
use of com.emc.storageos.db.client.model.ExportMask in project coprhd-controller by CoprHD.
the class VnxExportOperations method findExportMasks.
/**
* This call can be used to look up the passed in initiator/port names and find (if
* any) to which export masks they belong on the 'storage' array.
*
* @param storage
* [in] - StorageSystem object representing the array
* @param initiatorNames
* [in] - Port identifiers (WWPN or iSCSI name)
* @param mustHaveAllPorts
* [in] NOT APPLICABLE FOR VNX
* @return Map of port name to Set of ExportMask URIs
*/
@Override
public Map<String, Set<URI>> findExportMasks(StorageSystem storage, List<String> initiatorNames, boolean mustHaveAllPorts) throws DeviceControllerException {
long startTime = System.currentTimeMillis();
Map<String, Set<URI>> matchingMasks = new HashMap<String, Set<URI>>();
CloseableIterator<CIMInstance> lunMaskingIter = null;
try {
StringBuilder builder = new StringBuilder();
WBEMClient client = _helper.getConnection(storage).getCimClient();
lunMaskingIter = _helper.getClarLunMaskingProtocolControllers(storage);
while (lunMaskingIter.hasNext()) {
CIMInstance instance = lunMaskingIter.next();
String systemName = CIMPropertyFactory.getPropertyValue(instance, SmisConstants.CP_SYSTEM_NAME);
if (!systemName.contains(storage.getSerialNumber())) {
// SMISProvider pointed to by 'storage' system.
continue;
}
String name = CIMPropertyFactory.getPropertyValue(instance, SmisConstants.CP_ELEMENT_NAME);
CIMProperty<String> deviceIdProperty = (CIMProperty<String>) instance.getObjectPath().getKey(SmisConstants.CP_DEVICE_ID);
// Get volumes and initiators for the masking instance
Map<String, Integer> volumeWWNs = _helper.getVolumesFromLunMaskingInstance(client, instance);
List<String> initiatorPorts = _helper.getInitiatorsFromLunMaskingInstance(client, instance);
// Find out if the port is in this masking container
List<String> matchingInitiators = new ArrayList<String>();
for (String port : initiatorNames) {
String normalizedName = Initiator.normalizePort(port);
if (initiatorPorts.contains(normalizedName)) {
matchingInitiators.add(normalizedName);
}
}
builder.append(String.format("%nXM:%s I:{%s} V:{%s}%n", name, Joiner.on(',').join(initiatorPorts), Joiner.on(',').join(volumeWWNs.keySet())));
if (!matchingInitiators.isEmpty()) {
// Look up ExportMask by deviceId/name and storage URI
ExportMask exportMask = ExportMaskUtils.getExportMaskByName(_dbClient, storage.getId(), name);
boolean foundMaskInDb = (exportMask != null);
// then create a new one
if (!foundMaskInDb) {
exportMask = new ExportMask();
exportMask.setMaskName(name);
exportMask.setNativeId(deviceIdProperty.getValue());
exportMask.setStorageDevice(storage.getId());
exportMask.setId(URIUtil.createId(ExportMask.class));
exportMask.setCreatedBySystem(false);
// Grab the storage ports that have been allocated for this
// existing mask and add them.
List<String> storagePorts = _helper.getStoragePortsFromLunMaskingInstance(client, instance);
List<String> storagePortURIs = ExportUtils.storagePortNamesToURIs(_dbClient, storagePorts);
exportMask.setStoragePorts(storagePortURIs);
builder.append(String.format(" ----> SP { %s }\n" + " URI{ %s }\n", Joiner.on(',').join(storagePorts), Joiner.on(',').join(storagePortURIs)));
} else {
// refresh the export mask
refreshExportMask(storage, exportMask);
builder.append('\n');
}
// Update the tracking containers
exportMask.addToExistingVolumesIfAbsent(volumeWWNs);
exportMask.addToExistingInitiatorsIfAbsent(matchingInitiators);
// Update the initiator list to include existing initiators if we know about them.
for (String port : matchingInitiators) {
Initiator existingInitiator = ExportUtils.getInitiator(Initiator.toPortNetworkId(port), _dbClient);
if (existingInitiator != null) {
exportMask.addInitiator(existingInitiator);
exportMask.addToUserCreatedInitiators(existingInitiator);
exportMask.removeFromExistingInitiators(existingInitiator);
}
}
// so, add them to the initiator list and remove them from existing as well.
for (String port : initiatorPorts) {
Initiator existingInitiator = ExportUtils.getInitiator(Initiator.toPortNetworkId(port), _dbClient);
if (existingInitiator != null && !ExportMaskUtils.checkIfDifferentResource(exportMask, existingInitiator)) {
exportMask.addInitiator(existingInitiator);
exportMask.addToUserCreatedInitiators(existingInitiator);
exportMask.removeFromExistingInitiators(existingInitiator);
}
}
// Update the volume list to include existing volumes if know about them.
if (volumeWWNs != null) {
for (String wwn : volumeWWNs.keySet()) {
URIQueryResultList results = new URIQueryResultList();
_dbClient.queryByConstraint(AlternateIdConstraint.Factory.getVolumeWwnConstraint(wwn.toUpperCase()), results);
if (results != null) {
Iterator<URI> resultsIter = results.iterator();
if (resultsIter.hasNext()) {
Volume volume = _dbClient.queryObject(Volume.class, resultsIter.next());
if (volume != null) {
Integer hlu = volumeWWNs.get(wwn);
if (hlu == null) {
_log.warn(String.format("The HLU for %s could not be found from the provider. Setting this to -1 (Unknown).", wwn));
hlu = -1;
}
exportMask.addVolume(volume.getId(), hlu);
exportMask.removeFromExistingVolumes(volume);
}
}
}
}
}
Set existingInitiators = (exportMask.getExistingInitiators() != null) ? exportMask.getExistingInitiators() : Collections.emptySet();
Set existingVolumes = (exportMask.getExistingVolumes() != null) ? exportMask.getExistingVolumes().keySet() : Collections.emptySet();
builder.append(String.format("XM:%s is matching. " + "EI: { %s }, EV: { %s }", name, Joiner.on(',').join(existingInitiators), Joiner.on(',').join(existingVolumes)));
if (foundMaskInDb) {
ExportMaskUtils.sanitizeExportMaskContainers(_dbClient, exportMask);
_dbClient.updateObject(exportMask);
} else {
_dbClient.createObject(exportMask);
}
for (String it : matchingInitiators) {
Set<URI> maskURIs = matchingMasks.get(it);
if (maskURIs == null) {
maskURIs = new HashSet<URI>();
matchingMasks.put(it, maskURIs);
}
maskURIs.add(exportMask.getId());
}
}
}
_log.info(builder.toString());
} catch (Exception e) {
String msg = "Error when attempting to query LUN masking information: " + e.getMessage();
_log.error(MessageFormat.format("Encountered an SMIS error when attempting to query existing exports: {0}", msg), e);
throw SmisException.exceptions.queryExistingMasksFailure(msg, e);
} finally {
if (lunMaskingIter != null) {
lunMaskingIter.close();
}
long totalTime = System.currentTimeMillis() - startTime;
_log.info(String.format("findExportMasks took %f seconds", (double) totalTime / (double) 1000));
}
return matchingMasks;
}
use of com.emc.storageos.db.client.model.ExportMask in project coprhd-controller by CoprHD.
the class ExportMaskUtils method initializeExportMaskWithVolumes.
// don't want to disturb the existing method, hence overloaded
public static <T extends BlockObject> ExportMask initializeExportMaskWithVolumes(URI storage, ExportGroup exportGroup, String maskName, String maskLabel, List<Initiator> initiators, Map<URI, Integer> volumeMap, List<URI> targets, ZoneInfoMap zoneInfoMap, T volume, Set<String> unManagedInitiators, String nativeId, List<Initiator> userAddedInis, DbClient dbClient, Map<String, Integer> wwnToHluMap) throws Exception {
ExportMask exportMask = new ExportMask();
exportMask.setId(URIUtil.createId(ExportMask.class));
exportMask.setMaskName(maskName);
exportMask.setStorageDevice(storage);
String resourceRef;
if (exportGroup.getType() != null) {
if (exportGroup.getType().equals(ExportGroup.ExportGroupType.Cluster.name())) {
resourceRef = initiators.get(0).getClusterName();
} else {
resourceRef = initiators.get(0).getHost().toString();
}
exportMask.setResource(resourceRef);
} else {
// This resource is used when we add initiators to existing masks on VMAX, which should not be
// case with VPLEX and RP, which do not associate their initiators with hosts or clusters.
exportMask.setResource(NullColumnValueGetter.getNullURI().toString());
}
exportMask.setLabel(maskLabel);
exportMask.setCreatedBySystem(true);
exportMaskUpdate(exportMask, null, initiators, targets);
StringSetMap zoneMap = getZoneMapFromZoneInfoMap(zoneInfoMap, initiators);
if (!zoneMap.isEmpty()) {
exportMask.setZoningMap(zoneMap);
}
exportMask.addToExistingInitiatorsIfAbsent(new ArrayList<String>(unManagedInitiators));
exportMask.addToUserCreatedInitiators(userAddedInis);
// if the block object is marked as internal, then add to existing volumes of the mask
if (volume.checkInternalFlags(Flag.PARTIALLY_INGESTED)) {
_log.info("Block object {} is marked internal. Adding to existing volumes of the mask {}", volume.getNativeGuid(), exportMask.getMaskName());
String hlu = ExportGroup.LUN_UNASSIGNED_STR;
if (wwnToHluMap.containsKey(volume.getWWN())) {
hlu = String.valueOf(wwnToHluMap.get(volume.getWWN()));
}
exportMask.addToExistingVolumesIfAbsent(volume, hlu);
} else {
exportMask.addToUserCreatedVolumes(volume);
exportMask.removeFromExistingVolumes(volume);
}
Integer hlu = wwnToHluMap.get(volume.getWWN()) != null ? wwnToHluMap.get(volume.getWWN()) : ExportGroup.LUN_UNASSIGNED;
exportMask.addVolume(volume.getId(), hlu);
exportMask.setNativeId(nativeId);
// need to sync up all remaining existing volumes
exportMask.addToExistingVolumesIfAbsent(wwnToHluMap);
// Update the FCZoneReferences if zoning is enables for the varray
updateFCZoneReferences(exportGroup, exportMask, volume, zoneInfoMap, initiators, dbClient);
return exportMask;
}
use of com.emc.storageos.db.client.model.ExportMask in project coprhd-controller by CoprHD.
the class ExportMaskUtils method getNewPaths.
/*
* Get new paths which are not in any of the export masks zoning maps from the given paths
*
* @param dbClient
* @param exportMasks
* @param maskURIs - OUTPUT the export masks URI list which have zoning map entries
* @param paths - new and retained paths
* @return - the new paths for the export masks
*/
public static Map<URI, List<URI>> getNewPaths(DbClient dbClient, List<ExportMask> exportMasks, List<URI> maskURIs, Map<URI, List<URI>> paths) {
Map<URI, List<URI>> newPaths = new HashMap<URI, List<URI>>();
StringSetMap allZoningMap = new StringSetMap();
for (ExportMask mask : exportMasks) {
StringSetMap map = mask.getZoningMap();
if (map != null && !map.isEmpty()) {
for (String init : map.keySet()) {
StringSet allPorts = allZoningMap.get(init);
if (allPorts == null) {
allPorts = new StringSet();
allZoningMap.put(init, allPorts);
}
allPorts.addAll(map.get(init));
}
maskURIs.add(mask.getId());
}
}
for (Map.Entry<URI, List<URI>> entry : paths.entrySet()) {
URI init = entry.getKey();
List<URI> entryPorts = entry.getValue();
StringSet zoningPorts = allZoningMap.get(init.toString());
if (zoningPorts != null && !zoningPorts.isEmpty()) {
List<URI> diffPorts = new ArrayList<URI>(Sets.difference(newHashSet(entryPorts), zoningPorts));
if (diffPorts != null && !diffPorts.isEmpty()) {
newPaths.put(init, diffPorts);
}
} else {
newPaths.put(init, entryPorts);
}
}
return newPaths;
}
use of com.emc.storageos.db.client.model.ExportMask in project coprhd-controller by CoprHD.
the class ExportMaskUtils method hasExportMaskForStorageAndVArray.
/**
* For a given export group and storage system, this will check wheather there are any export mask exists
* in storage system which matches export group and storage ports in VArray
*
* @param dbClient
* @param exportGroup
* @param storageURI
* @return
*/
public static boolean hasExportMaskForStorageAndVArray(DbClient dbClient, ExportGroup exportGroup, URI storageURI) {
Set<String> storagePortURIsAssociatedWithVArrayAndStorageArray = ExportMaskUtils.getStoragePortUrisAssociatedWithVarrayAndStorageArray(storageURI, exportGroup.getVirtualArray(), dbClient);
StringSet maskUriSet = exportGroup.getExportMasks();
if (maskUriSet != null) {
for (String maskUriString : maskUriSet) {
ExportMask mask = dbClient.queryObject(ExportMask.class, URI.create(maskUriString));
URI maskStorageURI = mask.getStorageDevice();
if (maskStorageURI.equals(storageURI)) {
for (String storagePort : mask.getStoragePorts()) {
if (storagePortURIsAssociatedWithVArrayAndStorageArray.contains(storagePort)) {
return true;
}
}
}
}
}
return false;
}
Aggregations