Make add_tap_interface resillient to removal
This patch makes add_tap_interface safe to race conditions where the interface is removed in the middle of processing by catching exceptions and checking to see if the interface still exists. If it no longer exists it assumes the exception was caused by the missing interface and returns False as it would if the interface did not exist to begin with. Change-Id: Ie0d89fc2584490b6985aee66da70bae027a130ed Closes-bug: #1542972
This commit is contained in:
parent
df4966081a
commit
59d815c704
neutron
plugins/ml2/drivers/linuxbridge/agent
tests/unit/plugins/ml2/drivers/linuxbridge/agent
@ -407,6 +407,22 @@ class LinuxBridgeManager(amb.CommonAgentManagerBase):
|
||||
|
||||
def add_tap_interface(self, network_id, network_type, physical_network,
|
||||
segmentation_id, tap_device_name, device_owner):
|
||||
"""Add tap interface and handle interface missing exeptions."""
|
||||
try:
|
||||
return self._add_tap_interface(network_id, network_type,
|
||||
physical_network, segmentation_id,
|
||||
tap_device_name, device_owner)
|
||||
except Exception:
|
||||
with excutils.save_and_reraise_exception() as ctx:
|
||||
if not ip_lib.device_exists(tap_device_name):
|
||||
# the exception was likely a side effect of the tap device
|
||||
# being removed during handling so we just return false
|
||||
# like we would if it didn't exist to begin with.
|
||||
ctx.reraise = False
|
||||
return False
|
||||
|
||||
def _add_tap_interface(self, network_id, network_type, physical_network,
|
||||
segmentation_id, tap_device_name, device_owner):
|
||||
"""Add tap interface.
|
||||
|
||||
If a VIF has been plugged into a network, this function will
|
||||
|
@ -909,6 +909,23 @@ class TestLinuxBridgeManager(base.BaseTestCase):
|
||||
"physnet9", "1")
|
||||
self.assertEqual(1, log.call_count)
|
||||
|
||||
@mock.patch.object(ip_lib, "device_exists", return_value=False)
|
||||
def test_add_tap_interface_with_interface_disappearing(self, exists):
|
||||
with mock.patch.object(self.lbm, "_add_tap_interface",
|
||||
side_effect=RuntimeError("No such dev")):
|
||||
self.assertFalse(self.lbm.add_tap_interface("123",
|
||||
p_const.TYPE_VLAN,
|
||||
"physnet1", None,
|
||||
"tap1", "foo"))
|
||||
|
||||
@mock.patch.object(ip_lib, "device_exists", return_value=True)
|
||||
def test_add_tap_interface_with_other_error(self, exists):
|
||||
with mock.patch.object(self.lbm, "_add_tap_interface",
|
||||
side_effect=RuntimeError("No more fuel")):
|
||||
self.assertRaises(RuntimeError, self.lbm.add_tap_interface, "123",
|
||||
p_const.TYPE_VLAN, "physnet1", None, "tap1",
|
||||
"foo")
|
||||
|
||||
def test_add_tap_interface_owner_other(self):
|
||||
with mock.patch.object(ip_lib, "device_exists"):
|
||||
with mock.patch.object(self.lbm, "ensure_local_bridge"):
|
||||
|
Loading…
x
Reference in New Issue
Block a user