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 2af5fd889b
)
This commit is contained in:
parent
4575136fe9
commit
222c997022
|
@ -355,7 +355,7 @@ class OVSInterfaceDriver(LinuxInterfaceDriver):
|
|||
namespace_obj = ip_wrapper.ensure_namespace(namespace)
|
||||
for i in range(9):
|
||||
try:
|
||||
namespace_obj.add_device_to_namespace(device)
|
||||
namespace_obj.add_device_to_namespace(device, is_ovs_port=True)
|
||||
break
|
||||
except ip_lib.NetworkInterfaceNotFound:
|
||||
# NOTE(slaweq): if the exception was NetworkInterfaceNotFound
|
||||
|
|
|
@ -270,9 +270,9 @@ class IPWrapper(SubProcessBase):
|
|||
return True
|
||||
return False
|
||||
|
||||
def add_device_to_namespace(self, device):
|
||||
def add_device_to_namespace(self, device, is_ovs_port=False):
|
||||
if self.namespace:
|
||||
device.link.set_netns(self.namespace)
|
||||
device.link.set_netns(self.namespace, is_ovs_port=is_ovs_port)
|
||||
|
||||
def add_vlan(self, name, physical_interface, vlan_id):
|
||||
privileged.create_interface(name,
|
||||
|
@ -462,10 +462,15 @@ class IpLinkCommand(IpDeviceCommandBase):
|
|||
privileged.set_link_attribute(
|
||||
self.name, self._parent.namespace, state='down')
|
||||
|
||||
def set_netns(self, namespace):
|
||||
def set_netns(self, namespace, is_ovs_port=False):
|
||||
privileged.set_link_attribute(
|
||||
self.name, self._parent.namespace, net_ns_fd=namespace)
|
||||
self._parent.namespace = namespace
|
||||
if is_ovs_port:
|
||||
# NOTE(slaweq): because of the "shy port" which may dissapear for
|
||||
# short time after it's moved to the namespace we need to wait
|
||||
# a bit before checking if port really exists in the namespace
|
||||
time.sleep(1)
|
||||
common_utils.wait_until_true(lambda: self.exists, timeout=5,
|
||||
sleep=0.5)
|
||||
|
||||
|
|
|
@ -467,11 +467,11 @@ class TestOVSInterfaceDriver(TestBase):
|
|||
expected.extend(
|
||||
[mock.call().ensure_namespace(namespace),
|
||||
mock.call().ensure_namespace().add_device_to_namespace(
|
||||
mock.ANY),
|
||||
mock.ANY, is_ovs_port=True),
|
||||
mock.call().ensure_namespace().add_device_to_namespace(
|
||||
mock.ANY),
|
||||
mock.ANY, is_ovs_port=True),
|
||||
mock.call().ensure_namespace().add_device_to_namespace(
|
||||
mock.ANY)])
|
||||
mock.ANY, is_ovs_port=True)])
|
||||
expected.extend([
|
||||
mock.call(namespace=namespace),
|
||||
mock.call().device('tap0'),
|
||||
|
|
|
@ -507,7 +507,8 @@ class TestIpWrapper(base.BaseTestCase):
|
|||
def test_add_device_to_namespace(self):
|
||||
dev = mock.Mock()
|
||||
ip_lib.IPWrapper(namespace='ns').add_device_to_namespace(dev)
|
||||
dev.assert_has_calls([mock.call.link.set_netns('ns')])
|
||||
dev.assert_has_calls(
|
||||
[mock.call.link.set_netns('ns', is_ovs_port=False)])
|
||||
|
||||
def test_add_device_to_namespace_is_none(self):
|
||||
dev = mock.Mock()
|
||||
|
|
Loading…
Reference in New Issue