Search in sources :

Example 66 with VirtualArray

use of com.emc.storageos.db.client.model.VirtualArray in project coprhd-controller by CoprHD.

the class RecoverPointScheduler method cgPoolsHaveAvailableCapacity.

/**
 * Computes if the existing storage pools used have sufficient capacity to satisfy the placement request
 *
 * @param sourceVolume The Source volume to use for the capacity checks
 * @param capabilities Capabilities reference
 * @param vpool The vpool being used
 * @param protectionVarrays The protection Varrays of the vpool
 * @return true if capacity is available, false otherwise.
 */
private boolean cgPoolsHaveAvailableCapacity(Volume sourceVolume, VirtualPoolCapabilityValuesWrapper capabilities, VirtualPool vpool, List<VirtualArray> protectionVarrays) {
    boolean cgPoolsHaveAvailableCapacity = true;
    Map<URI, Long> storagePoolRequiredCapacity = new HashMap<URI, Long>();
    Map<URI, StoragePool> storagePoolCache = new HashMap<URI, StoragePool>();
    // Keep a map with some extra info in it so the logs have a better description of
    // why we can't reuse a particular pool.
    Map<URI, String> storagePoolErrorDetail = new HashMap<URI, String>();
    _log.info(String.format("Checking if the existing storage pools used have sufficient capacity to satisfy the placement request..."));
    if (sourceVolume != null) {
        // TODO: need to update code below to look like the stuff Bharath added for multiple resources
        long sourceVolumesRequiredCapacity = getSizeInKB(capabilities.getSize() * capabilities.getResourceCount());
        if (RPHelper.isVPlexVolume(sourceVolume, dbClient)) {
            if (null == sourceVolume.getAssociatedVolumes() || sourceVolume.getAssociatedVolumes().isEmpty()) {
                _log.error("VPLEX volume {} has no backend volumes.", sourceVolume.forDisplay());
                throw InternalServerErrorException.internalServerErrors.noAssociatedVolumesForVPLEXVolume(sourceVolume.forDisplay());
            }
            for (String backingVolumeId : sourceVolume.getAssociatedVolumes()) {
                Volume backingVolume = dbClient.queryObject(Volume.class, URI.create(backingVolumeId));
                StoragePool backingVolumePool = dbClient.queryObject(StoragePool.class, backingVolume.getPool());
                storagePoolCache.put(backingVolumePool.getId(), backingVolumePool);
                updateStoragePoolRequiredCapacityMap(storagePoolRequiredCapacity, backingVolumePool.getId(), sourceVolumesRequiredCapacity);
                storagePoolErrorDetail.put(backingVolumePool.getId(), sourceVolume.getPersonality());
            }
        } else {
            StoragePool sourcePool = dbClient.queryObject(StoragePool.class, sourceVolume.getPool());
            storagePoolCache.put(sourcePool.getId(), sourcePool);
            updateStoragePoolRequiredCapacityMap(storagePoolRequiredCapacity, sourcePool.getId(), sourceVolumesRequiredCapacity);
            storagePoolErrorDetail.put(sourcePool.getId(), sourceVolume.getPersonality());
        }
        List<Volume> sourceJournals = RPHelper.findExistingJournalsForCopy(dbClient, sourceVolume.getConsistencyGroup(), sourceVolume.getRpCopyName());
        Volume sourceJournal = sourceJournals.get(0);
        if (sourceJournal == null) {
            _log.error(String.format("No existing source journal found in CG [%s] for copy [%s], returning false", sourceVolume.getConsistencyGroup(), sourceVolume.getRpCopyName()));
            throw APIException.badRequests.unableToFindSuitableJournalRecommendation();
        }
        long sourceJournalSizePerPolicy = RPHelper.getJournalSizeGivenPolicy(String.valueOf(capabilities.getSize()), vpool.getJournalSize(), capabilities.getResourceCount());
        long sourceJournalVolumesRequiredCapacity = getSizeInKB(sourceJournalSizePerPolicy);
        if (RPHelper.isVPlexVolume(sourceJournal, dbClient)) {
            for (String backingVolumeId : sourceJournal.getAssociatedVolumes()) {
                Volume backingVolume = dbClient.queryObject(Volume.class, URI.create(backingVolumeId));
                StoragePool backingVolumePool = dbClient.queryObject(StoragePool.class, backingVolume.getPool());
                storagePoolCache.put(backingVolumePool.getId(), backingVolumePool);
                updateStoragePoolRequiredCapacityMap(storagePoolRequiredCapacity, backingVolumePool.getId(), sourceJournalVolumesRequiredCapacity);
                storagePoolErrorDetail.put(backingVolumePool.getId(), sourceVolume.getPersonality() + " " + sourceJournal.getPersonality());
            }
        } else {
            StoragePool sourceJournalPool = dbClient.queryObject(StoragePool.class, sourceJournal.getPool());
            storagePoolCache.put(sourceJournalPool.getId(), sourceJournalPool);
            updateStoragePoolRequiredCapacityMap(storagePoolRequiredCapacity, sourceJournalPool.getId(), sourceJournalVolumesRequiredCapacity);
            storagePoolErrorDetail.put(sourceJournalPool.getId(), sourceVolume.getPersonality() + " " + sourceJournal.getPersonality());
        }
        if (sourceVolume.getRpTargets() != null) {
            for (VirtualArray protectionVarray : protectionVarrays) {
                // Find the pools that apply to this virtual
                VpoolProtectionVarraySettings settings = RPHelper.getProtectionSettings(vpool, protectionVarray, dbClient);
                // If there was no vpool specified with the protection settings, use the base vpool for this varray.
                VirtualPool protectionVpool = vpool;
                if (settings.getVirtualPool() != null) {
                    protectionVpool = dbClient.queryObject(VirtualPool.class, settings.getVirtualPool());
                }
                // Find the existing source volume target that corresponds to this protection
                // virtual array. We need to see if the storage pool has capacity for another
                // target volume.
                Volume targetVolume = getTargetVolumeForProtectionVirtualArray(sourceVolume, protectionVarray);
                // Target volumes will be the same size as the source
                long targetVolumeRequiredCapacity = getSizeInKB(capabilities.getSize());
                if (RPHelper.isVPlexVolume(targetVolume, dbClient)) {
                    for (String backingVolumeId : targetVolume.getAssociatedVolumes()) {
                        Volume backingVolume = dbClient.queryObject(Volume.class, URI.create(backingVolumeId));
                        StoragePool backingVolumePool = dbClient.queryObject(StoragePool.class, backingVolume.getPool());
                        storagePoolCache.put(backingVolumePool.getId(), backingVolumePool);
                        updateStoragePoolRequiredCapacityMap(storagePoolRequiredCapacity, backingVolumePool.getId(), targetVolumeRequiredCapacity);
                        storagePoolErrorDetail.put(backingVolumePool.getId(), targetVolume.getPersonality());
                    }
                } else {
                    StoragePool targetPool = dbClient.queryObject(StoragePool.class, targetVolume.getPool());
                    storagePoolCache.put(targetPool.getId(), targetPool);
                    updateStoragePoolRequiredCapacityMap(storagePoolRequiredCapacity, targetPool.getId(), targetVolumeRequiredCapacity);
                    storagePoolErrorDetail.put(targetPool.getId(), targetVolume.getPersonality());
                }
                // Account for the target journal volumes.
                List<Volume> targetJournals = RPHelper.findExistingJournalsForCopy(dbClient, targetVolume.getConsistencyGroup(), targetVolume.getRpCopyName());
                Volume targetJournalVolume = targetJournals.get(0);
                if (targetJournalVolume == null) {
                    _log.error(String.format("No existing target journal found in CG [%s] for copy [%s], returning false", targetVolume.getConsistencyGroup(), targetVolume.getRpCopyName()));
                    throw APIException.badRequests.unableToFindSuitableJournalRecommendation();
                }
                long targetJournalSizePerPolicy = RPHelper.getJournalSizeGivenPolicy(String.valueOf(capabilities.getSize()), protectionVpool.getJournalSize(), capabilities.getResourceCount());
                long targetJournalVolumeRequiredCapacity = getSizeInKB(targetJournalSizePerPolicy);
                if (RPHelper.isVPlexVolume(targetJournalVolume, dbClient)) {
                    for (String backingVolumeId : targetJournalVolume.getAssociatedVolumes()) {
                        Volume backingVolume = dbClient.queryObject(Volume.class, URI.create(backingVolumeId));
                        StoragePool backingVolumePool = dbClient.queryObject(StoragePool.class, backingVolume.getPool());
                        storagePoolCache.put(backingVolumePool.getId(), backingVolumePool);
                        updateStoragePoolRequiredCapacityMap(storagePoolRequiredCapacity, backingVolumePool.getId(), targetJournalVolumeRequiredCapacity);
                        storagePoolErrorDetail.put(backingVolumePool.getId(), targetVolume.getPersonality() + " " + targetJournalVolume.getPersonality());
                    }
                } else {
                    StoragePool targetJournalPool = dbClient.queryObject(StoragePool.class, targetJournalVolume.getPool());
                    storagePoolCache.put(targetJournalPool.getId(), targetJournalPool);
                    updateStoragePoolRequiredCapacityMap(storagePoolRequiredCapacity, targetJournalPool.getId(), targetJournalVolumeRequiredCapacity);
                    storagePoolErrorDetail.put(targetJournalPool.getId(), targetVolume.getPersonality() + " " + targetJournalVolume.getPersonality());
                }
            }
        }
        BlockConsistencyGroup cg = dbClient.queryObject(BlockConsistencyGroup.class, capabilities.getBlockConsistencyGroup());
        for (Map.Entry<URI, Long> storagePoolEntry : storagePoolRequiredCapacity.entrySet()) {
            StoragePool storagePool = storagePoolCache.get(storagePoolEntry.getKey());
            long freeCapacity = storagePool.getFreeCapacity();
            long requiredCapacity = storagePoolEntry.getValue().longValue();
            if (requiredCapacity > freeCapacity) {
                cgPoolsHaveAvailableCapacity = false;
                _log.info(String.format("Unable to fully align placement with existing %s volume from " + "RecoverPoint consistency group [%s]. Required capacity is %s and we can't re-use storage pool [%s] " + "as it only has %s free capacity.", storagePoolErrorDetail.get(storagePool.getId()), sourceVolume.getLabel(), cg.getLabel(), SizeUtil.translateSize(requiredCapacity, SizeUtil.SIZE_GB), storagePool.getLabel(), SizeUtil.translateSize(freeCapacity, SizeUtil.SIZE_GB)));
                break;
            } else {
                _log.info(String.format("Storage pool [%s], used by consistency group [%s], has the required capacity and will be " + "used for this placement request.", storagePool.getLabel(), cg.getLabel()));
            }
        }
    }
    return cgPoolsHaveAvailableCapacity;
}
Also used : VirtualArray(com.emc.storageos.db.client.model.VirtualArray) StoragePool(com.emc.storageos.db.client.model.StoragePool) HashMap(java.util.HashMap) VpoolProtectionVarraySettings(com.emc.storageos.db.client.model.VpoolProtectionVarraySettings) VirtualPool(com.emc.storageos.db.client.model.VirtualPool) URI(java.net.URI) BlockConsistencyGroup(com.emc.storageos.db.client.model.BlockConsistencyGroup) Volume(com.emc.storageos.db.client.model.Volume) Map(java.util.Map) HashMap(java.util.HashMap) StringSetMap(com.emc.storageos.db.client.model.StringSetMap) StringMap(com.emc.storageos.db.client.model.StringMap)

Example 67 with VirtualArray

use of com.emc.storageos.db.client.model.VirtualArray in project coprhd-controller by CoprHD.

the class RecoverPointScheduler method swapSrcAndHAIfNeeded.

/**
 * This method is driven by the flag on the RP+VPLEX Source Vpool to use HA as RP Source or not.
 * When that flag is set we use the HA Varray and HA Vpool as the Sources for placement. Consequently,
 * the Source Varray and Source VPool are then used for HA placement.
 *
 * We may not need to swap if the flag isn't set, but this method returns the RPVPlexVarryVpool object
 * regardless so we can then just reference the resources in that object to pass down to the rest of the
 * scheduler methods.
 *
 * @param srcVarray Original src varray
 * @param srcVpool Original src vpool
 * @return RPVPlexVarryVpool which contains references to the src varray, src vpool, ha varray, ha vpool
 */
private SwapContainer swapSrcAndHAIfNeeded(VirtualArray srcVarray, VirtualPool srcVpool) {
    VirtualArray haVarray = null;
    VirtualPool haVpool = null;
    SwapContainer container = new SwapContainer();
    container.setSrcVarray(srcVarray);
    container.setSrcVpool(srcVpool);
    container.setHaVarray(haVarray);
    container.setHaVpool(haVpool);
    // Potentially will swap src and ha, returns the container.
    container = initializeSwapContainer(container, dbClient);
    return container;
}
Also used : VirtualArray(com.emc.storageos.db.client.model.VirtualArray) VirtualPool(com.emc.storageos.db.client.model.VirtualPool)

Example 68 with VirtualArray

use of com.emc.storageos.db.client.model.VirtualArray in project coprhd-controller by CoprHD.

the class RecoverPointScheduler method getProtectionVirtualArraysForVirtualPool.

/**
 * Gets and verifies that the protection varrays passed in the request are
 * accessible to the tenant.
 *
 * @param project A reference to the project.
 * @param vpool class of service, contains protection varrays
 * @return A reference to the varrays
 * @throws java.net.URISyntaxException
 * @throws com.emc.storageos.db.exceptions.DatabaseException
 */
public static List<VirtualArray> getProtectionVirtualArraysForVirtualPool(Project project, VirtualPool vpool, DbClient dbClient, PermissionsHelper permissionHelper) {
    List<VirtualArray> protectionVirtualArrays = new ArrayList<VirtualArray>();
    if (vpool.getProtectionVarraySettings() != null) {
        for (String protectionVirtualArray : vpool.getProtectionVarraySettings().keySet()) {
            try {
                VirtualArray varray = dbClient.queryObject(VirtualArray.class, new URI(protectionVirtualArray));
                protectionVirtualArrays.add(varray);
                permissionHelper.checkTenantHasAccessToVirtualArray(project.getTenantOrg().getURI(), varray);
            } catch (URISyntaxException e) {
                throw APIException.badRequests.invalidURI(protectionVirtualArray);
            }
        }
    }
    return protectionVirtualArrays;
}
Also used : VirtualArray(com.emc.storageos.db.client.model.VirtualArray) ArrayList(java.util.ArrayList) URISyntaxException(java.net.URISyntaxException) URI(java.net.URI)

Example 69 with VirtualArray

use of com.emc.storageos.db.client.model.VirtualArray in project coprhd-controller by CoprHD.

the class RecoverPointScheduler method initializeSwapContainer.

/**
 * This function will swap src and ha varrays and src and ha vpools IF
 * the src vpool has specified this.
 *
 * @param srcVarray Source varray
 * @param srcVpool Source vpool
 * @param haVarray HA varray
 * @param haVpool HA vpool
 * @param dbClient DB Client reference
 */
public static SwapContainer initializeSwapContainer(SwapContainer container, DbClient dbClient) {
    // Refresh vpools in case previous activities have changed their temporal representation.
    VirtualArray srcVarray = container.getSrcVarray();
    VirtualPool srcVpool = dbClient.queryObject(VirtualPool.class, container.getSrcVpool().getId());
    VirtualArray haVarray = container.getHaVarray();
    VirtualPool haVpool = container.getHaVpool();
    // as the RP Source.
    if (VirtualPool.isRPVPlexProtectHASide(srcVpool)) {
        // Get the HA Varray connected to RP
        haVarray = dbClient.queryObject(VirtualArray.class, URI.create(srcVpool.getHaVarrayConnectedToRp()));
        _log.info(String.format("Source Vpool[%s] indicates that we should use HA Varray[%s] as RP Source.", srcVpool.getLabel(), haVarray.getLabel()));
        String haVpoolId = srcVpool.getHaVarrayVpoolMap().get(srcVpool.getHaVarrayConnectedToRp());
        if (haVpoolId != null && !haVpoolId.isEmpty() && !haVpoolId.equals(NullColumnValueGetter.getNullStr())) {
            haVpool = dbClient.queryObject(VirtualPool.class, URI.create(haVpoolId));
            _log.info(String.format("HA Vpool has been defined [%s]", haVpool.getLabel()));
            // Temporarily inherit the HA and Protection Settings/RP specific info from Source Vpool.
            // These modifications will not be persisted to the db.
            haVpool.setProtectionVarraySettings(srcVpool.getProtectionVarraySettings());
            haVpool.setRpCopyMode(srcVpool.getRpCopyMode());
            haVpool.setRpRpoType(srcVpool.getRpRpoType());
            haVpool.setRpRpoValue(srcVpool.getRpRpoValue());
            haVpool.setMultivolumeConsistency(srcVpool.getMultivolumeConsistency());
            haVpool.setHighAvailability(srcVpool.getHighAvailability());
            haVpool.setMetroPoint(srcVpool.getMetroPoint());
            haVpool.setHaVarrayConnectedToRp(srcVarray.getId().toString());
            haVpool.setJournalSize(NullColumnValueGetter.isNotNullValue(srcVpool.getJournalSize()) ? srcVpool.getJournalSize() : null);
        } else {
            _log.info(String.format("HA Vpool has not been defined, using Source Vpool[%s].", srcVpool.getLabel()));
            // Use source vpool. That means the source vpool will have to have the HA varray
            // added to it, otherwise this will not work. That is done during vpool create via the UI
            // by the user.
            // This is the same behaviour as VPLEX. So we're just reusing that behaviour.
            // If not done, placement will fail.
            haVpool = srcVpool;
        }
        // Ensure that we define the haVarrayVpoolMap on the haVpool to use srcVarray and srcVpool.
        StringMap haVarrayVpoolMap = new StringMap();
        haVarrayVpoolMap.put(srcVarray.getId().toString(), srcVpool.getId().toString());
        haVpool.setHaVarrayVpoolMap(haVarrayVpoolMap);
        _log.info(String.format("HA Varray[%s] and HA Vpool[%s] will be used as Source Varray and Source Vpool.", haVarray.getLabel(), haVpool.getLabel()));
        _log.info(String.format("Source Varray[%s] and Source Vpool[%s] will be used as HA Varray and HA Vpool.", srcVarray.getLabel(), srcVpool.getLabel()));
        // Now HA becomes Source and Source becomes HA.
        VirtualArray tempVarray = srcVarray;
        VirtualPool tempVpool = srcVpool;
        container.setSrcVarray(haVarray);
        container.setSrcVpool(haVpool);
        container.setHaVarray(tempVarray);
        container.setHaVpool(tempVpool);
    }
    return container;
}
Also used : VirtualArray(com.emc.storageos.db.client.model.VirtualArray) StringMap(com.emc.storageos.db.client.model.StringMap) VirtualPool(com.emc.storageos.db.client.model.VirtualPool)

Example 70 with VirtualArray

use of com.emc.storageos.db.client.model.VirtualArray in project coprhd-controller by CoprHD.

the class SRDFScheduler method getSRDFPoolMappings.

/**
 * This method takes the source varray and a list of possible pools provided by common Bourne
 * placement logic and returns a list of source/destination pairs that are capable of SRDF
 *
 * When this method returns, we have a list of the possible source and destination pools This is
 * later used determine which entries in the list share a an SRDF link via the same source
 * storage system, and therefore can satisfy the request to protect to ALL virtual arrays.
 *
 * @param varray
 *            Source Varray
 * @param poolList
 *            Pool List from common placement logic for source
 * @param varrayPoolMap
 *            Pool List from common placement logic for target varrays
 * @return a list of source/destination pools
 */
private Set<SRDFPoolMapping> getSRDFPoolMappings(final VirtualArray varray, final List<StoragePool> poolList, final Map<VirtualArray, List<StoragePool>> varrayPoolMap, final VirtualPool vpool, final Volume vpoolChangeVolume, final long size) {
    // Maps to reduce hits on the database for objects we'll need more than one time during
    // calculations
    Map<StoragePool, StorageSystem> sourcePoolStorageMap = new HashMap<StoragePool, StorageSystem>();
    Map<StoragePool, StorageSystem> destPoolStorageMap = new HashMap<StoragePool, StorageSystem>();
    for (StoragePool sourcePool : poolList) {
        sourcePoolStorageMap.put(sourcePool, _dbClient.queryObject(StorageSystem.class, sourcePool.getStorageDevice()));
    }
    for (VirtualArray targetVarray : varrayPoolMap.keySet()) {
        for (StoragePool destPool : varrayPoolMap.get(targetVarray)) {
            destPoolStorageMap.put(destPool, _dbClient.queryObject(StorageSystem.class, destPool.getStorageDevice()));
        }
    }
    Set<SRDFPoolMapping> srcDestPoolList = new TreeSet<SRDFPoolMapping>();
    // For each storage pool that is considered a candidate for source...
    for (StoragePool sourcePool : sourcePoolStorageMap.keySet()) {
        // Go through each target virtual array and attempt to add an entry in the pool mapping
        for (VirtualArray targetVarray : varrayPoolMap.keySet()) {
            // Add an entry to the mapping if the source and destination storage systems can see
            // each other.
            populateSRDFPoolList(varray, destPoolStorageMap, srcDestPoolList, sourcePool, targetVarray, vpool, vpoolChangeVolume, size);
        }
    }
    return srcDestPoolList;
}
Also used : VirtualArray(com.emc.storageos.db.client.model.VirtualArray) StoragePool(com.emc.storageos.db.client.model.StoragePool) HashMap(java.util.HashMap) TreeSet(java.util.TreeSet) StorageSystem(com.emc.storageos.db.client.model.StorageSystem)

Aggregations

VirtualArray (com.emc.storageos.db.client.model.VirtualArray)183 URI (java.net.URI)91 ArrayList (java.util.ArrayList)91 VirtualPool (com.emc.storageos.db.client.model.VirtualPool)84 Project (com.emc.storageos.db.client.model.Project)53 NamedURI (com.emc.storageos.db.client.model.NamedURI)52 StorageSystem (com.emc.storageos.db.client.model.StorageSystem)52 StringSet (com.emc.storageos.db.client.model.StringSet)50 Volume (com.emc.storageos.db.client.model.Volume)46 VirtualPoolCapabilityValuesWrapper (com.emc.storageos.volumecontroller.impl.utils.VirtualPoolCapabilityValuesWrapper)44 List (java.util.List)44 StoragePool (com.emc.storageos.db.client.model.StoragePool)43 HashMap (java.util.HashMap)38 StringMap (com.emc.storageos.db.client.model.StringMap)37 Recommendation (com.emc.storageos.volumecontroller.Recommendation)37 RPRecommendation (com.emc.storageos.volumecontroller.RPRecommendation)31 RPProtectionRecommendation (com.emc.storageos.volumecontroller.RPProtectionRecommendation)30 BlockConsistencyGroup (com.emc.storageos.db.client.model.BlockConsistencyGroup)29 Network (com.emc.storageos.db.client.model.Network)27 VPlexRecommendation (com.emc.storageos.volumecontroller.VPlexRecommendation)27