Search in sources :

Example 41 with PortAllocationContext

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;
}
Also used : NetworkLite(com.emc.storageos.util.NetworkLite) StoragePort(com.emc.storageos.db.client.model.StoragePort) PortAllocationContext(com.emc.storageos.volumecontroller.placement.StoragePortsAllocator.PortAllocationContext)

Example 42 with PortAllocationContext

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;
}
Also used : HashMap(java.util.HashMap) NetworkLite(com.emc.storageos.util.NetworkLite) StoragePort(com.emc.storageos.db.client.model.StoragePort) URI(java.net.URI) StoragePortsAllocator(com.emc.storageos.volumecontroller.placement.StoragePortsAllocator) StringSet(com.emc.storageos.db.client.model.StringSet) ArrayList(java.util.ArrayList) List(java.util.List) HashMap(java.util.HashMap) Map(java.util.Map) StringSetMap(com.emc.storageos.db.client.model.StringSetMap) StringMap(com.emc.storageos.db.client.model.StringMap) HashSet(java.util.HashSet) PortAllocationContext(com.emc.storageos.volumecontroller.placement.StoragePortsAllocator.PortAllocationContext)

Example 43 with PortAllocationContext

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;
}
Also used : HashMap(java.util.HashMap) NetworkLite(com.emc.storageos.util.NetworkLite) StoragePort(com.emc.storageos.db.client.model.StoragePort) URI(java.net.URI) StoragePortsAllocator(com.emc.storageos.volumecontroller.placement.StoragePortsAllocator) StringSet(com.emc.storageos.db.client.model.StringSet) ArrayList(java.util.ArrayList) List(java.util.List) HashMap(java.util.HashMap) Map(java.util.Map) StringSetMap(com.emc.storageos.db.client.model.StringSetMap) StringMap(com.emc.storageos.db.client.model.StringMap) HashSet(java.util.HashSet) PortAllocationContext(com.emc.storageos.volumecontroller.placement.StoragePortsAllocator.PortAllocationContext)

Example 44 with PortAllocationContext

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;
}
Also used : HashMap(java.util.HashMap) NetworkLite(com.emc.storageos.util.NetworkLite) StoragePort(com.emc.storageos.db.client.model.StoragePort) URI(java.net.URI) StoragePortsAllocator(com.emc.storageos.volumecontroller.placement.StoragePortsAllocator) StringSet(com.emc.storageos.db.client.model.StringSet) ArrayList(java.util.ArrayList) List(java.util.List) HashMap(java.util.HashMap) Map(java.util.Map) StringSetMap(com.emc.storageos.db.client.model.StringSetMap) StringMap(com.emc.storageos.db.client.model.StringMap) HashSet(java.util.HashSet) PortAllocationContext(com.emc.storageos.volumecontroller.placement.StoragePortsAllocator.PortAllocationContext)

Example 45 with PortAllocationContext

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;
}
Also used : HashMap(java.util.HashMap) NetworkLite(com.emc.storageos.util.NetworkLite) StoragePort(com.emc.storageos.db.client.model.StoragePort) URI(java.net.URI) ArrayList(java.util.ArrayList) List(java.util.List) HashSet(java.util.HashSet) PortAllocationContext(com.emc.storageos.volumecontroller.placement.StoragePortsAllocator.PortAllocationContext)

Aggregations

PortAllocationContext (com.emc.storageos.volumecontroller.placement.StoragePortsAllocator.PortAllocationContext)95 StoragePort (com.emc.storageos.db.client.model.StoragePort)84 NetworkLite (com.emc.storageos.util.NetworkLite)82 URI (java.net.URI)65 ArrayList (java.util.ArrayList)65 HashMap (java.util.HashMap)28 List (java.util.List)27 Map (java.util.Map)20 Initiator (com.emc.storageos.db.client.model.Initiator)13 HashSet (java.util.HashSet)13 StringSetMap (com.emc.storageos.db.client.model.StringSetMap)10 Set (java.util.Set)7 StringMap (com.emc.storageos.db.client.model.StringMap)6 StringSet (com.emc.storageos.db.client.model.StringSet)6 StoragePortsAllocator (com.emc.storageos.volumecontroller.placement.StoragePortsAllocator)6 DummyDbClient (com.emc.storageos.util.DummyDbClient)5 PortAllocatorTestContext (com.emc.storageos.volumecontroller.placement.PortAllocatorTestContext)4 VPlexBackendManager (com.emc.storageos.vplexcontroller.VPlexBackendManager)4 ExportPathParams (com.emc.storageos.db.client.model.ExportPathParams)2