Merge "Do not delete trunk bridges if service port attached"
This commit is contained in:
commit
41bd39663e
@ -205,6 +205,20 @@ class OVSDBHandler(object):
|
|||||||
:param bridge_name: Name of the bridge used for locking purposes.
|
:param bridge_name: Name of the bridge used for locking purposes.
|
||||||
:param port: Parent port dict.
|
:param port: Parent port dict.
|
||||||
"""
|
"""
|
||||||
|
# TODO(njohnston): In the case of DPDK with trunk ports, if nova
|
||||||
|
# deletes an interface and then re-adds it we can get a race
|
||||||
|
# condition where the port is re-added and then the bridge is
|
||||||
|
# deleted because we did not properly catch the re-addition. To
|
||||||
|
# solve this would require transitioning to ordered event
|
||||||
|
# resolution, like the L3 agent does with the
|
||||||
|
# ResourceProcessingQueue class. Until we can make that happen, we
|
||||||
|
# try to mitigate the issue by checking if there is a port on the
|
||||||
|
# bridge and if so then do not remove it.
|
||||||
|
bridge = ovs_lib.OVSBridge(bridge_name)
|
||||||
|
if bridge_has_instance_port(bridge):
|
||||||
|
LOG.debug("The bridge %s has instances attached so it will not "
|
||||||
|
"be deleted.", bridge_name)
|
||||||
|
return
|
||||||
try:
|
try:
|
||||||
# TODO(jlibosva): Investigate how to proceed during removal of
|
# TODO(jlibosva): Investigate how to proceed during removal of
|
||||||
# trunk bridge that doesn't have metadata stored.
|
# trunk bridge that doesn't have metadata stored.
|
||||||
|
@ -193,3 +193,11 @@ class OVSDBHandlerTestCase(base.OVSAgentTestFramework):
|
|||||||
# Check no resources are left behind.
|
# Check no resources are left behind.
|
||||||
self.assertFalse(self.trunk_br.exists())
|
self.assertFalse(self.trunk_br.exists())
|
||||||
self.assertFalse(ovsdb_handler.bridge_has_service_port(br_int))
|
self.assertFalse(ovsdb_handler.bridge_has_service_port(br_int))
|
||||||
|
|
||||||
|
def test_do_not_delete_trunk_bridge_with_instance_ports(self):
|
||||||
|
ports = self._fill_trunk_dict()
|
||||||
|
self.setup_agent_and_ports(port_dicts=ports)
|
||||||
|
self.wait_until_ports_state(self.ports, up=True)
|
||||||
|
self.ovsdb_handler.handle_trunk_remove(self.trunk_br.br_name,
|
||||||
|
ports.pop())
|
||||||
|
self.assertTrue(self.trunk_br.exists())
|
||||||
|
@ -182,7 +182,9 @@ class TestOVSDBHandler(base.BaseTestCase):
|
|||||||
def test_handle_trunk_remove_trunk_manager_failure(self):
|
def test_handle_trunk_remove_trunk_manager_failure(self):
|
||||||
with mock.patch.object(self.ovsdb_handler, '_get_trunk_metadata',
|
with mock.patch.object(self.ovsdb_handler, '_get_trunk_metadata',
|
||||||
side_effect=trunk_manager.TrunkManagerError(error='error')):
|
side_effect=trunk_manager.TrunkManagerError(error='error')):
|
||||||
self.ovsdb_handler.handle_trunk_remove('foo', self.fake_port)
|
with mock.patch.object(ovsdb_handler, 'bridge_has_instance_port',
|
||||||
|
return_value=True):
|
||||||
|
self.ovsdb_handler.handle_trunk_remove('foo', self.fake_port)
|
||||||
|
|
||||||
@mock.patch('neutron.agent.common.ovs_lib.OVSBridge')
|
@mock.patch('neutron.agent.common.ovs_lib.OVSBridge')
|
||||||
def test_handle_trunk_remove_rpc_failure(self, br):
|
def test_handle_trunk_remove_rpc_failure(self, br):
|
||||||
|
Loading…
Reference in New Issue
Block a user