From: Aaron Rosen Date: Thu, 21 Mar 2013 01:19:04 +0000 (-0700) Subject: Fix race condition in dhcp agent X-Git-Url: https://review.fuel-infra.org/gitweb?a=commitdiff_plain;h=885cc41ff033a24191e93d40cd39d858e108f1d8;p=openstack-build%2Fneutron-build.git Fix race condition in dhcp agent This patch fixes a race condition that can happen in the dhcp agent when a subnet is created and then a host route is then immediately added to that subnet following a subnet.update.end notification. The race condition occurs in refresh_dhcp_helper() where self.enable_dhcp_helper() gets called twice since the first call had not completed self.cache.put(network). This same race condition can also occur in the other events so lockutils.synchronized() is added to synchronize those code segments as well. Fixes bug 1155748 Change-Id: I2ff52adc3dfebddd6d9c15d5dc79aa65be107179 --- diff --git a/quantum/agent/dhcp_agent.py b/quantum/agent/dhcp_agent.py index c5d4a0313..3ebcbcaf7 100644 --- a/quantum/agent/dhcp_agent.py +++ b/quantum/agent/dhcp_agent.py @@ -37,6 +37,7 @@ from quantum import manager from quantum.openstack.common import importutils from quantum.openstack.common import jsonutils from quantum.openstack.common import log as logging +from quantum.openstack.common import lockutils from quantum.openstack.common import loopingcall from quantum.openstack.common.rpc import proxy from quantum.openstack.common import service @@ -226,11 +227,13 @@ class DhcpAgent(manager.Manager): else: self.disable_dhcp_helper(network.id) + @lockutils.synchronized('agent', 'dhcp-') def network_create_end(self, context, payload): """Handle the network.create.end notification event.""" network_id = payload['network']['id'] self.enable_dhcp_helper(network_id) + @lockutils.synchronized('agent', 'dhcp-') def network_update_end(self, context, payload): """Handle the network.update.end notification event.""" network_id = payload['network']['id'] @@ -239,10 +242,12 @@ class DhcpAgent(manager.Manager): else: self.disable_dhcp_helper(network_id) + @lockutils.synchronized('agent', 'dhcp-') def network_delete_end(self, context, payload): """Handle the network.delete.end notification event.""" self.disable_dhcp_helper(payload['network_id']) + @lockutils.synchronized('agent', 'dhcp-') def subnet_update_end(self, context, payload): """Handle the subnet.update.end notification event.""" network_id = payload['subnet']['network_id'] @@ -251,6 +256,7 @@ class DhcpAgent(manager.Manager): # Use the update handler for the subnet create event. subnet_create_end = subnet_update_end + @lockutils.synchronized('agent', 'dhcp-') def subnet_delete_end(self, context, payload): """Handle the subnet.delete.end notification event.""" subnet_id = payload['subnet_id'] @@ -258,6 +264,7 @@ class DhcpAgent(manager.Manager): if network: self.refresh_dhcp_helper(network.id) + @lockutils.synchronized('agent', 'dhcp-') def port_update_end(self, context, payload): """Handle the port.update.end notification event.""" port = DictModel(payload['port']) @@ -269,6 +276,7 @@ class DhcpAgent(manager.Manager): # Use the update handler for the port create event. port_create_end = port_update_end + @lockutils.synchronized('agent', 'dhcp-') def port_delete_end(self, context, payload): """Handle the port.delete.end notification event.""" port = self.cache.get_port_by_id(payload['port_id'])