Search in sources :

Example 56 with ProtectionSet

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

the class RPHelper method rollbackProtectionOnVolume.

/**
 * Rollback protection specific fields on the existing volume. This is normally invoked if there are
 * errors during a change vpool operation. We want to return the volume back to its un-protected state
 * or in the case of upgrade to MP then to remove any MP features from the protected volume.
 *
 * One of the biggest motivations is to ensure that the old vpool is set back on the existing volume.
 *
 * @param volume Volume to remove protection from
 * @param oldVpool The old vpool, this the original vpool of the volume before trying to add protection
 * @param dbClient DBClient object
 */
public static void rollbackProtectionOnVolume(Volume volume, VirtualPool oldVpool, DbClient dbClient) {
    // Rollback any RP specific changes to this volume
    if (volume.checkForRp()) {
        if (!VirtualPool.vPoolSpecifiesProtection(oldVpool)) {
            _log.info(String.format("Start rollback of RP protection changes for volume [%s] (%s)...", volume.getLabel(), volume.getId()));
            // List of volume IDs to clean up from the ProtectionSet
            List<String> protectionSetVolumeIdsToRemove = new ArrayList<String>();
            protectionSetVolumeIdsToRemove.add(volume.getId().toString());
            // All source volumes in this CG
            List<Volume> cgSourceVolumes = getCgSourceVolumes(volume.getConsistencyGroup(), dbClient);
            // Only rollback the Journals if there is only one volume in the CG and it's the one we're
            // trying to roll back.
            boolean lastSourceVolumeInCG = (cgSourceVolumes != null && cgSourceVolumes.size() == 1 && cgSourceVolumes.get(0).getId().equals(volume.getId()));
            // order can be placed immediately.
            if (lastSourceVolumeInCG) {
                List<Volume> journals = getCgVolumes(dbClient, volume.getConsistencyGroup(), Volume.PersonalityTypes.METADATA.name());
                for (Volume journal : journals) {
                    _log.info(String.format("Rolling back RP Journal (%s)", journal.getLabel()));
                    protectionSetVolumeIdsToRemove.add(journal.getId().toString());
                    rollbackVolume(journal.getId(), dbClient);
                }
            }
            // Null out any RP specific fields on the volume
            volume.setConsistencyGroup(NullColumnValueGetter.getNullURI());
            volume.setPersonality(NullColumnValueGetter.getNullStr());
            volume.setProtectionController(NullColumnValueGetter.getNullURI());
            volume.setRSetName(NullColumnValueGetter.getNullStr());
            volume.setInternalSiteName(NullColumnValueGetter.getNullStr());
            volume.setRpCopyName(NullColumnValueGetter.getNullStr());
            StringSet resetRpTargets = volume.getRpTargets();
            if (resetRpTargets != null) {
                // Rollback any target volumes that were created
                for (String rpTargetId : resetRpTargets) {
                    protectionSetVolumeIdsToRemove.add(rpTargetId);
                    rollbackVolume(URI.create(rpTargetId), dbClient);
                }
                resetRpTargets.clear();
                volume.setRpTargets(resetRpTargets);
            }
            // Clean up the Protection Set
            if (!NullColumnValueGetter.isNullNamedURI(volume.getProtectionSet())) {
                ProtectionSet protectionSet = dbClient.queryObject(ProtectionSet.class, volume.getProtectionSet());
                if (protectionSet != null) {
                    // Remove volume IDs from the Protection Set
                    protectionSet.getVolumes().removeAll(protectionSetVolumeIdsToRemove);
                    _log.info(String.format("Removing the following volumes from Protection Set [%s] (%s): %s", protectionSet.getLabel(), protectionSet.getId(), Joiner.on(',').join(protectionSetVolumeIdsToRemove)));
                    // inactive.
                    if (lastSourceVolumeInCG) {
                        _log.info(String.format("Setting Protection Set [%s] (%s) to inactive", protectionSet.getLabel(), protectionSet.getId()));
                        protectionSet.setInactive(true);
                    }
                    dbClient.updateObject(protectionSet);
                }
            }
            volume.setProtectionSet(NullColumnValueGetter.getNullNamedURI());
        } else {
            _log.info(String.format("Rollback changes for existing protected RP volume [%s]...", volume.getLabel()));
        // No specific rollback steps for existing protected volumes
        }
        // the backing volumes if they were set to the new vpool.
        if (RPHelper.isVPlexVolume(volume, dbClient)) {
            if (null == volume.getAssociatedVolumes()) {
                // this is a rollback situation, so we probably don't want to
                // throw another exception...
                _log.warn("VPLEX volume {} has no backend volumes.", volume.forDisplay());
            } else {
                for (String associatedVolId : volume.getAssociatedVolumes()) {
                    Volume associatedVolume = dbClient.queryObject(Volume.class, URI.create(associatedVolId));
                    if (associatedVolume != null && !associatedVolume.getInactive()) {
                        if (!NullColumnValueGetter.isNullURI(associatedVolume.getVirtualPool()) && associatedVolume.getVirtualPool().equals(volume.getVirtualPool())) {
                            associatedVolume.setVirtualPool(oldVpool.getId());
                            _log.info(String.format("Backing volume [%s] has had its virtual pool rolled back to [%s].", associatedVolume.getLabel(), oldVpool.getLabel()));
                        }
                        associatedVolume.setConsistencyGroup(NullColumnValueGetter.getNullURI());
                        dbClient.updateObject(associatedVolume);
                    }
                    // before we get here anyway.
                    if (!oldVpool.getMultivolumeConsistency()) {
                        associatedVolume.setConsistencyGroup(NullColumnValueGetter.getNullURI());
                    }
                    dbClient.updateObject(associatedVolume);
                }
            }
        }
        // Set the old vpool back on the volume
        _log.info(String.format("Resetting vpool on volume [%s](%s) from (%s) back to its original vpool (%s)", volume.getLabel(), volume.getId(), volume.getVirtualPool(), oldVpool.getId()));
        volume.setVirtualPool(oldVpool.getId());
        dbClient.updateObject(volume);
        _log.info(String.format("Rollback of RP protection changes for volume [%s] (%s) has completed.", volume.getLabel(), volume.getId()));
    }
}
Also used : UnManagedVolume(com.emc.storageos.db.client.model.UnManagedDiscoveredObjects.UnManagedVolume) Volume(com.emc.storageos.db.client.model.Volume) ArrayList(java.util.ArrayList) StringSet(com.emc.storageos.db.client.model.StringSet) ProtectionSet(com.emc.storageos.db.client.model.ProtectionSet) UnManagedProtectionSet(com.emc.storageos.db.client.model.UnManagedDiscoveredObjects.UnManagedProtectionSet)

Example 57 with ProtectionSet

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

the class RPHelper method getVolumesToDelete.

/**
 * This method will return all volumes that should be deleted based on the entire list of volumes to be deleted.
 * If this is the last source volume in the CG, this method will return all journal volumes as well.
 *
 * @param reqDeleteVolumes all volumes in the delete request
 * @param dbClient DbClient
 * @return list of volumes to unexport and delete
 * @throws InternalException
 * @throws URISyntaxException
 */
public static Set<URI> getVolumesToDelete(Collection<URI> reqDeleteVolumes, DbClient dbClient) throws InternalException {
    _log.info(String.format("Getting all RP volumes to delete for requested list: %s", reqDeleteVolumes));
    Set<URI> volumeIDs = new HashSet<URI>();
    Set<URI> protectionSetIds = new HashSet<URI>();
    Iterator<Volume> volumes = dbClient.queryIterativeObjects(Volume.class, reqDeleteVolumes, true);
    // Divide the RP volumes by BlockConsistencyGroup so we can determine if all volumes in the
    // RP consistency group are being removed.
    Map<URI, Set<URI>> cgsToVolumesForDelete = new HashMap<URI, Set<URI>>();
    // to that volume to the list of volumes to be deleted
    while (volumes.hasNext()) {
        Volume volume = volumes.next();
        // get the list of all source and target volumes in the same replication set as the
        // volume passed in
        List<Volume> allVolsInRSet = getVolumesInRSet(volume, dbClient);
        List<URI> allVolsInRSetURI = new ArrayList<URI>();
        URI cgURI = null;
        // 3. If partially ingested volume, clean up corresponding unmanaged protection set
        for (Volume vol : allVolsInRSet) {
            allVolsInRSetURI.add(vol.getId());
            if (!NullColumnValueGetter.isNullURI(vol.getConsistencyGroup())) {
                cgURI = vol.getConsistencyGroup();
            }
            if (!NullColumnValueGetter.isNullNamedURI(vol.getProtectionSet())) {
                // Keep track of the protection sets for a cleanup operation later in case we
                // find any stale volume references
                protectionSetIds.add(vol.getProtectionSet().getURI());
            }
            // If this is a partially ingested RP volume, clean up the corresponding unmanaged protection set
            List<UnManagedProtectionSet> umpsets = CustomQueryUtility.getUnManagedProtectionSetByManagedVolumeId(dbClient, vol.getId().toString());
            for (UnManagedProtectionSet umpset : umpsets) {
                umpset.getManagedVolumeIds().remove(vol.getId().toString());
                // Clean up the volume's reference, if any, in the unmanaged volumes associated with the unmanaged protection set
                for (String umv : umpset.getUnManagedVolumeIds()) {
                    UnManagedVolume umVolume = dbClient.queryObject(UnManagedVolume.class, URI.create(umv));
                    StringSet rpManagedSourceVolumeInfo = umVolume.getVolumeInformation().get(SupportedVolumeInformation.RP_MANAGED_SOURCE_VOLUME.toString());
                    StringSet rpManagedTargetVolumeInfo = umVolume.getVolumeInformation().get(SupportedVolumeInformation.RP_MANAGED_TARGET_VOLUMES.toString());
                    if (rpManagedSourceVolumeInfo != null && !rpManagedSourceVolumeInfo.isEmpty()) {
                        rpManagedSourceVolumeInfo.remove(vol.getId().toString());
                    }
                    if (rpManagedTargetVolumeInfo != null && !rpManagedTargetVolumeInfo.isEmpty()) {
                        rpManagedTargetVolumeInfo.remove(vol.getId().toString());
                    }
                    dbClient.updateObject(umVolume);
                }
                dbClient.updateObject(umpset);
            }
        }
        // Add the replication set volume IDs to the list of volumes to be deleted
        _log.info(String.format("Adding volume %s to the list of volumes to be deleted", allVolsInRSetURI.toString()));
        volumeIDs.addAll(allVolsInRSetURI);
        // the entire CG which would indicate journals are also being deleted.
        if (cgURI != null) {
            if (cgsToVolumesForDelete.get(cgURI) == null) {
                cgsToVolumesForDelete.put(cgURI, new HashSet<URI>());
            }
            cgsToVolumesForDelete.get(cgURI).addAll(allVolsInRSetURI);
        } else {
            _log.warn(String.format("Unable to find a valid CG for replication set volumes %s. Unable to determine if the entire CG is being deleted as part of this request.", allVolsInRSetURI.toString()));
        }
    }
    // Determine if we're deleting all of the volumes in this consistency group
    for (Map.Entry<URI, Set<URI>> cgToVolumesForDelete : cgsToVolumesForDelete.entrySet()) {
        BlockConsistencyGroup cg = null;
        URI cgURI = cgToVolumesForDelete.getKey();
        cg = dbClient.queryObject(BlockConsistencyGroup.class, cgURI);
        List<Volume> cgVolumes = getAllCgVolumes(cgURI, dbClient);
        // determine if all of the source and target volumes in the consistency group are on the list
        // of volumes to delete; if so, we will add the journal volumes to the list.
        // also create a list of stale volumes to be removed from the protection set
        boolean wholeCG = true;
        if (cgVolumes != null) {
            for (Volume cgVol : cgVolumes) {
                Set<URI> cgVolsToDelete = cgToVolumesForDelete.getValue();
                // determine if it's a journal or another source/target not being deleted.
                if (!cgVolsToDelete.contains(cgVol.getId())) {
                    // Do not consider VPlex backing volumes or inactive volumes
                    if (!cgVol.getInactive() && NullColumnValueGetter.isNotNullValue(cgVol.getPersonality())) {
                        if (!Volume.PersonalityTypes.METADATA.toString().equals(cgVol.getPersonality())) {
                            // the volume is either a source or target; this means there are other volumes in the rset
                            wholeCG = false;
                            break;
                        }
                    }
                }
            }
        }
        if (wholeCG) {
            // add them to the list of volumes to be removed
            if (cg != null) {
                List<Volume> allJournals = getCgVolumes(dbClient, cg.getId(), Volume.PersonalityTypes.METADATA.toString());
                if (allJournals != null && !allJournals.isEmpty()) {
                    Set<URI> allJournalURIs = new HashSet<URI>();
                    for (Volume journalVolume : allJournals) {
                        allJournalURIs.add(journalVolume.getId());
                    }
                    _log.info(String.format("Determined that this is a request to delete consistency group %s.  Adding journal volumes to the list of volumes to delete: %s", cgURI, allJournalURIs.toString()));
                    volumeIDs.addAll(allJournalURIs);
                }
            } else {
                _log.info(String.format("Could not determine journal volumes for consistency group %s .", cgToVolumesForDelete.getKey()));
            }
        } else {
            _log.info(String.format("Consistency group %s will not be removed.  Only a subset of the replication sets are being removed.", cgToVolumesForDelete.getKey()));
        }
    }
    // "bad things" from happening.
    for (URI protSetId : protectionSetIds) {
        List<String> staleVolumes = new ArrayList<String>();
        ProtectionSet protectionSet = dbClient.queryObject(ProtectionSet.class, protSetId);
        if (protectionSet.getVolumes() != null) {
            for (String protSetVol : protectionSet.getVolumes()) {
                URI protSetVolUri = URI.create(protSetVol);
                if (!volumeIDs.contains(protSetVolUri)) {
                    Volume vol = dbClient.queryObject(Volume.class, protSetVolUri);
                    if (vol == null || vol.getInactive()) {
                        // The ProtectionSet references a stale volume that no longer exists in the DB.
                        _log.info("ProtectionSet " + protectionSet.getLabel() + " references volume " + protSetVol + " that no longer exists in the DB.  Removing this volume reference.");
                        staleVolumes.add(protSetVol);
                    }
                }
            }
        }
        // remove stale entries from protection set
        if (!staleVolumes.isEmpty()) {
            for (String vol : staleVolumes) {
                protectionSet.getVolumes().remove(vol);
            }
            dbClient.updateObject(protectionSet);
        }
    }
    return volumeIDs;
}
Also used : ProtectionSet(com.emc.storageos.db.client.model.ProtectionSet) Set(java.util.Set) HashSet(java.util.HashSet) UnManagedProtectionSet(com.emc.storageos.db.client.model.UnManagedDiscoveredObjects.UnManagedProtectionSet) AbstractChangeTrackingSet(com.emc.storageos.db.client.model.AbstractChangeTrackingSet) StringSet(com.emc.storageos.db.client.model.StringSet) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) ProtectionSet(com.emc.storageos.db.client.model.ProtectionSet) UnManagedProtectionSet(com.emc.storageos.db.client.model.UnManagedDiscoveredObjects.UnManagedProtectionSet) NamedURI(com.emc.storageos.db.client.model.NamedURI) URI(java.net.URI) UnManagedProtectionSet(com.emc.storageos.db.client.model.UnManagedDiscoveredObjects.UnManagedProtectionSet) BlockConsistencyGroup(com.emc.storageos.db.client.model.BlockConsistencyGroup) UnManagedVolume(com.emc.storageos.db.client.model.UnManagedDiscoveredObjects.UnManagedVolume) Volume(com.emc.storageos.db.client.model.Volume) UnManagedVolume(com.emc.storageos.db.client.model.UnManagedDiscoveredObjects.UnManagedVolume) StringSet(com.emc.storageos.db.client.model.StringSet) Map(java.util.Map) OpStatusMap(com.emc.storageos.db.client.model.OpStatusMap) HashMap(java.util.HashMap) TreeMap(java.util.TreeMap) StringMap(com.emc.storageos.db.client.model.StringMap) HashSet(java.util.HashSet)

Aggregations

ProtectionSet (com.emc.storageos.db.client.model.ProtectionSet)57 Volume (com.emc.storageos.db.client.model.Volume)39 URI (java.net.URI)30 NamedURI (com.emc.storageos.db.client.model.NamedURI)26 ArrayList (java.util.ArrayList)25 StringSet (com.emc.storageos.db.client.model.StringSet)18 UnManagedProtectionSet (com.emc.storageos.db.client.model.UnManagedDiscoveredObjects.UnManagedProtectionSet)14 BlockConsistencyGroup (com.emc.storageos.db.client.model.BlockConsistencyGroup)13 UnManagedVolume (com.emc.storageos.db.client.model.UnManagedDiscoveredObjects.UnManagedVolume)11 URISyntaxException (java.net.URISyntaxException)10 URIQueryResultList (com.emc.storageos.db.client.constraint.URIQueryResultList)9 BlockSnapshot (com.emc.storageos.db.client.model.BlockSnapshot)9 ProtectionSystem (com.emc.storageos.db.client.model.ProtectionSystem)9 RecoverPointClient (com.emc.storageos.recoverpoint.impl.RecoverPointClient)9 HashSet (java.util.HashSet)8 DatabaseException (com.emc.storageos.db.exceptions.DatabaseException)7 RecoverPointException (com.emc.storageos.recoverpoint.exceptions.RecoverPointException)7 FunctionalAPIActionFailedException_Exception (com.emc.fapiclient.ws.FunctionalAPIActionFailedException_Exception)6 FunctionalAPIInternalError_Exception (com.emc.fapiclient.ws.FunctionalAPIInternalError_Exception)6 RecoverPointVolumeIngestionContext (com.emc.storageos.api.service.impl.resource.blockingestorchestration.context.impl.RecoverPointVolumeIngestionContext)6