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));
}
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));
}
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;
}
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()));
}
}
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));
}
Aggregations