Search in sources :

Example 6 with SmisJob

use of com.emc.storageos.volumecontroller.impl.smis.job.SmisJob in project coprhd-controller by CoprHD.

the class SmisMetaVolumeOperations method expandVolumeAsMetaVolume.

/**
 * Expand regular volume as a meta volume.
 *
 * @param storageSystem
 * @param metaHead
 * @param metaMembers
 * @param metaType
 * @param metaVolumeTaskCompleter
 * @throws DeviceControllerException
 */
@Override
public void expandVolumeAsMetaVolume(StorageSystem storageSystem, StoragePool storagePool, Volume metaHead, List<String> metaMembers, String metaType, MetaVolumeTaskCompleter metaVolumeTaskCompleter) throws DeviceControllerException {
    String label = null;
    _log.info(String.format("Expand Volume as  Meta Volume Start - Array: %s, Head: %s, Recommended meta type: %s %n   Members:%s", storageSystem.getSerialNumber(), metaHead.getLabel(), metaType, metaMembers));
    label = metaHead.getLabel();
    boolean isRPVolume = false;
    if (metaHead != null) {
        // A volume is of type RP if the volume has an RP copy name or it's a VPlex backing volume associated to a
        // VPlex RP source volume.
        isRPVolume = metaHead.checkForRp() || RPHelper.isAssociatedToAnyRpVplexTypes(metaHead, _dbClient);
    }
    // initialize the retry/attempt variables
    int attempt = 0;
    int retries = 1;
    if (isRPVolume) {
        // if we are dealing with an RP volume, we need to set the retry count appropriately
        retries = MAX_RP_EXPAND_RETRIES;
    }
    // has not been received or processed yet.
    while (attempt++ <= retries) {
        try {
            CIMObjectPath elementCompositionServicePath = _cimPath.getElementCompositionSvcPath(storageSystem);
            CIMArgument[] inArgs;
            inArgs = _helper.getCreateMetaVolumeInputArguments(storageSystem, label, metaHead, metaMembers, metaType, true);
            CIMArgument[] outArgs = new CIMArgument[5];
            // TODO evaluate use of asunc call for the last operation in extend sequence
            // _helper.invokeMethod(storageSystem, elementCompositionServicePath, SmisConstants.CREATE_OR_MODIFY_COMPOSITE_ELEMENT,
            // inArgs,
            // outArgs);
            // CIMObjectPath job = _cimPath.getCimObjectPathFromOutputArgs(outArgs, SmisConstants.JOB);
            // if (job != null) {
            // ControllerServiceImpl.enqueueJob(new QueueJob(new SmisVolumeExpandJob(job, storageSystem.getId(),
            // taskCompleter, "ExpandAsMetaVolume")));
            // }
            // 
            StorageSystem forProvider = _helper.getStorageSystemForProvider(storageSystem, metaHead);
            _log.info("Selected Provider : {}", forProvider.getNativeGuid());
            SmisJob smisJobCompleter = new SmisVolumeExpandJob(null, forProvider.getId(), storagePool.getId(), metaVolumeTaskCompleter, "ExpandAsMetaVolume");
            if (isRPVolume) {
                _log.info(String.format("Attempt %s/%s to expand volume %s, which is associated with RecoverPoint", attempt, MAX_RP_EXPAND_RETRIES, metaHead.getLabel()));
            }
            _helper.invokeMethodSynchronously(forProvider, elementCompositionServicePath, SmisConstants.CREATE_OR_MODIFY_COMPOSITE_ELEMENT, inArgs, outArgs, smisJobCompleter);
            // No exceptions so break out of the retry loop
            break;
        } catch (WBEMException e) {
            _log.error("Problem making SMI-S call: ", e);
            ServiceError error = DeviceControllerErrors.smis.unableToCallStorageProvider(e.getMessage());
            metaVolumeTaskCompleter.getVolumeTaskCompleter().error(_dbClient, _locker, error);
        } catch (Exception e) {
            if (attempt != retries && isRPVolume && e.getMessage().contains("The requested device has active sessions")) {
                // RP has issued an async request to terminate the active session so we just need to wait
                // and retry the expand.
                _log.warn(String.format("Encountered exception attempting to expand RP volume %s.  Waiting %s milliseconds before trying again.  Error: %s", metaHead.getLabel(), RP_EXPAND_WAIT_FOR_RETRY, e.getMessage()));
                try {
                    Thread.sleep(RP_EXPAND_WAIT_FOR_RETRY);
                } catch (InterruptedException e1) {
                    Thread.currentThread().interrupt();
                }
            } else {
                _log.error("Problem in expandVolumeAsMetaVolume: ", e);
                ServiceError error = DeviceControllerErrors.smis.methodFailed("expandVolumeAsMetaVolume", e.getMessage());
                metaVolumeTaskCompleter.getVolumeTaskCompleter().error(_dbClient, _locker, error);
                // Break out of the retry loop
                break;
            }
        }
    }
    _log.info(String.format("Expand Volume as  Meta Volume End - Array:%s, Head:%s, %n  Head device ID: %s, Members:%s", storageSystem.getSerialNumber(), metaHead.getLabel(), metaHead.getNativeId(), metaMembers));
}
Also used : ServiceError(com.emc.storageos.svcs.errorhandling.model.ServiceError) CIMObjectPath(javax.cim.CIMObjectPath) WBEMException(javax.wbem.WBEMException) WBEMException(javax.wbem.WBEMException) DatabaseException(com.emc.storageos.db.exceptions.DatabaseException) DeviceControllerException(com.emc.storageos.exceptions.DeviceControllerException) SmisJob(com.emc.storageos.volumecontroller.impl.smis.job.SmisJob) CIMArgument(javax.cim.CIMArgument) StorageSystem(com.emc.storageos.db.client.model.StorageSystem) SmisVolumeExpandJob(com.emc.storageos.volumecontroller.impl.smis.job.SmisVolumeExpandJob)

Example 7 with SmisJob

use of com.emc.storageos.volumecontroller.impl.smis.job.SmisJob in project coprhd-controller by CoprHD.

the class SmisMetaVolumeOperations method expandMetaVolume.

/**
 * Expand meta volume.
 *
 * @param storageSystem
 * @param metaHead
 * @param newMetaMembers
 * @param metaVolumeTaskCompleter
 * @throws DeviceControllerException
 */
@Override
public void expandMetaVolume(StorageSystem storageSystem, StoragePool storagePool, Volume metaHead, List<String> newMetaMembers, MetaVolumeTaskCompleter metaVolumeTaskCompleter) throws DeviceControllerException {
    _log.info(String.format("Expand Meta Volume Start - Array: %s, Head: %s, %n   New members:%s", storageSystem.getSerialNumber(), metaHead.getLabel(), newMetaMembers));
    boolean isRPVolume = false;
    if (metaHead != null) {
        // A volume is of type RP if the volume has an RP copy name or it's a VPlex backing volume associated to a
        // VPlex RP source volume.
        isRPVolume = metaHead.checkForRp() || RPHelper.isAssociatedToAnyRpVplexTypes(metaHead, _dbClient);
    }
    // initialize the retry/attempt variables
    int attempt = 0;
    int retries = 1;
    if (isRPVolume) {
        // if we are dealing with an RP volume, we need to set the retry count appropriately
        retries = MAX_RP_EXPAND_RETRIES;
    }
    // has not been received or processed yet.
    while (attempt++ <= retries) {
        try {
            CIMObjectPath elementCompositionServicePath = _cimPath.getElementCompositionSvcPath(storageSystem);
            CIMArgument[] inArgs;
            inArgs = _helper.getExpandMetaVolumeInputArguments(storageSystem, metaHead, newMetaMembers);
            CIMArgument[] outArgs = new CIMArgument[5];
            // TODO evaluate use of asunc call for the last operation in extend sequence
            // _helper.invokeMethod(storageSystem, elementCompositionServicePath, SmisConstants.CREATE_OR_MODIFY_COMPOSITE_ELEMENT,
            // inArgs,
            // outArgs);
            // CIMObjectPath job = _cimPath.getCimObjectPathFromOutputArgs(outArgs, SmisConstants.JOB);
            // if (job != null) {
            // ControllerServiceImpl.enqueueJob(new QueueJob(new SmisVolumeExpandJob(job, storageSystem.getId(),
            // taskCompleter, "ExpandMetaVolume")));
            // }
            StorageSystem forProvider = _helper.getStorageSystemForProvider(storageSystem, metaHead);
            _log.info("Selected Provider : {}", forProvider.getNativeGuid());
            SmisJob smisJobCompleter = new SmisVolumeExpandJob(null, forProvider.getId(), storagePool.getId(), metaVolumeTaskCompleter, "ExpandMetaVolume");
            if (isRPVolume) {
                _log.info(String.format("Attempt %s/%s to expand volume %s, which is associated with RecoverPoint", attempt, MAX_RP_EXPAND_RETRIES, metaHead.getLabel()));
            }
            _helper.invokeMethodSynchronously(forProvider, elementCompositionServicePath, SmisConstants.CREATE_OR_MODIFY_COMPOSITE_ELEMENT, inArgs, outArgs, smisJobCompleter);
            // No exceptions so break out of the retry loop
            break;
        } catch (WBEMException e) {
            _log.error("Problem making SMI-S call: ", e);
            ServiceError error = DeviceControllerErrors.smis.unableToCallStorageProvider(e.getMessage());
            metaVolumeTaskCompleter.getVolumeTaskCompleter().error(_dbClient, _locker, error);
        } catch (Exception e) {
            if (attempt != retries && isRPVolume && e.getMessage().contains("The requested device has active sessions")) {
                // RP has issued an async request to terminate the active session so we just need to wait
                // and retry the expand.
                _log.warn(String.format("Encountered exception attempting to expand RP volume %s.  Waiting %s milliseconds before trying again.  Error: %s", metaHead.getLabel(), RP_EXPAND_WAIT_FOR_RETRY, e.getMessage()));
                try {
                    Thread.sleep(RP_EXPAND_WAIT_FOR_RETRY);
                } catch (InterruptedException e1) {
                    Thread.currentThread().interrupt();
                }
            } else {
                _log.error("Problem in expandMetaVolume: ", e);
                ServiceError error = DeviceControllerErrors.smis.methodFailed("expandVolume", e.getMessage());
                metaVolumeTaskCompleter.getVolumeTaskCompleter().error(_dbClient, _locker, error);
                // Break out of the retry loop
                break;
            }
        }
    }
    _log.info(String.format("Expand Meta Volume End - Array:%s, Head:%s, %n  Head device ID: %s, New members:%s", storageSystem.getSerialNumber(), metaHead.getLabel(), metaHead.getNativeId(), newMetaMembers));
}
Also used : ServiceError(com.emc.storageos.svcs.errorhandling.model.ServiceError) CIMObjectPath(javax.cim.CIMObjectPath) SmisJob(com.emc.storageos.volumecontroller.impl.smis.job.SmisJob) WBEMException(javax.wbem.WBEMException) WBEMException(javax.wbem.WBEMException) DatabaseException(com.emc.storageos.db.exceptions.DatabaseException) DeviceControllerException(com.emc.storageos.exceptions.DeviceControllerException) CIMArgument(javax.cim.CIMArgument) StorageSystem(com.emc.storageos.db.client.model.StorageSystem) SmisVolumeExpandJob(com.emc.storageos.volumecontroller.impl.smis.job.SmisVolumeExpandJob)

Example 8 with SmisJob

use of com.emc.storageos.volumecontroller.impl.smis.job.SmisJob in project coprhd-controller by CoprHD.

the class VmaxExportOperations method validateAndUpdateStorageGroupPolicyAndLimits.

/**
 * Validates and updates fast policy in storage group.
 *
 * @param storage
 *            the storage system
 * @param exportMask
 *            exportMask
 * @param childGroupName
 *            the child group name
 * @param volumeURIs
 *            the volume uris
 * @param newVirtualPool
 *            the new virtual pool where new policy name and host limits can be obtained
 * @param phantomSGNames
 *            the phantom SG names if any
 * @param taskCompleter
 *            task completer
 * @return true, if successfully updated policy for SG
 * @throws WBEMException
 *             the wBEM exception
 * @throws Exception
 *             the exception
 */
private boolean validateAndUpdateStorageGroupPolicyAndLimits(StorageSystem storage, ExportMask exportMask, String childGroupName, List<URI> volumeURIs, VirtualPool newVirtualPool, Set<String> phantomSGNames, TaskCompleter taskCompleter) throws WBEMException, Exception {
    boolean policyUpdated = false;
    boolean isVmax3 = storage.checkIfVmax3();
    _log.info("Checking on Storage Group {}", childGroupName);
    WBEMClient client = _helper.getConnection(storage).getCimClient();
    // we need auto tiering policy object to get its name.
    String newPolicyName = ControllerUtils.getFastPolicyNameFromVirtualPool(_dbClient, storage, newVirtualPool);
    if (isVmax3) {
        newPolicyName = _helper.getVMAX3FastSettingForVolume(volumeURIs.get(0), newPolicyName);
    }
    StorageGroupPolicyLimitsParam newVirtualPoolPolicyLimits = new StorageGroupPolicyLimitsParam(newPolicyName, newVirtualPool.getHostIOLimitBandwidth(), newVirtualPool.getHostIOLimitIOPs(), newVirtualPool.getCompressionEnabled(), storage);
    CIMObjectPath childGroupPath = _cimPath.getMaskingGroupPath(storage, childGroupName, SmisCommandHelper.MASKING_GROUP_TYPE.SE_DeviceMaskingGroup);
    if (isVmax3) {
        /**
         * VMAX3 part of multiple exports: volumes will be part of multiple SGs
         * One as FAST SG and others as non-FAST SG.
         * If the requested SG is non FAST, do nothing. Other export mask's call
         * will take care of updating FAST setting.
         */
        BlockObject bo = BlockObject.fetch(_dbClient, volumeURIs.get(0));
        if (_helper.isVolumePartOfMoreThanOneExport(storage, bo)) {
            String currentPolicyName = _helper.getVMAX3FastSettingAssociatedWithVolumeGroup(storage, childGroupPath);
            if (Constants.NONE.equalsIgnoreCase(currentPolicyName) && _helper.checkVolumeAssociatedWithAnyFASTSG(bo.getNativeId(), storage)) {
                Map<ExportMask, ExportGroup> maskToGroupMap = ExportUtils.getExportMasks(bo, _dbClient);
                if (maskToGroupMap.size() > 1) {
                    _log.info("Volumes {} are part of multiple storage groups. " + "FAST Policy will be (or might already be) changed during other export mask's call.", Joiner.on("\t").join(volumeURIs));
                    return true;
                } else {
                    _log.error("FAST Policy cannot be updated on this storage group" + " since volumes are already part of another FAST managed storage group.");
                    return false;
                }
            }
        }
    }
    if (!isVmax3 && !phantomSGNames.isEmpty() && !_helper.isFastPolicy(_helper.getAutoTieringPolicyNameAssociatedWithVolumeGroup(storage, childGroupPath)) && !_helper.isCascadedSG(storage, childGroupPath)) {
        /**
         * Phantom SG will be taken into consideration only if MV contains Non-cascaded Non-FAST SG
         */
        _log.info("**** Phantom Storage Group ****");
        /**
         * For Volumes in Phantom SG - Volumes part of Phantom SG will be in Non-cascaded Non-FAST Storage Group
         * (CTRL-9064)
         *
         * We have the phantom SGs having volumes which are part of this Masking view
         * Group requested volumes by SG
         * volumes in each Phantom SG
         * also add an entry with volumes to Non-FAST SG (volumes requested minus volumes already in phantom SG)
         *
         * For each SG,
         * If Phantom SG:
         * If it is requested for all volumes
         * change the policy associated with phantom SG
         * else
         * Remove the volumes from that phantom SG
         * add them to new/existing phantom SG which is associated with new policy
         * Note: if new policy is NONE, we just remove the volumes from phantom SG, no need to add them to another
         * phantom SG.
         * Since these volumes are already part of Non-FAST SG, they are part of MV.
         * Else if it is Non-FAST SG:
         * place those volumes in new/existing Phantom SG which is associated with new Policy
         */
        Map<String, List<URI>> volumeGroup = new HashMap<String, List<URI>>();
        List<URI> volumeURIsOfNonFASTSG = new ArrayList<URI>();
        volumeURIsOfNonFASTSG.addAll(volumeURIs);
        for (String phantomSGName : phantomSGNames) {
            List<URI> volURIs = _helper.findVolumesInStorageGroup(storage, phantomSGName, volumeURIs);
            if (!volURIs.isEmpty()) {
                volumeGroup.put(phantomSGName, volURIs);
                volumeURIsOfNonFASTSG.removeAll(volURIs);
            }
        }
        // put Non-FAST SG with volumes (volumes requested minus volumes already in phantom SG)
        if (!volumeURIsOfNonFASTSG.isEmpty()) {
            volumeGroup.put(childGroupName, volumeURIsOfNonFASTSG);
        }
        for (Entry<String, List<URI>> sgNameToVolumes : volumeGroup.entrySet()) {
            String sgName = sgNameToVolumes.getKey();
            List<URI> volumesInSG = sgNameToVolumes.getValue();
            CIMObjectPath sgPath = _cimPath.getMaskingGroupPath(storage, sgName, SmisCommandHelper.MASKING_GROUP_TYPE.SE_DeviceMaskingGroup);
            // Flag to indicate whether or not we need to use the EMCForce flag on this operation.
            // We currently use this flag when dealing with RP Volumes as they are tagged for RP and the
            // operation on these volumes would fail otherwise.
            boolean forceFlag = false;
            for (URI volURI : volumesInSG) {
                // The force flag only needs to be set once
                if (!forceFlag) {
                    forceFlag = ExportUtils.useEMCForceFlag(_dbClient, volURI);
                }
            }
            /**
             * update Policy on this SG. We don't use Phantom SG for IO Limits
             */
            String currentPolicyName = _helper.getAutoTieringPolicyNameAssociatedWithVolumeGroup(storage, sgPath);
            _log.info("FAST policy name associated with Storage Group {} : {}", sgName, currentPolicyName);
            if (!_helper.isFastPolicy(currentPolicyName)) {
                /**
                 * Not a Phantom SG. Create new or use existing Phantom SG for the requested volumes
                 * Request: non-FAST volumes in SG (associated with MV) to FAST volumes
                 */
                addVolumesToPhantomStorageGroup(storage, exportMask, volumesInSG, newPolicyName, childGroupName, taskCompleter, forceFlag);
            } else {
                /**
                 * phantom SG
                 */
                _log.info("Checking on Phantom Storage Group {}", sgName);
                // check if phantom SG has the same set of volumes as the volume list provided
                if (isGivenVolumeListSameAsInStorageGroup(storage, sgPath, volumesInSG)) {
                    _log.info("Changing Policy on Phantom Storage Group {} since it is requested " + "for all the volumes in the Group.", sgName);
                    if (!currentPolicyName.equalsIgnoreCase(newPolicyName)) {
                        if (_helper.isFastPolicy(currentPolicyName)) {
                            _helper.removeVolumeGroupFromAutoTieringPolicy(storage, sgPath);
                        }
                        if (_helper.isFastPolicy(newPolicyName)) {
                            _log.info("Adding Storage Group {} to FAST Policy {}", sgName, newPolicyName);
                            addVolumeGroupToAutoTieringPolicy(storage, newPolicyName, sgPath, taskCompleter);
                            StorageGroupPolicyLimitsParam phantomStorageGroupPolicyLimitsParam = new StorageGroupPolicyLimitsParam(newPolicyName);
                            String newSGName = generateNewNameForPhantomSG(storage, childGroupName, phantomStorageGroupPolicyLimitsParam);
                            // update SG name according to new policy
                            _helper.updateStorageGroupName(client, sgPath, newSGName);
                        }
                    } else {
                        _log.info("Current and new policy names are same '{}'." + " No need to update it on SG.", currentPolicyName);
                    }
                    /**
                     * if new policy is NONE & all volumes in request
                     * remove phantom SG since it won't be needed anymore
                     * (because volumes are already part of Non-FAST SG associated with MV)
                     * Request: FAST volumes to Non-FAST
                     */
                    if (!_helper.isFastPolicy(newPolicyName)) {
                        removePhantomStorageGroup(storage, client, exportMask.getId(), sgName, sgPath, volumesInSG, forceFlag);
                    }
                } else {
                    /**
                     * remove requested volumes from this phantom SG
                     * add them to the new/existing phantom SG which is associated with target policy
                     */
                    _log.info("Request is made for part of volumes in the Group");
                    removePhantomStorageGroup(storage, client, exportMask.getId(), sgName, sgPath, volumesInSG, forceFlag);
                    if (_helper.isFastPolicy(newPolicyName)) {
                        addVolumesToPhantomStorageGroup(storage, exportMask, volumesInSG, newPolicyName, childGroupName, taskCompleter, forceFlag);
                    }
                }
            }
            policyUpdated = true;
        }
    } else {
        /**
         * Usual flow for regular SGs
         *
         * check if SG has the same set of volumes as the volume list provided.
         */
        if (isGivenVolumeListSameAsInStorageGroup(storage, childGroupPath, volumeURIs)) {
            /**
             * update Policy and Limits on this SG
             */
            _log.info("Request is made for all volumes in the Group. Updating Policy and Limits on this Storage Group..");
            CIMInstance childGroupInstance = null;
            if (isVmax3) {
                childGroupInstance = _helper.getInstance(storage, childGroupPath, false, false, SmisConstants.PS_V3_STORAGE_GROUP_PROPERTIES);
            } else {
                childGroupInstance = _helper.checkExists(storage, childGroupPath, false, false);
            }
            StorageGroupPolicyLimitsParam currentStorageGroupPolicyLimits = _helper.createStorageGroupPolicyLimitsParam(storage, childGroupInstance);
            String currentPolicyName = currentStorageGroupPolicyLimits.getAutoTierPolicyName();
            if (!currentPolicyName.equalsIgnoreCase(newPolicyName)) {
                _log.info("FAST policy name associated with Storage Group {} : {}", childGroupName, currentPolicyName);
                if (isVmax3) {
                    newPolicyName = _helper.getVMAX3FastSettingWithRightNoneString(storage, newPolicyName);
                    CIMInstance toUpdate = new CIMInstance(childGroupInstance.getObjectPath(), _helper.getV3FastSettingProperties(newPolicyName));
                    _helper.modifyInstance(storage, toUpdate, SmisConstants.PS_V3_FAST_SETTING_PROPERTIES);
                    _log.info("Modified Storage Group {} FAST Setting to {}", childGroupName, newPolicyName);
                } else {
                    if (_helper.isFastPolicy(currentPolicyName)) {
                        _helper.removeVolumeGroupFromAutoTieringPolicy(storage, childGroupPath);
                    }
                    if (_helper.isFastPolicy(newPolicyName)) {
                        _log.info("Adding Storage Group {} to FAST Policy {}", childGroupName, newPolicyName);
                        addVolumeGroupToAutoTieringPolicy(storage, newPolicyName, childGroupPath, taskCompleter);
                    }
                }
            } else {
                _log.info("Current and new policy names are same '{}'." + " No need to update it on Storage Group.", currentPolicyName);
            }
            // Even if we don't change policy name on device
            // we need to set policyUpdated = true else rollback kicks in
            policyUpdated = true;
            // Update the compression attributes if it needs to be
            if (isVmax3) {
                // refresh the SG instance since compression property is enabled by default
                // when SG becomes FAST managed.
                childGroupInstance = _helper.getInstance(storage, childGroupPath, false, false, SmisConstants.PS_EMC_COMPRESSION);
                boolean currentCompressionSetting = SmisUtils.getEMCCompressionForStorageGroup(childGroupInstance);
                boolean newCompressionSetting = newVirtualPoolPolicyLimits.getCompression();
                if (currentCompressionSetting != newCompressionSetting) {
                    CIMInstance toUpdate = new CIMInstance(childGroupInstance.getObjectPath(), _helper.getV3CompressionProperties(newCompressionSetting));
                    _helper.modifyInstance(storage, toUpdate, SmisConstants.PS_EMC_COMPRESSION);
                    _log.info("Modified Storage Group {} Compression setting to {}", childGroupName, newCompressionSetting);
                } else {
                    _log.info("Current and new compression values are same '{}'." + " No need to update it on Storage Group.", newCompressionSetting);
                }
            }
            // update host io limits if need be
            if (!HostIOLimitsParam.isEqualsLimit(currentStorageGroupPolicyLimits.getHostIOLimitBandwidth(), newVirtualPoolPolicyLimits.getHostIOLimitBandwidth())) {
                _helper.updateHostIOLimitBandwidth(client, childGroupPath, newVirtualPoolPolicyLimits.getHostIOLimitBandwidth());
                policyUpdated = true;
            }
            if (!HostIOLimitsParam.isEqualsLimit(currentStorageGroupPolicyLimits.getHostIOLimitIOPs(), newVirtualPoolPolicyLimits.getHostIOLimitIOPs())) {
                _helper.updateHostIOLimitIOPs(client, childGroupPath, newVirtualPoolPolicyLimits.getHostIOLimitIOPs());
                policyUpdated = true;
            }
            if (policyUpdated) {
                Set<Initiator> initiators = ExportMaskUtils.getInitiatorsForExportMask(_dbClient, exportMask, null);
                _helper.updateStorageGroupName(client, childGroupPath, generateStorageGroupName(storage, exportMask, initiators, newVirtualPoolPolicyLimits));
            }
        } else if (isVmax3) {
            /**
             * Requested for fewer members in a SG
             *
             * V3 supports moveMembers from one SG to another, provided some conditions met.
             * see #helper.moveVolumesFromOneStorageGroupToAnother() for criteria.
             *
             * validate that current SG is not a parent SG and it is not associated with MV
             * check if there is another SG under CSG with new fastSetting & limits
             * else create new SG (with new fastSetting, IO limits) and associate it with CSG
             * call 'moveMembers' to move volumes from current SG to new SG
             */
            _log.info("Request is made for part of volumes in the Group (VMAX3). Moving those volumes to new Storage Group..");
            if (!_helper.isCascadedSG(storage, childGroupPath) && !_helper.findStorageGroupsAssociatedWithOtherMaskingViews(storage, childGroupName)) {
                String parentGroupName = _helper.getStorageGroupForGivenMaskingView(exportMask.getMaskName(), storage);
                Map<StorageGroupPolicyLimitsParam, List<String>> childGroupsByFast = _helper.groupStorageGroupsByAssociation(storage, parentGroupName);
                List<String> newChildGroups = childGroupsByFast.get(newVirtualPoolPolicyLimits);
                if (newChildGroups != null) {
                    // remove CSG
                    newChildGroups.remove(parentGroupName);
                }
                boolean newGroup = false;
                CIMObjectPath newChildGroupPath = null;
                String newChildGroupName = null;
                if (newChildGroups != null && !newChildGroups.isEmpty()) {
                    newChildGroupName = newChildGroups.iterator().next();
                    newChildGroupPath = _cimPath.getMaskingGroupPath(storage, newChildGroupName, SmisCommandHelper.MASKING_GROUP_TYPE.SE_DeviceMaskingGroup);
                } else {
                    newGroup = true;
                    newPolicyName = _helper.getVMAX3FastSettingWithRightNoneString(storage, newPolicyName);
                    String[] tokens = newPolicyName.split(Constants.SMIS_PLUS_REGEX);
                    newChildGroupPath = _helper.createVolumeGroupBasedOnSLO(storage, storage, tokens[0], tokens[1], tokens[2]);
                    // Flag to indicate whether or not we need to use the EMCForce flag on this operation.
                    // We currently use this flag when dealing with RP Volumes as they are tagged for RP and the
                    // operation on these volumes would fail otherwise.
                    boolean forceFlag = false;
                    for (URI volURI : volumeURIs) {
                        if (!forceFlag) {
                            forceFlag = ExportUtils.useEMCForceFlag(_dbClient, volURI);
                        }
                    }
                    addGroupsToCascadedVolumeGroup(storage, parentGroupName, newChildGroupPath, null, null, forceFlag);
                }
                // We could enter the same situation if any of the SG characteristics were modified without ViPR knowledge.
                if (childGroupName.equalsIgnoreCase(newChildGroupName)) {
                    _log.info("Current Storage Group {} has the required charcteristics" + "No need to invoke SMI-S moveMembers method. Performing NO-OP", newChildGroupName);
                } else {
                    SmisJob moveVolumesToSGJob = new SmisSynchSubTaskJob(null, storage.getId(), SmisConstants.MOVE_MEMBERS);
                    _helper.moveVolumesFromOneStorageGroupToAnother(storage, childGroupPath, newChildGroupPath, volumeURIs, moveVolumesToSGJob);
                }
                if (newGroup) {
                    // update host IO limits if need be
                    if (newVirtualPoolPolicyLimits.isHostIOLimitBandwidthSet()) {
                        _helper.updateHostIOLimitBandwidth(client, newChildGroupPath, newVirtualPoolPolicyLimits.getHostIOLimitBandwidth());
                    }
                    if (newVirtualPoolPolicyLimits.isHostIOLimitIOPsSet()) {
                        _helper.updateHostIOLimitIOPs(client, newChildGroupPath, newVirtualPoolPolicyLimits.getHostIOLimitIOPs());
                    }
                    // Honor the compression settings if needed..
                    if (!newVirtualPoolPolicyLimits.getCompression()) {
                        // If the user opted out of compression, and the created SG has compression enabled by default,
                        // we need to opt out..
                        CIMInstance newChildGroupInstance = _helper.getInstance(storage, newChildGroupPath, false, false, SmisConstants.PS_EMC_COMPRESSION);
                        if (SmisUtils.getEMCCompressionForStorageGroup(newChildGroupInstance)) {
                            CIMInstance toUpdate = new CIMInstance(newChildGroupInstance.getObjectPath(), _helper.getV3CompressionProperties(false));
                            _helper.modifyInstance(storage, toUpdate, SmisConstants.PS_EMC_COMPRESSION);
                        }
                    }
                    Set<Initiator> initiators = ExportMaskUtils.getInitiatorsForExportMask(_dbClient, exportMask, null);
                    _helper.updateStorageGroupName(client, newChildGroupPath, generateStorageGroupName(storage, exportMask, initiators, newVirtualPoolPolicyLimits));
                }
                policyUpdated = true;
            } else {
                _log.info("Conditions for 'moveMembers' didn't meet for Storage Group {}." + " Hence, cannot move volumes to new Storage Group with new policy and limits.", childGroupName);
            }
        } else {
            _log.info("Given Volume list is not same as the one in Storage Group {}." + " Hence, FAST policy change won't be done on it.", childGroupName);
        }
    }
    return policyUpdated;
}
Also used : Set(java.util.Set) Sets.newHashSet(com.google.common.collect.Sets.newHashSet) HashSet(java.util.HashSet) StringSet(com.emc.storageos.db.client.model.StringSet) HashMap(java.util.HashMap) ExportMask(com.emc.storageos.db.client.model.ExportMask) CIMObjectPath(javax.cim.CIMObjectPath) ArrayList(java.util.ArrayList) URI(java.net.URI) CIMInstance(javax.cim.CIMInstance) SmisSynchSubTaskJob(com.emc.storageos.volumecontroller.impl.smis.job.SmisSynchSubTaskJob) ExportGroup(com.emc.storageos.db.client.model.ExportGroup) Initiator(com.emc.storageos.db.client.model.Initiator) ArrayList(java.util.ArrayList) URIQueryResultList(com.emc.storageos.db.client.constraint.URIQueryResultList) List(java.util.List) StorageGroupPolicyLimitsParam(com.emc.storageos.volumecontroller.impl.StorageGroupPolicyLimitsParam) SmisJob(com.emc.storageos.volumecontroller.impl.smis.job.SmisJob) WBEMClient(javax.wbem.client.WBEMClient) Map(java.util.Map) HashMap(java.util.HashMap) AbstractMap(java.util.AbstractMap) BlockObject(com.emc.storageos.db.client.model.BlockObject)

Example 9 with SmisJob

use of com.emc.storageos.volumecontroller.impl.smis.job.SmisJob in project coprhd-controller by CoprHD.

the class SmisMetaVolumeOperations method bindMetaVolumeToPool.

private void bindMetaVolumeToPool(StorageSystem storageSystem, StoragePool storagePool, Volume volume, MetaVolumeTaskCompleter metaVolumeTaskCompleter, Boolean isLastJob) throws Exception {
    long thinMetaVolumePreAllocateSize = 0;
    if (volume.getThinVolumePreAllocationSize() != null && volume.getThinVolumePreAllocationSize() > 0) {
        thinMetaVolumePreAllocateSize = volume.getThinVolumePreAllocationSize();
    }
    _log.info(String.format("Bind Meta Volume to Pool Start - Array: %s, Pool: %s, %n   Volume: %s, ThinMetaVolumePreAllocateSize: %s, isLastJob: %s", storageSystem.getSerialNumber(), storagePool.getNativeId(), volume.getNativeId(), thinMetaVolumePreAllocateSize, isLastJob));
    try {
        CIMObjectPath configSvcPath = _cimPath.getConfigSvcPath(storageSystem);
        CIMArgument[] inArgs;
        // Prepare parameters and call method to bind meta head
        inArgs = _helper.getBindVolumeInputArguments(storageSystem, storagePool, volume, thinMetaVolumePreAllocateSize);
        CIMArgument[] outArgs = new CIMArgument[5];
        // SmisJob smisJobCompleter =
        // new SmisJob(null, storageSystem.getId(), metaVolumeTaskCompleter.getVolumeTaskCompleter(), "Bind volume to pool job");
        StorageSystem forProvider = _helper.getStorageSystemForProvider(storageSystem, volume);
        _log.info("Selected Provider : {}", forProvider.getNativeGuid());
        SmisJob smisJobCompleter = new SmisCreateMetaVolumeJob(null, forProvider.getId(), storagePool.getId(), volume, metaVolumeTaskCompleter, isLastJob);
        _helper.invokeMethodSynchronously(forProvider, configSvcPath, SmisConstants.EMC_BIND_ELEMENT, inArgs, outArgs, smisJobCompleter);
    } catch (WBEMException e) {
        _log.error("Problem making SMI-S call: ", e);
        ServiceError error = DeviceControllerErrors.smis.unableToCallStorageProvider(e.getMessage());
        metaVolumeTaskCompleter.getVolumeTaskCompleter().error(_dbClient, error);
        throw e;
    } catch (Exception e) {
        _log.error("Problem in bindVolumeToPool: " + volume.getLabel(), e);
        ServiceError error = DeviceControllerErrors.smis.unableToCallStorageProvider(e.getMessage());
        metaVolumeTaskCompleter.getVolumeTaskCompleter().error(_dbClient, error);
        throw e;
    } finally {
        _log.info(String.format("Bind Meta Volume to Pool End - Array:%s, Pool: %s, %n   Volume: %s", storageSystem.getSerialNumber(), storagePool.getNativeId(), volume.getNativeId()));
    }
}
Also used : ServiceError(com.emc.storageos.svcs.errorhandling.model.ServiceError) CIMObjectPath(javax.cim.CIMObjectPath) SmisCreateMetaVolumeJob(com.emc.storageos.volumecontroller.impl.smis.job.SmisCreateMetaVolumeJob) SmisJob(com.emc.storageos.volumecontroller.impl.smis.job.SmisJob) WBEMException(javax.wbem.WBEMException) WBEMException(javax.wbem.WBEMException) DatabaseException(com.emc.storageos.db.exceptions.DatabaseException) DeviceControllerException(com.emc.storageos.exceptions.DeviceControllerException) CIMArgument(javax.cim.CIMArgument) StorageSystem(com.emc.storageos.db.client.model.StorageSystem)

Example 10 with SmisJob

use of com.emc.storageos.volumecontroller.impl.smis.job.SmisJob in project coprhd-controller by CoprHD.

the class SmisMetaVolumeOperations method createMetaVolume.

/**
 * Create meta volume from provided meta head and meta members
 *
 * @param storageSystem storageSystem
 * @param metaHead meta head
 * @param metaMembers list of native ids of meta volume members (not including meta head)
 * @param metaType meta volume type to create, concatenate or stripe
 * @param capabilities capabilities
 * @param metaVolumeTaskCompleter task completer
 */
@Override
public void createMetaVolume(StorageSystem storageSystem, StoragePool storagePool, Volume metaHead, List<String> metaMembers, String metaType, VirtualPoolCapabilityValuesWrapper capabilities, MetaVolumeTaskCompleter metaVolumeTaskCompleter) throws Exception {
    String label = null;
    label = metaHead.getLabel();
    try {
        CIMObjectPath elementCompositionServicePath = _cimPath.getElementCompositionSvcPath(storageSystem);
        // Check if meta head is bound to pool. The binding state is not changed by create meta volume call below, so we can know in
        // advance if we need
        // to bind element after this call completes.
        CIMInstance cimVolume = null;
        CIMObjectPath volumePath = _cimPath.getBlockObjectPath(storageSystem, metaHead);
        cimVolume = _helper.getInstance(storageSystem, volumePath, false, false, new String[] { EMC_IS_BOUND });
        String isBoundStr = cimVolume.getPropertyValue(EMC_IS_BOUND).toString();
        Boolean isBound = Boolean.parseBoolean(isBoundStr);
        // When isBound is true, create meta volume job is the last job in meta volume create sequence and we can complete this task.
        // Otherwise, we can complete this task only after binding is executed.
        Boolean isLastJob = isBound;
        _log.info(String.format("Create Meta Volume Start - Array: %s, Head: %s, Type: %s %n   Members:%s, isLastJob: %s", storageSystem.getSerialNumber(), metaHead.getLabel(), metaType, metaMembers, isLastJob));
        CIMArgument[] inArgs;
        // Should not change meta head binding state.
        inArgs = _helper.getCreateMetaVolumeInputArguments(storageSystem, label, metaHead, metaMembers, metaType, false);
        CIMArgument[] outArgs = new CIMArgument[5];
        StorageSystem forProvider = _helper.getStorageSystemForProvider(storageSystem, metaHead);
        _log.info("Selected Provider : {}", forProvider.getNativeGuid());
        SmisJob smisJobCompleter = new SmisCreateMetaVolumeJob(null, forProvider.getId(), storagePool.getId(), metaHead, metaVolumeTaskCompleter, isLastJob);
        _helper.invokeMethodSynchronously(forProvider, elementCompositionServicePath, SmisConstants.CREATE_OR_MODIFY_COMPOSITE_ELEMENT, inArgs, outArgs, smisJobCompleter);
        // thin meta heads are created unbound from pool on VMAX
        if (metaVolumeTaskCompleter.getLastStepStatus() == Job.JobStatus.SUCCESS) {
            if (!isBound) {
                // Set thin meta volume preallocate size when thin meta is bound to pool
                bindMetaVolumeToPool(storageSystem, storagePool, metaHead, metaVolumeTaskCompleter, true);
            }
        }
    } catch (WBEMException e) {
        _log.error("Problem making SMI-S call: ", e);
        ServiceError error = DeviceControllerErrors.smis.unableToCallStorageProvider(e.getMessage());
        metaVolumeTaskCompleter.getVolumeTaskCompleter().error(_dbClient, error);
        throw e;
    } catch (Exception e) {
        _log.error("Problem in createMetaVolume: ", e);
        ServiceError error = DeviceControllerErrors.smis.methodFailed("createMetaVolume", e.getMessage());
        metaVolumeTaskCompleter.getVolumeTaskCompleter().error(_dbClient, error);
        throw e;
    }
    _log.info(String.format("Create Meta Volume End - Array:%s, Head:%s, %n  Head device ID: %s, Members:%s", storageSystem.getSerialNumber(), metaHead.getLabel(), metaHead.getNativeId(), metaMembers));
}
Also used : ServiceError(com.emc.storageos.svcs.errorhandling.model.ServiceError) CIMObjectPath(javax.cim.CIMObjectPath) SmisCreateMetaVolumeJob(com.emc.storageos.volumecontroller.impl.smis.job.SmisCreateMetaVolumeJob) SmisJob(com.emc.storageos.volumecontroller.impl.smis.job.SmisJob) WBEMException(javax.wbem.WBEMException) CIMInstance(javax.cim.CIMInstance) WBEMException(javax.wbem.WBEMException) DatabaseException(com.emc.storageos.db.exceptions.DatabaseException) DeviceControllerException(com.emc.storageos.exceptions.DeviceControllerException) CIMArgument(javax.cim.CIMArgument) StorageSystem(com.emc.storageos.db.client.model.StorageSystem)

Aggregations

SmisJob (com.emc.storageos.volumecontroller.impl.smis.job.SmisJob)10 CIMArgument (javax.cim.CIMArgument)8 CIMObjectPath (javax.cim.CIMObjectPath)8 WBEMException (javax.wbem.WBEMException)6 StorageSystem (com.emc.storageos.db.client.model.StorageSystem)5 DatabaseException (com.emc.storageos.db.exceptions.DatabaseException)5 DeviceControllerException (com.emc.storageos.exceptions.DeviceControllerException)5 ServiceError (com.emc.storageos.svcs.errorhandling.model.ServiceError)5 CIMInstance (javax.cim.CIMInstance)4 SmisSynchSubTaskJob (com.emc.storageos.volumecontroller.impl.smis.job.SmisSynchSubTaskJob)3 SmisCreateMetaVolumeJob (com.emc.storageos.volumecontroller.impl.smis.job.SmisCreateMetaVolumeJob)2 SmisVolumeExpandJob (com.emc.storageos.volumecontroller.impl.smis.job.SmisVolumeExpandJob)2 ArrayList (java.util.ArrayList)2 WBEMClient (javax.wbem.client.WBEMClient)2 CimConnection (com.emc.storageos.cimadapter.connections.cim.CimConnection)1 DbClient (com.emc.storageos.db.client.DbClient)1 AlternateIdConstraint (com.emc.storageos.db.client.constraint.AlternateIdConstraint)1 URIQueryResultList (com.emc.storageos.db.client.constraint.URIQueryResultList)1 BlockObject (com.emc.storageos.db.client.model.BlockObject)1 ExportGroup (com.emc.storageos.db.client.model.ExportGroup)1