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);
}
}
Aggregations