From 781b8f41498521041f7c9d4b4e0c0fa438736fc4 Mon Sep 17 00:00:00 2001 From: Kevin Benton Date: Mon, 5 Jun 2017 15:50:34 -0700 Subject: [PATCH] Stop binding attempts when network has no segments There is no point in retrying binding if the network has no segments to bind to. This occurs during normal operations when a network is being quickly created/deleted and the DHCP port gets created during the network deletion. By skipping binding we avoid misleading error messages and wasted CPU cycles. Closes-Bug: #1696010 Change-Id: I0b987ab7c3f65c1d860064a1b437b92a1dc1cb81 --- neutron/plugins/ml2/plugin.py | 4 ++++ neutron/tests/unit/plugins/ml2/test_plugin.py | 15 +++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/neutron/plugins/ml2/plugin.py b/neutron/plugins/ml2/plugin.py index 3cc92ced413..e6261c009dd 100644 --- a/neutron/plugins/ml2/plugin.py +++ b/neutron/plugins/ml2/plugin.py @@ -344,6 +344,10 @@ class Ml2Plugin(db_base_plugin_v2.NeutronDbPluginV2, @db_api.retry_db_errors def _bind_port_if_needed(self, context, allow_notify=False, need_notify=False): + if not context.network.network_segments: + LOG.debug("Network %s has no segments, skipping binding", + context.network.current['id']) + return context for count in range(1, MAX_BIND_TRIES + 1): if count > 1: # yield for binding retries so that we give other threads a diff --git a/neutron/tests/unit/plugins/ml2/test_plugin.py b/neutron/tests/unit/plugins/ml2/test_plugin.py index 880ae4baf51..21c1dae3333 100644 --- a/neutron/tests/unit/plugins/ml2/test_plugin.py +++ b/neutron/tests/unit/plugins/ml2/test_plugin.py @@ -1556,6 +1556,21 @@ class TestMl2PortBinding(Ml2PluginV2TestCase, self.assertEqual(expected_try_again, try_again) self.assertEqual(expected_bd_mock_called, bd_mock.called) + def test__bind_port_if_needed_early_exit_on_no_segments(self): + with self.network() as n: + ctx = context.get_admin_context() + seg_plugin = segments_plugin.Plugin.get_instance() + seg = seg_plugin.get_segments(ctx)[0] + seg_plugin.delete_segment(ctx, seg['id']) + plugin = directory.get_plugin() + mech_context = driver_context.PortContext( + plugin, ctx, None, + plugin.get_network(self.context, n['network']['id']), + None, None) + with mock.patch.object(plugin, '_attempt_binding') as ab: + plugin._bind_port_if_needed(mech_context) + self.assertFalse(ab.called) + def test__attempt_binding_retries(self): # Simulate cases of both successful and failed binding states for # vif_type unbound