Skip to content

Commit 09e1ab0

Browse files
authored
Merge pull request #110 from stackhpc/upstream/yoga-2024-01-15
Synchronise yoga with upstream
2 parents d6fe9ff + fe80262 commit 09e1ab0

File tree

4 files changed

+33
-8
lines changed

4 files changed

+33
-8
lines changed

neutron/agent/linux/interface.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -356,7 +356,7 @@ def _add_device_to_namespace(self, ip_wrapper, device, namespace):
356356
namespace_obj = ip_wrapper.ensure_namespace(namespace)
357357
for i in range(9):
358358
try:
359-
namespace_obj.add_device_to_namespace(device)
359+
namespace_obj.add_device_to_namespace(device, is_ovs_port=True)
360360
break
361361
except ip_lib.NetworkInterfaceNotFound:
362362
# NOTE(slaweq): if the exception was NetworkInterfaceNotFound
@@ -365,6 +365,11 @@ def _add_device_to_namespace(self, ip_wrapper, device, namespace):
365365
LOG.warning("Failed to set interface %s into namespace %s. "
366366
"Interface not found, attempt: %s, retrying.",
367367
device, namespace, i + 1)
368+
# NOTE(slaweq) In such case it's required to reset device's
369+
# namespace as it was already set to the "namespace"
370+
# and after retry neutron will look for it in that namespace
371+
# which is wrong
372+
device.namespace = None
368373
time.sleep(1)
369374
except utils.WaitTimeout:
370375
# NOTE(slaweq): if the exception was WaitTimeout then it means

neutron/agent/linux/ip_lib.py

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

273-
def add_device_to_namespace(self, device):
273+
def add_device_to_namespace(self, device, is_ovs_port=False):
274274
if self.namespace:
275-
device.link.set_netns(self.namespace)
275+
device.link.set_netns(self.namespace, is_ovs_port=is_ovs_port)
276276

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

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

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

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -468,11 +468,11 @@ def device_exists(dev, namespace=None):
468468
expected.extend(
469469
[mock.call().ensure_namespace(namespace),
470470
mock.call().ensure_namespace().add_device_to_namespace(
471-
mock.ANY),
471+
mock.ANY, is_ovs_port=True),
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
expected.extend([
477477
mock.call(namespace=namespace),
478478
mock.call().device('tap0'),
@@ -518,6 +518,20 @@ def test_unplug(self):
518518
ovs_br.assert_has_calls([mock.call('br-int'),
519519
mock.call().delete_port('tap0')])
520520

521+
def test__add_device_to_namespace_retries(self):
522+
ovs = interface.OVSInterfaceDriver(self.conf)
523+
namespace_obj = self.ip.return_value.ensure_namespace.return_value
524+
self.ip.ensure_namespace.return_value = namespace_obj
525+
namespace_obj.add_device_to_namespace.side_effect = (
526+
ip_lib.NetworkInterfaceNotFound)
527+
device = mock.MagicMock()
528+
self.assertRaises(
529+
ip_lib.NetworkInterfaceNotFound,
530+
ovs._add_device_to_namespace,
531+
self.ip, device, "test-ns")
532+
self.assertEqual(10, namespace_obj.add_device_to_namespace.call_count)
533+
self.assertIsNone(device.namespace)
534+
521535

522536
class TestOVSInterfaceDriverWithVeth(TestOVSInterfaceDriver):
523537

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

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

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

0 commit comments

Comments
 (0)