use of com.emc.storageos.volumecontroller.impl.VolumeURIHLU in project coprhd-controller by CoprHD.
the class VmaxExportOperations method addVolumes.
@Override
public void addVolumes(StorageSystem storage, URI exportMaskURI, VolumeURIHLU[] volumeURIHLUs, List<Initiator> initiatorList, TaskCompleter taskCompleter) throws DeviceControllerException {
_log.info("{} addVolumes START...", storage.getSerialNumber());
try {
_log.info("addVolumes: Export mask id: {}", exportMaskURI);
_log.info("addVolumes: volume-HLU pairs: {}", Joiner.on(',').join(volumeURIHLUs));
if (initiatorList != null) {
_log.info("addVolumes: initiators impacted: {}", Joiner.on(',').join(initiatorList));
}
boolean isVmax3 = storage.checkIfVmax3();
ExportMask mask = _dbClient.queryObject(ExportMask.class, exportMaskURI);
ExportOperationContext context = new VmaxExportOperationContext();
// Prime the context object
taskCompleter.updateWorkflowStepContext(context);
String maskingViewName = _helper.getExportMaskName(exportMaskURI);
// Always get the Storage Group from masking View, rather than depending on the name to find out SG.
String parentGroupName = _helper.getStorageGroupForGivenMaskingView(maskingViewName, storage);
// Storage Group does not exist, remove the volumes from the mask.
if (null == parentGroupName) {
List<URI> volumeURIList = new ArrayList<URI>();
for (VolumeURIHLU vuh : volumeURIHLUs) {
volumeURIList.add(vuh.getVolumeURI());
}
mask.removeVolumes(volumeURIList);
_dbClient.updateObject(mask);
taskCompleter.error(_dbClient, DeviceControllerException.errors.vmaxStorageGroupNameNotFound(maskingViewName));
return;
}
// For existing masking views on the array (co-existence),
// if it has stand alone storage group, convert it into cascaded storage group.
CIMObjectPath storageGroupPath = _cimPath.getMaskingGroupPath(storage, parentGroupName, SmisCommandHelper.MASKING_GROUP_TYPE.SE_DeviceMaskingGroup);
if (_helper.isStandAloneSG(storage, storageGroupPath)) {
_log.info("Found Stand alone storage group, verifying the storage array version before converting it to Cascaded..");
if (storage.checkIfVmax3()) {
_log.info("Converting Stand alone storage group to Cascaded..");
_helper.convertStandAloneStorageGroupToCascaded(storage, storageGroupPath, parentGroupName);
} else {
_log.info("Converting Stand alone storage group to Cascaded is not supported for VMAX2. Proceeding provisioning without conversion.");
}
}
// Get the export mask initiator list. This is required to compute the storage group name
Set<Initiator> initiators = ExportMaskUtils.getInitiatorsForExportMask(_dbClient, mask, null);
// 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;
// Determine if the volume is already in the masking view.
// If so, log and remove from volumes we need to process.
parentGroupName = _helper.getStorageGroupForGivenMaskingView(maskingViewName, storage);
Set<String> deviceIds = _helper.getVolumeDeviceIdsFromStorageGroup(storage, parentGroupName);
List<VolumeURIHLU> removeURIs = new ArrayList<>();
for (VolumeURIHLU volumeUriHLU : volumeURIHLUs) {
BlockObject bo = BlockObject.fetch(_dbClient, volumeUriHLU.getVolumeURI());
if (deviceIds.contains(bo.getNativeId())) {
_log.info("Found volume {} is already associated with masking view. Assuming this is from a previous operation.", bo.getLabel());
removeURIs.add(volumeUriHLU);
}
}
// Create the new array of volumes that don't exist yet in the masking view.
VolumeURIHLU[] addVolumeURIHLUs = new VolumeURIHLU[volumeURIHLUs.length - removeURIs.size()];
int index = 0;
for (VolumeURIHLU volumeUriHLU : volumeURIHLUs) {
if (!removeURIs.contains(volumeUriHLU)) {
addVolumeURIHLUs[index++] = volumeUriHLU;
}
}
/**
* Group Volumes by Fast Policy and Host IO limit attributes
*
* policyToVolumeGroupEntry - this will essentially have multiple Groups
* E.g Group 1--> Fast Policy (FP1)+ FEBandwidth (100)
* Group 2--> Fast Policy (FP2)+ IOPS (100)
* Group 3--> FEBandwidth (100) + IOPS (100) ..
*/
ListMultimap<StorageGroupPolicyLimitsParam, VolumeURIHLU> policyToVolumeGroup = ArrayListMultimap.create();
for (VolumeURIHLU volumeUriHLU : addVolumeURIHLUs) {
StorageGroupPolicyLimitsParam sgPolicyLimitsParam = null;
URI boUri = volumeUriHLU.getVolumeURI();
BlockObject bo = BlockObject.fetch(_dbClient, boUri);
boolean fastAssociatedAlready = false;
// Always treat fast volumes as non-fast if fast is associated on these volumes already
// Export fast volumes to 2 different nodes.
// Also note that Volumes with Compression set to true are also fast managed for VMAX3 Arrays.
String policyName = volumeUriHLU.getAutoTierPolicyName();
if (_helper.isFastPolicy(policyName) || ((isVmax3) && volumeUriHLU.getCompression())) {
if (isVmax3) {
policyName = _helper.getVMAX3FastSettingForVolume(boUri, policyName);
}
fastAssociatedAlready = _helper.checkVolumeAssociatedWithAnySGWithPolicy(bo.getNativeId(), storage, policyName);
}
// should not be created with a FAST policy assigned.
if (fastAssociatedAlready || isRPJournalVolume(bo)) {
_log.info("Forcing policy name to NONE to prevent volume from using FAST policy.");
volumeUriHLU.setAutoTierPolicyName(Constants.NONE);
// Compression was applied on existing SG associated with policy!!
volumeUriHLU.setCompression(false);
sgPolicyLimitsParam = new StorageGroupPolicyLimitsParam(Constants.NONE, volumeUriHLU.getHostIOLimitBandwidth(), volumeUriHLU.getHostIOLimitIOPs(), storage);
} else {
if (isVmax3) {
sgPolicyLimitsParam = new StorageGroupPolicyLimitsParam(volumeUriHLU, storage, _helper);
} else {
sgPolicyLimitsParam = new StorageGroupPolicyLimitsParam(volumeUriHLU, storage);
}
}
policyToVolumeGroup.put(sgPolicyLimitsParam, volumeUriHLU);
// The force flag only needs to be set once
if (!forceFlag) {
forceFlag = ExportUtils.useEMCForceFlag(_dbClient, volumeUriHLU.getVolumeURI());
}
}
_log.info(" {} Groups generated based on grouping volumes by fast policy", policyToVolumeGroup.size());
String storageGroupCustomTemplateName = CustomConfigConstants.VMAX_HOST_STORAGE_GROUP_MASK_NAME;
String exportType = ExportMaskUtils.getExportType(_dbClient, mask);
if (ExportGroupType.Cluster.name().equals(exportType)) {
storageGroupCustomTemplateName = CustomConfigConstants.VMAX_CLUSTER_STORAGE_GROUP_MASK_NAME;
}
DataSource sgDataSource = ExportMaskUtils.getExportDatasource(storage, new ArrayList<Initiator>(initiators), dataSourceFactory, storageGroupCustomTemplateName);
// Group volumes by Storage Group
Map<String, Collection<VolumeURIHLU>> volumesByStorageGroup = _helper.groupVolumesByStorageGroup(storage, parentGroupName, sgDataSource, storageGroupCustomTemplateName, policyToVolumeGroup, customConfigHandler);
// associate it with fast if needed, then add the new Child Group to the existing Parent Cascaded Group
for (Entry<String, Collection<VolumeURIHLU>> volumesByStorageGroupEntry : volumesByStorageGroup.entrySet()) {
VolumeURIHLU[] volumeURIHLUArray = null;
// Even though policy and limits info are already in volumURIHLU, let's still extract to a holder for
// easy access
// Is it safe to not touch the below variable as it seems to be used by non VMAX3 cases only?
StorageGroupPolicyLimitsParam volumePolicyLimitsParam = new StorageGroupPolicyLimitsParam(Constants.NONE);
if (null != volumesByStorageGroupEntry.getValue()) {
volumeURIHLUArray = volumesByStorageGroupEntry.getValue().toArray(new VolumeURIHLU[0]);
volumePolicyLimitsParam = _helper.createStorageGroupPolicyLimitsParam(volumesByStorageGroupEntry.getValue(), storage, _dbClient);
}
String childGroupName = volumesByStorageGroupEntry.getKey().toString();
if (isVmax3) {
childGroupName = childGroupName.replaceAll(Constants.SMIS_PLUS_REGEX, Constants.UNDERSCORE_DELIMITER);
}
_log.info("Group Name : {} --- volume storage group name : {}", childGroupName, (volumeURIHLUArray != null ? Joiner.on("\t").join(volumeURIHLUArray) : ""));
CIMObjectPath childGroupPath = _cimPath.getMaskingGroupPath(storage, childGroupName, SmisCommandHelper.MASKING_GROUP_TYPE.SE_DeviceMaskingGroup);
CIMInstance childGroupInstance = _helper.checkExists(storage, childGroupPath, false, false);
if (null == childGroupInstance) {
// For the newly created group, set policy, and other required properties bandwidth, iops as needed.
// Once child group created, add this child Group to existing Parent Cascaded Group.
// Empty child group is created to be able to add volumes with HLUs
// once this child group is added in the cascaded storage group.
_log.info("Group {} doesn't exist, creating a new group", childGroupName);
CIMObjectPath childGroupCreated = createVolumeGroup(storage, childGroupName, volumeURIHLUArray, taskCompleter, false);
_log.debug("Created Child Group {}", childGroupCreated);
// Get childGroupName from the child group path childGroupCreated as it
// could have been truncated in createVolumeGroup method
childGroupName = _cimPath.getMaskingGroupName(storage, childGroupCreated);
if (!isVmax3 && _helper.isFastPolicy(volumePolicyLimitsParam.getAutoTierPolicyName()) && !_helper.checkVolumeGroupAssociatedWithPolicy(storage, childGroupCreated, volumePolicyLimitsParam.getAutoTierPolicyName())) {
_log.debug("Adding Storage Group {} to Fast Policy {}", childGroupName, volumePolicyLimitsParam.getAutoTierPolicyName());
addVolumeGroupToAutoTieringPolicy(storage, volumePolicyLimitsParam.getAutoTierPolicyName(), childGroupCreated, taskCompleter);
}
// Add new Child Storage Group to Parent Cascaded Group
// NOTE: host IO limit is set during the first child SG created with cascaded group.
// Logically (or easy to follow) is to set limits after SG is created. However, because add job
// logic
// is executed in a queue. Hence, move update logic to SmisMaskingViewAddVolumeJob
addGroupsToCascadedVolumeGroup(storage, parentGroupName, childGroupCreated, null, taskCompleter, forceFlag);
_log.debug("Added newly created Storage Group {} to Parent Cascaded Group {}", childGroupName, parentGroupName);
// Add volumes to the newly created child group
_log.info("Adding Volumes to non cascaded Storage Group {} START", childGroupName);
// Create a relatively empty completer associated with the export mask. We don't have the export
// group
// at this level, so there's nothing decent to attach the completer to anyway.
String task = UUID.randomUUID().toString();
ExportMaskVolumeToStorageGroupCompleter completer = new ExportMaskVolumeToStorageGroupCompleter(null, exportMaskURI, task);
SmisMaskingViewAddVolumeJob job = new SmisMaskingViewAddVolumeJob(null, storage.getId(), exportMaskURI, volumeURIHLUArray, childGroupCreated, completer);
job.setCIMObjectPathfactory(_cimPath);
_helper.addVolumesToStorageGroup(volumeURIHLUArray, storage, childGroupName, job, forceFlag);
ExportOperationContext.insertContextOperation(taskCompleter, VmaxExportOperationContext.OPERATION_ADD_VOLUMES_TO_STORAGE_GROUP, childGroupName, volumeURIHLUArray, forceFlag);
_log.info("Adding Volumes to non cascaded Storage Group {} END", childGroupName);
} else // Only reusable groups will have null volumeURIHLUArray
if (null != volumeURIHLUArray) {
// Only add volumes that don't already exist in the StorageGroup
VolumeURIHLU[] newVolumesToAdd = getVolumesThatAreNotAlreadyInSG(storage, childGroupPath, childGroupName, volumesByStorageGroupEntry.getValue().toArray(new VolumeURIHLU[0]));
if (newVolumesToAdd != null) {
// We should not disturb any existing masking views on the Array. In this case, if the found
// storage group is not
// associated with expected fast policy, then we cannot proceed with neither of the below
// 1. Adding fast volumes to existing non fast storage group part of masking view
// 2. Creating a new Cascaded Group, and adding the existing storage group to it, as existing
// SG-->MV needs to be
// broken
StorageGroupPolicyLimitsParam childGroupKey = _helper.createStorageGroupPolicyLimitsParam(storage, childGroupInstance);
if (!isVmax3 && _helper.isFastPolicy(volumePolicyLimitsParam.getAutoTierPolicyName()) && !_helper.isFastPolicy(childGroupKey.getAutoTierPolicyName())) {
// Go through each volume associated with this storage group and pluck out by policy
for (StorageGroupPolicyLimitsParam phantomStorageGroupPolicyLimitsParam : policyToVolumeGroup.keySet()) {
String phantomPolicyName = phantomStorageGroupPolicyLimitsParam.getAutoTierPolicyName();
// If this is a non-FAST policy in the grouping, skip it.
if (!_helper.isFastPolicy(phantomPolicyName)) {
continue;
}
// Find the volumes in the volumeURIHLU associated with this policy
VolumeURIHLU[] phantomVolumesToAdd = getVolumesThatBelongToPolicy(newVolumesToAdd, phantomStorageGroupPolicyLimitsParam, storage);
_log.info(String.format("In order to add this volume to the masking view, we need to create/find a storage group " + "for the FAST policy %s and add the volume to the storage group and the existing storage group associated with the masking view", phantomStorageGroupPolicyLimitsParam));
// Check to see if there already is a phantom storage group with this policy on the
// array
List<String> phantomStorageGroupNames = _helper.findPhantomStorageGroupAssociatedWithFastPolicy(storage, phantomStorageGroupPolicyLimitsParam);
// If there's no existing phantom storage group, create one.
if (phantomStorageGroupNames == null || phantomStorageGroupNames.isEmpty()) {
// TODO: Probably need to use some name generator for this.
String phantomStorageGroupName = childGroupName + "_" + phantomStorageGroupPolicyLimitsParam;
// We need to create a new phantom storage group with our policy associated with it.
_log.info("phantom storage group {} doesn't exist, creating a new group", phantomStorageGroupName);
CIMObjectPath phantomStorageGroupCreated = createVolumeGroup(storage, phantomStorageGroupName, phantomVolumesToAdd, taskCompleter, true);
_log.info("Adding Storage Group {} to Fast Policy {}", phantomStorageGroupName, phantomPolicyName);
addVolumeGroupToAutoTieringPolicy(storage, phantomPolicyName, phantomStorageGroupCreated, taskCompleter);
} else {
// take the first matching phantom SG from the list
String phantomStorageGroupName = phantomStorageGroupNames.get(0);
// We found the phantom storage group, but we need to make sure the volumes aren't
// already in the
// storage
// group from a previous operation or manual intervention.
List<URI> phantomVolumeIds = new ArrayList<URI>();
for (VolumeURIHLU phantomVolume : phantomVolumesToAdd) {
phantomVolumeIds.add(phantomVolume.getVolumeURI());
}
phantomVolumeIds.removeAll(_helper.findVolumesInStorageGroup(storage, phantomStorageGroupName, phantomVolumeIds));
if (phantomVolumeIds.isEmpty()) {
_log.info("Found that the volume(s) we wanted to add to the phantom storage group are already added.");
} else {
// If we found a phantom storage group with our policy, use it.
_log.info("Found that we need to add volumes to the phantom storage group: " + phantomStorageGroupName);
// Create a relatively empty completer associated with the export mask. We don't
// have the export
// group
// at this level, so there's nothing decent to attach the completer to anyway.
String task = UUID.randomUUID().toString();
ExportMaskVolumeToStorageGroupCompleter completer = new ExportMaskVolumeToStorageGroupCompleter(null, exportMaskURI, task);
SmisMaskingViewAddVolumeJob job = new SmisMaskingViewAddVolumeJob(null, storage.getId(), exportMaskURI, phantomVolumesToAdd, null, completer);
job.setCIMObjectPathfactory(_cimPath);
_helper.addVolumesToStorageGroup(phantomVolumesToAdd, storage, phantomStorageGroupName, job, forceFlag);
ExportOperationContext.insertContextOperation(taskCompleter, VmaxExportOperationContext.OPERATION_ADD_VOLUMES_TO_STORAGE_GROUP, phantomStorageGroupName, phantomVolumesToAdd, forceFlag);
_log.info("Adding Volumes to non cascaded Storage Group {} END", phantomStorageGroupName);
}
}
}
}
if (isVmax3) {
// Remove volumes from the parking storage group
Set<String> nativeIds = new HashSet<String>();
for (VolumeURIHLU volURIHLU : newVolumesToAdd) {
nativeIds.add(_helper.getBlockObjectNativeId(volURIHLU.getVolumeURI()));
}
_helper.removeVolumeFromParkingSLOStorageGroup(storage, nativeIds.toArray(new String[] {}), forceFlag);
}
_log.info("Adding Volumes to non cascaded Storage Group {} START", childGroupName);
// Create a relatively empty completer associated with the export mask. We don't have the export
// group
// at this level, so there's nothing decent to attach the completer to anyway.
String task = UUID.randomUUID().toString();
ExportMaskVolumeToStorageGroupCompleter completer = new ExportMaskVolumeToStorageGroupCompleter(null, exportMaskURI, task);
SmisMaskingViewAddVolumeJob job = new SmisMaskingViewAddVolumeJob(null, storage.getId(), exportMaskURI, newVolumesToAdd, null, completer);
job.setCIMObjectPathfactory(_cimPath);
_helper.addVolumesToStorageGroup(newVolumesToAdd, storage, childGroupName, job, forceFlag);
ExportOperationContext.insertContextOperation(taskCompleter, VmaxExportOperationContext.OPERATION_ADD_VOLUMES_TO_STORAGE_GROUP, childGroupName, newVolumesToAdd, forceFlag);
_log.info("Adding Volumes to non cascaded Storage Group {} END", childGroupName);
} else {
// newVolumesToAdd == null, implying that all the requested
// volumes are already in the StorageGroup. This is a no-op.
_log.info("All volumes are already in the storage group");
}
} else // Else, we have existing groups which hold these volumes, hence add those groups to
// cascaded group.
{
_log.info("Adding Existing Storage Group {} to Cascaded Group {} START :", childGroupName, parentGroupName);
if (!isVmax3 && _helper.isFastPolicy(volumePolicyLimitsParam.getAutoTierPolicyName()) && !_helper.checkVolumeGroupAssociatedWithPolicy(storage, childGroupPath, volumePolicyLimitsParam.getAutoTierPolicyName())) {
_log.info("Adding Storage Group {} to Fast Policy {}", childGroupName, volumePolicyLimitsParam.getAutoTierPolicyName());
addVolumeGroupToAutoTieringPolicy(storage, volumePolicyLimitsParam.getAutoTierPolicyName(), childGroupPath, taskCompleter);
}
String task = UUID.randomUUID().toString();
ExportMaskVolumeToStorageGroupCompleter completer = new ExportMaskVolumeToStorageGroupCompleter(null, exportMaskURI, task);
SmisMaskingViewAddVolumeJob job = new SmisMaskingViewAddVolumeJob(null, storage.getId(), exportMaskURI, volumeURIHLUArray, null, completer);
job.setCIMObjectPathfactory(_cimPath);
addGroupsToCascadedVolumeGroup(storage, parentGroupName, childGroupPath, job, taskCompleter, forceFlag);
_log.debug("Adding Existing Storage Group {} to Cascaded Group {} END :", childGroupName, parentGroupName);
}
}
// Test mechanism to invoke a failure. No-op on production systems.
InvokeTestFailure.internalOnlyInvokeTestFailure(InvokeTestFailure.ARTIFICIAL_FAILURE_002);
taskCompleter.ready(_dbClient);
} catch (Exception e) {
_log.error(String.format("addVolumes failed - maskName: %s", exportMaskURI.toString()), e);
ServiceError serviceError = DeviceControllerException.errors.jobFailed(e);
taskCompleter.error(_dbClient, serviceError);
}
_log.info("{} addVolumes END...", storage.getSerialNumber());
}
use of com.emc.storageos.volumecontroller.impl.VolumeURIHLU in project coprhd-controller by CoprHD.
the class VmaxExportOperations method createVolumeGroup.
// //////////// VMAX specific export helpers ////////////////
private CIMObjectPath createVolumeGroup(StorageSystem storage, String groupName, VolumeURIHLU[] volumeURIHLUs, TaskCompleter taskCompleter, boolean addVolumes) throws Exception {
_log.debug("{} createVolumeGroup START...", storage.getSerialNumber());
CIMObjectPath volumeGroupObjectPath = null;
int index = 0;
String[] volumeNames = new String[volumeURIHLUs.length];
String policyName = null;
// 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 setOnce = false;
boolean forceFlag = false;
boolean disableCompression = false;
for (VolumeURIHLU volURIHlu : volumeURIHLUs) {
String volumeNativeId = _helper.getBlockObjectNativeId(volURIHlu.getVolumeURI());
volumeNames[index++] = volumeNativeId;
if (null == policyName && storage.checkIfVmax3()) {
policyName = _helper.getVMAX3FastSettingForVolume(volURIHlu.getVolumeURI(), volURIHlu.getAutoTierPolicyName(), volURIHlu.getCompression());
if (_helper.checkVolumeAssociatedWithAnySGWithPolicy(volumeNativeId, storage, policyName)) {
// A volume cannot be in multiple fast managed storage groups. Reset the fast policy
policyName = Constants.NONE.toString();
}
}
// The force flag only needs to be set once
if (!setOnce) {
setOnce = true;
forceFlag = ExportUtils.useEMCForceFlag(_dbClient, volURIHlu.getVolumeURI());
disableCompression = _helper.disableVMAX3Compression(volURIHlu.getVolumeURI(), storage);
}
}
CIMArgument[] inArgs = null;
String truncatedGroupName = groupName.length() >= 64 ? StringUtils.substring(groupName, 0, 63) : groupName;
if (storage.checkIfVmax3()) {
_helper.removeVolumeFromParkingSLOStorageGroup(storage, volumeNames, forceFlag);
_log.info("Done invoking remove volumes from parking SLO storage group before export");
policyName = _helper.getVMAX3FastSettingWithRightNoneString(storage, policyName);
String[] tokens = policyName.split(Constants.SMIS_PLUS_REGEX);
inArgs = _helper.getCreateVolumeGroupInputArguments(storage, truncatedGroupName, tokens[0], tokens[2], tokens[1], addVolumes ? volumeNames : null, disableCompression);
} else {
inArgs = _helper.getCreateVolumeGroupInputArguments(storage, truncatedGroupName, addVolumes ? volumeNames : null);
}
CIMArgument[] outArgs = new CIMArgument[5];
try {
_helper.invokeMethod(storage, _cimPath.getControllerConfigSvcPath(storage), "CreateGroup", inArgs, outArgs);
volumeGroupObjectPath = _cimPath.getCimObjectPathFromOutputArgs(outArgs, "MaskingGroup");
ExportOperationContext.insertContextOperation(taskCompleter, VmaxExportOperationContext.OPERATION_CREATE_STORAGE_GROUP, groupName, volumeURIHLUs);
} catch (WBEMException we) {
// If the VG by the same name exists, the WBEM exception thrown is CIM_ERR_FAILED.
_log.info("{} Problem when trying to create volume group ... going to look up volume group.", storage.getSystemType(), we);
volumeGroupObjectPath = handleCreateMaskingGroupException(storage, truncatedGroupName, inArgs, SmisCommandHelper.MASKING_GROUP_TYPE.SE_DeviceMaskingGroup);
if (volumeGroupObjectPath == null) {
_log.info("{} Problem looking up volume group.", storage.getSerialNumber(), we);
throw we;
} else {
_log.info("{} Found volume group.", storage.getSerialNumber());
}
}
_log.debug("{} createVolumeGroup END...", storage.getSerialNumber());
return volumeGroupObjectPath;
}
use of com.emc.storageos.volumecontroller.impl.VolumeURIHLU in project coprhd-controller by CoprHD.
the class VmaxExportOperations method exportMaskRollback.
/**
* Export mask operation rollback method.
*
* @param storage
* storage device
* @param taskCompleter
* task completer
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
private void exportMaskRollback(StorageSystem storage, ExportOperationContext context, TaskCompleter taskCompleter) throws Exception {
// Go through each operation and roll it back.
if (context != null && context.getOperations() != null) {
WBEMClient client = _helper.getConnection(storage).getCimClient();
ListIterator li = context.getOperations().listIterator(context.getOperations().size());
while (li.hasPrevious()) {
ExportOperationContextOperation operation = (ExportOperationContextOperation) li.previous();
// 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.
//
// IMPORTANT NOTE: Default is FALSE, each rollback method will need to determine if it should be set to
// true if it is needed.
boolean forceFlag = false;
try {
switch(operation.getOperation()) {
case VmaxExportOperationContext.OPERATION_ADD_INITIATORS_TO_INITIATOR_GROUP:
// remove initiators from the initiator group
List<Initiator> initiatorList = (List<Initiator>) operation.getArgs().get(0);
CIMObjectPath initiatorGroupPath = (CIMObjectPath) operation.getArgs().get(1);
CIMArgument[] inArgs = _helper.getRemoveInitiatorsFromMaskingGroupInputArguments(storage, initiatorGroupPath, initiatorList);
CIMArgument[] outArgs = new CIMArgument[5];
_helper.invokeMethodSynchronously(storage, _cimPath.getControllerConfigSvcPath(storage), "RemoveMembers", inArgs, outArgs, null);
break;
case VmaxExportOperationContext.OPERATION_ADD_INITIATOR_GROUPS_TO_INITIATOR_GROUP:
// remove initiator groups from cascaded initiator group
CIMObjectPath childInitiatorGroup = (CIMObjectPath) operation.getArgs().get(0);
CIMObjectPath parentInitiatorGroup = (CIMObjectPath) operation.getArgs().get(1);
inArgs = _helper.getRemoveIGFromCIG(childInitiatorGroup, parentInitiatorGroup);
outArgs = new CIMArgument[5];
_helper.invokeMethodSynchronously(storage, _cimPath.getControllerConfigSvcPath(storage), "RemoveMembers", inArgs, outArgs, null);
break;
case VmaxExportOperationContext.OPERATION_CREATE_CASCADING_STORAGE_GROUP:
case VmaxExportOperationContext.OPERATION_CREATE_STORAGE_GROUP:
// Delete storage group
String groupName = (String) operation.getArgs().get(0);
// .get(2) arg is different depending on the operation, but for now we don't need it so we
// won't get it.
_helper.deleteMaskingGroup(storage, groupName, SmisCommandHelper.MASKING_GROUP_TYPE.SE_DeviceMaskingGroup);
break;
case VmaxExportOperationContext.OPERATION_CREATE_PORT_GROUP:
// Delete port group
groupName = (String) operation.getArgs().get(0);
_helper.deleteMaskingGroup(storage, groupName, SmisCommandHelper.MASKING_GROUP_TYPE.SE_TargetMaskingGroup);
break;
case VmaxExportOperationContext.OPERATION_ADD_TIER_TO_STORAGE_GROUP:
// Remove tier policy from storage group
String policyName = (String) operation.getArgs().get(0);
CIMObjectPath[] volumeGroupPaths = (CIMObjectPath[]) operation.getArgs().get(1);
for (CIMObjectPath volumeGroupPath : volumeGroupPaths) {
_helper.removeVolumeGroupFromPolicyAndLimitsAssociation(client, storage, volumeGroupPath);
}
break;
case VmaxExportOperationContext.OPERATION_ADD_STORAGE_GROUP_TO_CASCADING_STORAGE_GROUP:
// Remove storage group from cascading storage group
groupName = (String) operation.getArgs().get(0);
forceFlag = (boolean) operation.getArgs().get(2);
CIMObjectPath[] volumeGroupPathList = (CIMObjectPath[]) operation.getArgs().get(1);
inArgs = _helper.modifyCascadedStorageGroupInputArguments(storage, groupName, volumeGroupPathList, forceFlag);
outArgs = new CIMArgument[5];
_helper.invokeMethodSynchronously(storage, _cimPath.getControllerConfigSvcPath(storage), "RemoveMembers", inArgs, outArgs, null);
break;
case VmaxExportOperationContext.OPERATION_CREATE_CASCADED_INITIATOR_GROUP:
case VmaxExportOperationContext.OPERATION_CREATE_INITIATOR_GROUP:
// Remove initiator group
groupName = (String) operation.getArgs().get(0);
_helper.deleteMaskingGroup(storage, groupName, SmisCommandHelper.MASKING_GROUP_TYPE.SE_InitiatorMaskingGroup);
break;
case VmaxExportOperationContext.OPERATION_CREATE_MASKING_VIEW:
// Remove masking view
String maskName = (String) operation.getArgs().get(0);
// Find the mask using the name
boolean foundMaskInDb = false;
ExportMask exportMask = null;
URIQueryResultList uriQueryList = new URIQueryResultList();
_dbClient.queryByConstraint(AlternateIdConstraint.Factory.getExportMaskByNameConstraint(maskName), uriQueryList);
while (uriQueryList.iterator().hasNext()) {
URI uri = uriQueryList.iterator().next();
exportMask = _dbClient.queryObject(ExportMask.class, uri);
if (exportMask != null && !exportMask.getInactive() && exportMask.getStorageDevice().equals(storage.getId())) {
foundMaskInDb = true;
// given name for any storage array.
break;
}
}
// If we have the mask, check to see if we need to use the force flag
if (foundMaskInDb) {
for (String volURI : exportMask.getUserAddedVolumes().values()) {
forceFlag = ExportUtils.useEMCForceFlag(_dbClient, URI.create(volURI));
if (forceFlag) {
break;
}
}
}
inArgs = _helper.getDeleteMaskingViewInputArguments(storage, maskName, forceFlag);
outArgs = new CIMArgument[5];
_helper.invokeMethodSynchronously(storage, _cimPath.getControllerConfigSvcPath(storage), "DeleteMaskingView", inArgs, outArgs, null);
break;
case VmaxExportOperationContext.OPERATION_ADD_PORTS_TO_PORT_GROUP:
// Remove ports from port group
groupName = (String) operation.getArgs().get(0);
List<URI> targetURIList = (List<URI>) operation.getArgs().get(1);
inArgs = _helper.getRemoveTargetPortsFromMaskingGroupInputArguments(storage, groupName, targetURIList);
outArgs = new CIMArgument[5];
_helper.invokeMethodSynchronously(storage, _cimPath.getControllerConfigSvcPath(storage), "RemoveMembers", inArgs, outArgs, null);
break;
case VmaxExportOperationContext.OPERATION_ADD_VOLUMES_TO_STORAGE_GROUP:
// Remove volumes from storage group
groupName = (String) operation.getArgs().get(0);
forceFlag = (boolean) operation.getArgs().get(2);
VolumeURIHLU[] volumeList = (VolumeURIHLU[]) operation.getArgs().get(1);
List<URI> volumesInSG = new ArrayList<>();
for (VolumeURIHLU volumeUriHlu : volumeList) {
volumesInSG.add(volumeUriHlu.getVolumeURI());
}
inArgs = _helper.getRemoveVolumesFromMaskingGroupInputArguments(storage, groupName, volumesInSG, forceFlag);
outArgs = new CIMArgument[5];
_helper.invokeMethodSynchronously(storage, _cimPath.getControllerConfigSvcPath(storage), "RemoveMembers", inArgs, outArgs, null);
break;
case VmaxExportOperationContext.OPERATION_ADD_EXISTING_INITIATOR_TO_EXPORT_GROUP:
URI initiator = (URI) operation.getArgs().get(0);
_log.info("Not removing initiator: {} because it already existed in the masking view", initiator);
// Ensure the task completer does not remove it from ViPR ExportMask/Group.
((ExportMaskRemoveInitiatorCompleter) taskCompleter).removeInitiator(initiator);
break;
default:
}
} catch (Exception e) {
_log.error("Exception caught while running rollback", e);
throw e;
}
}
}
}
use of com.emc.storageos.volumecontroller.impl.VolumeURIHLU in project coprhd-controller by CoprHD.
the class VmaxExportOperations method createMaskingView.
private void createMaskingView(StorageSystem storage, URI exportMaskURI, String maskingViewName, CIMObjectPath volumeGroupPath, VolumeURIHLU[] volumeURIHLUs, CIMObjectPath targetPortGroupPath, CIMObjectPath initiatorGroupPath, TaskCompleter taskCompleter) throws Exception {
_log.info("{} createMaskingView START...", storage.getSerialNumber());
// 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;
List<String> deviceNumbers = new ArrayList<String>();
for (VolumeURIHLU volURIHlu : volumeURIHLUs) {
String hlu = volURIHlu.getHLU();
// LUN_UNASSIGNED value (as a hex string).
if (hlu != null && !hlu.equalsIgnoreCase(ExportGroup.LUN_UNASSIGNED_STR)) {
deviceNumbers.add(hlu);
}
// The force flag only needs to be set once
if (!forceFlag) {
forceFlag = ExportUtils.useEMCForceFlag(_dbClient, volURIHlu.getVolumeURI());
}
}
String[] deviceNumbersStr = {};
CIMArgument[] inMVArgs = _helper.getCreateMaskingViewInputArguments(volumeGroupPath, targetPortGroupPath, initiatorGroupPath, deviceNumbers.toArray(deviceNumbersStr), maskingViewName, forceFlag);
CIMArgument[] outMVArgs = new CIMArgument[5];
try {
_helper.invokeMethod(storage, _cimPath.getControllerConfigSvcPath(storage), "CreateMaskingView", inMVArgs, outMVArgs);
CIMObjectPath cimJobPath = _cimPath.getCimObjectPathFromOutputArgs(outMVArgs, "Job");
if (cimJobPath != null) {
ControllerServiceImpl.enqueueJob(new QueueJob(new SmisCreateMaskingViewJob(cimJobPath, storage.getId(), exportMaskURI, volumeURIHLUs, volumeGroupPath, taskCompleter)));
} else {
// simulated environments
throw new WBEMException("No output argument was returned from CreateMaskingView operation");
}
// Rollback context is set in the job upon completion.
} catch (WBEMException we) {
_log.info("{} Problem when trying to create masking view ... going to look up masking view.", storage.getSerialNumber(), we);
boolean handleException = false;
try {
handleException = handleCreateMaskingViewException(storage, maskingViewName);
} catch (Exception e) {
_log.error("Issue trying to handle Export Mask exception", e);
}
if (handleException) {
_log.info("{} Found masking view: {}", storage.getSerialNumber(), maskingViewName);
taskCompleter.ready(_dbClient);
} else {
_log.debug("{} Problem when looking up masking view: {}", storage.getSerialNumber(), maskingViewName);
throw we;
}
}
_log.info("{} createMaskingView END...", storage.getSerialNumber());
}
use of com.emc.storageos.volumecontroller.impl.VolumeURIHLU in project coprhd-controller by CoprHD.
the class VmaxExportOperations method getVolumesThatBelongToPolicy.
/**
* Convenience method that collects volumes from the array that match the storage group.
*
* @param volumeURIHLUs
* volume objects
* @param storageGroupPolicyLimitsParam
* storage group attributes
* @return thinned-out list of volume objects that correspond to the supplied policy, or null
*/
private VolumeURIHLU[] getVolumesThatBelongToPolicy(VolumeURIHLU[] volumeURIHLUs, StorageGroupPolicyLimitsParam storageGroupPolicyLimitsParam, StorageSystem storage) {
VolumeURIHLU[] result = null;
Set<VolumeURIHLU> volumeURIHLUSet = new HashSet<VolumeURIHLU>();
for (VolumeURIHLU volumeURIHLU : volumeURIHLUs) {
StorageGroupPolicyLimitsParam tmpKey = new StorageGroupPolicyLimitsParam(volumeURIHLU.getAutoTierPolicyName(), volumeURIHLU.getHostIOLimitBandwidth(), volumeURIHLU.getHostIOLimitIOPs(), storage);
if (tmpKey.equals(storageGroupPolicyLimitsParam)) {
volumeURIHLUSet.add(volumeURIHLU);
}
}
if (!volumeURIHLUSet.isEmpty()) {
result = new VolumeURIHLU[volumeURIHLUSet.size()];
result = volumeURIHLUSet.toArray(result);
}
return result;
}
Aggregations