Handle deleted ports when creating a list of fdb entries

The issue might happen when VMs are intensively created/deleted.
With the patch deleted ports will be just skipped.

Closes-Bug: #1610303
Change-Id: I32b0de9c452cf973d687c72e8381584012c9f3b4
This commit is contained in:
Oleg Bondarev 2016-08-09 13:45:26 +03:00
parent fd401fe0a0
commit 26bdffb3d7
2 changed files with 35 additions and 4 deletions

View File

@ -40,6 +40,10 @@ class L2populationMechanismDriver(api.MechanismDriver):
self.rpc_ctx = n_context.get_admin_context_without_session()
def _get_port_fdb_entries(self, port):
# the port might be concurrently deleted
if not port or not port.get('fixed_ips'):
return []
return [l2pop_rpc.PortInfo(mac_address=port['mac_address'],
ip_address=ip['ip_address'])
for ip in port['fixed_ips']]

View File

@ -912,7 +912,7 @@ class TestL2PopulationMechDriver(base.BaseTestCase):
def _test_create_agent_fdb(self, fdb_network_ports, agent_ips):
mech_driver = l2pop_mech_driver.L2populationMechanismDriver()
tunnel_network_ports, tunnel_agent = (
self._mock_network_ports(HOST + '1', None))
self._mock_network_ports(HOST + '1', [None]))
agent_ips[tunnel_agent] = '10.0.0.1'
def agent_ip_side_effect(agent):
@ -935,17 +935,17 @@ class TestL2PopulationMechDriver(base.BaseTestCase):
segment,
'network_id')
def _mock_network_ports(self, host_name, binding):
def _mock_network_ports(self, host_name, bindings):
agent = mock.Mock()
agent.host = host_name
return [(binding, agent)], agent
return [(binding, agent) for binding in bindings], agent
def test_create_agent_fdb(self):
binding = mock.Mock()
binding.port = {'mac_address': '00:00:DE:AD:BE:EF',
'fixed_ips': [{'ip_address': '1.1.1.1'}]}
fdb_network_ports, fdb_agent = (
self._mock_network_ports(HOST + '2', binding))
self._mock_network_ports(HOST + '2', [binding]))
agent_ips = {fdb_agent: '20.0.0.1'}
agent_fdb = self._test_create_agent_fdb(fdb_network_ports,
@ -975,6 +975,33 @@ class TestL2PopulationMechDriver(base.BaseTestCase):
[constants.FLOODING_ENTRY]}}
self.assertEqual(expected_result, result)
def test_create_agent_fdb_concurrent_port_deletion(self):
binding = mock.Mock()
binding.port = {'mac_address': '00:00:DE:AD:BE:EF',
'fixed_ips': [{'ip_address': '1.1.1.1'}]}
binding2 = mock.Mock()
# the port was deleted
binding2.port = None
fdb_network_ports, fdb_agent = (
self._mock_network_ports(HOST + '2', [binding, binding2]))
agent_ips = {fdb_agent: '20.0.0.1'}
agent_fdb = self._test_create_agent_fdb(fdb_network_ports,
agent_ips)
result = agent_fdb['network_id']
expected_result = {'segment_id': 1,
'network_type': 'vxlan',
'ports':
{'10.0.0.1':
[constants.FLOODING_ENTRY],
'20.0.0.1':
[constants.FLOODING_ENTRY,
l2pop_rpc.PortInfo(
mac_address='00:00:DE:AD:BE:EF',
ip_address='1.1.1.1')]}}
self.assertEqual(expected_result, result)
def test_update_port_precommit_mac_address_changed_raises(self):
port = {'status': u'ACTIVE',
'device_owner': DEVICE_OWNER_COMPUTE,