Search in sources :

Example 16 with ExportGroup

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

the class UcsComputeDevice method getHBAToStoragePorts.

private Map<String, Map<String, Integer>> getHBAToStoragePorts(URI volumeId, URI hostId) {
    Host host = _dbClient.queryObject(Host.class, hostId);
    Map<String, String> initiatorToHBAMapping = getInitiatorToHBAMapping(host.getComputeElement());
    Volume volume = _dbClient.queryObject(Volume.class, volumeId);
    List<Initiator> initiators = CustomQueryUtility.queryActiveResourcesByRelation(_dbClient, hostId, Initiator.class, "host");
    Map<ExportMask, ExportGroup> exportMasks = ExportUtils.getExportMasks(volume, _dbClient);
    Map<String, Map<String, Integer>> hbaToStoragePortMapForBoot = new HashMap<String, Map<String, Integer>>();
    for (Initiator initiator : initiators) {
        for (ExportMask exportMask : exportMasks.keySet()) {
            List<URI> storagePorts = ExportUtils.getInitiatorPortsInMask(exportMask, initiator, _dbClient);
            if (storagePorts != null && !storagePorts.isEmpty()) {
                Integer volumeHLU = Integer.valueOf(exportMask.getVolumes().get(volumeId.toString()));
                for (URI storagePortUri : storagePorts) {
                    StoragePort port = _dbClient.queryObject(StoragePort.class, storagePortUri);
                    String hbaName = initiatorToHBAMapping.get(initiator.getInitiatorPort());
                    if (hbaName != null) {
                        if (hbaToStoragePortMapForBoot.get(hbaName) == null) {
                            hbaToStoragePortMapForBoot.put(hbaName, new HashMap<String, Integer>());
                        }
                        hbaToStoragePortMapForBoot.get(hbaName).put(port.getPortNetworkId(), volumeHLU);
                    }
                }
            }
        }
    }
    return hbaToStoragePortMapForBoot;
}
Also used : HashMap(java.util.HashMap) ExportMask(com.emc.storageos.db.client.model.ExportMask) StoragePort(com.emc.storageos.db.client.model.StoragePort) Host(com.emc.storageos.db.client.model.Host) URI(java.net.URI) ExportGroup(com.emc.storageos.db.client.model.ExportGroup) Volume(com.emc.storageos.db.client.model.Volume) Initiator(com.emc.storageos.db.client.model.Initiator) Map(java.util.Map) HashMap(java.util.HashMap)

Example 17 with ExportGroup

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

the class NetworkDeviceController method addRemoveZones.

/**
 * Add/remove a group of zones as given by their NetworkFabricInfo structures.
 * ALL fabricInfos must be using the same NetworkDevice, and the same fabricId. There is a higher level
 * subroutine to split complex requests into sets of requests with the same NetworkDevice and fabricId.
 *
 * @param networkSystem NetworkDevice
 * @param fabricId String
 * @param exportGroupUri The ExportGroup URI. Used for reference counting.
 * @param fabricInfos - Describe each zone.
 * @param activateZones - activate active zoneset after zones change
 * @param retryAltNetworkDevice - a boolean to indicate if re-try to be done.
 *            This is to stop this function from running again after the alternate
 *            system is retried once.
 * @return BiosCommandResult
 * @throws ControllerException
 */
private BiosCommandResult addRemoveZones(NetworkSystem networkSystem, String fabricId, String fabricWwn, URI exportGroupUri, List<NetworkFCZoneInfo> fabricInfos, boolean doRemove, boolean retryAltNetworkDevice) throws ControllerException {
    BiosCommandResult result = null;
    String taskId = UUID.randomUUID().toString();
    List<Zone> zones = new ArrayList<Zone>();
    // Make the zone operations. Don't make the same zone more than once,
    // as determined by its key. The same zone shows up multiple times because it
    // must be recorded for each volume in the FCZoneReference table.
    HashSet<String> keySet = new HashSet<String>();
    for (NetworkFCZoneInfo fabricInfo : fabricInfos) {
        String key = fabricInfo.makeEndpointsKey();
        if (false == keySet.contains(key)) {
            keySet.add(key);
            // neither create nor delete zones found on the switch
            if (fabricInfo.isExistingZone()) {
                _log.info("Zone {} will not be created or removed on {}, as it is not vipr created. ", fabricInfo.getZoneName(), fabricInfo.toString());
                // neither create nor delete zones found on the switch
                continue;
            }
            // Don't actually remove the zone if it's not the last reference
            if (doRemove && !fabricInfo._isLastReference) {
                _log.info("Zone {} will not be removed on {}, as still the zone is used to expose other volumes in export groups ", fabricInfo.getZoneName(), fabricInfo.toString());
                continue;
            }
            Zone zone = new Zone(fabricInfo.getZoneName());
            for (String address : fabricInfo.getEndPoints()) {
                ZoneMember member = new ZoneMember(address, ConnectivityMemberType.WWPN);
                zone.getMembers().add(member);
            }
            zones.add(zone);
        }
    }
    // Get the network device reference for the type of network device managed
    // by the controller.
    NetworkSystemDevice networkDevice = getDevice(networkSystem.getSystemType());
    if (networkDevice == null) {
        throw NetworkDeviceControllerException.exceptions.addRemoveZonesFailedNull(networkSystem.getSystemType());
    }
    // Lock to prevent concurrent operations on the same VSAN / FABRIC.
    InterProcessLock fabricLock = NetworkFabricLocker.lockFabric(fabricId, _coordinator);
    try {
        if (doRemove) {
            /* Removing zones */
            result = networkDevice.removeZones(networkSystem, zones, fabricId, fabricWwn, true);
            if (result.isCommandSuccess()) {
                for (NetworkFCZoneInfo fabricInfo : fabricInfos) {
                    String refKey = fabricInfo.getZoneName() + " " + fabricInfo.getFcZoneReferenceId().toString();
                    try {
                        FCZoneReference ref = deleteFCZoneReference(fabricInfo);
                        if (ref != null && !zones.isEmpty()) {
                            recordZoneEvent(ref, OperationTypeEnum.REMOVE_SAN_ZONE.name(), OperationTypeEnum.REMOVE_SAN_ZONE.getDescription());
                        }
                    } catch (DatabaseException ex) {
                        _log.error("Could not delete FCZoneReference: " + refKey);
                    }
                }
            }
        } else {
            /* Adding zones */
            _log.debug("Adding zones on network system {} ", networkSystem.getNativeGuid());
            result = networkDevice.addZones(networkSystem, zones, fabricId, fabricWwn, true);
            if (result.isCommandSuccess()) {
                for (NetworkFCZoneInfo fabricInfo : fabricInfos) {
                    String refKey = fabricInfo.getZoneName() + " " + fabricInfo.getVolumeId().toString();
                    try {
                        String[] newOrExisting = new String[1];
                        FCZoneReference ref = addZoneReference(exportGroupUri, fabricInfo, newOrExisting);
                        // this is needed for rollback
                        fabricInfo.setFcZoneReferenceId(ref.getId());
                        _log.info(String.format("%s FCZoneReference key: %s volume %s group %s", newOrExisting[0], ref.getPwwnKey(), ref.getVolumeUri(), exportGroupUri));
                        if (!zones.isEmpty()) {
                            recordZoneEvent(ref, OperationTypeEnum.ADD_SAN_ZONE.name(), OperationTypeEnum.ADD_SAN_ZONE.getDescription());
                        }
                    } catch (DatabaseException ex) {
                        _log.error("Could not persist FCZoneReference: " + refKey);
                    }
                }
            }
        }
        // Update the FCZoneInfo structures if we changed device state for rollback.
        Map<String, String> map = (Map<String, String>) result.getObjectList().get(0);
        for (NetworkFCZoneInfo info : fabricInfos) {
            if (NetworkSystemDevice.SUCCESS.equals(map.get(info.getZoneName()))) {
                info.setCanBeRolledBack(true);
            } else {
                info.setCanBeRolledBack(false);
            }
        }
        if (!result.isCommandSuccess()) {
            ServiceError serviceError = NetworkDeviceControllerException.errors.addRemoveZonesFailed(networkSystem.getSystemType());
            setStatus(ExportGroup.class, exportGroupUri, taskId, false, serviceError);
        } else {
            setStatus(ExportGroup.class, exportGroupUri, taskId, true, null);
        }
        return result;
    } catch (ControllerException ex) {
        String operation = doRemove ? "Remove Zones" : "Add Zones";
        _log.info(String.format("waiting for 2 min before retrying %s with alternate device", operation));
        try {
            Thread.sleep(1000 * 120);
        } catch (InterruptedException e) {
            _log.warn("Thread sleep interrupted.  Allowing to continue without sleep");
        }
        NetworkFCZoneInfo fabricInfo = fabricInfos.get(0);
        URI primaryUri = fabricInfo.getNetworkDeviceId();
        URI altUri = fabricInfo.getAltNetworkDeviceId();
        // If we took an error, attempt a retry with an alternate device if possible.
        if (altUri != null && retryAltNetworkDevice) {
            NetworkFabricLocker.unlockFabric(fabricId, fabricLock);
            fabricLock = null;
            _log.error("Zone operation failed using device: " + primaryUri + " retrying with alternate device: " + altUri);
            fabricInfo.setNetworkDeviceId(altUri);
            networkSystem = getNetworkSystemObject(altUri);
            return addRemoveZones(networkSystem, fabricId, fabricWwn, exportGroupUri, fabricInfos, doRemove, false);
        } else {
            if (result != null) {
                if (!result.isCommandSuccess()) {
                    ServiceError serviceError = NetworkDeviceControllerException.errors.addRemoveZonesFailed(networkSystem.getSystemType());
                    setStatus(ExportGroup.class, exportGroupUri, taskId, false, serviceError);
                } else {
                    setStatus(ExportGroup.class, exportGroupUri, taskId, true, null);
                }
            }
            throw ex;
        }
    } finally {
        NetworkFabricLocker.unlockFabric(fabricId, fabricLock);
    }
}
Also used : ServiceError(com.emc.storageos.svcs.errorhandling.model.ServiceError) DeviceControllerException(com.emc.storageos.exceptions.DeviceControllerException) ControllerException(com.emc.storageos.volumecontroller.ControllerException) NetworkDeviceControllerException(com.emc.storageos.networkcontroller.exceptions.NetworkDeviceControllerException) Zone(com.emc.storageos.networkcontroller.impl.mds.Zone) ArrayList(java.util.ArrayList) URI(java.net.URI) FCZoneReference(com.emc.storageos.db.client.model.FCZoneReference) ExportGroup(com.emc.storageos.db.client.model.ExportGroup) NetworkFCZoneInfo(com.emc.storageos.networkcontroller.NetworkFCZoneInfo) BiosCommandResult(com.emc.storageos.volumecontroller.impl.BiosCommandResult) ZoneMember(com.emc.storageos.networkcontroller.impl.mds.ZoneMember) InterProcessLock(org.apache.curator.framework.recipes.locks.InterProcessLock) DatabaseException(com.emc.storageos.db.exceptions.DatabaseException) ZoneInfoMap(com.emc.storageos.db.client.model.ZoneInfoMap) Map(java.util.Map) HashMap(java.util.HashMap) StringSetMap(com.emc.storageos.db.client.model.StringSetMap) StringMap(com.emc.storageos.db.client.model.StringMap) HashSet(java.util.HashSet)

Example 18 with ExportGroup

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

the class NetworkDeviceController method updateZoningMap.

/**
 * This method updates zoning map. This will mostly be called when volume(s) is/are removed
 * from the ExportMask which is shared across two/more varrays and varrays do not have same
 * storage ports which results in creating zoning based on the ports in the varray.
 *
 * lastReferenceZoneInfo contains the zones that were removed from the device,
 * according to this if there is initiator in the zoningMap with just one storage port
 * for which zone is removed then that entry is removed from the zoningMap.
 * If initiator has more than one storage port in the zoningMap for the initiator then
 * only storage port for which zone is removed is removed from the zoning map.
 * ExportMasks with ImmutableZoningMap set are skipped.
 *
 * @param lastReferenceZoneInfo list of NetworkFCZoneInfo for the zones that are removed.
 * @param exportGroupURI reference to exportGroup
 * @param exportMaskURIs list of reference to exportMask
 */
private void updateZoningMap(List<NetworkFCZoneInfo> lastReferenceZoneInfo, URI exportGroupURI, List<URI> exportMaskURIs) {
    List<URI> emURIs = new ArrayList<URI>();
    if (exportMaskURIs == null || exportMaskURIs.isEmpty()) {
        ExportGroup exportGroup = _dbClient.queryObject(ExportGroup.class, exportGroupURI);
        List<ExportMask> exportMasks = ExportMaskUtils.getExportMasks(_dbClient, exportGroup);
        if (exportGroup != null && !exportMasks.isEmpty()) {
            for (ExportMask mask : exportMasks) {
                emURIs.add(mask.getId());
            }
        }
    } else {
        emURIs.addAll(exportMaskURIs);
    }
    for (URI emURI : emURIs) {
        ExportMask exportMask = _dbClient.queryObject(ExportMask.class, emURI);
        if (exportMask != null && !exportMask.getInactive() && !exportMask.fetchDeviceDataMapEntry(ExportMask.DeviceDataMapKeys.ImmutableZoningMap.name()).contains(Boolean.TRUE.toString())) {
            for (NetworkFCZoneInfo zoneInfo : lastReferenceZoneInfo) {
                StringSetMap existingZoningMap = exportMask.getZoningMap();
                if (exportMask.getVolumes() == null) {
                    continue;
                }
                Set<String> exportMaskVolumes = exportMask.getVolumes().keySet();
                if (existingZoningMap != null && zoneInfo.getVolumeId() != null && exportMaskVolumes.contains(zoneInfo.getVolumeId().toString()) && zoneInfo.getEndPoints().size() == 2) {
                    Initiator initiator = NetworkUtil.findInitiatorInDB(zoneInfo.getEndPoints().get(0), _dbClient);
                    List<StoragePort> storagePorts = NetworkUtil.findStoragePortsInDB(zoneInfo.getEndPoints().get(1), _dbClient);
                    for (StoragePort storagePort : storagePorts) {
                        if (initiator != null && storagePort != null) {
                            for (String initiatorId : existingZoningMap.keySet()) {
                                if (initiator.getId().toString().equals(initiatorId)) {
                                    StringSet ports = existingZoningMap.get(initiatorId);
                                    if (ports != null) {
                                        if (ports.contains(storagePort.getId().toString())) {
                                            ports.remove(storagePort.getId().toString());
                                            if (ports.isEmpty()) {
                                                exportMask.removeZoningMapEntry(initiatorId);
                                                _log.info("Removing zoning map entry for initiator {}, in exportmask {}", initiatorId, emURI);
                                            } else {
                                                exportMask.addZoningMapEntry(initiatorId, ports);
                                                _log.info("Removing storagePort " + storagePort.getId() + " from zoning map for initiator " + initiatorId + " in export mask " + emURI);
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                _dbClient.persistObject(exportMask);
            }
        }
    }
}
Also used : StringSetMap(com.emc.storageos.db.client.model.StringSetMap) ExportMask(com.emc.storageos.db.client.model.ExportMask) ArrayList(java.util.ArrayList) StoragePort(com.emc.storageos.db.client.model.StoragePort) URI(java.net.URI) ExportGroup(com.emc.storageos.db.client.model.ExportGroup) NetworkFCZoneInfo(com.emc.storageos.networkcontroller.NetworkFCZoneInfo) Initiator(com.emc.storageos.db.client.model.Initiator) StringSet(com.emc.storageos.db.client.model.StringSet)

Example 19 with ExportGroup

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

the class NetworkDeviceController method refreshFCZoneReferences.

/**
 * Given the list of zone changes, the list of existing zone references for the initiators and ports,
 * update the FCZoneReference instances in the database. This function ensures that the zone
 * references updated are those of the export mask volumes.
 *
 * @param exportMask the export mask being refreshed
 * @param existingRefs a map of zone-reference-key-to-zone-references for each initiator-port pair
 *            of the mask, including those that were removed. This list may contain zone references for
 *            volumes not in the export mask.
 * @param addedZoneInfos the ZoneInfo instances of zones that were added in this refresh operation
 * @param updatedZoneInfos the ZoneInfo instances of zones that were updated in this refresh operation
 * @param removedZonesKeys the keys of the zones that were removed.
 * @param userRemovedInitiators optional field can be null. List of user removed initiators for this refresh operation
 */
private void refreshFCZoneReferences(ExportMask exportMask, Map<String, List<FCZoneReference>> existingRefs, List<ZoneInfo> addedZoneInfos, List<ZoneInfo> updatedZoneInfos, List<String> removedZonesKeys, List<String> userRemovedInitiators) {
    // get the export mask volumes and export groups because FCZoneReference are kept for each
    Map<URI, Integer> exportMaskVolumes = StringMapUtil.stringMapToVolumeMap(exportMask.getVolumes());
    List<ExportGroup> exportGroups = ExportUtils.getExportGroupsForMask(exportMask.getId(), _dbClient);
    // start with removing references
    List<FCZoneReference> temp = null;
    List<FCZoneReference> refs = new ArrayList<FCZoneReference>();
    for (String refKey : removedZonesKeys) {
        temp = existingRefs.get(refKey);
        if (temp == null) {
            continue;
        }
        for (FCZoneReference ref : temp) {
            for (ExportGroup exportGroup : exportGroups) {
                if (exportGroup.getId().equals(ref.getGroupUri()) && exportGroup.hasBlockObject(ref.getVolumeUri()) && exportMaskVolumes.containsKey(ref.getVolumeUri())) /*
                                                                               * &&
                                                                               * ref.getExistingZone()
                                                                               */
                {
                    if (isPartOfUserRemovedInitiator(ref, userRemovedInitiators)) {
                        _log.info("FCZoneReference {} for volume {} and exportGroup {} with userRemovedInitiators {} will not be deleted", new Object[] { ref.getPwwnKey(), ref.getVolumeUri(), ref.getGroupUri(), userRemovedInitiators });
                    } else {
                        _log.info("FCZoneReference {} for volume {} and exportGroup {} with userRemovedInitiators {} will be deleted", new Object[] { ref.getPwwnKey(), ref.getVolumeUri(), ref.getGroupUri(), userRemovedInitiators });
                        refs.add(ref);
                    }
                }
            }
        }
    }
    _dbClient.markForDeletion(refs);
    refs.clear();
    // update zone references with new zone info in case the zone was renamed
    for (ZoneInfo zoneInfo : updatedZoneInfos) {
        String refKey = zoneInfo.getZoneReferenceKey();
        temp = existingRefs.get(refKey);
        if (temp == null) {
            continue;
        }
        for (FCZoneReference ref : temp) {
            for (ExportGroup exportGroup : exportGroups) {
                if (exportGroup.getId().equals(ref.getGroupUri()) && exportGroup.hasBlockObject(ref.getVolumeUri()) && exportMaskVolumes.containsKey(ref.getVolumeUri())) {
                    // only update when there are changes to avoid unnecessary create/delete of indexes
                    if (zoneInfo.getZoneName() != null && !zoneInfo.getZoneName().equals(ref.getZoneName())) {
                        ref.setZoneName(zoneInfo.getZoneName());
                        ref.setExistingZone(true);
                    }
                    if (zoneInfo.getNetworkSystemId() != null && (ref.getNetworkSystemUri() == null || !zoneInfo.getNetworkSystemId().equals(ref.getNetworkSystemUri().toString()))) {
                        ref.setNetworkSystemUri(URI.create(zoneInfo.getNetworkSystemId()));
                    }
                    if (zoneInfo.getFabricId() != null && !zoneInfo.getFabricId().equals(ref.getFabricId())) {
                        ref.setFabricId(zoneInfo.getFabricId());
                    }
                    refs.add(ref);
                }
            }
        }
    }
    _dbClient.updateAndReindexObject(refs);
    refs.clear();
    // Create zone references as needed, one per volume and export group
    for (ZoneInfo zoneInfo : addedZoneInfos) {
        for (URI volUri : exportMaskVolumes.keySet()) {
            for (ExportGroup exportGroup : exportGroups) {
                if (exportGroup.hasBlockObject(volUri)) {
                    // do I need to check duplicates?
                    refs.add(createFCZoneReference(zoneInfo, volUri, exportGroup));
                    _log.info("FCZoneReference {} for volume {} and exportGroup {} will be added", new Object[] { zoneInfo.getZoneReferenceKey(), volUri, exportGroup.getId() });
                }
            }
        }
    }
    _dbClient.createObject(refs);
}
Also used : ExportGroup(com.emc.storageos.db.client.model.ExportGroup) ArrayList(java.util.ArrayList) URI(java.net.URI) NetworkFCZoneInfo(com.emc.storageos.networkcontroller.NetworkFCZoneInfo) ZoneInfo(com.emc.storageos.db.client.model.ZoneInfo) FCZoneReference(com.emc.storageos.db.client.model.FCZoneReference)

Example 20 with ExportGroup

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

the class NetworkZoningParam method convertExportMaskInitiatorMapsToNetworkZoningParam.

/**
 * Generates a list of NetworkZoningParam objects from a map of export mask URI to a list of initiator URIs.
 * Only the initiators in the exportMaskToInitiators map are retained from the ExportMask initiators.
 * @param exportGroupURI
 * @param exportMaskToInitiators
 * @param dbClient
 * @return
 */
public static List<NetworkZoningParam> convertExportMaskInitiatorMapsToNetworkZoningParam(URI exportGroupURI, Map<URI, List<URI>> exportMaskToInitiators, DbClient dbClient) {
    ExportGroup exportGroup = dbClient.queryObject(ExportGroup.class, exportGroupURI);
    List<NetworkZoningParam> zoningParams = new ArrayList<NetworkZoningParam>();
    for (Map.Entry<URI, List<URI>> entry : exportMaskToInitiators.entrySet()) {
        ExportMask exportMask = dbClient.queryObject(ExportMask.class, entry.getKey());
        if (exportMask == null || exportMask.getInactive()) {
            throw WorkflowException.exceptions.workflowConstructionError("ExportMask is null: " + entry.getKey().toString());
        }
        NetworkZoningParam zoningParam = new NetworkZoningParam(exportGroup, exportMask, dbClient);
        // Filter out entries in the zoning map not in the initiator list.
        // This is done by retaining all the initiators in the exportMaskToInitiators value.
        Set<String> retainedInitiators = StringSetUtil.uriListToSet(entry.getValue());
        zoningParam.getZoningMap().keySet().retainAll(retainedInitiators);
        // Add zoningParam to result
        zoningParams.add(zoningParam);
    }
    return zoningParams;
}
Also used : ExportGroup(com.emc.storageos.db.client.model.ExportGroup) ExportMask(com.emc.storageos.db.client.model.ExportMask) ArrayList(java.util.ArrayList) ArrayList(java.util.ArrayList) List(java.util.List) HashMap(java.util.HashMap) StringSetMap(com.emc.storageos.db.client.model.StringSetMap) Map(java.util.Map) URI(java.net.URI)

Aggregations

ExportGroup (com.emc.storageos.db.client.model.ExportGroup)278 URI (java.net.URI)206 ArrayList (java.util.ArrayList)139 ExportMask (com.emc.storageos.db.client.model.ExportMask)138 DeviceControllerException (com.emc.storageos.exceptions.DeviceControllerException)111 HashMap (java.util.HashMap)94 Initiator (com.emc.storageos.db.client.model.Initiator)86 StorageSystem (com.emc.storageos.db.client.model.StorageSystem)84 NamedURI (com.emc.storageos.db.client.model.NamedURI)80 HashSet (java.util.HashSet)70 ServiceError (com.emc.storageos.svcs.errorhandling.model.ServiceError)63 Workflow (com.emc.storageos.workflow.Workflow)61 List (java.util.List)59 URIQueryResultList (com.emc.storageos.db.client.constraint.URIQueryResultList)55 BlockObject (com.emc.storageos.db.client.model.BlockObject)49 Map (java.util.Map)47 ExportOrchestrationTask (com.emc.storageos.volumecontroller.impl.block.taskcompleter.ExportOrchestrationTask)44 ControllerException (com.emc.storageos.volumecontroller.ControllerException)41 StringSet (com.emc.storageos.db.client.model.StringSet)38 StringMap (com.emc.storageos.db.client.model.StringMap)33