Skip to content

Commit c5e70ad

Browse files
slawqoralonsoh
authored andcommitted
Add sleep before checking if ovs port is in the namespace
When network device which is ovs internal port is moved to the namespace it may happend sometimes that it will have "shy port syndrome" [1]. Even though there is wait for device to be in namespace in the set_netns method it may happend that device is in namespace during this check but it dissapears for short time later and that causes failures e.g. in functional tests like described in [2]. To avoid that, this patch proposed simple (and ugly) sleep for 1 second before checking if port really exists in the namespace. If it will be "shy" port it should already flap during that 1 second. [1] https://bugs.launchpad.net/neutron/+bug/1618987 [2] https://bugs.launchpad.net/neutron/+bug/1961740 Related-Bug: #1961740 Related-Bug: #1998337 Change-Id: I442587e7ef55917f4ea873e190bf8afbc0e911e1 (cherry picked from commit 2af5fd8)
1 parent ece7d9c commit c5e70ad

File tree

4 files changed

+14
-8
lines changed

4 files changed

+14
-8
lines changed

neutron/agent/linux/interface.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -365,7 +365,7 @@ def _add_device_to_namespace(self, ip_wrapper, device, namespace):
365365
namespace_obj = ip_wrapper.ensure_namespace(namespace)
366366
for i in range(9):
367367
try:
368-
namespace_obj.add_device_to_namespace(device)
368+
namespace_obj.add_device_to_namespace(device, is_ovs_port=True)
369369
break
370370
except ip_lib.NetworkInterfaceNotFound:
371371
# NOTE(slaweq): if the exception was NetworkInterfaceNotFound

neutron/agent/linux/ip_lib.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -269,9 +269,9 @@ def garbage_collect_namespace(self):
269269
return True
270270
return False
271271

272-
def add_device_to_namespace(self, device):
272+
def add_device_to_namespace(self, device, is_ovs_port=False):
273273
if self.namespace:
274-
device.link.set_netns(self.namespace)
274+
device.link.set_netns(self.namespace, is_ovs_port=is_ovs_port)
275275

276276
def add_vlan(self, name, physical_interface, vlan_id):
277277
privileged.create_interface(name,
@@ -461,10 +461,15 @@ def set_down(self):
461461
privileged.set_link_attribute(
462462
self.name, self._parent.namespace, state='down')
463463

464-
def set_netns(self, namespace):
464+
def set_netns(self, namespace, is_ovs_port=False):
465465
privileged.set_link_attribute(
466466
self.name, self._parent.namespace, net_ns_fd=namespace)
467467
self._parent.namespace = namespace
468+
if is_ovs_port:
469+
# NOTE(slaweq): because of the "shy port" which may dissapear for
470+
# short time after it's moved to the namespace we need to wait
471+
# a bit before checking if port really exists in the namespace
472+
time.sleep(1)
468473
common_utils.wait_until_true(lambda: self.exists, timeout=5,
469474
sleep=0.5)
470475

neutron/tests/unit/agent/linux/test_interface.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -470,11 +470,11 @@ def device_exists(dev, namespace=None):
470470
expected.extend(
471471
[mock.call().ensure_namespace(namespace),
472472
mock.call().ensure_namespace().add_device_to_namespace(
473-
mock.ANY),
473+
mock.ANY, is_ovs_port=True),
474474
mock.call().ensure_namespace().add_device_to_namespace(
475-
mock.ANY),
475+
mock.ANY, is_ovs_port=True),
476476
mock.call().ensure_namespace().add_device_to_namespace(
477-
mock.ANY)])
477+
mock.ANY, is_ovs_port=True)])
478478
expected.extend([
479479
mock.call(namespace=namespace),
480480
mock.call().device('tap0'),

neutron/tests/unit/agent/linux/test_ip_lib.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -507,7 +507,8 @@ def fake_create_interface(ifname, namespace, kind, **kwargs):
507507
def test_add_device_to_namespace(self):
508508
dev = mock.Mock()
509509
ip_lib.IPWrapper(namespace='ns').add_device_to_namespace(dev)
510-
dev.assert_has_calls([mock.call.link.set_netns('ns')])
510+
dev.assert_has_calls(
511+
[mock.call.link.set_netns('ns', is_ovs_port=False)])
511512

512513
def test_add_device_to_namespace_is_none(self):
513514
dev = mock.Mock()

0 commit comments

Comments
 (0)