use of com.emc.storageos.volumecontroller.impl.VolumeURIHLU in project coprhd-controller by CoprHD.
the class CinderExportOperations method addVolumes.
@Override
public void addVolumes(StorageSystem storage, URI exportMaskId, VolumeURIHLU[] volumeURIHLUs, List<Initiator> initiatorList, TaskCompleter taskCompleter) throws DeviceControllerException {
log.info("{} addVolumes START...", storage.getSerialNumber());
try {
log.info("addVolumes: Export mask id: {}", exportMaskId);
log.info("addVolumes: volume-HLU pairs: {}", Joiner.on(',').join(volumeURIHLUs));
if (initiatorList != null) {
log.info("addVolumes: initiators impacted: {}", Joiner.on(',').join(initiatorList));
}
log.info("User assigned HLUs will be ignored as Cinder does not support it.");
ExportMask exportMask = dbClient.queryObject(ExportMask.class, exportMaskId);
List<Volume> volumes = new ArrayList<Volume>();
List<Initiator> maskInitiatorList = new ArrayList<Initiator>();
// map to store target LUN id generated for each volume
Map<URI, Integer> volumeToTargetLunMap = new HashMap<URI, Integer>();
StringMap initiators = exportMask.getUserAddedInitiators();
for (VolumeURIHLU volumeURIHLU : volumeURIHLUs) {
URI volumeURI = volumeURIHLU.getVolumeURI();
Volume volume = dbClient.queryObject(Volume.class, volumeURI);
volumes.add(volume);
}
for (String ini : initiators.values()) {
Initiator initiator = dbClient.queryObject(Initiator.class, URI.create(ini));
maskInitiatorList.add(initiator);
}
// Map to store volume to initiatorTargetMap
Map<Volume, Map<String, List<String>>> volumeToFCInitiatorTargetMap = new HashMap<Volume, Map<String, List<String>>>();
attachVolumesToInitiators(storage, volumes, maskInitiatorList, volumeToTargetLunMap, volumeToFCInitiatorTargetMap, exportMask);
// Update targets in the export mask
if (!volumeToFCInitiatorTargetMap.isEmpty()) {
updateTargetsInExportMask(storage, volumes.get(0), volumeToFCInitiatorTargetMap, maskInitiatorList, exportMask);
}
updateTargetLunIdInExportMask(volumeToTargetLunMap, exportMask);
dbClient.updateObject(exportMask);
taskCompleter.ready(dbClient);
} catch (final Exception ex) {
log.error("Problem in AddVolumes: ", ex);
ServiceError serviceError = DeviceControllerErrors.cinder.operationFailed("doAddVolumes", ex.getMessage());
taskCompleter.error(dbClient, serviceError);
}
log.info("{} addVolumes END...", storage.getSerialNumber());
}
use of com.emc.storageos.volumecontroller.impl.VolumeURIHLU in project coprhd-controller by CoprHD.
the class SmisCommandHelper method groupVolumesByStorageGroup.
/**
* Algo : FastPolicy F1 ---> V1, V2 FastPolicy F2 ---> V3, V4 Use case : Add these volumes to
* existing Storage Group S1. 1. Find out the child Groups for given parent Group S1. 2. For
* each child Group, if its associated with Fast, get its policy name. CH1 --->F1 Now the
* resultant group would be CH1--->V1,V2 3. After looping through all child Storage Groups, if
* you still didn't encounter F2, then it means we need to create a new Storage Group CH2 and
* associate with F2. 4. Final result would be Volumes get grouped by child Storage Group Names.
*
* @param storage
* storage system
* @param parentGroupName
* parent storage group name
* @param policyToVolumeMap
* map of FAST policy to volume objects
* @return group of storage group to volume objects
* @throws Exception
*/
public Map<String, Collection<VolumeURIHLU>> groupVolumesByStorageGroup(StorageSystem storage, String parentGroupName, DataSource sgDataSource, String sgCustomTemplateName, ListMultimap<StorageGroupPolicyLimitsParam, VolumeURIHLU> policyLimitsParamToVolumeGroup, CustomConfigHandler customConfigHandler) throws Exception {
Map<String, Collection<VolumeURIHLU>> volumeGroup = new HashMap<String, Collection<VolumeURIHLU>>();
CloseableIterator<CIMInstance> cimInstanceItr = null;
try {
boolean isVmax3 = storage.checkIfVmax3();
CIMObjectPath maskingGroupPath = _cimPath.getMaskingGroupPath(storage, parentGroupName, SmisCommandHelper.MASKING_GROUP_TYPE.SE_DeviceMaskingGroup);
// Make sure the policy matches ours, if so grab the volumes.
if (!isCascadedSG(storage, maskingGroupPath)) {
// TODO: Add VMAX3 check and get fast policy for VMAX3 volume.
String policyName = getAutoTieringPolicyNameAssociatedWithVolumeGroup(storage, maskingGroupPath);
volumeGroup.put(parentGroupName, new ArrayList<VolumeURIHLU>());
for (Entry<StorageGroupPolicyLimitsParam, Collection<VolumeURIHLU>> policyToVolumeEntry : policyLimitsParamToVolumeGroup.asMap().entrySet()) {
if (policyName != null && policyName.equalsIgnoreCase(Constants.NONE.toString())) {
policyName = null;
}
String volumePolicy = policyToVolumeEntry.getKey().getAutoTierPolicyName();
if (volumePolicy != null && volumePolicy.equalsIgnoreCase(Constants.NONE.toString())) {
volumePolicy = null;
}
if ((policyName == null && volumePolicy == null) || (policyName != null && policyName.equalsIgnoreCase(volumePolicy))) {
volumeGroup.get(parentGroupName).addAll(policyToVolumeEntry.getValue());
}
// We want to be in the map as well.
if (volumePolicy != null && policyName == null) {
volumeGroup.get(parentGroupName).addAll(policyToVolumeEntry.getValue());
}
}
if (!volumeGroup.get(parentGroupName).isEmpty()) {
_log.info("Storage Group {} is not a cascading group, hence grouping all volumes under parent group.", parentGroupName);
return volumeGroup;
}
}
_log.info("Trying to find child Storage Groups for given Parent Group {}", parentGroupName);
/**
* get list of child storage groups
*/
if (isVmax3) {
cimInstanceItr = getAssociatorInstances(storage, maskingGroupPath, null, SmisCommandHelper.MASKING_GROUP_TYPE.SE_DeviceMaskingGroup.name(), null, null, PS_V3_STORAGE_GROUP_PROPERTIES);
} else {
cimInstanceItr = getAssociatorInstances(storage, maskingGroupPath, null, SmisCommandHelper.MASKING_GROUP_TYPE.SE_DeviceMaskingGroup.name(), null, null, new String[] { CP_ELEMENT_NAME, EMC_MAX_BANDWIDTH, EMC_MAX_IO });
}
Set<StorageGroupPolicyLimitsParam> storageGroupPolicyLimitsParamSet = new HashSet<StorageGroupPolicyLimitsParam>();
/**
* Loop through each Storage Group, find if its associated with fast Policy, limit bandwidth, and limit IO.
* Try to look
* up the given policyToVolumeMap data, to find out the right storage group bucket for
* these volumes
*/
Map<String, Integer> preferedChildGroupMap = new HashMap<String, Integer>();
Map<StorageGroupPolicyLimitsParam, String> preferedPolicyLimitsParamToChildGroup = new HashMap<StorageGroupPolicyLimitsParam, String>();
while (cimInstanceItr.hasNext()) {
CIMInstance childGroupInstance = cimInstanceItr.next();
String groupName = CIMPropertyFactory.getPropertyValue(childGroupInstance, CP_ELEMENT_NAME);
/**
* Get the properties (policyName, Bandwidth,IOPS) associated with this Storage Group
*/
StorageGroupPolicyLimitsParam storageGroupPolicyLimitsParam = createStorageGroupPolicyLimitsParam(storage, childGroupInstance);
_log.info("Group Name {} is associated with Fast Policy : {}", groupName, storageGroupPolicyLimitsParam.getAutoTierPolicyName());
// Count the number of volumes in this group. Lowest number of volumes in the storage
// group for that child storage group wins.
Integer numVolumes = getVMAXStorageGroupVolumeCount(storage, groupName);
String policyLimitAttribute = storageGroupPolicyLimitsParam.toString();
// for that group name.
if ((preferedChildGroupMap.get(policyLimitAttribute) == null) || ((preferedChildGroupMap.get(policyLimitAttribute) != null) && (numVolumes < preferedChildGroupMap.get(policyLimitAttribute)))) {
preferedChildGroupMap.put(policyLimitAttribute, numVolumes);
preferedPolicyLimitsParamToChildGroup.put(storageGroupPolicyLimitsParam, groupName);
}
}
// Now place the volumes in the respective storage group.
for (StorageGroupPolicyLimitsParam storageGroupPolicyLimitsParam : preferedPolicyLimitsParamToChildGroup.keySet()) {
if (policyLimitsParamToVolumeGroup.containsKey(storageGroupPolicyLimitsParam) && !storageGroupPolicyLimitsParamSet.contains(storageGroupPolicyLimitsParam)) {
volumeGroup.put(preferedPolicyLimitsParamToChildGroup.get(storageGroupPolicyLimitsParam), policyLimitsParamToVolumeGroup.get(storageGroupPolicyLimitsParam));
storageGroupPolicyLimitsParamSet.add(storageGroupPolicyLimitsParam);
}
}
_log.info("Storage Group exists already for given volume's fast Policies -->{}", Joiner.on("\t").join(storageGroupPolicyLimitsParamSet));
Set<String> existingGroupNames = getExistingStorageGroupsFromArray(storage);
/**
* At this point, we have the list of the volume groups (FP + bandwidth+IOPS), which has a Storage Group.
* For the remaining volume groups, we need to create a new Storage Group.
*
* No changes needed
*/
for (Entry<StorageGroupPolicyLimitsParam, Collection<VolumeURIHLU>> policyToVolumeEntry : policyLimitsParamToVolumeGroup.asMap().entrySet()) {
StorageGroupPolicyLimitsParam storageGroupPolicyLimitsParam = policyToVolumeEntry.getKey();
if (!storageGroupPolicyLimitsParamSet.contains(storageGroupPolicyLimitsParam)) {
_log.debug("Policy {} to which new Storage Group needs to be created", storageGroupPolicyLimitsParam);
ListMultimap<String, VolumeURIHLU> expectedVolumeHluMap = ControllerUtils.getVolumeNativeGuids(policyToVolumeEntry.getValue(), _dbClient);
if (!StringUtils.equalsIgnoreCase(storageGroupPolicyLimitsParam.getAutoTierPolicyName(), Constants.NONE)) {
_log.info("Running Storage Group Selection Process to find out if any groups can be reused");
Map<String, Set<String>> existingReusableGroups = findAnyStorageGroupsCanBeReUsed(storage, expectedVolumeHluMap, storageGroupPolicyLimitsParam);
// add existing group names, use later to add these
// groups to parent Cascaded Group.
_log.info("Existing Reusable Storage Groups Found {}", Joiner.on("\t").join(existingReusableGroups.keySet()));
for (String group : existingReusableGroups.keySet()) {
volumeGroup.put(group, null);
}
// find out remaining volumes which doesn't have any
// groups to fit into
Set<String> volumesInReusableStorageGroups = constructVolumeNativeGuids(existingReusableGroups.values());
Set<String> volumesNotPartOfAnyGroup = Sets.difference(expectedVolumeHluMap.asMap().keySet(), volumesInReusableStorageGroups);
_log.debug("Volumes not part of any Existing Storage Groups {}", Joiner.on("\t").join(volumesNotPartOfAnyGroup));
// right storage groups
if (!volumesNotPartOfAnyGroup.isEmpty()) {
_log.info("Creating an new Volume Group for these Volumes");
VolumeURIHLU[] volumeURIHLU = ControllerUtils.constructVolumeUriHLUs(volumesNotPartOfAnyGroup, expectedVolumeHluMap);
sgDataSource.addProperty(CustomConfigConstants.AUTO_TIERING_POLICY_NAME, storageGroupPolicyLimitsParam.toString());
String storageGroupName = customConfigHandler.getComputedCustomConfigValue(sgCustomTemplateName, storage.getSystemType(), sgDataSource);
String generatedGroupName = generateGroupName(existingGroupNames, storageGroupName);
volumeGroup.put(generatedGroupName, Arrays.asList(volumeURIHLU));
}
} else {
// TODO check if this need to taken care off for VMAX3 as volumes will have policy name
_log.info("Creating a new Storage Group always, as non fast");
sgDataSource.addProperty(CustomConfigConstants.AUTO_TIERING_POLICY_NAME, StorageGroupPolicyLimitsParam.NON_FAST_POLICY);
String storageGroupName = customConfigHandler.getComputedCustomConfigValue(sgCustomTemplateName, storage.getSystemType(), sgDataSource);
String generatedGroupName = generateGroupName(existingGroupNames, storageGroupName);
volumeGroup.put(generatedGroupName, policyToVolumeEntry.getValue());
}
}
}
} finally {
closeCIMIterator(cimInstanceItr);
}
return volumeGroup;
}
use of com.emc.storageos.volumecontroller.impl.VolumeURIHLU in project coprhd-controller by CoprHD.
the class SmisCommandHelper method addVolumesToStorageGroup.
public void addVolumesToStorageGroup(VolumeURIHLU[] volumeURIHLUs, StorageSystem storage, String storageGroupName, SmisJob job, boolean forceFlag) throws Exception {
// The 'DeviceNumbers' parameter that's used in the AddMembers call
// needs to match up with the list of volumes in the 'Members'
// parameter. The containers here are used to make sure that happens.
List<URI> uriList = new ArrayList<>();
List<String> deviceNumberList = new ArrayList<>();
for (VolumeURIHLU volURIHlu : volumeURIHLUs) {
String hlu = volURIHlu.getHLU();
// LUN_UNASSIGNED value (as a hex string).
if (hlu != null && !hlu.equalsIgnoreCase(ExportGroup.LUN_UNASSIGNED_STR)) {
deviceNumberList.add(hlu);
}
uriList.add(volURIHlu.getVolumeURI());
}
String[] HLUs = (!deviceNumberList.isEmpty()) ? deviceNumberList.toArray(new String[deviceNumberList.size()]) : null;
CIMArgument[] inArgs = getAddVolumesToMaskingGroupInputArguments(storage, storageGroupName, uriList, HLUs, forceFlag);
CIMArgument[] outArgs = new CIMArgument[5];
invokeMethodSynchronously(storage, _cimPath.getControllerConfigSvcPath(storage), "AddMembers", inArgs, outArgs, job);
}
use of com.emc.storageos.volumecontroller.impl.VolumeURIHLU in project coprhd-controller by CoprHD.
the class SmisCommandHelper method createStorageGroupPolicyLimitsParam.
/**
* Construct a storage group policy limits object from a volumeURIHLU object.
*
* @param volumeUriHLUs
* @param dbClient
* @return
*/
public StorageGroupPolicyLimitsParam createStorageGroupPolicyLimitsParam(Collection<VolumeURIHLU> volumeUriHLUs, StorageSystem storage, DbClient dbClient) {
StorageGroupPolicyLimitsParam policyQuota = new StorageGroupPolicyLimitsParam(Constants.NONE);
for (VolumeURIHLU volumeUriHLU : volumeUriHLUs) {
String policyName = null;
if (storage.checkIfVmax3()) {
policyName = getVMAX3FastSettingForVolume(volumeUriHLU.getVolumeURI(), volumeUriHLU.getAutoTierPolicyName());
} else {
policyName = volumeUriHLU.getAutoTierPolicyName();
}
policyQuota = new StorageGroupPolicyLimitsParam(policyName, volumeUriHLU.getHostIOLimitBandwidth(), volumeUriHLU.getHostIOLimitIOPs(), storage);
break;
}
return policyQuota;
}
use of com.emc.storageos.volumecontroller.impl.VolumeURIHLU in project coprhd-controller by CoprHD.
the class ExportMaskOperationsHelper method setHLUFromProtocolControllersOnAddVolume.
/**
* This method is invoked specifically on AddVolumeToMaskingView jobs, which in turn
* gets HLU's for processed volumes alone.
*
* @param dbClient
* @param cimConnection
* @param exportMaskURI
* @param volumeURIHLUs
* @param volumePaths
* @param taskCompleter
* @throws DeviceControllerException
*/
public static void setHLUFromProtocolControllersOnAddVolume(DbClient dbClient, CimConnection cimConnection, URI exportMaskURI, VolumeURIHLU[] volumeURIHLUs, CIMObjectPath[] volumePaths, TaskCompleter taskCompleter) throws DeviceControllerException {
long startTime = System.currentTimeMillis();
boolean hasNullHLU = volumeURIHLUsHasNullHLU(volumeURIHLUs);
if (!hasNullHLU || volumePaths.length == 0) {
return;
}
try {
ExportMask mask = dbClient.queryObject(ExportMask.class, exportMaskURI);
Map<String, URI> deviceIdToURI = new HashMap<String, URI>();
for (VolumeURIHLU vuh : volumeURIHLUs) {
BlockObject volume = BlockObject.fetch(dbClient, vuh.getVolumeURI());
deviceIdToURI.put(volume.getNativeId(), volume.getId());
}
boolean requiresUpdate = false;
CloseableIterator<CIMInstance> protocolControllerForUnitIter;
for (CIMObjectPath volumePath : volumePaths) {
_log.info(String.format("setHLUFromProtocolControllers -- protocolController=%s", volumePath.toString()));
protocolControllerForUnitIter = null;
try {
protocolControllerForUnitIter = cimConnection.getCimClient().referenceInstances(volumePath, CIM_PROTOCOL_CONTROLLER_FOR_UNIT, null, false, PS_DEVICE_NUMBER);
while (protocolControllerForUnitIter.hasNext()) {
CIMInstance pcu = protocolControllerForUnitIter.next();
CIMObjectPath pcuPath = pcu.getObjectPath();
CIMObjectPath maskingViewPath = (CIMObjectPath) pcuPath.getKey(ANTECEDENT).getValue();
// Provider returns multiple references with same relationship , hence looking for class name
if (!maskingViewPath.toString().contains(LUNMASKING)) {
_log.info("Skipping CIMPath other than masking view path {}", pcuPath);
continue;
}
String deviceId = volumePath.getKey(CP_DEVICE_ID).getValue().toString();
URI volumeURI = deviceIdToURI.get(deviceId);
if (volumeURI != null) {
String deviceNumber = CIMPropertyFactory.getPropertyValue(pcu, CP_DEVICE_NUMBER);
_log.info(String.format("setHLUFromProtocolControllers -- volumeURI=%s --> %s", volumeURI.toString(), deviceNumber));
mask.addVolume(volumeURI, (int) Long.parseLong(deviceNumber, 16));
requiresUpdate = true;
}
}
} finally {
if (protocolControllerForUnitIter != null) {
protocolControllerForUnitIter.close();
}
}
}
if (requiresUpdate) {
dbClient.updateObject(mask);
}
} catch (Exception e) {
_log.error("Unexpected error: setHLUFromProtocolControllers failed.", e);
ServiceError error = DeviceControllerErrors.smis.methodFailed("setHLUFromProtocolControllers", e.getMessage());
taskCompleter.error(dbClient, error);
} finally {
long totalTime = System.currentTimeMillis() - startTime;
_log.info(String.format("setHLUFromProtocolControllersDuringAddVolume took %f seconds", (double) totalTime / (double) 1000));
}
}
Aggregations