Search in sources :

Example 1 with VPlexStorageVolumeInfo

use of com.emc.storageos.vplex.api.VPlexStorageVolumeInfo in project coprhd-controller by CoprHD.

the class VplexVolumeValidator method validateStorageVolumes.

/**
 * Validates either storage volumes for either distributed or local vplex volumes.
 *
 * @param virtualVolume
 *            -- Vplex virtual volume
 * @param volumeId
 *            -- identification for log
 * @param topLevelDeviceName
 *            -- top level VPLEX device name
 * @param distributed
 *            -- if true VPLEX distributed, false if VPLEX local
 * @param cluster
 *            cluster-1 or cluster-2
 * @param hasMirror
 *            -- if true this cluster has a mirror
 * @return failed -- If true a discrepancy was detected
 */
private boolean validateStorageVolumes(Volume virtualVolume, String volumeId, String topLevelDeviceName, boolean distributed, String cluster, boolean hasMirror) {
    boolean failed = false;
    Map<String, VPlexStorageVolumeInfo> wwnToStorageVolumeInfos = client.getStorageVolumeInfoForDevice(topLevelDeviceName, distributed ? VPlexApiConstants.DISTRIBUTED_VIRTUAL_VOLUME : VPlexApiConstants.LOCAL_VIRTUAL_VOLUME, cluster, hasMirror);
    // Check local volume is present
    Volume assocVolume = VPlexUtil.getVPLEXBackendVolume(virtualVolume, true, getDbClient());
    if (!storageSystemSupportsValidation(assocVolume)) {
        return failed;
    }
    if (!wwnToStorageVolumeInfos.keySet().contains(assocVolume.getWWN())) {
        getValidatorLogger().logDiff(volumeId, "SOURCE storage volume WWN", assocVolume.getWWN(), wwnToStorageVolumeInfos.keySet().toString());
        failed = true;
    } else {
        wwnToStorageVolumeInfos.remove(assocVolume.getWWN());
    }
    // Check HA volume is present
    if (distributed) {
        assocVolume = VPlexUtil.getVPLEXBackendVolume(virtualVolume, false, getDbClient());
        if (!storageSystemSupportsValidation(assocVolume)) {
            return failed;
        }
        if (!wwnToStorageVolumeInfos.keySet().contains(assocVolume.getWWN())) {
            getValidatorLogger().logDiff(volumeId, "HA storage volume WWN", assocVolume.getWWN(), wwnToStorageVolumeInfos.keySet().toString());
            failed = true;
        } else {
            wwnToStorageVolumeInfos.remove(assocVolume.getWWN());
        }
    }
    // Process any mirrors that were found
    if (virtualVolume.getMirrors() != null) {
        for (String mirrorId : virtualVolume.getMirrors()) {
            VplexMirror mirror = getDbClient().queryObject(VplexMirror.class, URI.create(mirrorId));
            if (mirror == null || mirror.getInactive() || mirror.getAssociatedVolumes() == null) {
                // Not fully formed for some reason, skip it
                continue;
            }
            // Now get the underlying Storage Volume
            for (String mirrorAssociatedId : mirror.getAssociatedVolumes()) {
                Volume mirrorVolume = getDbClient().queryObject(Volume.class, URI.create(mirrorAssociatedId));
                if (!storageSystemSupportsValidation(mirrorVolume)) {
                    return failed;
                }
                if (mirrorVolume != null && !NullColumnValueGetter.isNullValue(mirrorVolume.getWWN())) {
                    if (!wwnToStorageVolumeInfos.keySet().contains(mirrorVolume.getWWN())) {
                        getValidatorLogger().logDiff(volumeId, "Mirror WWN", mirrorVolume.getWWN(), wwnToStorageVolumeInfos.keySet().toString());
                        failed = true;
                    } else {
                        wwnToStorageVolumeInfos.remove(mirrorVolume.getWWN());
                    }
                }
            }
        }
    }
    if (!wwnToStorageVolumeInfos.isEmpty()) {
        getValidatorLogger().logDiff(volumeId, "Extra storage volumes found", ValidatorLogger.NO_MATCHING_ENTRY, wwnToStorageVolumeInfos.keySet().toString());
        failed = true;
    }
    return failed;
}
Also used : Volume(com.emc.storageos.db.client.model.Volume) VPlexStorageVolumeInfo(com.emc.storageos.vplex.api.VPlexStorageVolumeInfo) VplexMirror(com.emc.storageos.db.client.model.VplexMirror)

Example 2 with VPlexStorageVolumeInfo

use of com.emc.storageos.vplex.api.VPlexStorageVolumeInfo in project coprhd-controller by CoprHD.

the class VPlexControllerUtils method getStorageVolumeInfoForDevice.

/**
 * Returns a Map of lowest-level storage-volume resource's WWN to its VPlexStorageVolumeInfo
 * object for a given device name, virtual volume type, and cluster name. If
 * hasMirror is true, this indicates the top-level device is composed of a
 * RAID-1 mirror, so there's an extra layers of components to traverse in finding
 * the lowest-level storage-volume resources.
 *
 * @param deviceName the name of the top-level device to look at
 * @param virtualVolumeType the type of virtual volume (local or distributed)
 * @param clusterName the cluster name
 * @param hasMirror indicates if the top-level device is a RAID-1 mirror
 * @param vplexUri the URI of the VPLEX system
 * @param dbClient a reference to the database client
 *
 * @return a map of WWNs to VPlexStorageVolumeInfo objects
 * @throws VPlexApiException
 */
public static Map<String, VPlexStorageVolumeInfo> getStorageVolumeInfoForDevice(String deviceName, String virtualVolumeType, String clusterName, boolean hasMirror, URI vplexUri, DbClient dbClient) throws VPlexApiException {
    Map<String, VPlexStorageVolumeInfo> storageVolumeInfo = null;
    VPlexApiClient client = null;
    try {
        VPlexApiFactory vplexApiFactory = VPlexApiFactory.getInstance();
        client = VPlexControllerUtils.getVPlexAPIClient(vplexApiFactory, vplexUri, dbClient);
    } catch (URISyntaxException e) {
        log.error("cannot load vplex api client", e);
    }
    if (null != client) {
        storageVolumeInfo = client.getStorageVolumeInfoForDevice(deviceName, virtualVolumeType, clusterName, hasMirror);
    }
    log.info("Backend storage volume wwns for {} are {}", deviceName, storageVolumeInfo);
    return storageVolumeInfo;
}
Also used : VPlexStorageVolumeInfo(com.emc.storageos.vplex.api.VPlexStorageVolumeInfo) VPlexApiClient(com.emc.storageos.vplex.api.VPlexApiClient) URISyntaxException(java.net.URISyntaxException) VPlexApiFactory(com.emc.storageos.vplex.api.VPlexApiFactory)

Example 3 with VPlexStorageVolumeInfo

use of com.emc.storageos.vplex.api.VPlexStorageVolumeInfo in project coprhd-controller by CoprHD.

the class VplexDBCkr method checkVolumesOnVplex.

public void checkVolumesOnVplex(URI vplexSystemURI, boolean deleteInvalidVolumes) {
    URIQueryResultList result = new URIQueryResultList();
    List<URI> deletevirtualvolumeURIs = new ArrayList<URI>();
    int nerrors = 0;
    int invalidVolumeCount = 0;
    dbClient.queryByConstraint(ContainmentConstraint.Factory.getStorageDeviceVolumeConstraint(vplexSystemURI), result);
    Iterator<URI> iter = result.iterator();
    VPlexApiClient client = getVPlexApiClient(vplexSystemURI);
    // Get all the virtual volumes. We elect for shallow here as it's quicker-
    // we will spend time below getting details.
    writeLog("Retrieving all virtual volumes... this will take some time...");
    Map<String, VPlexVirtualVolumeInfo> vvInfoMap = client.getVirtualVolumes(true);
    List<VPlexStorageViewInfo> storageViews = client.getStorageViewsLite();
    writeLog("... done");
    try {
        while (iter.hasNext()) {
            Volume volume = dbClient.queryObject(Volume.class, iter.next());
            if (volume == null || volume.getInactive()) {
                continue;
            }
            writeLog(String.format("Checking volume %s (%s)", volume.getLabel(), volume.getDeviceLabel()));
            if (volume.getAssociatedVolumes() == null || volume.getAssociatedVolumes().isEmpty()) {
                writeLog(String.format("Volume %s (%s) has no associated volumes... skipping", volume.getLabel(), volume.getDeviceLabel()));
                continue;
            }
            VPlexVirtualVolumeInfo vvInfo = vvInfoMap.get(volume.getDeviceLabel());
            if (vvInfo == null) {
                writeLog(String.format("ERROR: Volume %s (%s) had no VirtualVolumeInfo in VPlex", volume.getLabel(), volume.getDeviceLabel()));
                deletevirtualvolumeURIs.add(volume.getId());
                nerrors++;
                invalidVolumeCount++;
                continue;
            }
            if ((null != vvInfo.getWwn()) && (null != volume.getWWN())) {
                if (vvInfo.getName().equals(volume.getDeviceLabel())) {
                    if (vvInfo.getWwn().toUpperCase().equals(volume.getWWN().toUpperCase())) {
                        writeLog(String.format("Virtual Volume %s wwn %s matches VPLEX", vvInfo.getName(), vvInfo.getWwn()));
                    } else {
                        writeLog(String.format("ERROR: Virtual Volume %s wwn %s in VPLEX mismatch with viprdb %s", vvInfo.getName(), vvInfo.getWwn(), volume.getWWN()));
                        deletevirtualvolumeURIs.add(volume.getId());
                        invalidVolumeCount++;
                        nerrors++;
                    }
                }
            }
            StringSet wwns = new StringSet();
            for (String cluster : vvInfo.getClusters()) {
                Map<String, VPlexStorageVolumeInfo> svInfoMap = client.getStorageVolumeInfoForDevice(vvInfo.getSupportingDevice(), vvInfo.getLocality(), cluster, false);
                for (String wwn : svInfoMap.keySet()) {
                    // writeLog("adding wwn " + wwn.toUpperCase());
                    wwns.add(wwn.toUpperCase());
                    VPlexStorageVolumeInfo svInfo = svInfoMap.get(wwn);
                    writeLog(String.format("StorageVolume wwn %s name %s cluster %s", wwn, svInfo.getName(), cluster));
                }
            }
            // Now check associated volumes against the wwns.
            for (String associatedVolume : volume.getAssociatedVolumes()) {
                Volume assocVolume = dbClient.queryObject(Volume.class, URI.create(associatedVolume));
                if (assocVolume == null) {
                    writeLog("Associated volunme not found in database... skipping: " + associatedVolume);
                    continue;
                }
                if (wwns.contains(assocVolume.getWWN().toUpperCase())) {
                    writeLog(String.format("Volume %s wwn %s matches VPLEX", assocVolume.getLabel(), assocVolume.getWWN()));
                } else {
                    writeLog(String.format("ERROR: Volume %s wwn %s is not present in VPLEX", assocVolume.getLabel(), assocVolume.getWWN()));
                    nerrors++;
                }
            }
            List<ExportMask> exportMaskListInDB = isVolumeExported(volume.getId());
            if (null != exportMaskListInDB) {
                for (ExportMask exportMaskInDB : exportMaskListInDB) {
                    boolean found = false;
                    boolean storageviewfound = false;
                    for (VPlexStorageViewInfo storageView : storageViews) {
                        if (storageView.getName().equals(exportMaskInDB.getMaskName())) {
                            storageviewfound = true;
                            for (String volumeNameStr : storageView.getVirtualVolumes()) {
                                String[] tokens = volumeNameStr.split(",");
                                String volumeName = tokens[1];
                                if (volumeName.equals(volume.getDeviceLabel())) {
                                    found = true;
                                    break;
                                }
                            }
                            if (!found) {
                                writeLog(String.format("ERROR: volume %s is in exportmask %s in viprdb  but not in vplex storageview %s", volume.getDeviceLabel(), exportMaskInDB.getMaskName(), storageView.getName()));
                                nerrors++;
                            }
                            break;
                        }
                    }
                    if (!storageviewfound) {
                        writeLog(String.format("ERROR: volume %s is in exportmask %s in viprdb  but storageview not found in vplex", volume.getDeviceLabel(), exportMaskInDB.getMaskName()));
                        nerrors++;
                    }
                }
            }
            for (VPlexStorageViewInfo storageView : storageViews) {
                writeLog(String.format("Checking Storageview %s", storageView.getName()));
                for (String volumeNameStr : storageView.getVirtualVolumes()) {
                    String[] tokens = volumeNameStr.split(",");
                    String volumeName = tokens[1];
                    if (volumeName.equals(volume.getDeviceLabel())) {
                        boolean storageviewfound = false;
                        if (null != exportMaskListInDB) {
                            for (ExportMask exportMaskInDB : exportMaskListInDB) {
                                if (storageView.getName().equals(exportMaskInDB.getMaskName())) {
                                    storageviewfound = true;
                                    break;
                                }
                            }
                        }
                        if (!storageviewfound) {
                            writeLog(String.format("ERROR: volume %s is in vplex storageview %s but not in viprdb exportmask", volumeName, storageView.getName()));
                            nerrors++;
                        }
                    }
                }
            }
        }
        if (deleteInvalidVolumes) {
            writeLog("deleting invalid volumes");
            // deleting virtual volumes that no longer exist in vplex
            List<VolumeDescriptor> volumeDescriptors = getDescriptorsForVolumesToBeDeleted(vplexSystemURI, deletevirtualvolumeURIs, VolumeDeleteTypeEnum.VIPR_ONLY.name());
            cleanupForViPROnlyDelete(volumeDescriptors);
            // Mark them inactive. Note that some of the volumes may be mirrors,
            // which have a different database type.
            List<VolumeDescriptor> descriptorsForMirrors = VolumeDescriptor.getDescriptors(volumeDescriptors, VolumeDescriptor.Type.BLOCK_MIRROR);
            dbClient.markForDeletion(dbClient.queryObject(BlockMirror.class, VolumeDescriptor.getVolumeURIs(descriptorsForMirrors)));
            List<VolumeDescriptor> descriptorsForVolumes = VolumeDescriptor.filterByType(volumeDescriptors, null, new VolumeDescriptor.Type[] { VolumeDescriptor.Type.BLOCK_MIRROR });
            dbClient.markForDeletion(dbClient.queryObject(Volume.class, VolumeDescriptor.getVolumeURIs(descriptorsForVolumes)));
            // Update the task status for each volume
            for (URI volumeURI : deletevirtualvolumeURIs) {
                Volume volume = dbClient.queryObject(Volume.class, volumeURI);
                dbClient.updateObject(volume);
            }
        }
    } catch (Exception e) {
        writeLog(String.format("Exception: while verifying virtual volumes", e));
    }
    // List<URI> maskUrislist = new ArrayList<URI>();;
    // maskUrislist.add(URI.create("urn:storageos:ExportMask:3742e612-cc93-422b-a1a5-43490e0fe8ea:vdc1"));
    // for (URI mskUri : maskUrislist) {
    // boolean found = false;
    // ExportMask exportMaskUri = dbClient.queryObject(ExportMask.class, mskUri);
    // if (exportMaskUri == null || exportMaskUri.getInactive()) {
    // continue;
    // }
    // writeLog(String.format("exportMaskUri in ViPR DB is %s", exportMaskUri.getMaskName()));
    // for (VPlexStorageViewInfo storageView : storageViews) {
    // if (storageView.getName().equals(exportMaskUri.getMaskName())) {
    // found = true;
    // }
    // }
    // if(!found) {
    // writeLog(String.format("ERROR: exportMask not found in vplex %s",exportMaskUri.getMaskName()));
    // nerrors++;
    // }
    // }
    writeLog("Total errors for this VPLEX: " + nerrors);
}
Also used : VPlexStorageViewInfo(com.emc.storageos.vplex.api.VPlexStorageViewInfo) VolumeDescriptor(com.emc.storageos.blockorchestrationcontroller.VolumeDescriptor) BlockMirror(com.emc.storageos.db.client.model.BlockMirror) ExportMask(com.emc.storageos.db.client.model.ExportMask) ArrayList(java.util.ArrayList) URI(java.net.URI) VPlexVirtualVolumeInfo(com.emc.storageos.vplex.api.VPlexVirtualVolumeInfo) URIQueryResultList(com.emc.storageos.db.client.constraint.URIQueryResultList) ContainmentConstraint(com.emc.storageos.db.client.constraint.ContainmentConstraint) AlternateIdConstraint(com.emc.storageos.db.client.constraint.AlternateIdConstraint) Volume(com.emc.storageos.db.client.model.Volume) VPlexStorageVolumeInfo(com.emc.storageos.vplex.api.VPlexStorageVolumeInfo) VPlexApiClient(com.emc.storageos.vplex.api.VPlexApiClient) StringSet(com.emc.storageos.db.client.model.StringSet)

Example 4 with VPlexStorageVolumeInfo

use of com.emc.storageos.vplex.api.VPlexStorageVolumeInfo in project coprhd-controller by CoprHD.

the class VplexBackendIngestionContext method updateUnmanagedBackendVolumesInParent.

/**
 * Sets the VPLEX_BACKEND_VOLUMES information on the virtual UnManagedVolume
 * as well as the VPLEX_PARENT_VOLUME and VPLEX_BACKEND_CLUSTER_ID
 * on each associated UnManagedVolume.
 */
private void updateUnmanagedBackendVolumesInParent() {
    if (!getUnmanagedBackendVolumes().isEmpty()) {
        StringSet bvols = new StringSet();
        for (UnManagedVolume backendVol : unmanagedBackendVolumes) {
            bvols.add(backendVol.getNativeGuid());
            // set the parent volume native guid on the backend volume
            StringSet parentVol = new StringSet();
            parentVol.add(_unmanagedVirtualVolume.getNativeGuid());
            backendVol.putVolumeInfo(SupportedVolumeInformation.VPLEX_PARENT_VOLUME.name(), parentVol);
            if (isDistributed()) {
                // determine cluster location of distributed component storage volume leg
                VPlexStorageVolumeInfo storageVolume = getBackendVolumeWwnToInfoMap().get(backendVol.getWwn());
                if (null != storageVolume) {
                    String clusterId = getClusterLocationForStorageVolume(storageVolume);
                    if (null != clusterId && !clusterId.isEmpty()) {
                        _logger.info("setting VPLEX_BACKEND_CLUSTER_ID: " + clusterId);
                        StringSet clusterIds = new StringSet();
                        clusterIds.add(clusterId);
                        backendVol.putVolumeInfo(SupportedVolumeInformation.VPLEX_BACKEND_CLUSTER_ID.name(), clusterIds);
                    }
                }
            }
            _dbClient.updateObject(backendVol);
        }
        if (bvols != null && !bvols.isEmpty()) {
            _logger.info("setting VPLEX_BACKEND_VOLUMES: " + unmanagedBackendVolumes);
            _unmanagedVirtualVolume.putVolumeInfo(SupportedVolumeInformation.VPLEX_BACKEND_VOLUMES.name(), bvols);
            _unmanagedVirtualVolume.setLabel(getFriendlyLabel());
        }
    }
}
Also used : UnManagedVolume(com.emc.storageos.db.client.model.UnManagedDiscoveredObjects.UnManagedVolume) VPlexStorageVolumeInfo(com.emc.storageos.vplex.api.VPlexStorageVolumeInfo) StringSet(com.emc.storageos.db.client.model.StringSet)

Example 5 with VPlexStorageVolumeInfo

use of com.emc.storageos.vplex.api.VPlexStorageVolumeInfo in project coprhd-controller by CoprHD.

the class VplexBackendIngestionContext method getAssociatedVolumeForComponentDevice.

/**
 * Finds the backend associated UnManagedVolume for the given VPlexDeviceInfo
 * object. It does this by finding the overlap between the context paths
 * of the VPlexDeviceInfo and VPlexStorageVolumeInfo objects and then using
 * the WWN to locate the related UnManagedVolume.
 *
 * @param device the VPlexDeviceInfo object to search for
 * @return an UnManagedVolume matching the VPlexDeviceInfo.
 */
private UnManagedVolume getAssociatedVolumeForComponentDevice(VPlexDeviceInfo device) {
    String devicePath = device.getPath();
    _logger.info("associated volume device context path: " + devicePath);
    for (Entry<String, VPlexStorageVolumeInfo> entry : getBackendVolumeWwnToInfoMap().entrySet()) {
        String storageVolumePath = entry.getValue().getPath();
        _logger.info("\tstorage volume context path: " + storageVolumePath);
        // context paths should overlap if the device contains the storage volume...
        if (null != storageVolumePath && storageVolumePath.startsWith(devicePath)) {
            _logger.info("\t\tthis storage volume is a match, trying to find unmanaged backend volume");
            for (UnManagedVolume vol : getUnmanagedBackendVolumes()) {
                _logger.info("\t\t\tlooking at " + vol.getNativeGuid());
                if (vol.getWwn().equalsIgnoreCase(entry.getKey())) {
                    _logger.info("\t\t\t\tit's a match for " + vol.getWwn());
                    return vol;
                }
            }
        }
    }
    return null;
}
Also used : VPlexStorageVolumeInfo(com.emc.storageos.vplex.api.VPlexStorageVolumeInfo) UnManagedVolume(com.emc.storageos.db.client.model.UnManagedDiscoveredObjects.UnManagedVolume)

Aggregations

VPlexStorageVolumeInfo (com.emc.storageos.vplex.api.VPlexStorageVolumeInfo)5 StringSet (com.emc.storageos.db.client.model.StringSet)2 UnManagedVolume (com.emc.storageos.db.client.model.UnManagedDiscoveredObjects.UnManagedVolume)2 Volume (com.emc.storageos.db.client.model.Volume)2 VPlexApiClient (com.emc.storageos.vplex.api.VPlexApiClient)2 VolumeDescriptor (com.emc.storageos.blockorchestrationcontroller.VolumeDescriptor)1 AlternateIdConstraint (com.emc.storageos.db.client.constraint.AlternateIdConstraint)1 ContainmentConstraint (com.emc.storageos.db.client.constraint.ContainmentConstraint)1 URIQueryResultList (com.emc.storageos.db.client.constraint.URIQueryResultList)1 BlockMirror (com.emc.storageos.db.client.model.BlockMirror)1 ExportMask (com.emc.storageos.db.client.model.ExportMask)1 VplexMirror (com.emc.storageos.db.client.model.VplexMirror)1 VPlexApiFactory (com.emc.storageos.vplex.api.VPlexApiFactory)1 VPlexStorageViewInfo (com.emc.storageos.vplex.api.VPlexStorageViewInfo)1 VPlexVirtualVolumeInfo (com.emc.storageos.vplex.api.VPlexVirtualVolumeInfo)1 URI (java.net.URI)1 URISyntaxException (java.net.URISyntaxException)1 ArrayList (java.util.ArrayList)1