Search in sources :

Example 21 with VPlexRecommendation

use of com.emc.storageos.volumecontroller.VPlexRecommendation in project coprhd-controller by CoprHD.

the class RecoverPointScheduler method buildRpRecommendation.

/**
 * Construct RP Recommendation object
 *
 * @param associatedStorageSystem - Associated Storage System
 * @param varray - Virtual Array
 * @param vpool - Virtual Pool
 * @param sourcePool - Storage Pool
 * @param capabilities - VirtualPool capabilities
 * @param satisfiedSourceVolCount - resource count
 * @param sourceInternalSiteName - Internal site name
 * @param sourceStorageSytemUri - Storage System URI
 * @param type - StorageSystem Type
 * @param ps - Protection System
 * @return a fully formed RP Recommendation object
 */
private RPRecommendation buildRpRecommendation(String associatedStorageSystem, VirtualArray varray, VirtualPool vpool, StoragePool sourcePool, VirtualPoolCapabilityValuesWrapper capabilities, int satisfiedSourceVolCount, String sourceInternalSiteName, URI sourceStorageSytemUri, String type, ProtectionSystem ps) {
    RPRecommendation rpRecommendation = new RPRecommendation();
    rpRecommendation.setRpSiteAssociateStorageSystem(associatedStorageSystem);
    rpRecommendation.setSourceStoragePool(sourcePool.getId());
    rpRecommendation.setSourceStorageSystem(sourcePool.getStorageDevice());
    rpRecommendation.setResourceCount(satisfiedSourceVolCount);
    rpRecommendation.setVirtualArray(varray.getId());
    rpRecommendation.setVirtualPool(vpool);
    rpRecommendation.setInternalSiteName(sourceInternalSiteName);
    rpRecommendation.setSize(capabilities.getSize());
    // VPLEX will consume this to create the virtual volumes.
    if (DiscoveredDataObject.Type.vplex.name().equals(type)) {
        VPlexRecommendation virtualVolumeRecommendation = new VPlexRecommendation();
        virtualVolumeRecommendation.setVirtualArray(rpRecommendation.getVirtualArray());
        virtualVolumeRecommendation.setVirtualPool(rpRecommendation.getVirtualPool());
        virtualVolumeRecommendation.setVPlexStorageSystem((sourceStorageSytemUri));
        virtualVolumeRecommendation.setSourceStoragePool(sourcePool.getId());
        virtualVolumeRecommendation.setSourceStorageSystem(sourcePool.getStorageDevice());
        // Always force count to 1 for a VPLEX rec for RP. VPLEX uses
        // these recs and they are invoked one at a time even
        // in a multi-volume request.
        virtualVolumeRecommendation.setResourceCount(1);
        rpRecommendation.setVirtualVolumeRecommendation(virtualVolumeRecommendation);
    }
    return rpRecommendation;
}
Also used : VPlexRecommendation(com.emc.storageos.volumecontroller.VPlexRecommendation) RPRecommendation(com.emc.storageos.volumecontroller.RPRecommendation)

Example 22 with VPlexRecommendation

use of com.emc.storageos.volumecontroller.VPlexRecommendation in project coprhd-controller by CoprHD.

the class RecoverPointScheduler method getAllHARecommendations.

/**
 * Gets all the HA placement recommendations.
 *
 * @param srcVarray The source virtual array
 * @param srcVpool The source virtual pool
 * @param requestedHaVarray The requested highly available virtual array
 * @param haVpool The highly available virtual pool
 * @param capabilities The virtual pool capabilities
 * @param vplexPoolMapForSrcVarray The source virtual array, VPlex connected storage pools
 * @param srcStorageSystem The selected VPlex source leg storage system
 * @param isRpTarget true if the request is specific to a RecoverPoint target, false otherwise
 *
 * @return A list of VPlexRecommendation instances specifying the
 *         HA recommended resource placement resources
 */
protected List<Recommendation> getAllHARecommendations(VirtualArray srcVarray, VirtualPool srcVpool, VirtualArray requestedHaVarray, VirtualPool haVpool, VirtualPoolCapabilityValuesWrapper capabilities, Map<String, List<StoragePool>> vplexPoolMapForSrcVarray) {
    _log.info("Executing VPlex high availability placement strategy");
    // Initialize the list of recommendations.
    List<Recommendation> recommendations = new ArrayList<Recommendation>();
    // The list of potential VPlex storage systems.
    Set<String> vplexStorageSystemIds = vplexPoolMapForSrcVarray.keySet();
    _log.info(String.format("%s VPlex storage systems have matching pools", vplexStorageSystemIds.size()));
    // For an HA request, get the possible high availability varrays
    // for each potential VPlex storage system.
    Map<String, List<String>> vplexHaVarrayMap = ConnectivityUtil.getVPlexVarrays(dbClient, vplexStorageSystemIds, srcVarray.getId());
    // passed VirtualPool is use.
    if (haVpool == null) {
        haVpool = srcVpool;
    }
    _log.info(String.format("Requested HA varray is %s", (requestedHaVarray != null ? requestedHaVarray.getId() : "not specified")));
    // Loop over the potential VPlex storage systems, and attempt
    // to place the resources.
    Iterator<String> vplexSystemIdsIter = vplexStorageSystemIds.iterator();
    while (vplexSystemIdsIter.hasNext()) {
        String vplexStorageSystemId = vplexSystemIdsIter.next();
        _log.info(String.format("Check matching pools for VPlex %s", vplexStorageSystemId));
        // pools for this VPlex storage system.
        if (VirtualPool.ProvisioningType.Thin.toString().equalsIgnoreCase(srcVpool.getSupportedProvisioningType())) {
            capabilities.put(VirtualPoolCapabilityValuesWrapper.THIN_PROVISIONING, Boolean.TRUE);
        }
        // Otherwise we now have to see if there is an HA varray
        // for the VPlex that also contains pools suitable to place
        // the resources.
        List<String> vplexHaVarrayIds = vplexHaVarrayMap.get(vplexStorageSystemId);
        _log.info(String.format("Found %s HA varrays", vplexHaVarrayIds.size()));
        for (String vplexHaVarrayId : vplexHaVarrayIds) {
            _log.info(String.format("Check HA varray %s", vplexHaVarrayId));
            // varray is not it, then skip the varray.
            if ((requestedHaVarray != null) && (!vplexHaVarrayId.equals(requestedHaVarray.getId().toString()))) {
                _log.info("Not the requested HA varray, skip");
                continue;
            }
            // Get all storage pools that match the passed VirtualPool params,
            // and this HA VirtualArray. In addition, the
            // pool must have enough capacity to hold at least one
            // resource of the requested size.
            VirtualArray vplexHaVarray = dbClient.queryObject(VirtualArray.class, URI.create(vplexHaVarrayId));
            Map<String, Object> attributeMap = new HashMap<String, Object>();
            List<StoragePool> allMatchingPoolsForHaVarray = vplexScheduler.getMatchingPools(vplexHaVarray, null, haVpool, capabilities, attributeMap);
            _log.info(String.format("Found %s matching pools for HA varray", allMatchingPoolsForHaVarray.size()));
            // Now from the list of candidate pools, we only want pools
            // on storage systems that are connected to the VPlex
            // storage system. We find these storage pools and associate
            // them to the VPlex storage systems to which their storage
            // system is connected.
            Map<String, List<StoragePool>> vplexPoolMapForHaVarray = vplexScheduler.sortPoolsByVPlexStorageSystem(allMatchingPoolsForHaVarray, vplexHaVarrayId);
            // If the HA varray has candidate pools for this
            // VPlex, see if the candidate pools in this HA
            // varray are sufficient to place the resources.
            List<Recommendation> recommendationsForHaVarray = new ArrayList<Recommendation>();
            if (vplexPoolMapForHaVarray.containsKey(vplexStorageSystemId)) {
                _log.info(String.format("Found matching pools in HA varray for VPlex %s", vplexStorageSystemId));
                if (VirtualPool.ProvisioningType.Thin.toString().equalsIgnoreCase(haVpool.getSupportedProvisioningType())) {
                    capabilities.put(VirtualPoolCapabilityValuesWrapper.THIN_PROVISIONING, Boolean.TRUE);
                }
                recommendationsForHaVarray = blockScheduler.getRecommendationsForPools(vplexHaVarray.getId().toString(), vplexPoolMapForHaVarray.get(vplexStorageSystemId), capabilities);
            } else {
                _log.info(String.format("No matching pools in HA varray for VPlex %s", vplexStorageSystemId));
            }
            // the source and HA varrays.
            if (!recommendationsForHaVarray.isEmpty()) {
                _log.info("Matching pools in HA varray sufficient for placement.");
                recommendations.addAll(vplexScheduler.createVPlexRecommendations(vplexStorageSystemId, vplexHaVarray, haVpool, recommendationsForHaVarray));
            }
            // varrays for this VPlex.
            if (!recommendations.isEmpty() || (requestedHaVarray != null)) {
                _log.info("Done trying to place resource for VPlex.");
                break;
            }
        }
    }
    return recommendations;
}
Also used : VirtualArray(com.emc.storageos.db.client.model.VirtualArray) StoragePool(com.emc.storageos.db.client.model.StoragePool) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) VPlexRecommendation(com.emc.storageos.volumecontroller.VPlexRecommendation) Recommendation(com.emc.storageos.volumecontroller.Recommendation) RPRecommendation(com.emc.storageos.volumecontroller.RPRecommendation) RPProtectionRecommendation(com.emc.storageos.volumecontroller.RPProtectionRecommendation) List(java.util.List) ArrayList(java.util.ArrayList) URIQueryResultList(com.emc.storageos.db.client.constraint.URIQueryResultList) DiscoveredDataObject(com.emc.storageos.db.client.model.DiscoveredDataObject)

Example 23 with VPlexRecommendation

use of com.emc.storageos.volumecontroller.VPlexRecommendation in project coprhd-controller by CoprHD.

the class VPlexScheduler method createVPlexRecommendations.

/**
 * Sets the Id of the VPlex storage system into the passed recommendations.
 *
 * @param vplexStorageSystemId The id of the VPlex storage system.
 * @param varray The varray for the recommendation.
 * @param vpool The vpool for the recommendation.
 * @param recommendations The list of recommendations.
 */
protected List<VPlexRecommendation> createVPlexRecommendations(String vplexStorageSystemId, VirtualArray varray, VirtualPool vpool, List<Recommendation> recommendations) {
    List<VPlexRecommendation> vplexRecommendations = new ArrayList<VPlexRecommendation>();
    for (Recommendation recommendation : recommendations) {
        VPlexRecommendation vplexRecommendation = new VPlexRecommendation();
        vplexRecommendation.setSourceStorageSystem(recommendation.getSourceStorageSystem());
        vplexRecommendation.setSourceStoragePool(recommendation.getSourceStoragePool());
        vplexRecommendation.setResourceCount(recommendation.getResourceCount());
        // vplexRecommendation.setSourceDevice(URI.create(vplexStorageSystemId));
        vplexRecommendation.setVPlexStorageSystem(URI.create(vplexStorageSystemId));
        vplexRecommendation.setVirtualArray(varray.getId());
        vplexRecommendation.setVirtualPool(vpool);
        vplexRecommendations.add(vplexRecommendation);
    }
    return vplexRecommendations;
}
Also used : VPlexRecommendation(com.emc.storageos.volumecontroller.VPlexRecommendation) ArrayList(java.util.ArrayList) Recommendation(com.emc.storageos.volumecontroller.Recommendation) VPlexRecommendation(com.emc.storageos.volumecontroller.VPlexRecommendation)

Example 24 with VPlexRecommendation

use of com.emc.storageos.volumecontroller.VPlexRecommendation in project coprhd-controller by CoprHD.

the class VPlexScheduler method scheduleStorageForDistributedVPLEXVolume.

/**
 * Get recommendations for resource placement for distributed VLPEX volumes.
 *
 * @param srcVarray The virtual array in which the resources were requested.
 * @param requestedVPlexSystems The URIs of the VPlex systems to which
 *            placement should be limited, or null when it doesn't matter.
 * @param srcStorageSystem The URI of a specific backend storage system to
 *            which the source resource should be limited, or null when it
 *            doesn't matter.
 * @param srcVpool The virtual pool requested for the source resources.
 * @param haVarray The desired HA varray.
 * @param haVpool The virtual pool for the HA resources.
 * @param capabilities The virtual pool capabilities.
 *
 * @return A list of VPlexRecommendation instances specifying the
 *         recommended resource placement.
 */
private List<Recommendation> scheduleStorageForDistributedVPLEXVolume(VirtualArray srcVarray, Set<URI> requestedVPlexSystems, URI srcStorageSystem, VirtualPool srcVpool, VirtualArray haVarray, VirtualPool haVpool, VirtualPoolCapabilityValuesWrapper capabilities, Project project, VpoolUse srcVpoolUse, Map<VpoolUse, List<Recommendation>> currentRecommendations) {
    _log.info("Executing VPLEX high availability placement strategy for Distributed VPLEX Volumes.");
    // Initialize the list of recommendations.
    List<Recommendation> recommendations = new ArrayList<Recommendation>();
    // of the StorageSystemsMatcher.
    if (srcStorageSystem != null) {
        StorageSystem sourceStorageSystem = _dbClient.queryObject(StorageSystem.class, srcStorageSystem);
        capabilities.put(VirtualPoolCapabilityValuesWrapper.SOURCE_STORAGE_SYSTEM, sourceStorageSystem);
    }
    // Call the lower level scheduler to get its recommendations.
    Scheduler nextScheduler = _placementManager.getNextScheduler(SCHEDULER_NAME, srcVpool, srcVpoolUse);
    _log.info(String.format("Calling next scheduler: %s", nextScheduler.getClass().getSimpleName()));
    List<Recommendation> baseRecommendations = nextScheduler.getRecommendationsForVpool(srcVarray, project, srcVpool, srcVpoolUse, capabilities, currentRecommendations);
    _log.info(String.format("Received %d recommendations from %s", baseRecommendations.size(), nextScheduler.getClass().getSimpleName()));
    if (baseRecommendations.isEmpty()) {
        throw BadRequestException.badRequests.noVplexLocalRecommendationFromSubScheduler(nextScheduler.getClass().getSimpleName(), srcVpool.getLabel(), srcVarray.getLabel());
    }
    _log.info(String.format("Received %d recommendations from %s", baseRecommendations.size(), nextScheduler.getClass().getSimpleName()));
    List<StoragePool> allMatchingPoolsForSrcVarray = _placementManager.getStoragePoolsFromRecommendations(baseRecommendations);
    _log.info("Found {} matching pools for source varray", allMatchingPoolsForSrcVarray.size());
    URI cgURI = capabilities.getBlockConsistencyGroup();
    BlockConsistencyGroup cg = (cgURI == null ? null : _dbClient.queryObject(BlockConsistencyGroup.class, cgURI));
    // Sort the matching pools for the source varray by VPLEX system.
    Map<String, List<StoragePool>> vplexPoolMapForSrcVarray = getVPlexConnectedMatchingPools(srcVarray, requestedVPlexSystems, capabilities, allMatchingPoolsForSrcVarray);
    if (vplexPoolMapForSrcVarray.isEmpty()) {
        _log.info("No matching pools on storage systems connected to a VPLEX");
        // and there are none for that VPlex system.
        return recommendations;
    }
    // Get all storage pools that match the passed HA VirtualPool params,
    // and HA virtual array. In addition, the pool must have enough
    // capacity to hold at least one resource of the requested size.
    _log.info("Getting all matching pools for HA varray {}", haVarray.getId());
    URI haStorageSystem = null;
    VirtualPoolCapabilityValuesWrapper haCapabilities = new VirtualPoolCapabilityValuesWrapper(capabilities);
    // Don't look for SRDF in the HA side.
    haCapabilities.put(VirtualPoolCapabilityValuesWrapper.PERSONALITY, null);
    // We don't require that the HA side have the same storage controller.
    haCapabilities.put(VirtualPoolCapabilityValuesWrapper.BLOCK_CONSISTENCY_GROUP, null);
    Map<String, Object> attributeMap = new HashMap<String, Object>();
    List<StoragePool> allMatchingPoolsForHaVarray = getMatchingPools(haVarray, haStorageSystem, haVpool, haCapabilities, attributeMap);
    if (allMatchingPoolsForHaVarray.isEmpty()) {
        StringBuffer errorMessage = new StringBuffer();
        if (attributeMap.get(AttributeMatcher.ERROR_MESSAGE) != null) {
            errorMessage = (StringBuffer) attributeMap.get(AttributeMatcher.ERROR_MESSAGE);
        }
        throw BadRequestException.badRequests.noMatchingHighAvailabilityStoragePools(haVpool.getLabel(), haVarray.getLabel(), errorMessage.toString());
    }
    _log.info("Found {} matching pools for HA varray", allMatchingPoolsForHaVarray.size());
    // Sort the matching pools for the HA varray by VPLEX system.
    Map<String, List<StoragePool>> vplexPoolMapForHaVarray = sortPoolsByVPlexStorageSystem(allMatchingPoolsForHaVarray, haVarray.getId().toString());
    if (vplexPoolMapForHaVarray.isEmpty()) {
        _log.info("No matching pools on storage systems connected to a VPlex");
        // on storage systems connected to a VPlex storage system.
        return recommendations;
    }
    // Get the list of potential VPlex storage systems for the source
    // virtual array.
    Set<String> vplexStorageSystemIds = vplexPoolMapForSrcVarray.keySet();
    _log.info("{} VPlex storage systems have matching pools", vplexStorageSystemIds.size());
    // Get the possible high availability varrays for each of these
    // potential VPlex storage system.
    Map<String, List<String>> vplexHaVarrayMap = ConnectivityUtil.getVPlexVarrays(_dbClient, vplexStorageSystemIds, srcVarray.getId());
    // Loop over the potential VPlex storage systems, and attempt
    // to place the resources.
    Iterator<String> vplexSystemIdsIter = vplexStorageSystemIds.iterator();
    while ((vplexSystemIdsIter.hasNext()) && (recommendations.isEmpty())) {
        String vplexStorageSystemId = vplexSystemIdsIter.next();
        _log.info("Attempting placement on VPlex {}", vplexStorageSystemId);
        // Check if this VPLEX can satisfy the requested HA varray.
        List<String> vplexHaVarrays = vplexHaVarrayMap.get(vplexStorageSystemId);
        if (!vplexHaVarrays.contains(haVarray.getId().toString())) {
            // It cannot, try the next VPLEX.
            continue;
        }
        // Check if there are HA storage pools for this VPLEX.
        if (!vplexPoolMapForHaVarray.containsKey(vplexStorageSystemId)) {
            // There are no HA pools for this VPLEX, try the next.
            continue;
        }
        // Check if the resource can be placed on the matching
        // pools for this VPlex storage system in the source varray.
        List<Recommendation> recommendationsForSrcVarray = new ArrayList<Recommendation>();
        recommendationsForSrcVarray.addAll(createVPlexRecommendations(baseRecommendations, vplexStorageSystemId, srcVarray, srcVpool));
        if (recommendationsForSrcVarray.isEmpty()) {
            _log.info("Matching pools for source varray insufficient for placement");
            // not sufficient, so we need to try another VPlex.
            continue;
        }
        // Get the storage systems specified by these recommendations.
        // We don't want to use these same storage systems on the HA
        // side when the same system is available to both, else you
        // could create a distributed volume with both backend volumes
        // on the same physical array.
        Set<URI> recommendedSrcSystems = new HashSet<URI>();
        for (Recommendation recommendation : recommendationsForSrcVarray) {
            recommendedSrcSystems.add(recommendation.getSourceStorageSystem());
        }
        // Remove any storage pools on these systems from the list of
        // matching pools for the HA varray for this VPLEX system.
        boolean haPoolsLimitedBySrcSelections = false;
        List<StoragePool> vplexPoolsForHaVarray = new ArrayList<StoragePool>(vplexPoolMapForHaVarray.get(vplexStorageSystemId));
        Iterator<StoragePool> vplexPoolsForHaVarrayIter = vplexPoolsForHaVarray.iterator();
        while (vplexPoolsForHaVarrayIter.hasNext()) {
            StoragePool haPool = vplexPoolsForHaVarrayIter.next();
            URI poolSystem = haPool.getStorageDevice();
            if (recommendedSrcSystems.contains(poolSystem)) {
                _log.info("Removing pool {} on system {} from consideration for HA placement", haPool.getId(), poolSystem);
                vplexPoolsForHaVarrayIter.remove();
                haPoolsLimitedBySrcSelections = true;
            }
        }
        // Now check if the resource can be placed on the matching
        // pools for this VPlex storage system in the HA varray.
        List<Recommendation> recommendationsForHaVarray = getRecommendationsForPools(haVarray.getId().toString(), haVpool, vplexPoolsForHaVarray, capabilities);
        if (recommendationsForHaVarray.isEmpty()) {
            _log.info("Matching pools for HA varray insufficient for placement");
            if (haPoolsLimitedBySrcSelections) {
                // If we limited the pools on the HA side and failed to place,
                // then let's reverse and use all pools on the HA side and limit
                // the source side. This is certainly not perfect, but at least
                // will try and use the pools on both sides before giving up.
                recommendationsForHaVarray = getRecommendationsForPools(haVarray.getId().toString(), haVpool, vplexPoolMapForHaVarray.get(vplexStorageSystemId), capabilities);
                if (recommendationsForHaVarray.isEmpty()) {
                    // Still can't place them on the HA side.
                    _log.info("Matching pools for HA varray still insufficient for placement");
                    continue;
                } else {
                    // Remove the systems from the source side and see
                    // if the source side can still be placed when limited.
                    _log.info("Matching pools for HA varray now sufficient for placement");
                }
            } else {
                // not sufficient, so we need to try another VPlex.
                continue;
            }
        }
        // We have recommendations for pools in both the source and HA varrays.
        recommendations.addAll(recommendationsForSrcVarray);
        recommendations.addAll(createVPlexRecommendations(vplexStorageSystemId, haVarray, haVpool, recommendationsForHaVarray));
        _log.info("Done trying to place resources for VPlex.");
        break;
    }
    _placementManager.logRecommendations("VPLEX Distributed", recommendations);
    return recommendations;
}
Also used : VirtualPoolCapabilityValuesWrapper(com.emc.storageos.volumecontroller.impl.utils.VirtualPoolCapabilityValuesWrapper) StoragePool(com.emc.storageos.db.client.model.StoragePool) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) URI(java.net.URI) ArrayList(java.util.ArrayList) List(java.util.List) StorageSystem(com.emc.storageos.db.client.model.StorageSystem) HashSet(java.util.HashSet) Recommendation(com.emc.storageos.volumecontroller.Recommendation) VPlexRecommendation(com.emc.storageos.volumecontroller.VPlexRecommendation) BlockConsistencyGroup(com.emc.storageos.db.client.model.BlockConsistencyGroup)

Aggregations

VPlexRecommendation (com.emc.storageos.volumecontroller.VPlexRecommendation)24 ArrayList (java.util.ArrayList)21 Recommendation (com.emc.storageos.volumecontroller.Recommendation)17 VirtualArray (com.emc.storageos.db.client.model.VirtualArray)15 VirtualPool (com.emc.storageos.db.client.model.VirtualPool)15 URI (java.net.URI)15 List (java.util.List)15 NamedURI (com.emc.storageos.db.client.model.NamedURI)13 StorageSystem (com.emc.storageos.db.client.model.StorageSystem)13 Project (com.emc.storageos.db.client.model.Project)11 StoragePool (com.emc.storageos.db.client.model.StoragePool)11 SRDFCopyRecommendation (com.emc.storageos.volumecontroller.SRDFCopyRecommendation)11 VirtualPoolCapabilityValuesWrapper (com.emc.storageos.volumecontroller.impl.utils.VirtualPoolCapabilityValuesWrapper)11 StringSet (com.emc.storageos.db.client.model.StringSet)10 SRDFRecommendation (com.emc.storageos.volumecontroller.SRDFRecommendation)10 Volume (com.emc.storageos.db.client.model.Volume)8 FCTN_STRING_TO_URI (com.emc.storageos.db.client.util.CommonTransformerFunctions.FCTN_STRING_TO_URI)8 FCTN_VPLEX_MIRROR_TO_URI (com.emc.storageos.db.client.util.CommonTransformerFunctions.FCTN_VPLEX_MIRROR_TO_URI)8 RPRecommendation (com.emc.storageos.volumecontroller.RPRecommendation)8 VolumeRecommendation (com.emc.storageos.api.service.impl.placement.VolumeRecommendation)7