Search in sources :

Example 1 with VolumeVpoolAutoTieringPolicyChangeTaskCompleter

use of com.emc.storageos.volumecontroller.impl.block.taskcompleter.VolumeVpoolAutoTieringPolicyChangeTaskCompleter in project coprhd-controller by CoprHD.

the class BlockDeviceExportController method updatePolicyAndLimits.

@Override
public void updatePolicyAndLimits(List<URI> volumeURIs, URI newVpoolURI, String opId) throws ControllerException {
    _log.info("Received request to update Auto-tiering policy. Creating master workflow.");
    VolumeVpoolAutoTieringPolicyChangeTaskCompleter taskCompleter = null;
    URI oldVpoolURI = null;
    List<Volume> volumes = new ArrayList<Volume>();
    List<Volume> vplexBackendVolumes = new ArrayList<Volume>();
    try {
        // Read volume from database, update the vPool to the new vPool
        // and update new auto tiering policy uri, and create task completer.
        volumes = _dbClient.queryObject(Volume.class, volumeURIs);
        VirtualPool newVpool = _dbClient.queryObject(VirtualPool.class, newVpoolURI);
        Map<URI, URI> oldVolToPolicyMap = new HashMap<URI, URI>();
        for (Volume volume : volumes) {
            oldVpoolURI = volume.getVirtualPool();
            volume.setVirtualPool(newVpoolURI);
            _log.info(String.format("Changing VirtualPool Auto-tiering Policy for volume %s (%s) from %s to %s", volume.getLabel(), volume.getId(), oldVpoolURI, newVpoolURI));
            oldVolToPolicyMap.put(volume.getId(), volume.getAutoTieringPolicyUri());
            updateAutoTieringPolicyUriInVolume(volume, newVpool);
            // Check if it is a VPlex volume, and get backend volumes
            Volume backendSrc = VPlexUtil.getVPLEXBackendVolume(volume, true, _dbClient, false);
            if (backendSrc != null) {
                // Change the back end volume's vPool too
                backendSrc.setVirtualPool(newVpoolURI);
                vplexBackendVolumes.add(backendSrc);
                _log.info(String.format("Changing VirtualPool Auto-tiering Policy for VPLEX backend source volume %s (%s) from %s to %s", backendSrc.getLabel(), backendSrc.getId(), oldVpoolURI, newVpoolURI));
                oldVolToPolicyMap.put(backendSrc.getId(), backendSrc.getAutoTieringPolicyUri());
                updateAutoTieringPolicyUriInVolume(backendSrc, newVpool);
                // VPlex volume, check if it is distributed
                Volume backendHa = VPlexUtil.getVPLEXBackendVolume(volume, false, _dbClient, false);
                if (backendHa != null) {
                    VirtualPool newHAVpool = VirtualPool.getHAVPool(newVpool, _dbClient);
                    if (newHAVpool == null) {
                        // it may not be set
                        newHAVpool = newVpool;
                    }
                    backendHa.setVirtualPool(newHAVpool.getId());
                    vplexBackendVolumes.add(backendHa);
                    _log.info(String.format("Changing VirtualPool Auto-tiering Policy for VPLEX backend distributed volume %s (%s) from %s to %s", backendHa.getLabel(), backendHa.getId(), oldVpoolURI, newHAVpool.getId()));
                    oldVolToPolicyMap.put(backendHa.getId(), backendHa.getAutoTieringPolicyUri());
                    updateAutoTieringPolicyUriInVolume(backendHa, newHAVpool);
                }
            }
        }
        _dbClient.updateObject(volumes);
        _dbClient.updateObject(vplexBackendVolumes);
        // The VolumeVpoolChangeTaskCompleter will restore the old Virtual Pool
        // and old auto tiering policy in event of error.
        // Assume all volumes belong to the same vPool. This should be take care by BlockService API.
        taskCompleter = new VolumeVpoolAutoTieringPolicyChangeTaskCompleter(volumeURIs, oldVpoolURI, oldVolToPolicyMap, opId);
    } catch (Exception ex) {
        _log.error("Unexpected exception reading volume or generating taskCompleter: ", ex);
        ServiceError serviceError = DeviceControllerException.errors.jobFailed(ex);
        VolumeWorkflowCompleter completer = new VolumeWorkflowCompleter(volumeURIs, opId);
        completer.error(_dbClient, serviceError);
    }
    try {
        Workflow workflow = _wfUtils.newWorkflow("updateAutoTieringPolicy", false, opId);
        /**
         * For VMAX:
         * get corresponding export mask for each volume
         * group volumes by export mask
         * create workflow step for each export mask.
         *
         * For VNX Block:
         * Policy is set on volume during its creation.
         * Whether it is exported or not, send all volumes
         * to update StorageTierMethodology property on them.
         * Create workflow step for each storage system.
         */
        // Use backend volumes list if it is VPLEX volume
        List<Volume> volumesToUse = !vplexBackendVolumes.isEmpty() ? vplexBackendVolumes : volumes;
        // move applicable volumes from all volumes list to a separate list.
        Map<URI, List<URI>> systemToVolumeMap = getVolumesToModify(volumesToUse);
        String stepId = null;
        for (URI systemURI : systemToVolumeMap.keySet()) {
            stepId = _wfUtils.generateExportChangePolicyAndLimits(workflow, "updateAutoTieringPolicy", stepId, systemURI, null, null, systemToVolumeMap.get(systemURI), newVpoolURI, oldVpoolURI);
        }
        Map<URI, List<URI>> storageToNotExportedVolumesMap = new HashMap<URI, List<URI>>();
        Map<URI, List<URI>> exportMaskToVolumeMap = new HashMap<URI, List<URI>>();
        Map<URI, URI> maskToGroupURIMap = new HashMap<URI, URI>();
        for (Volume volume : volumesToUse) {
            // Locate all the ExportMasks containing the given volume
            Map<ExportMask, ExportGroup> maskToGroupMap = ExportUtils.getExportMasks(volume, _dbClient);
            if (maskToGroupMap.isEmpty()) {
                URI storageURI = volume.getStorageController();
                StorageSystem storage = _dbClient.queryObject(StorageSystem.class, storageURI);
                if (storage.checkIfVmax3()) {
                    if (!storageToNotExportedVolumesMap.containsKey(storageURI)) {
                        storageToNotExportedVolumesMap.put(storageURI, new ArrayList<URI>());
                    }
                    storageToNotExportedVolumesMap.get(storageURI).add(volume.getId());
                }
            }
            for (ExportMask mask : maskToGroupMap.keySet()) {
                if (!exportMaskToVolumeMap.containsKey(mask.getId())) {
                    exportMaskToVolumeMap.put(mask.getId(), new ArrayList<URI>());
                }
                exportMaskToVolumeMap.get(mask.getId()).add(volume.getId());
                maskToGroupURIMap.put(mask.getId(), maskToGroupMap.get(mask).getId());
            }
        }
        VirtualPool oldVpool = _dbClient.queryObject(VirtualPool.class, oldVpoolURI);
        for (URI exportMaskURI : exportMaskToVolumeMap.keySet()) {
            ExportMask exportMask = _dbClient.queryObject(ExportMask.class, exportMaskURI);
            List<URI> exportMaskVolumes = exportMaskToVolumeMap.get(exportMaskURI);
            URI exportMaskNewVpool = newVpoolURI;
            URI exportMaskOldVpool = oldVpoolURI;
            Volume vol = _dbClient.queryObject(Volume.class, exportMaskVolumes.get(0));
            // all volumes are already updated with respective new vPool
            if (Volume.checkForVplexBackEndVolume(_dbClient, vol) && !newVpoolURI.equals(vol.getVirtualPool())) {
                // backend distributed volume; HA vPool set in Vplex vPool
                exportMaskNewVpool = vol.getVirtualPool();
                VirtualPool oldHAVpool = VirtualPool.getHAVPool(oldVpool, _dbClient);
                if (oldHAVpool == null) {
                    // it may not be set
                    oldHAVpool = oldVpool;
                }
                exportMaskOldVpool = oldHAVpool.getId();
            }
            stepId = _wfUtils.generateExportChangePolicyAndLimits(workflow, "updateAutoTieringPolicy", stepId, exportMask.getStorageDevice(), exportMaskURI, maskToGroupURIMap.get(exportMaskURI), exportMaskVolumes, exportMaskNewVpool, exportMaskOldVpool);
        }
        for (URI storageURI : storageToNotExportedVolumesMap.keySet()) {
            stepId = _wfUtils.generateChangeAutoTieringPolicy(workflow, "updateAutoTieringPolicyForNotExportedVMAX3Volumes", stepId, storageURI, storageToNotExportedVolumesMap.get(storageURI), newVpoolURI, oldVpoolURI);
        }
        if (!workflow.getAllStepStatus().isEmpty()) {
            _log.info("The updateAutoTieringPolicy workflow has {} step(s). Starting the workflow.", workflow.getAllStepStatus().size());
            workflow.executePlan(taskCompleter, "Updated the export group on all storage systems successfully.");
        } else {
            taskCompleter.ready(_dbClient);
        }
    } catch (Exception ex) {
        _log.error("Unexpected exception: ", ex);
        ServiceError serviceError = DeviceControllerException.errors.jobFailed(ex);
        taskCompleter.error(_dbClient, serviceError);
    }
}
Also used : VolumeVpoolAutoTieringPolicyChangeTaskCompleter(com.emc.storageos.volumecontroller.impl.block.taskcompleter.VolumeVpoolAutoTieringPolicyChangeTaskCompleter) ServiceError(com.emc.storageos.svcs.errorhandling.model.ServiceError) HashMap(java.util.HashMap) VolumeWorkflowCompleter(com.emc.storageos.volumecontroller.impl.block.taskcompleter.VolumeWorkflowCompleter) ExportMask(com.emc.storageos.db.client.model.ExportMask) ArrayList(java.util.ArrayList) Workflow(com.emc.storageos.workflow.Workflow) VirtualPool(com.emc.storageos.db.client.model.VirtualPool) URI(java.net.URI) DeviceControllerException(com.emc.storageos.exceptions.DeviceControllerException) ControllerException(com.emc.storageos.volumecontroller.ControllerException) IOException(java.io.IOException) LockRetryException(com.emc.storageos.locking.LockRetryException) ExportGroup(com.emc.storageos.db.client.model.ExportGroup) Volume(com.emc.storageos.db.client.model.Volume) List(java.util.List) ArrayList(java.util.ArrayList) StorageSystem(com.emc.storageos.db.client.model.StorageSystem)

Aggregations

ExportGroup (com.emc.storageos.db.client.model.ExportGroup)1 ExportMask (com.emc.storageos.db.client.model.ExportMask)1 StorageSystem (com.emc.storageos.db.client.model.StorageSystem)1 VirtualPool (com.emc.storageos.db.client.model.VirtualPool)1 Volume (com.emc.storageos.db.client.model.Volume)1 DeviceControllerException (com.emc.storageos.exceptions.DeviceControllerException)1 LockRetryException (com.emc.storageos.locking.LockRetryException)1 ServiceError (com.emc.storageos.svcs.errorhandling.model.ServiceError)1 ControllerException (com.emc.storageos.volumecontroller.ControllerException)1 VolumeVpoolAutoTieringPolicyChangeTaskCompleter (com.emc.storageos.volumecontroller.impl.block.taskcompleter.VolumeVpoolAutoTieringPolicyChangeTaskCompleter)1 VolumeWorkflowCompleter (com.emc.storageos.volumecontroller.impl.block.taskcompleter.VolumeWorkflowCompleter)1 Workflow (com.emc.storageos.workflow.Workflow)1 IOException (java.io.IOException)1 URI (java.net.URI)1 ArrayList (java.util.ArrayList)1 HashMap (java.util.HashMap)1 List (java.util.List)1