fix issue with OVS plugin VLAN allocation after a quantum-server restart
bug 962853 Also use constants for VLAN_MIN/VLAN_MAX and clean-up VlanMap unit tests. Change-Id: Id7b580d604092b5fc16d4c87ae866d419aad4d1f
This commit is contained in:
parent
ac7fb076c1
commit
540f1eda0b
@ -40,15 +40,26 @@ LOG.basicConfig(level=LOG.WARN)
|
|||||||
LOG.getLogger("ovs_quantum_plugin")
|
LOG.getLogger("ovs_quantum_plugin")
|
||||||
|
|
||||||
|
|
||||||
|
# Exception thrown if no more VLANs are available
|
||||||
|
class NoFreeVLANException(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class VlanMap(object):
|
class VlanMap(object):
|
||||||
vlans = {}
|
vlans = {}
|
||||||
net_ids = {}
|
net_ids = {}
|
||||||
free_vlans = set()
|
free_vlans = set()
|
||||||
|
VLAN_MIN = 1
|
||||||
|
VLAN_MAX = 4094
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.vlans.clear()
|
self.vlans.clear()
|
||||||
self.net_ids.clear()
|
self.net_ids.clear()
|
||||||
self.free_vlans = set(xrange(2, 4094))
|
self.free_vlans = set(xrange(self.VLAN_MIN, self.VLAN_MAX + 1))
|
||||||
|
|
||||||
|
def already_used(self, vlan_id, network_id):
|
||||||
|
self.free_vlans.remove(vlan_id)
|
||||||
|
self.set_vlan(vlan_id, network_id)
|
||||||
|
|
||||||
def set_vlan(self, vlan_id, network_id):
|
def set_vlan(self, vlan_id, network_id):
|
||||||
self.vlans[vlan_id] = network_id
|
self.vlans[vlan_id] = network_id
|
||||||
@ -58,13 +69,11 @@ class VlanMap(object):
|
|||||||
if len(self.free_vlans):
|
if len(self.free_vlans):
|
||||||
vlan = self.free_vlans.pop()
|
vlan = self.free_vlans.pop()
|
||||||
self.set_vlan(vlan, network_id)
|
self.set_vlan(vlan, network_id)
|
||||||
# LOG.debug("VlanMap::acquire %s -> %s", x, network_id)
|
LOG.debug("Allocated VLAN %s for network %s" % (vlan, network_id))
|
||||||
return vlan
|
return vlan
|
||||||
else:
|
else:
|
||||||
raise Exception("No free vlans..")
|
raise NoFreeVLANException("No VLAN free for network %s" %
|
||||||
|
network_id)
|
||||||
def get(self, vlan_id):
|
|
||||||
return self.vlans.get(vlan_id, None)
|
|
||||||
|
|
||||||
def release(self, network_id):
|
def release(self, network_id):
|
||||||
vlan = self.net_ids.get(network_id, None)
|
vlan = self.net_ids.get(network_id, None)
|
||||||
@ -72,7 +81,8 @@ class VlanMap(object):
|
|||||||
self.free_vlans.add(vlan)
|
self.free_vlans.add(vlan)
|
||||||
del self.vlans[vlan]
|
del self.vlans[vlan]
|
||||||
del self.net_ids[network_id]
|
del self.net_ids[network_id]
|
||||||
# LOG.debug("VlanMap::release %s", vlan)
|
LOG.debug("Deallocated VLAN %s (used by network %s)"
|
||||||
|
% (vlan, network_id))
|
||||||
else:
|
else:
|
||||||
LOG.error("No vlan found with network \"%s\"", network_id)
|
LOG.error("No vlan found with network \"%s\"", network_id)
|
||||||
|
|
||||||
@ -103,9 +113,9 @@ class OVSQuantumPlugin(QuantumPluginBase):
|
|||||||
vlans = ovs_db.get_vlans()
|
vlans = ovs_db.get_vlans()
|
||||||
for x in vlans:
|
for x in vlans:
|
||||||
vlan_id, network_id = x
|
vlan_id, network_id = x
|
||||||
# LOG.debug("Adding already populated vlan %s -> %s"
|
LOG.debug("Adding already populated vlan %s -> %s"
|
||||||
# % (vlan_id, network_id))
|
% (vlan_id, network_id))
|
||||||
self.vmap.set_vlan(vlan_id, network_id)
|
self.vmap.already_used(vlan_id, network_id)
|
||||||
|
|
||||||
def get_all_networks(self, tenant_id, **kwargs):
|
def get_all_networks(self, tenant_id, **kwargs):
|
||||||
nets = []
|
nets = []
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
import unittest
|
import unittest
|
||||||
from ovs_quantum_plugin import VlanMap
|
from ovs_quantum_plugin import VlanMap, NoFreeVLANException
|
||||||
|
|
||||||
|
|
||||||
class VlanMapTest(unittest.TestCase):
|
class VlanMapTest(unittest.TestCase):
|
||||||
@ -28,18 +28,35 @@ class VlanMapTest(unittest.TestCase):
|
|||||||
|
|
||||||
def testAddVlan(self):
|
def testAddVlan(self):
|
||||||
vlan_id = self.vmap.acquire("foobar")
|
vlan_id = self.vmap.acquire("foobar")
|
||||||
self.assertTrue(vlan_id == 2)
|
self.assertTrue(vlan_id >= VlanMap.VLAN_MIN)
|
||||||
|
self.assertTrue(vlan_id <= VlanMap.VLAN_MAX)
|
||||||
|
|
||||||
def testReleaseVlan(self):
|
def testReleaseVlan(self):
|
||||||
vlan_id = self.vmap.acquire("foobar")
|
vlan_id = self.vmap.acquire("foobar")
|
||||||
self.vmap.release("foobar")
|
self.vmap.release("foobar")
|
||||||
self.assertTrue(self.vmap.get(vlan_id) is None)
|
|
||||||
|
|
||||||
def testAddRelease4kVlans(self):
|
def testAddRelease4kVlans(self):
|
||||||
vlan_id = None
|
vlan_id = None
|
||||||
for id in range(2, 4000):
|
num_vlans = VlanMap.VLAN_MAX - VlanMap.VLAN_MIN
|
||||||
vlan_id = self.vmap.acquire(id)
|
for id in xrange(num_vlans):
|
||||||
self.assertTrue(vlan_id == id)
|
vlan_id = self.vmap.acquire("net-%s" % id)
|
||||||
for id in range(2, 4000):
|
self.assertTrue(vlan_id >= VlanMap.VLAN_MIN)
|
||||||
self.vmap.release(id)
|
self.assertTrue(vlan_id <= VlanMap.VLAN_MAX)
|
||||||
self.assertTrue(self.vmap.get(id) is None)
|
for id in xrange(num_vlans):
|
||||||
|
self.vmap.release("net-%s" % id)
|
||||||
|
|
||||||
|
def testAlreadyUsed(self):
|
||||||
|
existing_vlan = 2
|
||||||
|
self.vmap.already_used(existing_vlan, "net1")
|
||||||
|
try:
|
||||||
|
# this value is high enough that we will exhaust
|
||||||
|
# all VLANs. We want to make sure 'existing_vlan'
|
||||||
|
# is never reallocated.
|
||||||
|
num_vlans = VlanMap.VLAN_MAX - VlanMap.VLAN_MIN + 1
|
||||||
|
for x in xrange(num_vlans):
|
||||||
|
vlan_id = self.vmap.acquire("net-%x" % x)
|
||||||
|
self.assertTrue(vlan_id != existing_vlan)
|
||||||
|
|
||||||
|
self.fail("Did not run out of VLANs as expected")
|
||||||
|
except NoFreeVLANException:
|
||||||
|
pass # Expected exit
|
||||||
|
Loading…
x
Reference in New Issue
Block a user