use of com.emc.storageos.volumecontroller.placement.StoragePortsAllocator.PortAllocationContext in project coprhd-controller by CoprHD.
the class StoragePortsAssignerTest method createVNXNet4.
protected static PortAllocationContext createVNXNet4() {
NetworkLite tz = new NetworkLite(URI.create("net2"), "net2");
PortAllocationContext context = new PortAllocationContext(tz, "test");
StoragePort port;
port = createFCPort("SP_A:4", "50:00:00:00:00:00:00:04");
addPort(context, port, "mds-a");
port = createFCPort("SP_B:4", "50:00:00:00:00:00:01:04");
addPort(context, port, "mds-a");
return context;
}
use of com.emc.storageos.volumecontroller.placement.StoragePortsAllocator.PortAllocationContext in project coprhd-controller by CoprHD.
the class VPlexVmaxMaskingOrchestrator method getPortGroups.
@Override
public Set<Map<URI, List<List<StoragePort>>>> getPortGroups(Map<URI, List<StoragePort>> allocatablePorts, Map<URI, NetworkLite> networkMap, URI varrayURI, int nInitiatorGroups, Map<URI, Map<String, Integer>> switchToPortNumber, Map<URI, PortAllocationContext> contextMap, StringBuilder errorMessages) {
Set<Map<URI, List<List<StoragePort>>>> portGroups = new HashSet<Map<URI, List<List<StoragePort>>>>();
StringSet netNames = new StringSet();
// Order the networks from those with fewest ports to those with the most ports.
List<URI> orderedNetworks = orderNetworksByNumberOfPorts(allocatablePorts);
for (URI networkURI : orderedNetworks) {
netNames.add(networkMap.get(networkURI).getLabel());
}
_log.info("Calculating PortGroups for Networks: " + netNames.toString());
Set<String> cpusUsed = new HashSet<String>();
Map<URI, List<StoragePort>> useablePorts = new HashMap<URI, List<StoragePort>>();
Set<String> eliminatedPorts = new HashSet<String>();
Set<String> usedPorts = new HashSet<String>();
// Eliminate ports from the same cpus, which are in the same portGroup.
// This is to avoid the 4096 LUN limit per cpu.
// Cycle through the networks, picking ports that can be used while considering cpus.
// Pick one port from each network, then cycle through them again.
boolean portWasPicked;
do {
portWasPicked = false;
for (URI networkURI : orderedNetworks) {
if (!useablePorts.containsKey(networkURI)) {
useablePorts.put(networkURI, new ArrayList<StoragePort>());
}
// Pick a port if possible
for (StoragePort port : allocatablePorts.get(networkURI)) {
// Do not choose a port that has already been chosen
if (usedPorts.contains(port.getPortName())) {
continue;
}
if (!cpusUsed.contains(port.getPortGroup())) {
// Choose this port, it has a new cpu.
cpusUsed.add(port.getPortGroup());
usedPorts.add(port.getPortName());
useablePorts.get(networkURI).add(port);
portWasPicked = true;
break;
} else {
// This port shares a cpu, don't choose it.
eliminatedPorts.add(port.getPortName());
}
}
}
} while (portWasPicked);
// If all networks have some ports remaining, use the filtered ports.
// If not, emit a warning and do not use the filtered port configuration.
boolean useFilteredPorts = true;
for (URI networkURI : orderedNetworks) {
if (useablePorts.get(networkURI).isEmpty()) {
useFilteredPorts = false;
break;
}
}
if (useFilteredPorts) {
String message = String.format("Ports successfully selected are %s. Ports eliminated because of sharing a cpu with an already-selected port are %s.", usedPorts.toString(), eliminatedPorts.toString());
_log.info(message);
if (errorMessages != null) {
errorMessages.append(message);
}
allocatablePorts = useablePorts;
} else {
_log.info("Some networks have zero remaining ports after cpu filtering, will use duplicate ports on some cpus. " + "This is not a recommended configuration.");
}
// Determine the network with the lowest number of allocatable ports.
int minPorts = Integer.MAX_VALUE;
for (URI networkURI : allocatablePorts.keySet()) {
int numPorts = allocatablePorts.get(networkURI).size();
if (numPorts > MAX_PORTS_PER_NETWORK) {
numPorts = MAX_PORTS_PER_NETWORK;
}
if (numPorts < minPorts) {
minPorts = numPorts;
}
}
// Figure out the number of ports in each network per port group (PG).
// Then figure out the number of port groups to be generated.
// HEURISTIC:
// If the smallest network has 1 port, then allow 1 port per Network unless there's only 1 Network.
// If there is only one network, require two ports per network in the Port Group.
// If it has 2 or more ports per network, use 2 ports per network per MV.
// If there are one or two networks, if it has 9 or more ports, use 3 ports per network per MV.
// If there are one or two networks, if it has 16 or more ports, use 4 ports per network per MV.
// oneNetwork indicates if there is only one Network available.
// portsPerPG is the number of ports to be allocated per PortGroup from the
// network with the fewest ports.
// numPG is the number of Port Groups that will be configured.
boolean oneNetwork = allocatablePorts.keySet().size() == 1;
boolean moreThanTwoNetworks = allocatablePorts.keySet().size() > 2;
int portsPerNetPerPG = oneNetwork ? 2 : 1;
// But if "morePortGroups" is set, will make additional portGroups if there are fewer ports.
if (morePortGroups) {
// This can be set true for testing environments
if (minPorts >= 4) {
// Makes at least two Port Groups if there are two ports
portsPerNetPerPG = 2;
}
} else {
if (minPorts >= 2) {
// Default is to require at least two ports per Port Group
portsPerNetPerPG = 2;
}
}
if (!moreThanTwoNetworks) {
if (minPorts >= 9) {
portsPerNetPerPG = 3;
}
if (minPorts >= 16) {
portsPerNetPerPG = 4;
}
}
int numPG = minPorts / portsPerNetPerPG;
String message = String.format("Min Ports: %d. Number Port Groups: %d. Ports Per Network Per Port Group: %d.", minPorts, numPG, portsPerNetPerPG);
_log.info(message);
if (errorMessages != null) {
errorMessages.append(message);
}
if (numPG == 0) {
return portGroups;
}
// Make a map per Network of number of ports to allocate.
Map<URI, Integer> portsAllocatedPerNetwork = new HashMap<URI, Integer>();
for (URI netURI : allocatablePorts.keySet()) {
Integer nports = allocatablePorts.get(netURI).size() / numPG;
// ports from the network with the fewest ports, i.e. do not exceed 2x portsPerPG.
if (nports > (2 * portsPerNetPerPG)) {
nports = 2 * portsPerNetPerPG;
}
portsAllocatedPerNetwork.put(netURI, nports);
}
// Now call the StoragePortsAllocator for each Network, assigning required number of ports.
StoragePortsAllocator allocator = new StoragePortsAllocator();
for (int i = 0; i < numPG; i++) {
Map<URI, List<List<StoragePort>>> portGroup = new HashMap<URI, List<List<StoragePort>>>();
StringSet portNames = new StringSet();
for (URI netURI : allocatablePorts.keySet()) {
NetworkLite net = networkMap.get(netURI);
Map<String, Integer> switchCountMap = null;
if (switchToPortNumber != null) {
switchCountMap = switchToPortNumber.get(netURI);
}
PortAllocationContext context = null;
if (contextMap != null) {
context = contextMap.get(netURI);
}
List<StoragePort> allocatedPorts = allocatePorts(allocator, allocatablePorts.get(netURI), portsAllocatedPerNetwork.get(netURI), net, varrayURI, switchCountMap, context);
if (portGroup.get(netURI) == null) {
portGroup.put(netURI, new ArrayList<List<StoragePort>>());
}
portGroup.get(netURI).add(allocatedPorts);
allocatablePorts.get(netURI).removeAll(allocatedPorts);
for (StoragePort port : allocatedPorts) {
portNames.add(port.getPortName());
}
}
portGroups.add(portGroup);
_log.info(String.format("Port Group %d: %s", i, portNames.toString()));
// Reinitialize the context in the allocator; we want redundancy within PG
if (allocator.getContext() != null) {
allocator.getContext().reinitialize();
}
}
return portGroups;
}
use of com.emc.storageos.volumecontroller.placement.StoragePortsAllocator.PortAllocationContext in project coprhd-controller by CoprHD.
the class VPlexXIVMaskingOrchestrator method getPortGroups.
/*
* (non-Javadoc)
*
* @see com.emc.storageos.volumecontroller.impl.block.
* VplexBackEndMaskingOrchestrator#getPortGroups(java.util.Map, java.util.Map, java.net.URI, int)
*/
@Override
public Set<Map<URI, List<List<StoragePort>>>> getPortGroups(Map<URI, List<StoragePort>> allocatablePorts, Map<URI, NetworkLite> networkMap, URI varrayURI, int nInitiatorGroups, Map<URI, Map<String, Integer>> switchToPortNumber, Map<URI, PortAllocationContext> contextMap, StringBuilder errorMessages) {
_log.debug("START - getPortGroups");
Set<Map<URI, List<List<StoragePort>>>> portGroups = new HashSet<Map<URI, List<List<StoragePort>>>>();
Map<URI, Integer> portsAllocatedPerNetwork = new HashMap<URI, Integer>();
// Port Group is always 1 for XIV as of now.
for (URI netURI : allocatablePorts.keySet()) {
Integer nports = allocatablePorts.get(netURI).size() / XIV_NUM_PORT_GROUP;
portsAllocatedPerNetwork.put(netURI, nports);
}
StoragePortsAllocator allocator = new StoragePortsAllocator();
for (int i = 0; i < XIV_NUM_PORT_GROUP; i++) {
Map<URI, List<List<StoragePort>>> portGroup = new HashMap<URI, List<List<StoragePort>>>();
StringSet portNames = new StringSet();
for (URI netURI : allocatablePorts.keySet()) {
NetworkLite net = networkMap.get(netURI);
Map<String, Integer> switchCountMap = null;
if (switchToPortNumber != null) {
switchCountMap = switchToPortNumber.get(netURI);
}
PortAllocationContext context = null;
if (contextMap != null) {
context = contextMap.get(netURI);
}
List<StoragePort> allocatedPorts = allocatePorts(allocator, allocatablePorts.get(netURI), portsAllocatedPerNetwork.get(netURI), net, varrayURI, switchCountMap, context);
if (portGroup.get(netURI) == null) {
portGroup.put(netURI, new ArrayList<List<StoragePort>>());
}
portGroup.get(netURI).add(allocatedPorts);
allocatablePorts.get(netURI).removeAll(allocatedPorts);
for (StoragePort port : allocatedPorts) {
portNames.add(port.getPortName());
}
}
portGroups.add(portGroup);
_log.info(String.format("Port Group %d: port names in the port group {%s}", i, portNames.toString()));
}
_log.debug("END - getPortGroups");
return portGroups;
}
use of com.emc.storageos.volumecontroller.placement.StoragePortsAllocator.PortAllocationContext in project coprhd-controller by CoprHD.
the class VplexUnityMaskingOrchestrator method getPortGroups.
@Override
public Set<Map<URI, List<List<StoragePort>>>> getPortGroups(Map<URI, List<StoragePort>> allocatablePorts, Map<URI, NetworkLite> networkMap, URI varrayURI, int nInitiatorGroups, Map<URI, Map<String, Integer>> switchToPortNumber, Map<URI, PortAllocationContext> contextMap, StringBuilder errorMessages) {
log.info("START - getPortGroups");
Set<Map<URI, List<List<StoragePort>>>> portGroups = new HashSet<Map<URI, List<List<StoragePort>>>>();
Map<URI, Integer> portsAllocatedPerNetwork = new HashMap<URI, Integer>();
// Port Group is always 1.
for (URI netURI : allocatablePorts.keySet()) {
Integer nports = allocatablePorts.get(netURI).size();
portsAllocatedPerNetwork.put(netURI, nports);
}
StoragePortsAllocator allocator = new StoragePortsAllocator();
Map<URI, List<List<StoragePort>>> portGroup = new HashMap<URI, List<List<StoragePort>>>();
StringSet portNames = new StringSet();
for (URI netURI : allocatablePorts.keySet()) {
NetworkLite net = networkMap.get(netURI);
Map<String, Integer> switchCountMap = null;
PortAllocationContext context = null;
if (switchToPortNumber != null) {
switchCountMap = switchToPortNumber.get(netURI);
}
if (contextMap != null) {
context = contextMap.get(netURI);
}
List<StoragePort> allocatedPorts = VPlexBackEndOrchestratorUtil.allocatePorts(allocator, allocatablePorts.get(netURI), portsAllocatedPerNetwork.get(netURI), net, varrayURI, simulation, _blockScheduler, _dbClient, switchCountMap, context);
if (portGroup.get(netURI) == null) {
portGroup.put(netURI, new ArrayList<List<StoragePort>>());
}
portGroup.get(netURI).add(allocatedPorts);
allocatablePorts.get(netURI).removeAll(allocatedPorts);
for (StoragePort port : allocatedPorts) {
portNames.add(port.getPortName());
}
}
portGroups.add(portGroup);
log.info(String.format("Port Group: port names in the port group {%s}", portNames.toString()));
return portGroups;
}
use of com.emc.storageos.volumecontroller.placement.StoragePortsAllocator.PortAllocationContext in project coprhd-controller by CoprHD.
the class VplexXtremIOMaskingOrchestrator method getUsablePortsSet.
/**
* Returns a Set of Storage Ports selected equally across networks. Minimum of 2 and maximum of 4 storage ports.
* It returns null when all storage ports have been processed and the minimum requirement is not met.
*
* @param allocatablePorts
* the allocatable ports
* @param orderedNetworks
* the ordered networks
* @param usedPorts
* the used ports
* @param networkToSelectedXbricks
* @param xBricksToSelectedSCs
* @param networkMap
* @param allocator
* Storage Ports Allocator
* @param sanZoningEnabled
* on vArray
* @return the usable ports set
*/
private Map<URI, List<StoragePort>> getUsablePortsSet(Map<URI, List<StoragePort>> allocatablePorts, List<URI> orderedNetworks, Set<String> usedPorts, Map<String, List<String>> xBricksToSelectedSCs, Map<URI, List<String>> networkToSelectedXbricks, Map<URI, NetworkLite> networkMap, StoragePortsAllocator allocator, boolean sanZoningEnabled, Map<URI, Map<String, Integer>> switchToPortNumber, Map<URI, PortAllocationContext> contextMap) {
Map<URI, List<StoragePort>> useablePorts = new HashMap<URI, List<StoragePort>>();
Set<String> usedPortsSet = new HashSet<String>();
Set<String> portsSelected = new HashSet<String>(usedPorts);
do {
int previousSize = usedPortsSet.size();
Iterator<URI> networkItr = orderedNetworks.iterator();
while (networkItr.hasNext() && usedPortsSet.size() < MAXIMUM_NUMBER_OF_STORAGE_PORTS_PER_SET) {
URI networkURI = networkItr.next();
_log.debug(String.format("network: %s, xBricksToSelectedSCs: %s, networkToSelectedXbricks: %s", networkURI, xBricksToSelectedSCs.entrySet(), networkToSelectedXbricks.get(networkURI)));
NetworkLite net = networkMap.get(networkURI);
// Determine if we should check connectivity from the Network's varray.auto_san_zoning
boolean checkConnectivity = sanZoningEnabled && !StorageProtocol.Transport.IP.name().equals(net.getTransportType());
Map<String, Integer> switchNumberMap = null;
PortAllocationContext context = null;
if (switchToPortNumber != null) {
switchNumberMap = switchToPortNumber.get(networkURI);
}
if (contextMap != null) {
context = contextMap.get(networkURI);
}
StoragePort port = getNetworkPortUniqueXbrick(networkURI, allocatablePorts.get(networkURI), portsSelected, networkToSelectedXbricks, xBricksToSelectedSCs, allocator, checkConnectivity, switchNumberMap, context);
_log.debug("Port selected {} for network {}", port != null ? port.getPortName() : null, networkURI);
if (port != null) {
usedPortsSet.add(port.getPortName());
portsSelected.add(port.getPortName());
if (!useablePorts.containsKey(networkURI)) {
useablePorts.put(networkURI, new ArrayList<StoragePort>());
}
useablePorts.get(networkURI).add(port);
}
}
// If No ports have been selected in this round, then clear the X-bricks map
if (previousSize == usedPortsSet.size()) {
xBricksToSelectedSCs.clear();
networkToSelectedXbricks.clear();
}
_log.debug("Ports selected so far : {}", usedPortsSet);
} while (usedPortsSet.size() < MAXIMUM_NUMBER_OF_STORAGE_PORTS_PER_SET && !isAllPortsLooped(orderedNetworks, allocatablePorts, portsSelected));
_log.info("Set Done: Ports selected in this set: {}", usedPortsSet);
if (usedPortsSet.size() < REQUIRED_MINIMUM_NUMBER_OF_STORAGE_PORTS_PER_SET) {
// requirement not met
return null;
}
// if usedPortsSet.size() >= 2, satisfies minimum requirement, min 2 paths
// add to all usedPorts list
usedPorts.addAll(usedPortsSet);
return useablePorts;
}
Aggregations