Skip to content

Commit

Permalink
Fix race condition in dhcp agent
Browse files Browse the repository at this point in the history
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
  • Loading branch information
aaronorosen committed Mar 21, 2013
1 parent c6bf10d commit 885cc41
Showing 1 changed file with 8 additions and 0 deletions.
8 changes: 8 additions & 0 deletions quantum/agent/dhcp_agent.py
Expand Up @@ -37,6 +37,7 @@
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
Expand Down Expand Up @@ -226,11 +227,13 @@ def refresh_dhcp_helper(self, network_id):
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']
Expand All @@ -239,10 +242,12 @@ def network_update_end(self, context, payload):
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']
Expand All @@ -251,13 +256,15 @@ def subnet_update_end(self, context, payload):
# 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']
network = self.cache.get_network_by_subnet_id(subnet_id)
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'])
Expand All @@ -269,6 +276,7 @@ def port_update_end(self, context, payload):
# 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'])
Expand Down

0 comments on commit 885cc41

Please sign in to comment.