use of com.emc.storageos.volumecontroller.impl.VolumeURIHLU in project coprhd-controller by CoprHD.
the class ExternalDeviceExportOperations method prepareVolumes.
/**
* Prepare new driver volumes for driver export request (Ex. in context of create a new export mask,
* or add new volumes to the existing mask).
*
* @param storage
* storage sytem
* @param volumeURIHLUs
* mapping of volume uri to volume hlu
* @param driverVolumes
* driver volumes (output)
* @param driverVolumeToHLUMap
* map of driver volumes to hlu values
* @param volumeNativeIdToUriMap
* map of volume native id to uri
*/
private void prepareVolumes(StorageSystem storage, VolumeURIHLU[] volumeURIHLUs, List<StorageVolume> driverVolumes, Map<String, String> driverVolumeToHLUMap, Map<String, URI> volumeNativeIdToUriMap) {
for (VolumeURIHLU volumeURIHLU : volumeURIHLUs) {
URI volumeURI = volumeURIHLU.getVolumeURI();
BlockObject volume = (BlockObject) dbClient.queryObject(volumeURI);
StorageVolume driverVolume = createDriverVolume(storage, volume);
driverVolumes.add(driverVolume);
// We send volume lun number to driver in decimal format.
Integer decimalHLU;
if (volumeURIHLU.getHLU().equals(ExportGroup.LUN_UNASSIGNED_STR)) {
// cannot parse "ffffffff" with
// Integer.parseInt(volumeURIHLU.getHLU(),
// 16),
// got "NumberFormatException". Looks as
// Java error ???
decimalHLU = ExportGroup.LUN_UNASSIGNED;
} else {
decimalHLU = Integer.parseInt(volumeURIHLU.getHLU(), 16);
}
driverVolumeToHLUMap.put(driverVolume.getNativeId(), decimalHLU.toString());
volumeNativeIdToUriMap.put(driverVolume.getNativeId(), volumeURI);
}
log.info("prepareVolumes: volume-HLU pairs for driver: {}", driverVolumeToHLUMap);
}
use of com.emc.storageos.volumecontroller.impl.VolumeURIHLU in project coprhd-controller by CoprHD.
the class HDSExportOperations method getVolumeLunMap.
/**
* @param volumeURIHLUs
* @return
* @throws Exception
*/
private Map<String, String> getVolumeLunMap(String systemId, String hsdObjectID, VolumeURIHLU[] volumeURIHLUs, HDSApiExportManager exportMgr) throws Exception {
List<FreeLun> freeLunList = exportMgr.getFreeLUNInfo(systemId, hsdObjectID);
log.info("There are {} freeLUN's available for HSD Id {}", freeLunList.size(), hsdObjectID);
Map<String, String> volumeHLUMap = new HashMap<String, String>();
int i = 0;
String lun = null;
for (VolumeURIHLU volumeURIHLU : volumeURIHLUs) {
BlockObject volume = BlockObject.fetch(dbClient, volumeURIHLU.getVolumeURI());
if (null == volumeURIHLU.getHLU() || "-1".equalsIgnoreCase(volumeURIHLU.getHLU())) {
if (i < freeLunList.size()) {
FreeLun freeLun = freeLunList.get(i);
lun = freeLun.getLun();
log.info("HLU is unassigned for volume {} and assinging lun {} from array.", volumeURIHLU.getVolumeURI(), lun);
i++;
} else {
// received request to create more volumes than the free luns available on the array.
log.info("No free LUN's available on HSD {}", hsdObjectID);
throw HDSException.exceptions.unableToProcessRequestDueToUnavailableFreeLUNs();
}
} else {
log.info("HLU {} is assigned for volume {} and using the free lun from array.", volumeURIHLU.getHLU(), volumeURIHLU.getVolumeURI());
lun = volumeURIHLU.getHLU();
}
volumeHLUMap.put(volume.getNativeId(), lun);
}
return volumeHLUMap;
}
use of com.emc.storageos.volumecontroller.impl.VolumeURIHLU in project coprhd-controller by CoprHD.
the class HDSExportOperations method updateVolumeHLUInfo.
/**
* Updates the HLU information in the exportmask.
*
* @param volumeURIHLUs
* @param pathList
* @param exportMask
*/
private void updateVolumeHLUInfo(VolumeURIHLU[] volumeURIHLUs, List<Path> pathList, ExportMask exportMask) {
if (null != exportMask.getVolumes() && !exportMask.getVolumes().isEmpty()) {
Map<String, URI> deviceIdToURI = new HashMap<String, URI>();
Map<URI, Integer> hluMap = new HashMap<URI, Integer>();
for (VolumeURIHLU vuh : volumeURIHLUs) {
BlockObject volume = BlockObject.fetch(dbClient, vuh.getVolumeURI());
exportMask.addToUserCreatedVolumes(volume);
deviceIdToURI.put(volume.getNativeId(), volume.getId());
}
if (!deviceIdToURI.isEmpty()) {
for (Path path : pathList) {
if (deviceIdToURI.containsKey(path.getDevNum())) {
URI volumeURI = deviceIdToURI.get(path.getDevNum());
log.info("updating volume {} info in exportmask.", volumeURI);
hluMap.put(volumeURI, Integer.parseInt(path.getLun()));
}
}
exportMask.addVolumes(hluMap);
} else {
log.error("No HLU's found for the volumes.");
}
}
}
use of com.emc.storageos.volumecontroller.impl.VolumeURIHLU in project coprhd-controller by CoprHD.
the class HDSExportOperations method addInitiators.
@Override
public void addInitiators(StorageSystem storage, URI exportMaskURI, List<URI> volumeURIs, List<Initiator> initiators, List<URI> targetURIList, TaskCompleter taskCompleter) throws DeviceControllerException {
log.info("{} addInitiator START...", storage.getSerialNumber());
HDSApiClient hdsApiClient = null;
String systemObjectID = null;
List<HostStorageDomain> hsdsToCreate = null;
List<HostStorageDomain> hsdsWithInitiators = null;
try {
log.info("addInitiator: Export mask id: {}", exportMaskURI);
if (volumeURIs != null) {
log.info("addInitiator: volumes : {}", Joiner.on(',').join(volumeURIs));
}
log.info("addInitiator: initiators : {}", Joiner.on(',').join(initiators));
log.info("addInitiator: targets : {}", Joiner.on(",").join(targetURIList));
hdsApiClient = hdsApiFactory.getClient(HDSUtils.getHDSServerManagementServerInfo(storage), storage.getSmisUserName(), storage.getSmisPassword());
HDSApiExportManager exportMgr = hdsApiClient.getHDSApiExportManager();
systemObjectID = HDSUtils.getSystemObjectID(storage);
ExportMask exportMask = dbClient.queryObject(ExportMask.class, exportMaskURI);
List<StoragePort> ports = dbClient.queryObject(StoragePort.class, targetURIList, true);
if (checkIfMixedTargetPortTypeSelected(ports)) {
log.error("Unsupported Host as it has both FC & iSCSI Initiators");
throw HDSException.exceptions.unsupportedConfigurationFoundInHost();
}
// @TODO register new initiators by adding them to host on HiCommand DM.
// Currently, HiCommand is not supporting this. Need to see how we can handle.
String hostName = getHostNameForInitiators(initiators);
String hostMode = null, hostModeOption = null;
Pair<String, String> hostModeInfo = getHostModeInfo(storage, initiators);
if (hostModeInfo != null) {
hostMode = hostModeInfo.first;
hostModeOption = hostModeInfo.second;
}
if (targetURIList != null && !targetURIList.isEmpty()) {
Set<URI> newTargetPorts = new HashSet<>(targetURIList);
Set<URI> existingTargetPortsInMask = new HashSet<>();
if (exportMask.getStoragePorts() != null) {
existingTargetPortsInMask = new HashSet<>(targetURIList);
Collection<URI> targetPorts = Collections2.transform(exportMask.getStoragePorts(), CommonTransformerFunctions.FCTN_STRING_TO_URI);
existingTargetPortsInMask.retainAll(targetPorts);
}
newTargetPorts.removeAll(existingTargetPortsInMask);
log.info("list of new storage target ports {}", newTargetPorts);
log.info("list of existing storage target ports available in export masks {}", existingTargetPortsInMask);
// Case 1 is handled here for the new initiators & new target ports.
if (!newTargetPorts.isEmpty()) {
// If the HLU's are already configured on this target port, then an exception is thrown.
// User should make sure that all volumes should have same HLU across all target HSD's.
VolumeURIHLU[] volumeURIHLUs = getVolumeURIHLUFromExportMask(exportMask);
if (0 < volumeURIHLUs.length) {
List<URI> portList = new ArrayList<>(newTargetPorts);
hsdsToCreate = processTargetPortsToFormHSDs(hdsApiClient, storage, portList, hostName, exportMask, hostModeInfo, systemObjectID);
// Step 1: Create all HSD's using batch operation.
List<HostStorageDomain> hsdResponseList = hdsApiClient.getHDSBatchApiExportManager().addHostStorageDomains(systemObjectID, hsdsToCreate, storage.getModel());
if (null == hsdResponseList || hsdResponseList.isEmpty()) {
log.error("Batch HSD creation failed to add new initiators. Aborting operation...");
throw HDSException.exceptions.notAbleToAddHSD(storage.getSerialNumber());
}
// Step 2: Add initiators to all HSD's.
Iterator<StoragePort> storagePortIterator = dbClient.queryIterativeObjects(StoragePort.class, newTargetPorts);
List<StoragePort> stPortList = new ArrayList<>();
while (storagePortIterator.hasNext()) {
StoragePort stPort = storagePortIterator.next();
if (stPort != null && !stPort.getInactive()) {
stPortList.add(stPort);
}
}
hsdsWithInitiators = executeBatchHSDAddInitiatorsCommand(hdsApiClient, systemObjectID, hsdResponseList, stPortList, initiators, storage.getModel());
// Step 3: Add volumes to all HSD's.
List<Path> allHSDPaths = executeBatchHSDAddVolumesCommand(hdsApiClient, systemObjectID, hsdsWithInitiators, volumeURIHLUs, storage.getModel());
if (null != allHSDPaths && !allHSDPaths.isEmpty()) {
updateExportMaskDetailInDB(hsdsWithInitiators, allHSDPaths, exportMask, storage, volumeURIHLUs);
}
} else {
log.info("There are no volumes on this exportmask: {} to add to new initiator", exportMaskURI);
}
}
// existing HSD to access the volumes already exported in the exportmask.
if (!existingTargetPortsInMask.isEmpty()) {
// Step 1: Collect all HSDs from export mask
StringSetMap deviceDataMap = exportMask.getDeviceDataMap();
if (null != deviceDataMap && !deviceDataMap.isEmpty()) {
List<HostStorageDomain> hsdResponseList = new ArrayList<>();
Set<String> hsdObjectIdSet = deviceDataMap.keySet();
for (String hsdObjectId : hsdObjectIdSet) {
HostStorageDomain hsd = exportMgr.getHostStorageDomain(systemObjectID, hsdObjectId);
if (null == hsd) {
throw HDSException.exceptions.notAbleToFindHostStorageDomain(hsdObjectId);
}
hsdResponseList.add(hsd);
}
// Step 2: Add initiators to all HSD's.
Iterator<StoragePort> storagePortIterator = dbClient.queryIterativeObjects(StoragePort.class, existingTargetPortsInMask, true);
List<StoragePort> stPortList = new ArrayList<>();
while (storagePortIterator.hasNext()) {
StoragePort stPort = storagePortIterator.next();
if (stPort != null) {
stPortList.add(stPort);
}
}
hsdsWithInitiators = executeBatchHSDAddInitiatorsCommand(hdsApiClient, systemObjectID, hsdResponseList, stPortList, initiators, storage.getModel());
} else {
log.info("There are no hsd information in exportMask to add initiators");
}
}
}
taskCompleter.ready(dbClient);
} catch (Exception ex) {
try {
log.info("Exception occurred while adding new initiators: {}", ex.getMessage());
if (null != hsdsWithInitiators && !hsdsWithInitiators.isEmpty()) {
hdsApiClient.getHDSBatchApiExportManager().deleteBatchHostStorageDomains(systemObjectID, hsdsWithInitiators, storage.getModel());
} else {
if (null != hsdsToCreate && !hsdsToCreate.isEmpty()) {
List<HostStorageDomain> allHSDs = hdsApiClient.getHDSApiExportManager().getHostStorageDomains(systemObjectID);
List<HostStorageDomain> partialHSDListToRemove = getPartialHSDListToDelete(allHSDs, hsdsToCreate);
hdsApiClient.getHDSBatchApiExportManager().deleteBatchHostStorageDomains(systemObjectID, partialHSDListToRemove, storage.getModel());
}
}
log.error(String.format("addInitiator failed - maskURI: %s", exportMaskURI.toString()), ex);
} catch (Exception ex1) {
log.error("Exception occurred while deleting unsuccessful HSDs on system: {}", systemObjectID, ex1.getMessage());
} finally {
ServiceError serviceError = DeviceControllerException.errors.jobFailedOpMsg(ResourceOperationTypeEnum.ADD_EXPORT_INITIATOR.getName(), ex.getMessage());
taskCompleter.error(dbClient, serviceError);
}
}
log.info("{} addInitiator END...", storage.getSerialNumber());
}
use of com.emc.storageos.volumecontroller.impl.VolumeURIHLU in project coprhd-controller by CoprHD.
the class VnxExportOperations method createOrGrowStorageGroup.
private CIMObjectPath[] createOrGrowStorageGroup(StorageSystem storage, URI exportMaskURI, VolumeURIHLU[] volumeURIHLUs, List<Initiator> initiatorList, List<URI> targetURIList, TaskCompleter completer) throws Exception {
// TODO - Refactor createOrGrowStorageGroup by moving code for creating an empty storage group
// to its own createStorageGroup method which calls exposePaths with null for initiators
// and targets
_log.info("{} createOrGrowStorageGroup START...", storage.getSerialNumber());
try {
List<CIMObjectPath> paths = new ArrayList<CIMObjectPath>();
Map<String, CIMObjectPath> existingHwStorageIds = getStorageHardwareIds(storage);
// If so, we need to register that initiator as the same name as the existing initiators. (CTRL-8407)
if (initiatorList != null) {
for (Initiator initiator : initiatorList) {
updateInitiatorBasedOnPeers(storage, existingHwStorageIds, initiator);
if (initiator != null) {
_log.info("After updateIntiatorBasedOnPeers : {} {}", initiator.getHostName(), initiator.toString());
}
}
}
Multimap<String, String> existingTargets = createStorageHWIDs(storage, existingHwStorageIds, initiatorList, completer);
if (initiatorList != null && existingTargets.keySet().size() == initiatorList.size()) {
_log.info(String.format("All the initiators are known to the array and have target endpoints: %s\n." + "These are the targets %s", Joiner.on(',').join(existingTargets.entries()), Joiner.on(',').join(targetURIList)));
}
Multimap<URI, Initiator> targetPortsToInitiators = HashMultimap.create();
// Some of the Initiators are already registered partially on the array based on pre existing zoning
// COP-16954 We need to manually register them, the Initiators will have HardwareId created but,
// The registration is not complete.. createHardwareIDs method above will include those Initiators
_log.info("Preregistered Target and Initiator ports processing .. Start");
// Map to hash translations
HashMap<String, URI> targetPortMap = new HashMap<>();
for (String initPort : existingTargets.keySet()) {
_log.info("InitiatorPort {} and TargetStoragePort {}", initPort, existingTargets.get(initPort));
// CLARIION+CKM00115001014+PORT+50:06:01:61:3E:A0:45:79]
if (!WWNUtility.isValidNoColonWWN(initPort)) {
_log.info("InitiatorPort {} is not a valid FC WWN so ignore it", initPort);
continue;
}
Collection<String> targetPorts = existingTargets.get(initPort);
for (String targetPortGuid : targetPorts) {
URI targetPortURI = targetPortMap.get(targetPortGuid);
if (targetPortURI == null) {
targetPortURI = getStoragePortURI(targetPortGuid);
targetPortMap.put(targetPortGuid, targetPortURI);
}
Initiator translatedInitiator = getInitiatorForWWN(initPort);
_log.info("Calculating Initiator {} and Target {}", translatedInitiator, targetPortURI);
if (targetPortURI != null && translatedInitiator != null) {
targetPortsToInitiators.put(targetPortURI, translatedInitiator);
} else {
_log.info("Initiator WWN {} translation was null or targetPort is null {}", initPort, targetPortURI);
}
}
}
_log.info("Preregistered Target and Initiator ports processing .. End");
List<URI> volumeURIs = new ArrayList<URI>();
if (volumeURIHLUs != null && volumeURIHLUs.length > 0) {
for (VolumeURIHLU volumeURIHLU : volumeURIHLUs) {
volumeURIs.add(volumeURIHLU.getVolumeURI());
}
}
if (initiatorList == null || initiatorList.isEmpty()) {
_log.info("InitiatorList is null or Empty so call exposePathsWithVolumesOnly");
paths.addAll(Arrays.asList(exposePathsWithVolumesOnly(storage, exportMaskURI, volumeURIHLUs)));
} else {
ExportMask mask = _dbClient.queryObject(ExportMask.class, exportMaskURI);
for (Initiator initiator : initiatorList) {
// TODO - Ask Tom is there is a reason why we should not do this instead of old code
List<URI> tzTargets = ExportUtils.getInitiatorPortsInMask(mask, initiator, _dbClient);
_log.info("Calculating Intiator {} and Targets {}", initiator, tzTargets);
if (!tzTargets.isEmpty()) {
for (URI targetURI : tzTargets) {
targetPortsToInitiators.put(targetURI, initiator);
}
}
}
_log.info("Call manuallyRegisterHostInitiators with {} ", targetPortsToInitiators.toString());
// Register the initiator to target port mappings
manuallyRegisterHostInitiators(storage, targetPortsToInitiators);
// CTRL-9086
// Modify the list of initiators list to match what is being mapped. If there are any initiators
// that are passed to the ExposePaths call that weren't manuallyRegistered (above), then those
// initiators will automatically get mapped all the array's StoragePorts.
//
// If the targetPortsToInitiators MultiMap is empty, then we will send all the initiators.
// Presumably, in this situation there are already some existing mappings for the initiators,
// so would just need to call ExposePaths with those initiators, so that they get added to the
// StorageGroup
List<Initiator> initiatorsToExpose = initiatorList;
if (!targetPortsToInitiators.isEmpty()) {
Map<URI, Initiator> uniqueInitiatorMap = new HashMap<>();
for (Collection<Initiator> initiatorCollection : targetPortsToInitiators.asMap().values()) {
for (Initiator initiator : initiatorCollection) {
uniqueInitiatorMap.put(initiator.getId(), initiator);
}
}
initiatorsToExpose = new ArrayList<>(uniqueInitiatorMap.values());
// confused about the initiators.
if (completer instanceof ExportMaskCreateCompleter) {
ExportMaskCreateCompleter createCompleter = ((ExportMaskCreateCompleter) completer);
List<URI> removedInitiators = new ArrayList<>();
List<URI> maskInitiators = StringSetUtil.stringSetToUriList(mask.getInitiators());
for (URI maskInitiator : maskInitiators) {
if (!uniqueInitiatorMap.containsKey(maskInitiator)) {
mask.removeInitiator(maskInitiator);
removedInitiators.add(maskInitiator);
}
}
_dbClient.updateObject(mask);
if (!removedInitiators.isEmpty()) {
_log.info(String.format("The following initiators will not be mapped, hence they will be " + "removed from the initiator list of ExportMask %s (%s): %s", mask.getMaskName(), mask.getId(), Joiner.on(',').join(removedInitiators)));
}
// Adjust the completer's initiator list
createCompleter.removeInitiators(removedInitiators);
}
}
_log.info(String.format("ExposePaths will be called with these initiators: %s", Joiner.on(',').join(Collections2.transform(initiatorsToExpose, CommonTransformerFunctions.fctnInitiatorToPortName()))));
// Add all the initiators to the StorageGroup
paths.addAll(Arrays.asList(exposePathsWithVolumesAndInitiatorsOnly(storage, exportMaskURI, volumeURIHLUs, initiatorsToExpose)));
}
ExportOperationContext.insertContextOperation(completer, VnxExportOperationContext.OPERATION_ADD_VOLUMES_TO_STORAGE_GROUP, volumeURIs);
_log.info("{} createOrGrowStorageGroup END...", storage.getSerialNumber());
return paths.toArray(new CIMObjectPath[paths.size()]);
} catch (WBEMException e) {
_log.error("Problem making SMI-S call: ", e);
throw e;
} catch (Exception e) {
_log.error("Unexpected error: createOrGrowStorageGroup failed.", e);
throw e;
}
}
Aggregations