From ffa11a64706e898ba3ae45f84920d632b5947add Mon Sep 17 00:00:00 2001 From: armando-migliaccio Date: Fri, 27 Sep 2013 18:38:16 -0700 Subject: [PATCH] Avoid dhcp agent race condition on subnet and network delete This patch ensures that, when the dhcp agent queries the server to retrieve and delete its DHCP port, it does so by selecting for update. This has been done by introducing a new method that combines the get and delete in one shot. Closes-Bug:1197627 Change-Id: I1e8a87d7dc1a1cb9309aeefd41619e20f49f95a6 --- neutron/db/db_base_plugin_v2.py | 8 ++++++++ neutron/db/dhcp_rpc_base.py | 5 +---- neutron/tests/unit/test_db_rpc_base.py | 6 +++--- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/neutron/db/db_base_plugin_v2.py b/neutron/db/db_base_plugin_v2.py index 52fc45389..f7b0442f0 100644 --- a/neutron/db/db_base_plugin_v2.py +++ b/neutron/db/db_base_plugin_v2.py @@ -1402,6 +1402,14 @@ class NeutronDbPluginV2(neutron_plugin_base_v2.NeutronPluginBaseV2, with context.session.begin(subtransactions=True): self._delete_port(context, id) + def delete_ports(self, context, filters): + with context.session.begin(subtransactions=True): + ports = self._get_ports_query( + context, filters=filters).with_lockmode('update') + if ports: + for port in ports: + self.delete_port(context, port['id']) + def _delete_port(self, context, id): port = self._get_port(context, id) diff --git a/neutron/db/dhcp_rpc_base.py b/neutron/db/dhcp_rpc_base.py index a8a2b4bf2..2eacbbff4 100644 --- a/neutron/db/dhcp_rpc_base.py +++ b/neutron/db/dhcp_rpc_base.py @@ -179,10 +179,7 @@ class DhcpRpcCallbackMixin(object): {'network_id': network_id, 'host': host}) plugin = manager.NeutronManager.get_plugin() filters = dict(network_id=[network_id], device_id=[device_id]) - ports = plugin.get_ports(context, filters=filters) - - if ports: - plugin.delete_port(context, ports[0]['id']) + plugin.delete_ports(context, filters=filters) def release_port_fixed_ip(self, context, **kwargs): """Release the fixed_ip associated the subnet on a port.""" diff --git a/neutron/tests/unit/test_db_rpc_base.py b/neutron/tests/unit/test_db_rpc_base.py index 9be906529..e878f0936 100644 --- a/neutron/tests/unit/test_db_rpc_base.py +++ b/neutron/tests/unit/test_db_rpc_base.py @@ -131,9 +131,9 @@ class TestDhcpRpcCallackMixin(base.BaseTestCase): device_id='devid') self.plugin.assert_has_calls([ - mock.call.get_ports(mock.ANY, filters=dict(network_id=['netid'], - device_id=['devid'])), - mock.call.delete_port(mock.ANY, 'port_id')]) + mock.call.delete_ports(mock.ANY, + filters=dict(network_id=['netid'], + device_id=['devid']))]) def test_release_port_fixed_ip(self): port_retval = dict(id='port_id', fixed_ips=[dict(subnet_id='a')]) -- 2.45.2