Search in sources :

Example 31 with VolumeURIHLU

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());
}
Also used : ServiceError(com.emc.storageos.svcs.errorhandling.model.ServiceError) StringMap(com.emc.storageos.db.client.model.StringMap) HashMap(java.util.HashMap) ExportMask(com.emc.storageos.db.client.model.ExportMask) ArrayList(java.util.ArrayList) URI(java.net.URI) DeviceControllerException(com.emc.storageos.exceptions.DeviceControllerException) Volume(com.emc.storageos.db.client.model.Volume) Initiator(com.emc.storageos.db.client.model.Initiator) ArrayList(java.util.ArrayList) List(java.util.List) HashMap(java.util.HashMap) Map(java.util.Map) StringSetMap(com.emc.storageos.db.client.model.StringSetMap) StringMap(com.emc.storageos.db.client.model.StringMap) VolumeURIHLU(com.emc.storageos.volumecontroller.impl.VolumeURIHLU)

Example 32 with VolumeURIHLU

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;
}
Also used : Set(java.util.Set) HashSet(java.util.HashSet) StringSet(com.emc.storageos.db.client.model.StringSet) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) CIMObjectPath(javax.cim.CIMObjectPath) CIMInstance(javax.cim.CIMInstance) Collection(java.util.Collection) StorageGroupPolicyLimitsParam(com.emc.storageos.volumecontroller.impl.StorageGroupPolicyLimitsParam) VolumeURIHLU(com.emc.storageos.volumecontroller.impl.VolumeURIHLU) HashSet(java.util.HashSet)

Example 33 with VolumeURIHLU

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);
}
Also used : ArrayList(java.util.ArrayList) URI(java.net.URI) VolumeURIHLU(com.emc.storageos.volumecontroller.impl.VolumeURIHLU) CIMArgument(javax.cim.CIMArgument)

Example 34 with VolumeURIHLU

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;
}
Also used : StorageGroupPolicyLimitsParam(com.emc.storageos.volumecontroller.impl.StorageGroupPolicyLimitsParam) VolumeURIHLU(com.emc.storageos.volumecontroller.impl.VolumeURIHLU)

Example 35 with VolumeURIHLU

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));
    }
}
Also used : ServiceError(com.emc.storageos.svcs.errorhandling.model.ServiceError) HashMap(java.util.HashMap) ExportMask(com.emc.storageos.db.client.model.ExportMask) CIMObjectPath(javax.cim.CIMObjectPath) URI(java.net.URI) CIMInstance(javax.cim.CIMInstance) DeviceControllerException(com.emc.storageos.exceptions.DeviceControllerException) BlockObject(com.emc.storageos.db.client.model.BlockObject) VolumeURIHLU(com.emc.storageos.volumecontroller.impl.VolumeURIHLU)

Aggregations

VolumeURIHLU (com.emc.storageos.volumecontroller.impl.VolumeURIHLU)35 URI (java.net.URI)26 ArrayList (java.util.ArrayList)22 BlockObject (com.emc.storageos.db.client.model.BlockObject)19 ExportMask (com.emc.storageos.db.client.model.ExportMask)18 DeviceControllerException (com.emc.storageos.exceptions.DeviceControllerException)17 ServiceError (com.emc.storageos.svcs.errorhandling.model.ServiceError)14 HashMap (java.util.HashMap)14 HashSet (java.util.HashSet)13 CIMObjectPath (javax.cim.CIMObjectPath)13 Initiator (com.emc.storageos.db.client.model.Initiator)9 WBEMException (javax.wbem.WBEMException)9 AlternateIdConstraint (com.emc.storageos.db.client.constraint.AlternateIdConstraint)8 StorageGroupPolicyLimitsParam (com.emc.storageos.volumecontroller.impl.StorageGroupPolicyLimitsParam)7 CIMInstance (javax.cim.CIMInstance)7 Volume (com.emc.storageos.db.client.model.Volume)6 ContainmentConstraint (com.emc.storageos.db.client.constraint.ContainmentConstraint)5 StringSet (com.emc.storageos.db.client.model.StringSet)5 SmisException (com.emc.storageos.volumecontroller.impl.smis.SmisException)5 URIQueryResultList (com.emc.storageos.db.client.constraint.URIQueryResultList)4