Search in sources :

Example 1 with VplexBackendIngestionContext

use of com.emc.storageos.vplexcontroller.VplexBackendIngestionContext in project coprhd-controller by CoprHD.

the class VPlexCommunicationInterface method updateUnmanagedVolume.

/**
 * Updates an existing UnManagedVolume with the latest info from
 * the VPLEX virtual volume.
 *
 * @param info a VPlexVirtualVolumeInfo descriptor
 * @param vplex the VPLEX storage system managing the volume
 * @param volume the existing UnManagedVolume
 * @param volumesToCgs a Map of volume labels to consistency group names
 * @param allVPools cache of all virtual pools for filtering
 */
private void updateUnmanagedVolume(VPlexVirtualVolumeInfo info, StorageSystem vplex, UnManagedVolume volume, Map<String, String> volumesToCgs, Map<String, String> clusterIdToNameMap, Map<String, String> varrayToClusterIdMap, Map<String, String> distributedDevicePathToClusterMap, Map<String, String> backendVolumeGuidToVvolGuidMap, Map<String, Set<VPlexStorageViewInfo>> volumeToStorageViewMap, Collection<VirtualPool> allVpools) {
    s_logger.info("Updating UnManagedVolume {} with latest from VPLEX volume {}", volume.getLabel(), info.getName());
    volume.setStorageSystemUri(vplex.getId());
    volume.setNativeGuid(info.getPath());
    volume.setLabel(info.getName());
    volume.setWwn(info.getWwn());
    volume.getUnmanagedExportMasks().clear();
    volume.getInitiatorUris().clear();
    volume.getInitiatorNetworkIds().clear();
    // set volume characteristics and volume information
    StringSetMap unManagedVolumeInformation = new StringSetMap();
    StringMap unManagedVolumeCharacteristics = new StringMap();
    // Set up default MAXIMUM_IO_BANDWIDTH and MAXIMUM_IOPS
    StringSet bwValues = new StringSet();
    bwValues.add("0");
    if (unManagedVolumeInformation.get(SupportedVolumeInformation.EMC_MAXIMUM_IO_BANDWIDTH.toString()) == null) {
        unManagedVolumeInformation.put(SupportedVolumeInformation.EMC_MAXIMUM_IO_BANDWIDTH.toString(), bwValues);
    } else {
        unManagedVolumeInformation.get(SupportedVolumeInformation.EMC_MAXIMUM_IO_BANDWIDTH.toString()).replace(bwValues);
    }
    StringSet iopsVal = new StringSet();
    iopsVal.add("0");
    if (unManagedVolumeInformation.get(SupportedVolumeInformation.EMC_MAXIMUM_IOPS.toString()) == null) {
        unManagedVolumeInformation.put(SupportedVolumeInformation.EMC_MAXIMUM_IOPS.toString(), iopsVal);
    } else {
        unManagedVolumeInformation.get(SupportedVolumeInformation.EMC_MAXIMUM_IOPS.toString()).replace(iopsVal);
    }
    // check if volume is part of a consistency group, and set the name if so
    if (volumesToCgs.containsKey(info.getName())) {
        unManagedVolumeCharacteristics.put(SupportedVolumeCharacterstics.IS_VOLUME_ADDED_TO_CONSISTENCYGROUP.toString(), TRUE);
        StringSet set = new StringSet();
        set.add(volumesToCgs.get(info.getName()));
        unManagedVolumeInformation.put(SupportedVolumeInformation.VPLEX_CONSISTENCY_GROUP_NAME.toString(), set);
    } else {
        unManagedVolumeCharacteristics.put(SupportedVolumeCharacterstics.IS_VOLUME_ADDED_TO_CONSISTENCYGROUP.toString(), FALSE);
    }
    // set system type
    StringSet systemTypes = new StringSet();
    systemTypes.add(vplex.getSystemType());
    unManagedVolumeInformation.put(SupportedVolumeInformation.SYSTEM_TYPE.toString(), systemTypes);
    // set volume capacity
    // For Vplex virtual volumes set allocated capacity to 0 (cop-18608)
    StringSet provCapacity = new StringSet();
    provCapacity.add(String.valueOf(info.getCapacityBytes()));
    StringSet allocatedCapacity = new StringSet();
    allocatedCapacity.add(String.valueOf(0));
    unManagedVolumeInformation.put(SupportedVolumeInformation.PROVISIONED_CAPACITY.toString(), provCapacity);
    unManagedVolumeInformation.put(SupportedVolumeInformation.ALLOCATED_CAPACITY.toString(), allocatedCapacity);
    // set vplex virtual volume properties
    unManagedVolumeCharacteristics.put(SupportedVolumeCharacterstics.IS_VPLEX_VOLUME.toString(), TRUE);
    StringSet locality = new StringSet();
    locality.add(info.getLocality());
    unManagedVolumeInformation.put(SupportedVolumeInformation.VPLEX_LOCALITY.toString(), locality);
    StringSet supportingDevice = new StringSet();
    supportingDevice.add(info.getSupportingDevice());
    unManagedVolumeInformation.put(SupportedVolumeInformation.VPLEX_SUPPORTING_DEVICE_NAME.toString(), supportingDevice);
    StringSet volumeClusters = new StringSet();
    volumeClusters.addAll(info.getClusters());
    unManagedVolumeInformation.put(SupportedVolumeInformation.VPLEX_CLUSTER_IDS.toString(), volumeClusters);
    StringSet accesses = new StringSet();
    accesses.add(Volume.VolumeAccessState.READWRITE.getState());
    unManagedVolumeInformation.put(SupportedVolumeInformation.ACCESS.toString(), accesses);
    // set supported vpool list
    StringSet matchedVPools = new StringSet();
    String highAvailability = info.getLocality().equals(LOCAL) ? VirtualPool.HighAvailabilityType.vplex_local.name() : VirtualPool.HighAvailabilityType.vplex_distributed.name();
    s_logger.info("finding valid virtual pools for UnManagedVolume {}", volume.getLabel());
    for (VirtualPool vpool : allVpools) {
        // - The vpool is RPVPLEX and this is a VPLEX local volume (likely a journal)
        if (!vpool.getHighAvailability().equals(highAvailability) && !(VirtualPool.vPoolSpecifiesRPVPlex(vpool) && highAvailability.equals(VirtualPool.HighAvailabilityType.vplex_local.name()))) {
            s_logger.info("   virtual pool {} is not valid because " + "its high availability setting does not match the unmanaged volume", vpool.getLabel());
            continue;
        }
        // If the volume is in a CG, the vpool must specify multi-volume consistency.
        Boolean mvConsistency = vpool.getMultivolumeConsistency();
        if ((TRUE.equals(unManagedVolumeCharacteristics.get(SupportedVolumeCharacterstics.IS_VOLUME_ADDED_TO_CONSISTENCYGROUP.toString()))) && ((mvConsistency == null) || (mvConsistency == Boolean.FALSE))) {
            s_logger.info("   virtual pool {} is not valid because it does not have the " + "multi-volume consistency flag set, and the unmanaged volume is in a consistency group", vpool.getLabel());
            continue;
        }
        // VPool must be assigned to a varray corresponding to volumes clusters.
        StringSet varraysForVpool = vpool.getVirtualArrays();
        for (String varrayId : varraysForVpool) {
            String varrayClusterId = varrayToClusterIdMap.get(varrayId);
            if (null == varrayClusterId) {
                varrayClusterId = ConnectivityUtil.getVplexClusterForVarray(URI.create(varrayId), vplex.getId(), _dbClient);
                varrayToClusterIdMap.put(varrayId, varrayClusterId);
            }
            if (!ConnectivityUtil.CLUSTER_UNKNOWN.equals(varrayClusterId)) {
                String varrayClusterName = clusterIdToNameMap.get(varrayClusterId);
                if (volumeClusters.contains(varrayClusterName)) {
                    matchedVPools.add(vpool.getId().toString());
                    break;
                }
            }
        }
        if (!matchedVPools.contains(vpool.getId().toString())) {
            s_logger.info("   virtual pool {} is not valid because " + "the volume resides on a cluster that does not match the varray(s) associated with the vpool", vpool.getLabel());
        }
    }
    // set thin provisioning state from virtual-volume thin-enabled property
    String thinlyProvisioned = info.isThinEnabled() ? TRUE : FALSE;
    unManagedVolumeCharacteristics.put(SupportedVolumeCharacterstics.IS_THINLY_PROVISIONED.toString(), thinlyProvisioned);
    // add this info to the unmanaged volume object
    volume.setVolumeCharacterstics(unManagedVolumeCharacteristics);
    volume.setVolumeInformation(unManagedVolumeInformation);
    // discover backend volume data
    String discoveryMode = ControllerUtils.getPropertyValueFromCoordinator(_coordinator, VplexBackendIngestionContext.DISCOVERY_MODE);
    if (!VplexBackendIngestionContext.DISCOVERY_MODE_INGESTION_ONLY.equals(discoveryMode)) {
        try {
            VplexBackendIngestionContext context = new VplexBackendIngestionContext(volume, _dbClient);
            context.setDistributedDevicePathToClusterMap(distributedDevicePathToClusterMap);
            context.discover();
            for (UnManagedVolume bvol : context.getUnmanagedBackendVolumes()) {
                // map this backend volume's GUID to its parent front-end volume GUID
                backendVolumeGuidToVvolGuidMap.put(bvol.getNativeGuid(), volume.getNativeGuid());
                // check if this backend volume is a full copy (and is target of clone)
                // if so, write this volume's GUID to the parent vvol's LOCAL_REPLICA_SOURCE_VOLUME
                // so that we can swap it out for the backend parent vvol's GUID
                String isFullCopyStr = bvol.getVolumeCharacterstics().get(SupportedVolumeCharacterstics.IS_FULL_COPY.toString());
                boolean isFullCopy = (null != isFullCopyStr && Boolean.parseBoolean(isFullCopyStr));
                if (isFullCopy) {
                    String fullCopySourceBvol = VplexBackendIngestionContext.extractValueFromStringSet(SupportedVolumeInformation.LOCAL_REPLICA_SOURCE_VOLUME.name(), bvol.getVolumeInformation());
                    if (fullCopySourceBvol != null && !fullCopySourceBvol.isEmpty()) {
                        StringSet set = new StringSet();
                        set.add(fullCopySourceBvol);
                        volume.putVolumeInfo(SupportedVolumeInformation.LOCAL_REPLICA_SOURCE_VOLUME.name(), set);
                        volume.putVolumeCharacterstics(SupportedVolumeCharacterstics.IS_FULL_COPY.toString(), Boolean.TRUE.toString());
                    }
                }
                // check if this backend volume has a replica (and is source of clone)
                // if so, write this volume's GUID to the parent vvol's FULL_COPIES
                // so that we can swap it out for the backend parent vvol's GUID
                String hasReplicasStr = bvol.getVolumeCharacterstics().get(SupportedVolumeCharacterstics.HAS_REPLICAS.toString());
                boolean hasReplicas = (null != hasReplicasStr && Boolean.parseBoolean(hasReplicasStr));
                if (hasReplicas) {
                    StringSet fullCopyTargetBvols = bvol.getVolumeInformation().get(SupportedVolumeInformation.FULL_COPIES.name());
                    if (fullCopyTargetBvols != null && !fullCopyTargetBvols.isEmpty()) {
                        // if this backend volume has FULL_COPIES, add them
                        // to the parent virtual volume's FULL_COPIES
                        // and make HAS_REPLICAS is set.
                        StringSet parentSet = volume.getVolumeInformation().get(SupportedVolumeInformation.FULL_COPIES.name());
                        if (parentSet == null) {
                            parentSet = new StringSet();
                        }
                        for (String fullCopyTargetBvol : fullCopyTargetBvols) {
                            parentSet.add(fullCopyTargetBvol);
                        }
                        volume.putVolumeInfo(SupportedVolumeInformation.FULL_COPIES.name(), parentSet);
                        volume.putVolumeCharacterstics(SupportedVolumeCharacterstics.HAS_REPLICAS.toString(), Boolean.TRUE.toString());
                    }
                }
                // set replica state on parent if found in backend volume
                String replicaState = VplexBackendIngestionContext.extractValueFromStringSet(SupportedVolumeInformation.REPLICA_STATE.name(), bvol.getVolumeInformation());
                if (replicaState != null && !replicaState.isEmpty()) {
                    StringSet set = new StringSet();
                    set.add(replicaState);
                    volume.putVolumeInfo(SupportedVolumeInformation.REPLICA_STATE.name(), set);
                }
                // set sync active state on parent if found in backend volume
                String syncActive = VplexBackendIngestionContext.extractValueFromStringSet(SupportedVolumeInformation.IS_SYNC_ACTIVE.name(), bvol.getVolumeInformation());
                if (syncActive != null && !syncActive.isEmpty()) {
                    StringSet set = new StringSet();
                    set.add(syncActive);
                    volume.putVolumeInfo(SupportedVolumeInformation.IS_SYNC_ACTIVE.name(), set);
                }
            }
            s_logger.info(context.getPerformanceReport());
        } catch (Exception ex) {
            s_logger.warn("error discovering backend structure for {}: ", volume.getNativeGuid(), ex);
        // no need to throw further
        }
    }
    unManagedVolumeCharacteristics.put(SupportedVolumeCharacterstics.IS_INGESTABLE.toString(), TRUE);
    if (null == matchedVPools || matchedVPools.isEmpty()) {
        // clean all supported vpools.
        volume.getSupportedVpoolUris().clear();
        s_logger.info("No matching VPOOLS found for unmanaged volume " + volume.getLabel());
    } else {
        // replace with new StringSet
        volume.getSupportedVpoolUris().replace(matchedVPools);
        s_logger.info("Replaced Pools : {}", volume.getSupportedVpoolUris());
    }
    Set<VPlexStorageViewInfo> svs = volumeToStorageViewMap.get(info.getName());
    if (svs != null) {
        updateWwnAndHluInfo(volume, info.getName(), svs);
    }
}
Also used : StringSetMap(com.emc.storageos.db.client.model.StringSetMap) StringMap(com.emc.storageos.db.client.model.StringMap) VPlexStorageViewInfo(com.emc.storageos.vplex.api.VPlexStorageViewInfo) UnManagedVolume(com.emc.storageos.db.client.model.UnManagedDiscoveredObjects.UnManagedVolume) StringSet(com.emc.storageos.db.client.model.StringSet) VplexBackendIngestionContext(com.emc.storageos.vplexcontroller.VplexBackendIngestionContext) VirtualPool(com.emc.storageos.db.client.model.VirtualPool) URISyntaxException(java.net.URISyntaxException) DatabaseException(com.emc.storageos.db.exceptions.DatabaseException) BaseCollectionException(com.emc.storageos.plugins.BaseCollectionException) VPlexApiException(com.emc.storageos.vplex.api.VPlexApiException) VPlexCollectionException(com.emc.storageos.plugins.metering.vplex.VPlexCollectionException) IOException(java.io.IOException)

Aggregations

StringMap (com.emc.storageos.db.client.model.StringMap)1 StringSet (com.emc.storageos.db.client.model.StringSet)1 StringSetMap (com.emc.storageos.db.client.model.StringSetMap)1 UnManagedVolume (com.emc.storageos.db.client.model.UnManagedDiscoveredObjects.UnManagedVolume)1 VirtualPool (com.emc.storageos.db.client.model.VirtualPool)1 DatabaseException (com.emc.storageos.db.exceptions.DatabaseException)1 BaseCollectionException (com.emc.storageos.plugins.BaseCollectionException)1 VPlexCollectionException (com.emc.storageos.plugins.metering.vplex.VPlexCollectionException)1 VPlexApiException (com.emc.storageos.vplex.api.VPlexApiException)1 VPlexStorageViewInfo (com.emc.storageos.vplex.api.VPlexStorageViewInfo)1 VplexBackendIngestionContext (com.emc.storageos.vplexcontroller.VplexBackendIngestionContext)1 IOException (java.io.IOException)1 URISyntaxException (java.net.URISyntaxException)1