Search in sources :

Example 46 with ExportMask

use of com.emc.storageos.db.client.model.ExportMask in project coprhd-controller by CoprHD.

the class HDSExportOperations method findExportMasks.

@Override
public Map<String, Set<URI>> findExportMasks(StorageSystem storage, List<String> initiatorNames, boolean mustHaveAllPorts) throws DeviceControllerException {
    Map<String, Set<URI>> matchingMasks = new HashMap<String, Set<URI>>();
    log.info("finding export masks for storage {}", storage.getId());
    String systemObjectID = HDSUtils.getSystemObjectID(storage);
    Map<URI, Set<HostStorageDomain>> matchedHostHSDsMap = new HashMap<URI, Set<HostStorageDomain>>();
    Map<URI, Set<URI>> hostToInitiatorMap = new HashMap<URI, Set<URI>>();
    Map<URI, Set<String>> matchedHostInitiators = new HashMap<URI, Set<String>>();
    try {
        HDSApiClient client = hdsApiFactory.getClient(HDSUtils.getHDSServerManagementServerInfo(storage), storage.getSmisUserName(), storage.getSmisPassword());
        HDSApiExportManager exportManager = client.getHDSApiExportManager();
        List<HostStorageDomain> hsdList = exportManager.getHostStorageDomains(systemObjectID);
        for (HostStorageDomain hsd : hsdList) {
            List<String> initiatorsExistsOnHSD = getInitiatorsExistsOnHSD(hsd.getWwnList(), hsd.getIscsiList());
            // Find out if the port is in this masking container
            for (String initiatorName : initiatorNames) {
                String normalizedName = initiatorName.replace(HDSConstants.COLON, HDSConstants.DOT_OPERATOR);
                if (initiatorsExistsOnHSD.contains(normalizedName)) {
                    log.info("Found a matching HSD for {}", initiatorName);
                    Initiator initiator = fetchInitiatorByName(initiatorName);
                    Set<HostStorageDomain> matchedHSDs = matchedHostHSDsMap.get(initiator.getHost());
                    if (matchedHSDs == null) {
                        matchedHSDs = new HashSet<HostStorageDomain>();
                        matchedHostHSDsMap.put(initiator.getHost(), matchedHSDs);
                    }
                    matchedHSDs.add(hsd);
                    Set<String> matchedInitiators = matchedHostInitiators.get(initiator.getHost());
                    if (null == matchedInitiators) {
                        matchedInitiators = new HashSet<String>();
                        matchedHostInitiators.put(initiator.getHost(), matchedInitiators);
                    }
                    matchedInitiators.add(initiatorName);
                }
            }
        }
        hsdList.clear();
        log.info("matchedHSDs: {}", matchedHostHSDsMap);
        log.info("initiatorURIToNameMap: {}", matchedHostInitiators);
        processInitiators(initiatorNames, hostToInitiatorMap);
        List<URI> activeMaskIdsInDb = dbClient.queryByType(ExportMask.class, true);
        List<ExportMask> activeMasks = dbClient.queryObject(ExportMask.class, activeMaskIdsInDb);
        if (null != matchedHostHSDsMap && !matchedHostHSDsMap.isEmpty()) {
            // Iterate through each host
            for (URI hostURI : hostToInitiatorMap.keySet()) {
                Set<URI> hostInitiators = hostToInitiatorMap.get(hostURI);
                boolean isNewExportMask = false;
                // Create single ExportMask for each host-varray combination
                List<ExportMask> exportMaskWithHostInitiators = fetchExportMasksFromDB(activeMasks, hostInitiators, storage);
                Set<HostStorageDomain> hsds = matchedHostHSDsMap.get(hostURI);
                if (!CollectionUtils.isEmpty(hsds)) {
                    for (HostStorageDomain hsd : hsds) {
                        String storagePortOFHDSURI = getStoragePortURIs(Arrays.asList(hsd.getPortID()), storage).get(0);
                        ExportMask maskForHSD = null;
                        for (ExportMask exportMaskhavingInitiators : exportMaskWithHostInitiators) {
                            if (exportMaskhavingInitiators.getStoragePorts().contains(storagePortOFHDSURI)) {
                                maskForHSD = exportMaskhavingInitiators;
                                break;
                            }
                        }
                        if (null == maskForHSD) {
                            // first get the varrays associated with the storage port of the HSD and then check if
                            // any of the export masks have storage ports, which have virtual arrays overlapping with the virtual
                            // arrays of the HSD storage port
                            // NOTE: If the storageport is assigned to multiple varrays, then maintaining one
                            // export mask per varray is not possible. Proper seggregation has to be done.
                            StringSet varraysAssociatedWithHSDStoragePort = getTaggedVarrays(storagePortOFHDSURI);
                            if (!varraysAssociatedWithHSDStoragePort.isEmpty()) {
                                boolean bMaskFound = false;
                                for (ExportMask exportMaskhavingInitiators : exportMaskWithHostInitiators) {
                                    for (String storagePortUriIter : exportMaskhavingInitiators.getStoragePorts()) {
                                        // get the storage port entity
                                        StringSet varraysOfStoragePort = getTaggedVarrays(storagePortUriIter);
                                        if (StringSetUtil.hasIntersection(varraysOfStoragePort, varraysAssociatedWithHSDStoragePort)) {
                                            maskForHSD = exportMaskhavingInitiators;
                                            // Ingest the foreign HSD into a matching export mask with same host and varray combination
                                            bMaskFound = true;
                                            break;
                                        }
                                    }
                                    if (bMaskFound) {
                                        break;
                                    }
                                }
                            } else {
                                // Since this HSD port is not tagged to any varray, we will not ingest it
                                continue;
                            }
                            if (null == maskForHSD) {
                                // No matching export mask found for the same host and varray combination. Creating a new export mask.
                                isNewExportMask = true;
                                maskForHSD = new ExportMask();
                                maskForHSD.setId(URIUtil.createId(ExportMask.class));
                                maskForHSD.setStorageDevice(storage.getId());
                                maskForHSD.setCreatedBySystem(false);
                            }
                        }
                        Set<HostStorageDomain> hsdSet = new HashSet<>();
                        hsdSet.add(hsd);
                        updateHSDInfoInExportMask(maskForHSD, hostInitiators, hsdSet, storage, matchingMasks);
                        if (isNewExportMask) {
                            dbClient.createObject(maskForHSD);
                            exportMaskWithHostInitiators.add(maskForHSD);
                        } else {
                            ExportMaskUtils.sanitizeExportMaskContainers(dbClient, maskForHSD);
                            dbClient.updateObject(maskForHSD);
                        }
                        updateMatchingMasksForHost(matchedHostInitiators.get(hostURI), maskForHSD, matchingMasks);
                    }
                }
            }
        }
    } catch (Exception e) {
        log.error("Error when attempting to query LUN masking information", e);
        throw HDSException.exceptions.queryExistingMasksFailure(e.getMessage());
    }
    log.info("Found matching masks: {}", matchingMasks);
    return matchingMasks;
}
Also used : Set(java.util.Set) HashSet(java.util.HashSet) StringSet(com.emc.storageos.db.client.model.StringSet) HashMap(java.util.HashMap) URI(java.net.URI) HostStorageDomain(com.emc.storageos.hds.model.HostStorageDomain) Initiator(com.emc.storageos.db.client.model.Initiator) StringSet(com.emc.storageos.db.client.model.StringSet) HashSet(java.util.HashSet) HDSApiClient(com.emc.storageos.hds.api.HDSApiClient) ExportMask(com.emc.storageos.db.client.model.ExportMask) HDSApiExportManager(com.emc.storageos.hds.api.HDSApiExportManager) DeviceControllerException(com.emc.storageos.exceptions.DeviceControllerException) HDSException(com.emc.storageos.hds.HDSException)

Example 47 with ExportMask

use of com.emc.storageos.db.client.model.ExportMask in project coprhd-controller by CoprHD.

the class HDSExportOperations method addInitiators.

@Override
public void addInitiators(StorageSystem storage, URI exportMaskURI, List<URI> volumeURIs, List<Initiator> initiators, List<URI> targetURIList, TaskCompleter taskCompleter) throws DeviceControllerException {
    log.info("{} addInitiator START...", storage.getSerialNumber());
    HDSApiClient hdsApiClient = null;
    String systemObjectID = null;
    List<HostStorageDomain> hsdsToCreate = null;
    List<HostStorageDomain> hsdsWithInitiators = null;
    try {
        log.info("addInitiator: Export mask id: {}", exportMaskURI);
        if (volumeURIs != null) {
            log.info("addInitiator: volumes : {}", Joiner.on(',').join(volumeURIs));
        }
        log.info("addInitiator: initiators : {}", Joiner.on(',').join(initiators));
        log.info("addInitiator: targets : {}", Joiner.on(",").join(targetURIList));
        hdsApiClient = hdsApiFactory.getClient(HDSUtils.getHDSServerManagementServerInfo(storage), storage.getSmisUserName(), storage.getSmisPassword());
        HDSApiExportManager exportMgr = hdsApiClient.getHDSApiExportManager();
        systemObjectID = HDSUtils.getSystemObjectID(storage);
        ExportMask exportMask = dbClient.queryObject(ExportMask.class, exportMaskURI);
        List<StoragePort> ports = dbClient.queryObject(StoragePort.class, targetURIList, true);
        if (checkIfMixedTargetPortTypeSelected(ports)) {
            log.error("Unsupported Host as it has both FC & iSCSI Initiators");
            throw HDSException.exceptions.unsupportedConfigurationFoundInHost();
        }
        // @TODO register new initiators by adding them to host on HiCommand DM.
        // Currently, HiCommand is not supporting this. Need to see how we can handle.
        String hostName = getHostNameForInitiators(initiators);
        String hostMode = null, hostModeOption = null;
        Pair<String, String> hostModeInfo = getHostModeInfo(storage, initiators);
        if (hostModeInfo != null) {
            hostMode = hostModeInfo.first;
            hostModeOption = hostModeInfo.second;
        }
        if (targetURIList != null && !targetURIList.isEmpty()) {
            Set<URI> newTargetPorts = new HashSet<>(targetURIList);
            Set<URI> existingTargetPortsInMask = new HashSet<>();
            if (exportMask.getStoragePorts() != null) {
                existingTargetPortsInMask = new HashSet<>(targetURIList);
                Collection<URI> targetPorts = Collections2.transform(exportMask.getStoragePorts(), CommonTransformerFunctions.FCTN_STRING_TO_URI);
                existingTargetPortsInMask.retainAll(targetPorts);
            }
            newTargetPorts.removeAll(existingTargetPortsInMask);
            log.info("list of new storage target ports {}", newTargetPorts);
            log.info("list of existing storage target ports available in export masks {}", existingTargetPortsInMask);
            // Case 1 is handled here for the new initiators & new target ports.
            if (!newTargetPorts.isEmpty()) {
                // If the HLU's are already configured on this target port, then an exception is thrown.
                // User should make sure that all volumes should have same HLU across all target HSD's.
                VolumeURIHLU[] volumeURIHLUs = getVolumeURIHLUFromExportMask(exportMask);
                if (0 < volumeURIHLUs.length) {
                    List<URI> portList = new ArrayList<>(newTargetPorts);
                    hsdsToCreate = processTargetPortsToFormHSDs(hdsApiClient, storage, portList, hostName, exportMask, hostModeInfo, systemObjectID);
                    // Step 1: Create all HSD's using batch operation.
                    List<HostStorageDomain> hsdResponseList = hdsApiClient.getHDSBatchApiExportManager().addHostStorageDomains(systemObjectID, hsdsToCreate, storage.getModel());
                    if (null == hsdResponseList || hsdResponseList.isEmpty()) {
                        log.error("Batch HSD creation failed to add new initiators. Aborting operation...");
                        throw HDSException.exceptions.notAbleToAddHSD(storage.getSerialNumber());
                    }
                    // Step 2: Add initiators to all HSD's.
                    Iterator<StoragePort> storagePortIterator = dbClient.queryIterativeObjects(StoragePort.class, newTargetPorts);
                    List<StoragePort> stPortList = new ArrayList<>();
                    while (storagePortIterator.hasNext()) {
                        StoragePort stPort = storagePortIterator.next();
                        if (stPort != null && !stPort.getInactive()) {
                            stPortList.add(stPort);
                        }
                    }
                    hsdsWithInitiators = executeBatchHSDAddInitiatorsCommand(hdsApiClient, systemObjectID, hsdResponseList, stPortList, initiators, storage.getModel());
                    // Step 3: Add volumes to all HSD's.
                    List<Path> allHSDPaths = executeBatchHSDAddVolumesCommand(hdsApiClient, systemObjectID, hsdsWithInitiators, volumeURIHLUs, storage.getModel());
                    if (null != allHSDPaths && !allHSDPaths.isEmpty()) {
                        updateExportMaskDetailInDB(hsdsWithInitiators, allHSDPaths, exportMask, storage, volumeURIHLUs);
                    }
                } else {
                    log.info("There are no volumes on this exportmask: {} to add to new initiator", exportMaskURI);
                }
            }
            // existing HSD to access the volumes already exported in the exportmask.
            if (!existingTargetPortsInMask.isEmpty()) {
                // Step 1: Collect all HSDs from export mask
                StringSetMap deviceDataMap = exportMask.getDeviceDataMap();
                if (null != deviceDataMap && !deviceDataMap.isEmpty()) {
                    List<HostStorageDomain> hsdResponseList = new ArrayList<>();
                    Set<String> hsdObjectIdSet = deviceDataMap.keySet();
                    for (String hsdObjectId : hsdObjectIdSet) {
                        HostStorageDomain hsd = exportMgr.getHostStorageDomain(systemObjectID, hsdObjectId);
                        if (null == hsd) {
                            throw HDSException.exceptions.notAbleToFindHostStorageDomain(hsdObjectId);
                        }
                        hsdResponseList.add(hsd);
                    }
                    // Step 2: Add initiators to all HSD's.
                    Iterator<StoragePort> storagePortIterator = dbClient.queryIterativeObjects(StoragePort.class, existingTargetPortsInMask, true);
                    List<StoragePort> stPortList = new ArrayList<>();
                    while (storagePortIterator.hasNext()) {
                        StoragePort stPort = storagePortIterator.next();
                        if (stPort != null) {
                            stPortList.add(stPort);
                        }
                    }
                    hsdsWithInitiators = executeBatchHSDAddInitiatorsCommand(hdsApiClient, systemObjectID, hsdResponseList, stPortList, initiators, storage.getModel());
                } else {
                    log.info("There are no hsd information in exportMask to add initiators");
                }
            }
        }
        taskCompleter.ready(dbClient);
    } catch (Exception ex) {
        try {
            log.info("Exception occurred while adding new initiators: {}", ex.getMessage());
            if (null != hsdsWithInitiators && !hsdsWithInitiators.isEmpty()) {
                hdsApiClient.getHDSBatchApiExportManager().deleteBatchHostStorageDomains(systemObjectID, hsdsWithInitiators, storage.getModel());
            } else {
                if (null != hsdsToCreate && !hsdsToCreate.isEmpty()) {
                    List<HostStorageDomain> allHSDs = hdsApiClient.getHDSApiExportManager().getHostStorageDomains(systemObjectID);
                    List<HostStorageDomain> partialHSDListToRemove = getPartialHSDListToDelete(allHSDs, hsdsToCreate);
                    hdsApiClient.getHDSBatchApiExportManager().deleteBatchHostStorageDomains(systemObjectID, partialHSDListToRemove, storage.getModel());
                }
            }
            log.error(String.format("addInitiator failed - maskURI: %s", exportMaskURI.toString()), ex);
        } catch (Exception ex1) {
            log.error("Exception occurred while deleting unsuccessful HSDs on system: {}", systemObjectID, ex1.getMessage());
        } finally {
            ServiceError serviceError = DeviceControllerException.errors.jobFailedOpMsg(ResourceOperationTypeEnum.ADD_EXPORT_INITIATOR.getName(), ex.getMessage());
            taskCompleter.error(dbClient, serviceError);
        }
    }
    log.info("{} addInitiator END...", storage.getSerialNumber());
}
Also used : ArrayList(java.util.ArrayList) URI(java.net.URI) HostStorageDomain(com.emc.storageos.hds.model.HostStorageDomain) List(java.util.List) ArrayList(java.util.ArrayList) URIQueryResultList(com.emc.storageos.db.client.constraint.URIQueryResultList) HashSet(java.util.HashSet) Path(com.emc.storageos.hds.model.Path) HDSApiClient(com.emc.storageos.hds.api.HDSApiClient) StringSetMap(com.emc.storageos.db.client.model.StringSetMap) ServiceError(com.emc.storageos.svcs.errorhandling.model.ServiceError) ExportMask(com.emc.storageos.db.client.model.ExportMask) StoragePort(com.emc.storageos.db.client.model.StoragePort) HDSApiExportManager(com.emc.storageos.hds.api.HDSApiExportManager) DeviceControllerException(com.emc.storageos.exceptions.DeviceControllerException) HDSException(com.emc.storageos.hds.HDSException) VolumeURIHLU(com.emc.storageos.volumecontroller.impl.VolumeURIHLU)

Example 48 with ExportMask

use of com.emc.storageos.db.client.model.ExportMask in project coprhd-controller by CoprHD.

the class VmaxMaskingOrchestrator method changePortGroup.

@Override
public void changePortGroup(URI storageURI, URI exportGroupURI, URI portGroupURI, List<URI> exportMaskURIs, boolean waitForApproval, String token) {
    ExportChangePortGroupCompleter taskCompleter = null;
    try {
        ExportGroup exportGroup = _dbClient.queryObject(ExportGroup.class, exportGroupURI);
        StorageSystem storage = _dbClient.queryObject(StorageSystem.class, storageURI);
        StoragePortGroup portGroup = _dbClient.queryObject(StoragePortGroup.class, portGroupURI);
        taskCompleter = new ExportChangePortGroupCompleter(storageURI, exportGroupURI, token, portGroupURI);
        logExportGroup(exportGroup, storageURI);
        String workflowKey = "changePortGroup";
        if (_workflowService.hasWorkflowBeenCreated(token, workflowKey)) {
            return;
        }
        Workflow workflow = _workflowService.getNewWorkflow(MaskingWorkflowEntryPoints.getInstance(), workflowKey, false, token);
        if (CollectionUtils.isEmpty(exportMaskURIs)) {
            _log.info("No export masks to change");
            taskCompleter.ready(_dbClient);
            return;
        }
        List<ExportMask> exportMasks = _dbClient.queryObject(ExportMask.class, exportMaskURIs);
        String previousStep = null;
        Set<URI> hostURIs = new HashSet<URI>();
        for (ExportMask oldMask : exportMasks) {
            // create a new masking view using the new port group
            SmisStorageDevice device = (SmisStorageDevice) getDevice();
            oldMask = device.refreshExportMask(storage, oldMask);
            StringSet existingInits = oldMask.getExistingInitiators();
            StringMap existingVols = oldMask.getExistingVolumes();
            if (!CollectionUtils.isEmpty(existingInits)) {
                String error = String.format("The export mask %s has unmanaged initiators %s", oldMask.getMaskName(), Joiner.on(',').join(existingInits));
                _log.error(error);
                ServiceError serviceError = DeviceControllerException.errors.changePortGroupValidationError(error);
                taskCompleter.error(_dbClient, serviceError);
                return;
            }
            if (!CollectionUtils.isEmpty(existingVols)) {
                String error = String.format("The export mask %s has unmanaged volumes %s", oldMask.getMaskName(), Joiner.on(',').join(existingVols.keySet()));
                _log.error(error);
                ServiceError serviceError = DeviceControllerException.errors.changePortGroupValidationError(error);
                taskCompleter.error(_dbClient, serviceError);
                return;
            }
            InitiatorHelper initiatorHelper = new InitiatorHelper(StringSetUtil.stringSetToUriList(oldMask.getInitiators())).process(exportGroup);
            List<String> initiatorNames = initiatorHelper.getPortNames();
            List<URI> volumes = StringSetUtil.stringSetToUriList(oldMask.getVolumes().keySet());
            ExportPathParams pathParams = _blockScheduler.calculateExportPathParamForVolumes(volumes, 0, storageURI, exportGroupURI);
            pathParams.setStoragePorts(portGroup.getStoragePorts());
            List<Initiator> initiators = ExportUtils.getExportMaskInitiators(oldMask, _dbClient);
            List<URI> initURIs = new ArrayList<URI>();
            for (Initiator init : initiators) {
                if (!NullColumnValueGetter.isNullURI(init.getHost())) {
                    hostURIs.add(init.getHost());
                }
                initURIs.add(init.getId());
            }
            // Get impacted export groups
            List<ExportGroup> impactedExportGroups = ExportMaskUtils.getExportGroups(_dbClient, oldMask);
            List<URI> exportGroupURIs = URIUtil.toUris(impactedExportGroups);
            _log.info("changePortGroup: exportMask {}, impacted export groups: {}", oldMask.getMaskName(), Joiner.on(',').join(exportGroupURIs));
            Map<URI, List<URI>> assignments = _blockScheduler.assignStoragePorts(storage, exportGroup, initiators, null, pathParams, volumes, _networkDeviceController, exportGroup.getVirtualArray(), token);
            // Trying to find if there is existing export mask or masking view for the same host and using the new
            // port group. If found one, add the volumes in the current export mask to the new one; otherwise, create
            // a new export mask/masking view, with the same storage group, initiator group and the new port group.
            // then delete the current export mask.
            ExportMask newMask = device.findExportMasksForPortGroupChange(storage, initiatorNames, portGroupURI);
            Map<URI, Integer> volumesToAdd = StringMapUtil.stringMapToVolumeMap(oldMask.getVolumes());
            if (newMask != null) {
                updateZoningMap(exportGroup, newMask, true);
                _log.info(String.format("adding these volumes %s to mask %s", Joiner.on(",").join(volumesToAdd.keySet()), newMask.getMaskName()));
                previousStep = generateZoningAddVolumesWorkflow(workflow, previousStep, exportGroup, Arrays.asList(newMask), new ArrayList<URI>(volumesToAdd.keySet()));
                String addVolumeStep = workflow.createStepId();
                ExportTaskCompleter exportTaskCompleter = new ExportMaskAddVolumeCompleter(exportGroupURI, newMask.getId(), volumesToAdd, addVolumeStep);
                exportTaskCompleter.setExportGroups(exportGroupURIs);
                Workflow.Method maskingExecuteMethod = new Workflow.Method("doExportGroupAddVolumes", storageURI, exportGroupURI, newMask.getId(), volumesToAdd, null, exportTaskCompleter);
                Workflow.Method maskingRollbackMethod = new Workflow.Method("rollbackExportGroupAddVolumes", storageURI, exportGroupURI, exportGroupURIs, newMask.getId(), volumesToAdd, initURIs, addVolumeStep);
                previousStep = workflow.createStep(EXPORT_GROUP_MASKING_TASK, String.format("Adding volumes to mask %s (%s)", newMask.getMaskName(), newMask.getId().toString()), previousStep, storageURI, storage.getSystemType(), MaskingWorkflowEntryPoints.class, maskingExecuteMethod, maskingRollbackMethod, addVolumeStep);
                previousStep = generateExportMaskAddVolumesWorkflow(workflow, previousStep, storage, exportGroup, newMask, volumesToAdd, null);
            } else {
                // We don't find existing export mask /masking view, we will create a new one.
                // first, to construct the new export mask name, if the export mask has the original name, then
                // append the new port group name to the current export mask name; if the export mask already has the current
                // port group name appended, then remove the current port group name, and append the new one.
                String oldName = oldMask.getMaskName();
                URI oldPGURI = oldMask.getPortGroup();
                if (oldPGURI != null) {
                    StoragePortGroup oldPG = _dbClient.queryObject(StoragePortGroup.class, oldPGURI);
                    if (oldPG != null) {
                        String pgName = oldPG.getLabel();
                        if (oldName.endsWith(pgName)) {
                            oldName = oldName.replaceAll(pgName, "");
                        }
                    }
                }
                String maskName = null;
                if (oldName.endsWith("_")) {
                    maskName = String.format("%s%s", oldName, portGroup.getLabel());
                } else {
                    maskName = String.format("%s_%s", oldName, portGroup.getLabel());
                }
                newMask = ExportMaskUtils.initializeExportMask(storage, exportGroup, initiators, volumesToAdd, getStoragePortsInPaths(assignments), assignments, maskName, _dbClient);
                newMask.setPortGroup(portGroupURI);
                List<BlockObject> vols = new ArrayList<BlockObject>();
                for (URI boURI : volumesToAdd.keySet()) {
                    BlockObject bo = BlockObject.fetch(_dbClient, boURI);
                    vols.add(bo);
                }
                newMask.addToUserCreatedVolumes(vols);
                _dbClient.updateObject(newMask);
                _log.info(String.format("Creating new exportMask %s", maskName));
                // Make a new TaskCompleter for the exportStep. It has only one subtask.
                // This is due to existing requirements in the doExportGroupCreate completion
                // logic.
                String maskingStep = workflow.createStepId();
                ExportTaskCompleter exportTaskCompleter = new ExportMaskChangePortGroupAddMaskCompleter(newMask.getId(), exportGroupURI, maskingStep);
                exportTaskCompleter.setExportGroups(exportGroupURIs);
                Workflow.Method maskingExecuteMethod = new Workflow.Method("doExportChangePortGroupAddPaths", storageURI, exportGroupURI, newMask.getId(), oldMask.getId(), portGroupURI, exportTaskCompleter);
                Workflow.Method maskingRollbackMethod = new Workflow.Method("rollbackExportGroupCreate", storageURI, exportGroupURI, newMask.getId(), maskingStep);
                maskingStep = workflow.createStep(EXPORT_GROUP_MASKING_TASK, String.format("Create export mask(%s) to use port group %s", newMask.getMaskName(), portGroup.getNativeGuid()), previousStep, storageURI, storage.getSystemType(), MaskingWorkflowEntryPoints.class, maskingExecuteMethod, maskingRollbackMethod, maskingStep);
                String zoningStep = workflow.createStepId();
                List<URI> masks = new ArrayList<URI>();
                masks.add(newMask.getId());
                previousStep = generateZoningCreateWorkflow(workflow, maskingStep, exportGroup, masks, volumesToAdd, zoningStep);
            }
        }
        previousStep = _wfUtils.generateHostRescanWorkflowSteps(workflow, hostURIs, previousStep);
        if (waitForApproval) {
            // Insert a step that will be suspended. When it resumes, it will re-acquire the lock keys,
            // which are released when the workflow suspends.
            List<String> lockKeys = ControllerLockingUtil.getHostStorageLockKeys(_dbClient, ExportGroup.ExportGroupType.valueOf(exportGroup.getType()), StringSetUtil.stringSetToUriList(exportGroup.getInitiators()), storageURI);
            String suspendMessage = "Adjust/rescan host/cluster paths. Press \"Resume\" to start removal of unnecessary paths." + "\"Rollback\" will terminate the order and roll back";
            Workflow.Method method = WorkflowService.acquireWorkflowLocksMethod(lockKeys, LockTimeoutValue.get(LockType.EXPORT_GROUP_OPS));
            Workflow.Method rollbackNull = Workflow.NULL_METHOD;
            previousStep = workflow.createStep("AcquireLocks", "Suspending for user verification of host/cluster connectivity.", previousStep, storage.getId(), storage.getSystemType(), WorkflowService.class, method, rollbackNull, waitForApproval, null);
            workflow.setSuspendedStepMessage(previousStep, suspendMessage);
        }
        for (ExportMask exportMask : exportMasks) {
            previousStep = generateChangePortGroupDeleteMaskWorkflowstep(storageURI, exportGroup, exportMask, previousStep, workflow);
        }
        _wfUtils.generateHostRescanWorkflowSteps(workflow, hostURIs, previousStep);
        if (!workflow.getAllStepStatus().isEmpty()) {
            _log.info("The change port group workflow has {} steps. Starting the workflow.", workflow.getAllStepStatus().size());
            // update ExportChangePortGroupCompleter with affected export groups
            Set<URI> affectedExportGroups = new HashSet<URI>();
            for (ExportMask mask : exportMasks) {
                List<ExportGroup> assocExportGroups = ExportMaskUtils.getExportGroups(_dbClient, mask);
                for (ExportGroup eg : assocExportGroups) {
                    affectedExportGroups.add(eg.getId());
                }
            }
            taskCompleter.setAffectedExportGroups(affectedExportGroups);
            workflow.executePlan(taskCompleter, "Change port group successfully.");
            _workflowService.markWorkflowBeenCreated(token, workflowKey);
        } else {
            taskCompleter.ready(_dbClient);
        }
    } catch (Exception e) {
        _log.error("Export change port group Orchestration failed.", e);
        if (taskCompleter != null) {
            ServiceError serviceError = DeviceControllerException.errors.jobFailedMsg(e.getMessage(), e);
            taskCompleter.error(_dbClient, serviceError);
        }
    }
}
Also used : StoragePortGroup(com.emc.storageos.db.client.model.StoragePortGroup) StringMap(com.emc.storageos.db.client.model.StringMap) ExportTaskCompleter(com.emc.storageos.volumecontroller.impl.block.taskcompleter.ExportTaskCompleter) Lists.newArrayList(com.google.common.collect.Lists.newArrayList) ArrayList(java.util.ArrayList) URI(java.net.URI) Initiator(com.emc.storageos.db.client.model.Initiator) WorkflowService(com.emc.storageos.workflow.WorkflowService) StringSet(com.emc.storageos.db.client.model.StringSet) List(java.util.List) Lists.newArrayList(com.google.common.collect.Lists.newArrayList) ArrayList(java.util.ArrayList) URIQueryResultList(com.emc.storageos.db.client.constraint.URIQueryResultList) BlockObject(com.emc.storageos.db.client.model.BlockObject) StorageSystem(com.emc.storageos.db.client.model.StorageSystem) HashSet(java.util.HashSet) ServiceError(com.emc.storageos.svcs.errorhandling.model.ServiceError) ExportMask(com.emc.storageos.db.client.model.ExportMask) ExportMaskChangePortGroupAddMaskCompleter(com.emc.storageos.volumecontroller.impl.block.taskcompleter.ExportMaskChangePortGroupAddMaskCompleter) Workflow(com.emc.storageos.workflow.Workflow) DeviceControllerException(com.emc.storageos.exceptions.DeviceControllerException) ExportGroup(com.emc.storageos.db.client.model.ExportGroup) ExportChangePortGroupCompleter(com.emc.storageos.volumecontroller.impl.block.taskcompleter.ExportChangePortGroupCompleter) ExportMaskAddVolumeCompleter(com.emc.storageos.volumecontroller.impl.block.taskcompleter.ExportMaskAddVolumeCompleter) SmisStorageDevice(com.emc.storageos.volumecontroller.impl.smis.SmisStorageDevice) ExportPathParams(com.emc.storageos.db.client.model.ExportPathParams)

Example 49 with ExportMask

use of com.emc.storageos.db.client.model.ExportMask in project coprhd-controller by CoprHD.

the class VmaxMaskingOrchestrator method updatePlacementMapForCluster.

/**
 * Special case for VMAX with a cluster compute resource:
 *
 * In the case where a mask may contain a subset of nodes of a cluster, we wish to leverage it.
 *
 * Logic is as follows: Attempt to discover which ports have not been placed in the map yet (specific to VMAX),
 * and add those ports to the map in the circumstance where we are doing cluster and the
 * existing mask is already handling multiple hosts.
 *
 * In the case of brownfield cluster, some of these port to ExportMask may be missing because the array doesn't
 * have them yet. Find this condition and add the additional ports to the map.
 *
 * @param exportGroup export group
 * @param resourceToInitiators resource -> initiator list
 * @param initiatorToExportMaskPlacementMap placement mask map from the default orchestrator
 */
private void updatePlacementMapForCluster(ExportGroup exportGroup, Map<String, List<URI>> resourceToInitiators, Map<String, Set<URI>> initiatorToExportMaskPlacementMap) {
    // double check we're dealing with cluster
    if (exportGroup.forCluster() || exportGroup.forHost()) {
        // Safety, ensure the map has been created.
        if (initiatorToExportMaskPlacementMap == null) {
            initiatorToExportMaskPlacementMap = new HashMap<String, Set<URI>>();
        }
        // Check each compute resource's initiator list
        for (Map.Entry<String, List<URI>> entry : resourceToInitiators.entrySet()) {
            List<URI> initiatorSet = entry.getValue();
            for (URI initiatorURI : initiatorSet) {
                Initiator initiator = _dbClient.queryObject(Initiator.class, initiatorURI);
                // Is this initiator covered in the map yet?
                Set<URI> exportMasksToAdd = new HashSet<URI>();
                if (!initiatorToExportMaskPlacementMap.keySet().contains(Initiator.normalizePort(initiator.getInitiatorPort()))) {
                    // Can we find an existing intiatorToExportMaskURIMap entry that contains the same compute resource?
                    for (String port : initiatorToExportMaskPlacementMap.keySet()) {
                        // Verify it's the same compute resource
                        Initiator existingInitiator = ExportUtils.getInitiator(Initiator.toPortNetworkId(port), _dbClient);
                        if (existingInitiator != null && ((exportGroup.forCluster() && existingInitiator.getClusterName().equals(initiator.getClusterName())) || (exportGroup.forHost() && existingInitiator.getHostName().equals(initiator.getHostName())))) {
                            // Go through the masks, verify they are all multi-host already
                            for (URI maskId : initiatorToExportMaskPlacementMap.get(port)) {
                                ExportMask mask = _dbClient.queryObject(ExportMask.class, maskId);
                                if (exportGroup.forHost() || maskAppliesToMultipleHosts(mask)) {
                                    // Create a new map entry for this initiator.
                                    exportMasksToAdd.add(mask.getId());
                                }
                            }
                        } else {
                            _log.info("Initiator {} does not have any masks that match its compute resource", initiator.getInitiatorPort());
                        }
                    }
                }
                if (!exportMasksToAdd.isEmpty()) {
                    _log.info("Initiator {} - to be added to export masks: {}", initiator.getInitiatorPort(), exportMasksToAdd);
                    initiatorToExportMaskPlacementMap.put(Initiator.normalizePort(initiator.getInitiatorPort()), exportMasksToAdd);
                }
            }
        }
    }
}
Also used : Set(java.util.Set) HashSet(java.util.HashSet) StringSet(com.emc.storageos.db.client.model.StringSet) Initiator(com.emc.storageos.db.client.model.Initiator) ExportMask(com.emc.storageos.db.client.model.ExportMask) List(java.util.List) Lists.newArrayList(com.google.common.collect.Lists.newArrayList) ArrayList(java.util.ArrayList) URIQueryResultList(com.emc.storageos.db.client.constraint.URIQueryResultList) Map(java.util.Map) HashMap(java.util.HashMap) StringMap(com.emc.storageos.db.client.model.StringMap) URI(java.net.URI) HashSet(java.util.HashSet)

Example 50 with ExportMask

use of com.emc.storageos.db.client.model.ExportMask in project coprhd-controller by CoprHD.

the class VmaxMaskingOrchestrator method partialMasksContainSameSG.

/**
 * Determines if the mask has the same SG as the other masks that are partial masks.
 *
 * @param partialMasks list of export masks that are partial masks
 * @param masks
 * @param mask export mask
 * @return true if all masks in partialMasks have the same SG
 */
private boolean partialMasksContainSameSG(Set<URI> partialMasks, Map<ExportMask, ExportMaskPolicy> masks, ExportMask mask) {
    String sgName = null;
    // Find the mask in the mask mapping, grab the SG name
    for (Map.Entry<ExportMask, ExportMaskPolicy> entry : masks.entrySet()) {
        ExportMaskPolicy policy = entry.getValue();
        sgName = policy.sgName;
    }
    for (URI partialMaskURI : partialMasks) {
        // Find the mask in the mask mapping
        for (Map.Entry<ExportMask, ExportMaskPolicy> entry : masks.entrySet()) {
            ExportMask myMask = entry.getKey();
            if (myMask.getId().equals(partialMaskURI)) {
                ExportMaskPolicy policy = entry.getValue();
                if (sgName == null || !sgName.equalsIgnoreCase(policy.sgName)) {
                    return false;
                }
            }
        }
    }
    return true;
}
Also used : ExportMask(com.emc.storageos.db.client.model.ExportMask) Map(java.util.Map) HashMap(java.util.HashMap) StringMap(com.emc.storageos.db.client.model.StringMap) URI(java.net.URI)

Aggregations

ExportMask (com.emc.storageos.db.client.model.ExportMask)368 URI (java.net.URI)274 ArrayList (java.util.ArrayList)224 Initiator (com.emc.storageos.db.client.model.Initiator)155 DeviceControllerException (com.emc.storageos.exceptions.DeviceControllerException)140 ExportGroup (com.emc.storageos.db.client.model.ExportGroup)134 HashMap (java.util.HashMap)128 HashSet (java.util.HashSet)121 ServiceError (com.emc.storageos.svcs.errorhandling.model.ServiceError)107 StorageSystem (com.emc.storageos.db.client.model.StorageSystem)102 List (java.util.List)79 StringSet (com.emc.storageos.db.client.model.StringSet)68 URIQueryResultList (com.emc.storageos.db.client.constraint.URIQueryResultList)65 Map (java.util.Map)65 StringMap (com.emc.storageos.db.client.model.StringMap)60 BlockObject (com.emc.storageos.db.client.model.BlockObject)56 NamedURI (com.emc.storageos.db.client.model.NamedURI)56 Workflow (com.emc.storageos.workflow.Workflow)54 Set (java.util.Set)51 Volume (com.emc.storageos.db.client.model.Volume)44