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