use of com.emc.storageos.networkcontroller.NetworkFCZoneInfo in project coprhd-controller by CoprHD.
the class NetworkScheduler method getZoningTargetsForPaths.
/**
* This is called when ExportGroupService adds paths.
* Creates list of NetworkFabricInfo structures for zoning each volume
* to the newly added paths
*
* @param exportGroup - The ExportGroup structure.
* @param varrayUri - The URI of the virtual array, this can be the export group's
* virtual array or its alternate virtual array
* @param exportMask - The ExportMask structure.
* @param initiators - Contains the initiators
* @param zonesMap a list of existing zones mapped by the initiator port WWN
* @return List<NetworkFCZoneInfo> indicating zones and zone references to be created.
* @throws IOException
* @throws DeviceControllerException
*/
private List<NetworkFCZoneInfo> getZoningTargetsForPaths(ExportGroup exportGroup, List<URI> volumes, URI varrayUri, Map<URI, List<URI>> paths, Map<String, List<Zone>> zonesMap) throws DeviceControllerException {
List<NetworkFCZoneInfo> fabricInfos = new ArrayList<NetworkFCZoneInfo>();
for (Map.Entry<URI, List<URI>> entry : paths.entrySet()) {
URI initiatorURI = entry.getKey();
List<URI> ports = entry.getValue();
Initiator initiator = _dbClient.queryObject(Initiator.class, initiatorURI);
if (StorageProtocol.block2Transport(initiator.getProtocol()) != Transport.FC) {
continue;
}
for (URI storagePort : ports) {
StoragePort sp = _dbClient.queryObject(StoragePort.class, storagePort);
if (sp == null || sp.getTaggedVirtualArrays() == null || !sp.getTaggedVirtualArrays().contains(varrayUri.toString())) {
_log.warn(String.format("The storage port %s is not in the virtual array %s", sp.getNativeGuid(), varrayUri.toString()));
continue;
}
try {
NetworkFCZoneInfo fabricInfo = placeZones(exportGroup.getId(), varrayUri, initiator.getProtocol(), formatWWN(initiator.getInitiatorPort()), sp, initiator.getHostName(), zonesMap.get(initiator.getInitiatorPort()), true);
if (fabricInfo != null) {
for (URI volId : volumes) {
NetworkFCZoneInfo volFabricInfo = fabricInfo.clone();
volFabricInfo.setVolumeId(volId);
fabricInfos.add(volFabricInfo);
}
}
} catch (DeviceControllerException ex) {
_log.error(String.format("Initiator %s could not be paired with port %s", initiator.getInitiatorPort(), sp.getPortNetworkId()));
}
}
}
return fabricInfos;
}
use of com.emc.storageos.networkcontroller.NetworkFCZoneInfo in project coprhd-controller by CoprHD.
the class NetworkScheduler method unexportVolumes.
/**
* Called from the unexportVolume call. and others. This method builds the NetworkFabricInfo to be passed to the
* NetworkDeviceController for automatic unzoning.
*
* @param volUris Collection of URIs for volumes whose references are to be deleted
* @param exportGroupUris List of URIs of all the export groups being processed that might contain the volumes.
* @param storagePortUri the URI of the StoragePort
* @param initiatorPort String WWPN with colons
* @param hasExistingVolumes If true, will not mark a zone as last reference, keeping them from being deleted
* @return List<NetworkFCZoneInfo> detailing zones to be removed or at least unreferenced
* @throws IOException
*/
public List<NetworkFCZoneInfo> unexportVolumes(URI varrayURI, Collection<URI> volUris, List<URI> exportGroupUris, URI storagePortUri, String initiatorPort, boolean hasExistingVolumes) {
List<NetworkFCZoneInfo> ourReferences = new ArrayList<NetworkFCZoneInfo>();
VirtualArray virtualArray = _dbClient.queryObject(VirtualArray.class, varrayURI);
if (virtualArray != null && virtualArray.getAutoSanZoning() == false) {
_log.info("Automatic SAN zoning is disabled in virtual array: " + virtualArray.getLabel());
return null;
}
initiatorPort = formatWWN(initiatorPort);
// Get the StoragePort
StoragePort port = null;
try {
port = _dbClient.queryObject(StoragePort.class, storagePortUri);
if (port == null) {
return null;
}
} catch (DatabaseException ex) {
return null;
}
// See if we can find our zone references
List<String> endPoints = new ArrayList<String>();
endPoints.add(initiatorPort);
endPoints.add(formatWWN(port.getPortNetworkId()));
// Make the key for our endPoints
String key = null;
{
NetworkFCZoneInfo fabricInfo = new NetworkFCZoneInfo();
fabricInfo.setEndPoints(endPoints);
key = fabricInfo.makeEndpointsKey();
}
// Create a map of the references keyed by volUri concatenated with export group URI.
// This allows for multiple export groups to export the same volume, and the zone will not
// be deleted until the volume's references are removed from all export groups.
// Then we can tell if other volumes are using this.
Map<String, FCZoneReference> volRefMap = makeExportToReferenceMap(key);
// If there were no references at all, we don't do anything.
if (volRefMap.isEmpty()) {
return null;
} else {
// Do this for each of the Export Groups being processed.
for (URI volUri : volUris) {
for (URI exportGroupUri : exportGroupUris) {
FCZoneReference ourReference = volRefMap.get(make2UriKey(volUri, exportGroupUri));
if (ourReference == null) {
continue;
}
// We need a fabricInfo for each,
// so as to remove the FCZoneReference that is keyed on volume/exportGroup.
NetworkFCZoneInfo fabricInfo = createZoneInfoForRef(ourReference, volUri, initiatorPort, port.getPortNetworkId(), null, exportGroupUri);
ourReferences.add(fabricInfo);
volRefMap.remove(make2UriKey(volUri, exportGroupUri));
}
}
// See if all the remaining entries have been marked for deletion.
boolean live = false;
for (FCZoneReference ref : volRefMap.values()) {
if (ref.getInactive() == false) {
// Here is an apparent live reference; look up the volume and make
// sure it's still active too.
BlockObject vol = BlockObject.fetch(_dbClient, ref.getVolumeUri());
ExportGroup group = _dbClient.queryObject(ExportGroup.class, ref.getGroupUri());
if (vol != null && vol.getInactive() == false && group != null && group.getInactive() == false) {
live = true;
} else {
// mark the errant reference inactive
_dbClient.markForDeletion(ref);
}
}
}
// sets existingZone which will prohibit deletion.
for (NetworkFCZoneInfo fabricInfo : ourReferences) {
fabricInfo.setLastReference(!live);
if (hasExistingVolumes) {
fabricInfo.setExistingZone(true);
}
// Pick an alternate device, just in case
NetworkLite portNet = getStoragePortNetwork(port);
NetworkLite iniNet = BlockStorageScheduler.lookupNetworkLite(_dbClient, StorageProtocol.block2Transport("FC"), initiatorPort);
List<NetworkSystem> networkSystems = getZoningNetworkSystems(iniNet, portNet);
for (NetworkSystem ns : networkSystems) {
if (!ns.getId().equals(fabricInfo.getNetworkDeviceId())) {
fabricInfo.setAltNetworkDeviceId(ns.getId());
break;
}
}
}
return ourReferences;
}
}
use of com.emc.storageos.networkcontroller.NetworkFCZoneInfo in project coprhd-controller by CoprHD.
the class NetworkScheduler method createZoneInfoForRef.
/**
* Creates a NetworkFCZoneInfo from a {@link FCZoneReference}
*
* @param ourReference
* @param volUri
* @param initiator
* @param port
* @param network
* @param exportGroup
* @return
*/
private NetworkFCZoneInfo createZoneInfoForRef(FCZoneReference ourReference, URI volUri, String initiator, String port, NetworkLite network, URI exportGroup) {
if (ourReference == null) {
return null;
}
// We need a fabricInfo for each,
// so as to remove the FCZoneReference that is keyed on volume/exportGroup.
NetworkFCZoneInfo fabricInfo = new NetworkFCZoneInfo();
fabricInfo.setEndPoints(Arrays.asList(new String[] { initiator, port }));
fabricInfo.setFcZoneReferenceId(ourReference.getId());
fabricInfo.setNetworkDeviceId(ourReference.getNetworkSystemUri());
fabricInfo.setFabricId(ourReference.getFabricId());
fabricInfo.setZoneName(ourReference.getZoneName());
fabricInfo.setVolumeId(volUri);
fabricInfo.setExportGroup(exportGroup);
fabricInfo.setExistingZone(ourReference.getExistingZone());
if (network != null) {
fabricInfo.setFabricWwn(NetworkUtil.getNetworkWwn(network));
}
return fabricInfo;
}
use of com.emc.storageos.networkcontroller.NetworkFCZoneInfo in project coprhd-controller by CoprHD.
the class NetworkScheduler method getZoningRemoveTargets.
/**
* Generate the NetworkFCZoneInfo structures representing the zone/volume duples
* that are fed to the actual zoning code to remove zones.
* @param zoningParams -- Collection of NetworkZoningParam that contains initiator information
* @param volumeURIs -- Optional Collection of volumes being affected by the zoning operation.
* If null, the zoningParams.getVolumes() is used instead, which comes from the ExportMask volumes keyset.
* @return list of NetworkFCZonInfos representing zones and FCZoneReferences to be removed
*/
public List<NetworkFCZoneInfo> getZoningRemoveTargets(Collection<NetworkZoningParam> zoningParams, Collection<URI> volumeURIs) {
List<NetworkFCZoneInfo> zoningTargets = new ArrayList<NetworkFCZoneInfo>();
// and add them to the zoningTargets result list.
for (NetworkZoningParam zoningParam : zoningParams) {
URI varray = zoningParam.getVirtualArray();
_log.info(String.format("Generating remove zoning targets for ExportMask %s (%s)", zoningParam.getMaskName(), zoningParam.getMaskId()));
// validate the initiators are FC, and calculate the zone information
for (Map.Entry<String, AbstractChangeTrackingSet<String>> entry : zoningParam.getZoningMap().entrySet()) {
String initiatorId = entry.getKey();
Initiator initiator = _dbClient.queryObject(Initiator.class, URI.create(initiatorId));
if (initiator == null || initiator.getInactive()) {
_log.info("Initiator inactive: " + initiatorId);
continue;
}
if (StorageProtocol.block2Transport(initiator.getProtocol()) != Transport.FC) {
_log.info(String.format("Initiator not FC %s %s", initiator.getInitiatorPort(), initiatorId));
continue;
}
Set<String> portSet = entry.getValue();
if (portSet == null || portSet.isEmpty()) {
_log.info(String.format("No ports in zoningMap for initiator %s %s", initiator.getInitiatorPort(), initiatorId));
continue;
}
List<URI> exportGroupURIs = new ArrayList<URI>();
exportGroupURIs.add(zoningParam.getExportGroupId());
if (zoningParam.getAlternateExportGroupIds() != null) {
exportGroupURIs.addAll(zoningParam.getAlternateExportGroupIds());
}
// Calculate the zone information for each initiator/port combination
for (String portId : portSet) {
// Calculate the zone information
List<NetworkFCZoneInfo> zoneInfos = unexportVolumes(varray, (volumeURIs != null ? volumeURIs : zoningParam.getVolumes()), exportGroupURIs, URI.create(portId), formatWWN(initiator.getInitiatorPort()), zoningParam.hasExistingVolumes());
if (zoneInfos != null) {
zoningTargets.addAll(zoneInfos);
}
}
}
}
return zoningTargets;
}
use of com.emc.storageos.networkcontroller.NetworkFCZoneInfo in project coprhd-controller by CoprHD.
the class NetworkScheduler method determineIfLastZoneReferences.
/**
* For a given set of NetworkFCZoneInfo records, determine if they represent all the FCZoneReferences
* for each particular zone. If so, that zone can be marked as lastRef = true, meaning it will be deleted.
* Note that we are processing multiple zone infos representing multiple zones here.
* This code is used in the rollback path to determine which zones are safe to delete.
* Upon returning the zoneInfos are appropriately updated with lastRef set true if all the zone references
* for the zone were accounted for by a zone info.
* @param infos -- List of NetworkFCZoneInfo that will be updated
*/
public void determineIfLastZoneReferences(List<NetworkFCZoneInfo> infos) {
// First make a map of zoneName to all last references.
Map<String, Set<URI>> zoneNameToZoneReferencesSet = new HashMap<String, Set<URI>>();
for (NetworkFCZoneInfo info : infos) {
String zoneName = info.getZoneName();
if (zoneNameToZoneReferencesSet.containsKey(zoneName)) {
// already looked up zone references for this zone
continue;
}
String key = FCZoneReference.makeEndpointsKey(info.getEndPoints());
URIQueryResultList result = new URIQueryResultList();
_dbClient.queryByConstraint(AlternateIdConstraint.Factory.getFCZoneReferenceKeyConstraint(key), result);
Iterator<URI> iter = result.iterator();
Set<URI> referenceSet = new HashSet<URI>();
while (iter.hasNext()) {
referenceSet.add(iter.next());
}
zoneNameToZoneReferencesSet.put(zoneName, referenceSet);
}
_log.info(String.format("Checking if last references for zones: %s", zoneNameToZoneReferencesSet.keySet().toString()));
// Now loop through all zone infos, removing the FCZoneReferences that are known
for (NetworkFCZoneInfo info : infos) {
zoneNameToZoneReferencesSet.get(info.getZoneName()).remove(info.getFcZoneReferenceId());
}
// has an empty list (no more zone references), can be marked lastRef = true so the zone will be deleted.
for (NetworkFCZoneInfo info : infos) {
Boolean noReferences = zoneNameToZoneReferencesSet.get(info.getZoneName()).isEmpty();
info.setLastReference(noReferences);
Log.info(String.format("Zone %s lastRef %s", info.getZoneName(), noReferences.toString()));
}
}
Aggregations