use of javax.wbem.WBEMException in project coprhd-controller by CoprHD.
the class VmaxSnapshotOperations method unlinkSnapshotSessionTarget.
/**
* {@inheritDoc}
*/
@SuppressWarnings("rawtypes")
@Override
public void unlinkSnapshotSessionTarget(StorageSystem system, URI snapSessionURI, URI snapshotURI, Boolean deleteTarget, TaskCompleter completer) throws DeviceControllerException {
// Only supported for VMAX3 storage systems.
if (!system.checkIfVmax3()) {
throw DeviceControllerException.exceptions.blockDeviceOperationNotSupported();
}
try {
_log.info("Unlink target {} from snapshot session {} START", snapshotURI, snapSessionURI);
BlockSnapshot snapshot = _dbClient.queryObject(BlockSnapshot.class, snapshotURI);
String targetDeviceId = snapshot.getNativeId();
if (isNullOrEmpty(targetDeviceId)) {
// The snapshot has no target device id. This means we must
// have failed creating the target device for a link target
// request and unlink target is being called in rollback.
// Since the target was never created, we just return
// success.
_log.info("Snapshot target {} was never created.", snapshotURI);
completer.ready(_dbClient);
return;
}
// If the snapshot has a native id, then we at least
// know the target device was created. Now we try and get
// the sync object path representing the linked target so
// that it can be detached.
boolean syncObjectFound = false;
List<BlockSnapshot> snapshots = null;
BlockObject sourceObj = BlockObject.fetch(_dbClient, snapshot.getParent().getURI());
CIMObjectPath syncObjectPath = SmisConstants.NULL_CIM_OBJECT_PATH;
if (snapshot.hasConsistencyGroup() && NullColumnValueGetter.isNotNullValue(snapshot.getReplicationGroupInstance())) {
String replicationGroupName = snapshot.getReplicationGroupInstance();
String sourceReplicationGroupName = sourceObj.getReplicationGroupInstance();
List<CIMObjectPath> groupSyncs = getAllGroupSyncObjects(system, snapshot);
if (groupSyncs != null && !groupSyncs.isEmpty()) {
// the passed snapshot is the sync'd element.
for (CIMObjectPath groupSynchronized : groupSyncs) {
String syncElementPath = groupSynchronized.getKeyValue(SmisConstants.CP_SYNCED_ELEMENT).toString();
String systemElementPath = groupSynchronized.getKeyValue(SmisConstants.CP_SYSTEM_ELEMENT).toString();
if (syncElementPath.contains(replicationGroupName) && systemElementPath.contains(sourceReplicationGroupName)) {
syncObjectPath = groupSynchronized;
break;
}
}
}
snapshots = ControllerUtils.getSnapshotsPartOfReplicationGroup(snapshot, _dbClient);
} else {
syncObjectPath = getSyncObject(system, snapshot, sourceObj);
snapshots = Lists.newArrayList(snapshot);
}
if (!SmisConstants.NULL_CIM_OBJECT_PATH.equals(syncObjectPath)) {
syncObjectFound = true;
CIMArgument[] inArgs = _helper.getUnlinkBlockSnapshotSessionTargetInputArguments(syncObjectPath);
CIMArgument[] outArgs = new CIMArgument[5];
CIMObjectPath replicationSvcPath = _cimPath.getControllerReplicationSvcPath(system);
SmisBlockSnapshotSessionUnlinkTargetJob job = new SmisBlockSnapshotSessionUnlinkTargetJob(null, system.getId(), completer);
_helper.invokeMethodSynchronously(system, replicationSvcPath, SmisConstants.MODIFY_REPLICA_SYNCHRONIZATION, inArgs, outArgs, job);
// Succeeded in unlinking the target from the snapshot.
for (BlockSnapshot snapshotToUpdate : snapshots) {
snapshotToUpdate.setSettingsInstance(NullColumnValueGetter.getNullStr());
}
_dbClient.updateObject(snapshots);
} else {
// For some reason we could not find the path for the
// CIM_StorageSychronized instance for the linked target.
// If the settingsInstance for the snapshot is not set,
// this may mean we just failed a link target request
// and unlink target is being called in rollback. In this
// case we successfully created the target volume, but
// failed to link the target to the snapshot, in which
// case the settingsInstance would be null. Otherwise,
// we could be retrying a failed unlink request. In this
// case, we must have succeeded in unlinking the target
// from the array snapshot, but failed attempting to
// delete the target volume. If the unlink is successful,
// the settingsInstance is reset to null. So, if the
// settingsInstance is null, we move on without failing.
// Otherwise, we should throw an exception.
String settingsInstance = snapshot.getSettingsInstance();
if (NullColumnValueGetter.isNotNullValue(settingsInstance)) {
throw DeviceControllerException.exceptions.couldNotFindSyncObjectToUnlinkTarget(targetDeviceId);
}
}
if (deleteTarget) {
_log.info("Delete target device {} :{}", targetDeviceId, snapshotURI);
Collection<String> nativeIds = transform(snapshots, fctnBlockObjectToNativeID());
if (snapshot.hasConsistencyGroup() && NullColumnValueGetter.isNotNullValue(snapshot.getReplicationGroupInstance())) {
try {
checkReplicationGroupAccessibleOrFail(system, snapshot, _dbClient, _helper, _cimPath);
deleteTargetGroup(system, snapshot.getReplicationGroupInstance());
} catch (DeviceControllerException | WBEMException e) {
_log.info("Failed to delete the target group. It may have already been deleted.");
}
}
// remove snapshot from them before deleting it.
for (BlockSnapshot snap : snapshots) {
try {
_helper.removeVolumeFromStorageGroupsIfVolumeIsNotInAnyMV(system, snap);
} catch (Exception e) {
_log.info("Failed to remove snap {} from storage groups. It may have already been removed.", snap.getNativeGuid());
}
}
callEMCRefresh(_helper, system, true);
deleteTargetDevices(system, nativeIds.toArray(new String[] {}), completer);
_log.info("Delete target device complete");
} else if (!syncObjectFound) {
// Need to be sure the completer is called.
completer.ready(_dbClient);
}
} catch (Exception e) {
_log.error("Exception unlinking snapshot session target", e);
ServiceError error = DeviceControllerErrors.smis.unableToCallStorageProvider(e.getMessage());
completer.error(_dbClient, error);
}
}
use of javax.wbem.WBEMException in project coprhd-controller by CoprHD.
the class VnxExportOperations method deleteStorageHWIDs.
/**
* Method invokes the SMI-S operation to remove the initiator hardware ID from the
* array. This should be called whenever the initiator is removed from an export or
* when the export is deleted.
*
* @param storage
* [in] - StorageSystem representing the array
* @param initiators
* [in] - An array Initiator objects, whose representation will
* be removed from the array.
* @throws Exception
*/
private void deleteStorageHWIDs(StorageSystem storage, List<Initiator> initiators) throws Exception {
if (initiators == null || initiators.isEmpty()) {
_log.debug("No initiators ...");
return;
}
CIMObjectPath hwIdManagementSvc = _cimPath.getStorageHardwareIDManagementService(storage);
for (Initiator initiator : initiators) {
try {
CIMArgument[] createHwIdIn = _helper.getDeleteStorageHardwareIDArgs(storage, initiator);
CIMArgument[] createHwIdOut = new CIMArgument[5];
_helper.invokeMethod(storage, hwIdManagementSvc, SmisConstants.DELETE_STORAGE_HARDWARE_ID, createHwIdIn, createHwIdOut);
} catch (WBEMException e) {
_log.error("deleteStorageHWIDs -- WBEMException: " + e.getMessage());
throw e;
} catch (Exception e) {
_log.error("deleteStorageHWIDs -- Exception: " + e.getMessage());
throw e;
}
}
}
use of javax.wbem.WBEMException in project coprhd-controller by CoprHD.
the class VnxExportOperations method getEMCTargetEndpoints.
/**
* Looks up the targets that are associated with the initiator (if any).
*
* @param idMgmtSvcPath
* [in] - Clar_StorageHardwareIDManagementService CIMObjectPath
* @param storage
* [in] - StorageSystem object representing the array
* @param initiator
* [in] - CIMObjectPath representing initiator to lookup target endpoints (StoragePorts) for
* @return List or StoragePort URIs that were found to be end points for the initiator
* @throws Exception
*/
private List<String> getEMCTargetEndpoints(CIMObjectPath idMgmtSvcPath, StorageSystem storage, CIMObjectPath initiator) throws Exception {
List<String> endpoints = new ArrayList<>();
try {
CIMArgument[] input = _helper.getEMCGetConnectedTargetEndpoints(initiator);
CIMArgument[] output = new CIMArgument[5];
_helper.invokeMethod(storage, idMgmtSvcPath, SmisConstants.EMC_GET_TARGET_ENDPOINTS, input, output);
CIMObjectPath[] tePaths = (CIMObjectPath[]) _cimPath.getFromOutputArgs(output, SmisConstants.CP_TARGET_ENDPOINTS);
if (tePaths != null) {
for (CIMObjectPath tePath : tePaths) {
CIMInstance teInstance = _helper.getInstance(storage, tePath, false, false, SmisConstants.PS_NAME);
String tePortNetworkId = CIMPropertyFactory.getPropertyValue(teInstance, SmisConstants.CP_NAME);
List<StoragePort> storagePorts = CustomQueryUtility.queryActiveResourcesByAltId(_dbClient, StoragePort.class, "portNetworkId", WWNUtility.getWWNWithColons(tePortNetworkId));
for (StoragePort port : storagePorts) {
endpoints.add(port.getNativeGuid());
}
}
}
_log.info(String.format("Initiator %s has these target endpoints: [ %s ]", initiator.toString(), Joiner.on(',').join(endpoints)));
} catch (WBEMException e) {
// The initiator CIMObjectPath passed into this function was determined by getting
// the associators to the StorageHardwareIDManagementService. When we call
// getEMCTargetEndpoints, it is done based on seeing that the initiator is in this
// associator list. Sometimes, the provider is returing initiator CIMObjectPaths
// that actually do not exist on the array. In this case, there will be WBEMException
// thrown when we try to get the targets storage ports using this CIMObject reference.
// So, here we're trying to protect against this possibility.
_log.info(String.format("Could not get TargetEndPoints for %s - %s", initiator, e.getMessage()));
}
return endpoints;
}
use of javax.wbem.WBEMException in project coprhd-controller by CoprHD.
the class VnxExportOperations method refreshExportMask.
@Override
public ExportMask refreshExportMask(StorageSystem storage, ExportMask mask) throws DeviceControllerException {
try {
CIMInstance instance = _helper.getLunMaskingProtocolController(storage, mask);
if (instance != null) {
StringBuilder builder = new StringBuilder();
WBEMClient client = _helper.getConnection(storage).getCimClient();
String name = CIMPropertyFactory.getPropertyValue(instance, SmisConstants.CP_ELEMENT_NAME);
// Get volumes and initiators for the masking instance
Map<String, Integer> discoveredVolumes = _helper.getVolumesFromLunMaskingInstance(client, instance);
// Update user added volume's HLU information in ExportMask and ExportGroup
ExportMaskUtils.updateHLUsInExportMask(mask, discoveredVolumes, _dbClient);
List<String> discoveredPorts = _helper.getInitiatorsFromLunMaskingInstance(client, instance);
Set existingInitiators = (mask.getExistingInitiators() != null) ? mask.getExistingInitiators() : Collections.emptySet();
Set existingVolumes = (mask.getExistingVolumes() != null) ? mask.getExistingVolumes().keySet() : Collections.emptySet();
builder.append(String.format("%nXM existing objects: %s I{%s} V:{%s}%n", name, Joiner.on(',').join(existingInitiators), Joiner.on(',').join(existingVolumes)));
builder.append(String.format("XM discovered: %s I:{%s} V:{%s}%n", name, Joiner.on(',').join(discoveredPorts), Joiner.on(',').join(discoveredVolumes.keySet())));
List<String> initiatorsToAddToExisting = new ArrayList<String>();
List<Initiator> initiatorsToAddToUserAddedAndInitiatorList = new ArrayList<Initiator>();
/**
* For the newly discovered initiators, if they are ViPR discovered ports and belong to same resource
* add them to user added and initiators list, otherwise add to existing list.
*/
for (String port : discoveredPorts) {
String normalizedPort = Initiator.normalizePort(port);
if (!mask.hasExistingInitiator(normalizedPort) && !mask.hasUserInitiator(normalizedPort)) {
Initiator existingInitiator = ExportUtils.getInitiator(Initiator.toPortNetworkId(port), _dbClient);
// Don't add additional initiator to initiators list if it belongs to different host/cluster
if (existingInitiator != null && !ExportMaskUtils.checkIfDifferentResource(mask, existingInitiator)) {
_log.info("Initiator {}->{} belonging to same compute, adding to userAdded and initiator list.", normalizedPort, existingInitiator.getId());
initiatorsToAddToUserAddedAndInitiatorList.add(existingInitiator);
} else {
initiatorsToAddToExisting.add(normalizedPort);
}
}
}
/**
* Get the existing initiators from the mask and remove the non-discovered ports because
* they are not discovered and are stale.
*
* If the mask has existing initiators but if they are discovered and belongs to same compute resource, then the
* initiators has to get added to user Added and initiators list, and removed from existing list.
*/
List<String> initiatorsToRemoveFromExistingList = new ArrayList<String>();
if (mask.getExistingInitiators() != null && !mask.getExistingInitiators().isEmpty()) {
for (String existingInitiatorStr : mask.getExistingInitiators()) {
if (!discoveredPorts.contains(existingInitiatorStr)) {
initiatorsToRemoveFromExistingList.add(existingInitiatorStr);
} else {
Initiator existingInitiator = ExportUtils.getInitiator(Initiator.toPortNetworkId(existingInitiatorStr), _dbClient);
if (existingInitiator != null && !ExportMaskUtils.checkIfDifferentResource(mask, existingInitiator)) {
_log.info("Initiator {}->{} belonging to same compute, removing from existing," + " and adding to userAdded and initiator list", existingInitiatorStr, existingInitiator.getId());
initiatorsToAddToUserAddedAndInitiatorList.add(existingInitiator);
initiatorsToRemoveFromExistingList.add(existingInitiatorStr);
}
}
}
}
/**
* Get all the initiators from the mask and remove all the ViPR discovered ports.
* The remaining list has to be removed from user Added and initiator list, because they are not available in ViPR
* but has to be moved to existing list.
*/
List<URI> initiatorsToRemoveFromUserAddedAndInitiatorList = new ArrayList<URI>();
if (mask.getInitiators() != null && !mask.getInitiators().isEmpty()) {
initiatorsToRemoveFromUserAddedAndInitiatorList.addAll(transform(mask.getInitiators(), CommonTransformerFunctions.FCTN_STRING_TO_URI));
for (String port : discoveredPorts) {
String normalizedPort = Initiator.normalizePort(port);
Initiator initiatorDiscoveredInViPR = ExportUtils.getInitiator(Initiator.toPortNetworkId(port), _dbClient);
if (initiatorDiscoveredInViPR != null) {
initiatorsToRemoveFromUserAddedAndInitiatorList.remove(initiatorDiscoveredInViPR.getId());
} else if (!mask.hasExistingInitiator(normalizedPort)) {
_log.info("Initiator {} not found in database, removing from user Added and initiator list," + " and adding to existing list.", port);
initiatorsToAddToExisting.add(normalizedPort);
}
}
}
boolean removeInitiators = !initiatorsToRemoveFromExistingList.isEmpty() || !initiatorsToRemoveFromUserAddedAndInitiatorList.isEmpty();
boolean addInitiators = !initiatorsToAddToUserAddedAndInitiatorList.isEmpty() || !initiatorsToAddToExisting.isEmpty();
// Check the volumes and update the lists as necessary
Map<String, Integer> volumesToAdd = ExportMaskUtils.diffAndFindNewVolumes(mask, discoveredVolumes);
boolean addVolumes = !volumesToAdd.isEmpty();
boolean removeVolumes = false;
List<String> volumesToRemove = new ArrayList<String>();
if (mask.getExistingVolumes() != null && !mask.getExistingVolumes().isEmpty()) {
volumesToRemove.addAll(mask.getExistingVolumes().keySet());
volumesToRemove.removeAll(discoveredVolumes.keySet());
}
// if the volume is in export mask's user added volumes and also in the existing volumes, remove from existing volumes
for (String wwn : discoveredVolumes.keySet()) {
if (mask.hasExistingVolume(wwn)) {
URIQueryResultList volumeList = new URIQueryResultList();
_dbClient.queryByConstraint(AlternateIdConstraint.Factory.getVolumeWwnConstraint(wwn), volumeList);
if (volumeList.iterator().hasNext()) {
URI volumeURI = volumeList.iterator().next();
if (mask.hasUserCreatedVolume(volumeURI)) {
builder.append(String.format("\texisting volumes contain wwn %s, but it is also in the " + "export mask's user added volumes, so removing from existing volumes", wwn));
volumesToRemove.add(wwn);
}
}
}
}
removeVolumes = !volumesToRemove.isEmpty();
// NOTE/TODO: We are not modifying the storage ports upon refresh like we do for VMAX.
// Refer to CTRL-6982.
builder.append(String.format("XM refresh: %s existing initiators; add:{%s} remove:{%s}%n", name, Joiner.on(',').join(initiatorsToAddToExisting), Joiner.on(',').join(initiatorsToRemoveFromExistingList)));
builder.append(String.format("XM refresh: %s user added and initiator list; add:{%s} remove:{%s}%n", name, Joiner.on(',').join(initiatorsToAddToUserAddedAndInitiatorList), Joiner.on(',').join(initiatorsToRemoveFromUserAddedAndInitiatorList)));
builder.append(String.format("XM refresh: %s volumes; add:{%s} remove:{%s}%n", name, Joiner.on(',').join(volumesToAdd.keySet()), Joiner.on(',').join(volumesToRemove)));
// Any changes indicated, then update the mask and persist it
if (addInitiators || removeInitiators || addVolumes || removeVolumes) {
builder.append("XM refresh: There are changes to mask, " + "updating it...\n");
mask.removeFromExistingInitiators(initiatorsToRemoveFromExistingList);
mask.removeInitiatorURIs(initiatorsToRemoveFromUserAddedAndInitiatorList);
mask.removeFromUserAddedInitiatorsByURI(initiatorsToRemoveFromUserAddedAndInitiatorList);
mask.addInitiators(initiatorsToAddToUserAddedAndInitiatorList);
mask.addToUserCreatedInitiators(initiatorsToAddToUserAddedAndInitiatorList);
mask.addToExistingInitiatorsIfAbsent(initiatorsToAddToExisting);
mask.removeFromExistingVolumes(volumesToRemove);
mask.addToExistingVolumesIfAbsent(volumesToAdd);
// Update the volume list to include existing volumes if know about them.
if (addVolumes) {
for (String wwn : volumesToAdd.keySet()) {
URIQueryResultList results = new URIQueryResultList();
_dbClient.queryByConstraint(AlternateIdConstraint.Factory.getVolumeWwnConstraint(wwn.toUpperCase()), results);
if (results != null) {
Iterator<URI> resultsIter = results.iterator();
if (resultsIter.hasNext()) {
Volume volume = _dbClient.queryObject(Volume.class, resultsIter.next());
if (null != volume) {
mask.addVolume(volume.getId(), volumesToAdd.get(wwn));
}
}
}
}
}
ExportMaskUtils.sanitizeExportMaskContainers(_dbClient, mask);
_dbClient.updateObject(mask);
} else {
builder.append("XM refresh: There are no changes to the mask\n");
}
_networkDeviceController.refreshZoningMap(mask, transform(initiatorsToRemoveFromUserAddedAndInitiatorList, CommonTransformerFunctions.FCTN_URI_TO_STRING), Collections.<String>emptyList(), (addInitiators || removeInitiators), true);
_log.info(builder.toString());
}
} catch (Exception e) {
boolean throwException = true;
if (e instanceof WBEMException) {
WBEMException we = (WBEMException) e;
// Only throw exception if code is not CIM_ERROR_NOT_FOUND
throwException = (we.getID() != WBEMException.CIM_ERR_NOT_FOUND);
}
if (throwException) {
String msg = "Error when attempting to query LUN masking information: " + e.getMessage();
_log.error(MessageFormat.format("Encountered an SMIS error when attempting to refresh existing exports: {0}", msg), e);
throw SmisException.exceptions.refreshExistingMaskFailure(msg, e);
}
}
return mask;
}
use of javax.wbem.WBEMException in project coprhd-controller by CoprHD.
the class VnxExportOperations method createOrGrowStorageGroup.
private CIMObjectPath[] createOrGrowStorageGroup(StorageSystem storage, URI exportMaskURI, VolumeURIHLU[] volumeURIHLUs, List<Initiator> initiatorList, List<URI> targetURIList, TaskCompleter completer) throws Exception {
// TODO - Refactor createOrGrowStorageGroup by moving code for creating an empty storage group
// to its own createStorageGroup method which calls exposePaths with null for initiators
// and targets
_log.info("{} createOrGrowStorageGroup START...", storage.getSerialNumber());
try {
List<CIMObjectPath> paths = new ArrayList<CIMObjectPath>();
Map<String, CIMObjectPath> existingHwStorageIds = getStorageHardwareIds(storage);
// If so, we need to register that initiator as the same name as the existing initiators. (CTRL-8407)
if (initiatorList != null) {
for (Initiator initiator : initiatorList) {
updateInitiatorBasedOnPeers(storage, existingHwStorageIds, initiator);
if (initiator != null) {
_log.info("After updateIntiatorBasedOnPeers : {} {}", initiator.getHostName(), initiator.toString());
}
}
}
Multimap<String, String> existingTargets = createStorageHWIDs(storage, existingHwStorageIds, initiatorList, completer);
if (initiatorList != null && existingTargets.keySet().size() == initiatorList.size()) {
_log.info(String.format("All the initiators are known to the array and have target endpoints: %s\n." + "These are the targets %s", Joiner.on(',').join(existingTargets.entries()), Joiner.on(',').join(targetURIList)));
}
Multimap<URI, Initiator> targetPortsToInitiators = HashMultimap.create();
// Some of the Initiators are already registered partially on the array based on pre existing zoning
// COP-16954 We need to manually register them, the Initiators will have HardwareId created but,
// The registration is not complete.. createHardwareIDs method above will include those Initiators
_log.info("Preregistered Target and Initiator ports processing .. Start");
// Map to hash translations
HashMap<String, URI> targetPortMap = new HashMap<>();
for (String initPort : existingTargets.keySet()) {
_log.info("InitiatorPort {} and TargetStoragePort {}", initPort, existingTargets.get(initPort));
// CLARIION+CKM00115001014+PORT+50:06:01:61:3E:A0:45:79]
if (!WWNUtility.isValidNoColonWWN(initPort)) {
_log.info("InitiatorPort {} is not a valid FC WWN so ignore it", initPort);
continue;
}
Collection<String> targetPorts = existingTargets.get(initPort);
for (String targetPortGuid : targetPorts) {
URI targetPortURI = targetPortMap.get(targetPortGuid);
if (targetPortURI == null) {
targetPortURI = getStoragePortURI(targetPortGuid);
targetPortMap.put(targetPortGuid, targetPortURI);
}
Initiator translatedInitiator = getInitiatorForWWN(initPort);
_log.info("Calculating Initiator {} and Target {}", translatedInitiator, targetPortURI);
if (targetPortURI != null && translatedInitiator != null) {
targetPortsToInitiators.put(targetPortURI, translatedInitiator);
} else {
_log.info("Initiator WWN {} translation was null or targetPort is null {}", initPort, targetPortURI);
}
}
}
_log.info("Preregistered Target and Initiator ports processing .. End");
List<URI> volumeURIs = new ArrayList<URI>();
if (volumeURIHLUs != null && volumeURIHLUs.length > 0) {
for (VolumeURIHLU volumeURIHLU : volumeURIHLUs) {
volumeURIs.add(volumeURIHLU.getVolumeURI());
}
}
if (initiatorList == null || initiatorList.isEmpty()) {
_log.info("InitiatorList is null or Empty so call exposePathsWithVolumesOnly");
paths.addAll(Arrays.asList(exposePathsWithVolumesOnly(storage, exportMaskURI, volumeURIHLUs)));
} else {
ExportMask mask = _dbClient.queryObject(ExportMask.class, exportMaskURI);
for (Initiator initiator : initiatorList) {
// TODO - Ask Tom is there is a reason why we should not do this instead of old code
List<URI> tzTargets = ExportUtils.getInitiatorPortsInMask(mask, initiator, _dbClient);
_log.info("Calculating Intiator {} and Targets {}", initiator, tzTargets);
if (!tzTargets.isEmpty()) {
for (URI targetURI : tzTargets) {
targetPortsToInitiators.put(targetURI, initiator);
}
}
}
_log.info("Call manuallyRegisterHostInitiators with {} ", targetPortsToInitiators.toString());
// Register the initiator to target port mappings
manuallyRegisterHostInitiators(storage, targetPortsToInitiators);
// CTRL-9086
// Modify the list of initiators list to match what is being mapped. If there are any initiators
// that are passed to the ExposePaths call that weren't manuallyRegistered (above), then those
// initiators will automatically get mapped all the array's StoragePorts.
//
// If the targetPortsToInitiators MultiMap is empty, then we will send all the initiators.
// Presumably, in this situation there are already some existing mappings for the initiators,
// so would just need to call ExposePaths with those initiators, so that they get added to the
// StorageGroup
List<Initiator> initiatorsToExpose = initiatorList;
if (!targetPortsToInitiators.isEmpty()) {
Map<URI, Initiator> uniqueInitiatorMap = new HashMap<>();
for (Collection<Initiator> initiatorCollection : targetPortsToInitiators.asMap().values()) {
for (Initiator initiator : initiatorCollection) {
uniqueInitiatorMap.put(initiator.getId(), initiator);
}
}
initiatorsToExpose = new ArrayList<>(uniqueInitiatorMap.values());
// confused about the initiators.
if (completer instanceof ExportMaskCreateCompleter) {
ExportMaskCreateCompleter createCompleter = ((ExportMaskCreateCompleter) completer);
List<URI> removedInitiators = new ArrayList<>();
List<URI> maskInitiators = StringSetUtil.stringSetToUriList(mask.getInitiators());
for (URI maskInitiator : maskInitiators) {
if (!uniqueInitiatorMap.containsKey(maskInitiator)) {
mask.removeInitiator(maskInitiator);
removedInitiators.add(maskInitiator);
}
}
_dbClient.updateObject(mask);
if (!removedInitiators.isEmpty()) {
_log.info(String.format("The following initiators will not be mapped, hence they will be " + "removed from the initiator list of ExportMask %s (%s): %s", mask.getMaskName(), mask.getId(), Joiner.on(',').join(removedInitiators)));
}
// Adjust the completer's initiator list
createCompleter.removeInitiators(removedInitiators);
}
}
_log.info(String.format("ExposePaths will be called with these initiators: %s", Joiner.on(',').join(Collections2.transform(initiatorsToExpose, CommonTransformerFunctions.fctnInitiatorToPortName()))));
// Add all the initiators to the StorageGroup
paths.addAll(Arrays.asList(exposePathsWithVolumesAndInitiatorsOnly(storage, exportMaskURI, volumeURIHLUs, initiatorsToExpose)));
}
ExportOperationContext.insertContextOperation(completer, VnxExportOperationContext.OPERATION_ADD_VOLUMES_TO_STORAGE_GROUP, volumeURIs);
_log.info("{} createOrGrowStorageGroup END...", storage.getSerialNumber());
return paths.toArray(new CIMObjectPath[paths.size()]);
} catch (WBEMException e) {
_log.error("Problem making SMI-S call: ", e);
throw e;
} catch (Exception e) {
_log.error("Unexpected error: createOrGrowStorageGroup failed.", e);
throw e;
}
}
Aggregations