Search in sources :

Example 6 with VplexMirror

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

the class VPlexBlockServiceApiImpl method preparePromotedVolumes.

/**
 * This method creates volume objects for the copiesToStop which will used as
 * independent virtual volumes if detach mirror action completes successfully.
 */
private List<URI> preparePromotedVolumes(List<VplexMirror> copiesToStop, TaskList taskList, String opId) {
    List<URI> promotedVolumes = new ArrayList<URI>();
    for (VplexMirror copy : copiesToStop) {
        Volume v = new Volume();
        v.setId(URIUtil.createId(Volume.class));
        Volume sourceVplexVolume = _dbClient.queryObject(Volume.class, copy.getSource());
        String promotedLabel = String.format("%s-%s", sourceVplexVolume.getLabel(), copy.getLabel());
        v.setProject(new NamedURI(copy.getProject().getURI(), promotedLabel));
        StringSet protocols = new StringSet();
        protocols.add(StorageProtocol.Block.FC.name());
        v.setProtocol(protocols);
        v.setTenant(new NamedURI(copy.getTenant().getURI(), promotedLabel));
        _dbClient.createObject(v);
        Operation op = _dbClient.createTaskOpStatus(Volume.class, v.getId(), opId, ResourceOperationTypeEnum.PROMOTE_COPY_TO_VPLEX, copy.getId().toString());
        taskList.getTaskList().add(toTask(v, Arrays.asList(copy), opId, op));
        promotedVolumes.add(v.getId());
    }
    return promotedVolumes;
}
Also used : Volume(com.emc.storageos.db.client.model.Volume) NamedURI(com.emc.storageos.db.client.model.NamedURI) ArrayList(java.util.ArrayList) StringSet(com.emc.storageos.db.client.model.StringSet) Operation(com.emc.storageos.db.client.model.Operation) FCTN_STRING_TO_URI(com.emc.storageos.db.client.util.CommonTransformerFunctions.FCTN_STRING_TO_URI) NamedURI(com.emc.storageos.db.client.model.NamedURI) URI(java.net.URI) FCTN_VPLEX_MIRROR_TO_URI(com.emc.storageos.db.client.util.CommonTransformerFunctions.FCTN_VPLEX_MIRROR_TO_URI) VplexMirror(com.emc.storageos.db.client.model.VplexMirror)

Example 7 with VplexMirror

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

the class VPlexBlockServiceApiImpl method changeVirtualArrayForVolumes.

/**
 * {@inheritDoc}
 */
@Override
public void changeVirtualArrayForVolumes(List<Volume> volumes, BlockConsistencyGroup cg, List<Volume> cgVolumes, VirtualArray newVirtualArray, String taskId) throws InternalException {
    // if they remove the snapshots, they can perform the varray change.
    for (Volume volume : volumes) {
        List<BlockSnapshot> snapshots = getSnapshots(volume);
        if (!snapshots.isEmpty()) {
            for (BlockSnapshot snapshot : snapshots) {
                if (!snapshot.getInactive()) {
                    throw APIException.badRequests.volumeForVarrayChangeHasSnaps(volume.getId().toString());
                }
            }
        }
        // If the volume has mirrors then varray change will not
        // be allowed. User needs to explicitly delete mirrors first.
        // This is applicable for both Local and Distributed volumes.
        // For distributed volume getMirrors will get mirror if any
        // on source or HA side.
        StringSet mirrorURIs = volume.getMirrors();
        if (mirrorURIs != null && !mirrorURIs.isEmpty()) {
            List<VplexMirror> mirrors = _dbClient.queryObject(VplexMirror.class, StringSetUtil.stringSetToUriList(mirrorURIs));
            if (mirrors != null && !mirrors.isEmpty()) {
                throw APIException.badRequests.volumeForVarrayChangeHasMirrors(volume.getId().toString(), volume.getLabel());
            }
        }
    }
    // vpool change.
    if ((cg != null) && (volumes.size() > _maxCgVolumesForMigration)) {
        throw APIException.badRequests.cgContainsTooManyVolumesForVArrayChange(cg.getLabel(), volumes.size(), _maxCgVolumesForMigration);
    }
    // we don't allow the varray change.
    if ((cg != null) && (cg.checkForType(Types.LOCAL)) && (cgVolumes.size() > 1)) {
        verifyTargetSystemsForCGDataMigration(volumes, null, newVirtualArray.getId());
    }
    // Create the volume descriptors for the virtual array change.
    List<VolumeDescriptor> descriptors = createVolumeDescriptorsForVarrayChange(volumes, newVirtualArray, taskId);
    try {
        // Orchestrate the virtual array change.
        BlockOrchestrationController controller = getController(BlockOrchestrationController.class, BlockOrchestrationController.BLOCK_ORCHESTRATION_DEVICE);
        controller.changeVirtualArray(descriptors, taskId);
        s_logger.info("Successfully invoked block orchestrator.");
    } catch (InternalException e) {
        s_logger.error("Controller error", e);
        for (VolumeDescriptor descriptor : descriptors) {
            // migration targets and migrations.
            if (VolumeDescriptor.Type.VPLEX_MIGRATE_VOLUME.equals(descriptor.getType())) {
                _dbClient.error(Volume.class, descriptor.getVolumeURI(), taskId, e);
                _dbClient.error(Migration.class, descriptor.getMigrationId(), taskId, e);
            }
        }
        throw e;
    }
}
Also used : VolumeDescriptor(com.emc.storageos.blockorchestrationcontroller.VolumeDescriptor) BlockOrchestrationController(com.emc.storageos.blockorchestrationcontroller.BlockOrchestrationController) Volume(com.emc.storageos.db.client.model.Volume) Migration(com.emc.storageos.db.client.model.Migration) BlockSnapshot(com.emc.storageos.db.client.model.BlockSnapshot) StringSet(com.emc.storageos.db.client.model.StringSet) VplexMirror(com.emc.storageos.db.client.model.VplexMirror) InternalException(com.emc.storageos.svcs.errorhandling.resources.InternalException)

Example 8 with VplexMirror

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

the class VPlexBlockServiceApiImpl method updateBackendVolumeToMirrorVpoolMap.

/**
 * Convenience method to update backendVolumeToMirrorVpoolMap for the VPLEX Distributed volume.
 * In case if there is already mirror for the vplex volume, this method ensures
 * to add entry to the map only if there isn't already mirror on either leg.
 *
 * @param vplexVolume The reference to vplex distributed volume
 * @param associatedVolumeIds URIs of the associated volumes
 * @param sourceVirtualPool The reference to virtual pool to which vplex volume is associated with
 * @param sourceMirrorVPool The reference to virtual pool for the mirror on the source side
 * @param haMirrorVPool The reference to virtual pool for the mirror on the HA side
 * @param backendVolumeToMirrorVpoolMap OUT param containing map of backend volume to mirror vpool
 */
private void updateBackendVolumeToMirrorVpoolMap(Volume vplexVolume, StringSet associatedVolumeIds, VirtualPool sourceVirtualPool, VirtualPool sourceMirrorVPool, VirtualPool haMirrorVPool, Map<Volume, VirtualPool> backendVolumeToMirrorVpoolMap) {
    Set<String> vplexClusterWithMirrorForVolume = new HashSet<String>();
    // Set vplexClusterWithMirrorForVolume contains Vplex Cluster on which mirror already exist for the vplex volume
    if (vplexVolume.getMirrors() != null && !vplexVolume.getMirrors().isEmpty()) {
        StringSet existingMirrors = vplexVolume.getMirrors();
        for (String existingMirrorURI : existingMirrors) {
            VplexMirror existingMirror = _dbClient.queryObject(VplexMirror.class, URI.create(existingMirrorURI));
            if (existingMirror != null && !existingMirror.getInactive()) {
                String cluster = ConnectivityUtil.getVplexClusterForVarray(existingMirror.getVirtualArray(), vplexVolume.getStorageController(), _dbClient);
                checkIfClusterIsUnknown(cluster, existingMirror.getVirtualArray().toString(), vplexVolume.getStorageController().toString());
                vplexClusterWithMirrorForVolume.add(cluster);
            }
        }
        s_logger.info("Vplex Mirror(s) already exists for Vplex volume" + vplexVolume.getLabel() + " " + vplexVolume.getId() + " on cluster " + vplexClusterWithMirrorForVolume);
    }
    for (String associatedVolumeId : associatedVolumeIds) {
        if (sourceMirrorVPool != null && sourceVirtualPool.getMaxNativeContinuousCopies() > 0) {
            // Get the source backend volume
            Volume associatedVolume = VPlexUtil.getVPLEXBackendVolume(vplexVolume, true, _dbClient);
            if (associatedVolume != null && associatedVolume.getId().toString().equals(associatedVolumeId)) {
                if (!vplexClusterWithMirrorForVolume.isEmpty()) {
                    // Get the vplex cluster for the source varray
                    String cluster = ConnectivityUtil.getVplexClusterForVarray(vplexVolume.getVirtualArray(), vplexVolume.getStorageController(), _dbClient);
                    checkIfClusterIsUnknown(cluster, vplexVolume.getVirtualArray().toString(), vplexVolume.getStorageController().toString());
                    // If there isn't already mirror on the source side then add entry to backendVolumeToMirrorVpoolMap
                    if (!vplexClusterWithMirrorForVolume.contains(cluster)) {
                        backendVolumeToMirrorVpoolMap.put(associatedVolume, sourceMirrorVPool);
                    }
                } else {
                    backendVolumeToMirrorVpoolMap.put(associatedVolume, sourceMirrorVPool);
                }
            }
        } else {
            s_logger.info("The max native continuous copies for the source Vpool {} is {} ", sourceVirtualPool.getLabel(), sourceVirtualPool.getMaxNativeContinuousCopies());
            if (sourceMirrorVPool == null) {
                s_logger.info("The mirror will not be created on the source side as the source mirror pool is not provided " + "in the virtual pool {} {}", sourceVirtualPool.getLabel(), sourceVirtualPool.getId());
            }
        }
        VirtualPool haVPool = VirtualPool.getHAVPool(sourceVirtualPool, _dbClient);
        if (haMirrorVPool != null && haVPool != null && haVPool.getMaxNativeContinuousCopies() > 0) {
            // Get the HA backend volume
            Volume associatedVolume = VPlexUtil.getVPLEXBackendVolume(vplexVolume, false, _dbClient);
            if (associatedVolume != null && associatedVolume.getId().toString().equals(associatedVolumeId)) {
                if (!vplexClusterWithMirrorForVolume.isEmpty()) {
                    // Get HA varray
                    URI haVarrayURI = VPlexUtil.getHAVarray(sourceVirtualPool);
                    if (haVarrayURI != null) {
                        // Get the vplex cluster for the HA varray
                        String cluster = ConnectivityUtil.getVplexClusterForVarray(haVarrayURI, vplexVolume.getStorageController(), _dbClient);
                        checkIfClusterIsUnknown(cluster, haVarrayURI.toString(), vplexVolume.getStorageController().toString());
                        // If there isn't already mirror on the HA side then add entry to backendVolumeToMirrorVpoolMap
                        if (!vplexClusterWithMirrorForVolume.contains(cluster)) {
                            backendVolumeToMirrorVpoolMap.put(associatedVolume, haMirrorVPool);
                        }
                    }
                } else {
                    backendVolumeToMirrorVpoolMap.put(associatedVolume, haMirrorVPool);
                }
            }
        } else {
            if (haVPool != null) {
                s_logger.info("The max native continuous copies for the HA Vpool {} is {} ", haVPool.getLabel(), haVPool.getMaxNativeContinuousCopies());
                if (haMirrorVPool == null) {
                    s_logger.info("The mirror will not be created on the HA side as the HA mirror pool is not provided " + "in the virtual pool {} {}", haVPool.getLabel(), haVPool.getId());
                }
            }
        }
    }
}
Also used : Volume(com.emc.storageos.db.client.model.Volume) StringSet(com.emc.storageos.db.client.model.StringSet) VirtualPool(com.emc.storageos.db.client.model.VirtualPool) VplexMirror(com.emc.storageos.db.client.model.VplexMirror) FCTN_STRING_TO_URI(com.emc.storageos.db.client.util.CommonTransformerFunctions.FCTN_STRING_TO_URI) NamedURI(com.emc.storageos.db.client.model.NamedURI) URI(java.net.URI) FCTN_VPLEX_MIRROR_TO_URI(com.emc.storageos.db.client.util.CommonTransformerFunctions.FCTN_VPLEX_MIRROR_TO_URI) HashSet(java.util.HashSet)

Example 9 with VplexMirror

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

the class VplexMirrorDeactivateCompleter method complete.

@Override
protected void complete(DbClient dbClient, Operation.Status status, ServiceCoded coded) throws DeviceControllerException {
    try {
        super.complete(dbClient, status, coded);
        VplexMirror mirror = dbClient.queryObject(VplexMirror.class, getMirrorURI());
        Volume sourceVplexVolume = dbClient.queryObject(Volume.class, mirror.getSource());
        switch(status) {
            case error:
                dbClient.error(VplexMirror.class, mirror.getId(), getOpId(), coded);
                dbClient.error(Volume.class, sourceVplexVolume.getId(), getOpId(), coded);
                break;
            default:
                _log.info("Removing mirror {} from source volume {}", mirror.getId().toString(), sourceVplexVolume.getId().toString());
                sourceVplexVolume.getMirrors().remove(mirror.getId().toString());
                dbClient.persistObject(sourceVplexVolume);
                if (mirror.getAssociatedVolumes() != null && !mirror.getAssociatedVolumes().isEmpty()) {
                    for (String volumeUri : mirror.getAssociatedVolumes()) {
                        Volume assocVolume = dbClient.queryObject(Volume.class, URI.create(volumeUri));
                        if (assocVolume != null && !assocVolume.getInactive()) {
                            dbClient.markForDeletion(assocVolume);
                        }
                    }
                }
                dbClient.markForDeletion(mirror);
                dbClient.ready(VplexMirror.class, mirror.getId(), getOpId());
                dbClient.ready(Volume.class, sourceVplexVolume.getId(), getOpId());
        }
        recordVplexMirrorOperation(dbClient, OperationTypeEnum.DEACTIVATE_VOLUME_MIRROR, status, eventMessage(status, sourceVplexVolume, mirror), mirror, sourceVplexVolume);
    } catch (Exception e) {
        _log.error("Failed updating status. VplexMirrorDeactivate {}, for task " + getOpId(), getId(), e);
    }
}
Also used : Volume(com.emc.storageos.db.client.model.Volume) VplexMirror(com.emc.storageos.db.client.model.VplexMirror) DeviceControllerException(com.emc.storageos.exceptions.DeviceControllerException)

Example 10 with VplexMirror

use of com.emc.storageos.db.client.model.VplexMirror 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)

Aggregations

VplexMirror (com.emc.storageos.db.client.model.VplexMirror)36 Volume (com.emc.storageos.db.client.model.Volume)31 NamedURI (com.emc.storageos.db.client.model.NamedURI)15 DeviceControllerException (com.emc.storageos.exceptions.DeviceControllerException)15 InternalException (com.emc.storageos.svcs.errorhandling.resources.InternalException)15 URI (java.net.URI)15 DatabaseException (com.emc.storageos.db.exceptions.DatabaseException)12 InternalServerErrorException (com.emc.storageos.svcs.errorhandling.resources.InternalServerErrorException)12 ControllerException (com.emc.storageos.volumecontroller.ControllerException)12 URISyntaxException (java.net.URISyntaxException)12 ArrayList (java.util.ArrayList)12 StringSet (com.emc.storageos.db.client.model.StringSet)11 VPlexApiException (com.emc.storageos.vplex.api.VPlexApiException)11 WorkflowException (com.emc.storageos.workflow.WorkflowException)11 IOException (java.io.IOException)11 VPlexApiClient (com.emc.storageos.vplex.api.VPlexApiClient)10 StorageSystem (com.emc.storageos.db.client.model.StorageSystem)8 VolumeDescriptor (com.emc.storageos.blockorchestrationcontroller.VolumeDescriptor)7 HashMap (java.util.HashMap)6 URIQueryResultList (com.emc.storageos.db.client.constraint.URIQueryResultList)5