Skip to content

Commit

Permalink
Disassociate fixed IPs not known to dnsmasq
Browse files Browse the repository at this point in the history
Currently, fix_ip disassociation only happens in release_fixed_ip(),
which is called by dhcp-bridge script when ip is released. But there
are circumstances when instancs fail to get lease from dnsmasq(instances
fail to boot or instances fail to spawn). In such case, DHCPRELEASE
packet sent to dnsmasq would never trigger dhcp-bridge to run. Thus the
fixed ip would not be disassociated from instance until
_disassociate_stale_fixed_ips() begins to run.

Actually, this patch borrows the idea from Vishvananda's
3f6739e commit: explicitly disassociate
fixed ip which is not known to dnsmasq, instead of via the dhcp-release
script.

Steps to reproduce:
1. Create an instance which doesn't send dhcp request to dnsmasq.
2. Delete the instance.
3. The fixed ip associated with the instance is not returned to pool.

Bug 1180766

Change-Id: Icc022ea2fb7af08fb7354e3a49c77ad5ae58f34c
  • Loading branch information
yufang521247 authored and openstack-gerrit committed Jul 8, 2013
1 parent e39e0c9 commit 383ca6c
Showing 1 changed file with 17 additions and 1 deletion.
18 changes: 17 additions & 1 deletion nova/network/manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -921,11 +921,27 @@ def deallocate_fixed_ip(self, context, address, host=None, teardown=True):
LOG.error(msg % address)
return

# NOTE(cfb): Call teardown before release_dhcp to ensure
# that the IP can't be re-leased after a release
# packet is sent.
self._teardown_network_on_host(context, network)
# NOTE(vish): This forces a packet so that the release_fixed_ip
# callback will get called by nova-dhcpbridge.
self.driver.release_dhcp(dev, address, vif['address'])

self._teardown_network_on_host(context, network)
# NOTE(yufang521247): This is probably a failed dhcp fixed ip.
# DHCPRELEASE packet sent to dnsmasq would not trigger
# dhcp-bridge to run. Thus it is better to disassociate such
# fixed ip here.
fixed_ip_ref = self.db.fixed_ip_get_by_address(context,
address)
if (instance_uuid == fixed_ip_ref['instance_uuid'] and
not fixed_ip_ref.get('leased')):
self.db.fixed_ip_disassociate(context, address)

else:
# We can't try to free the IP address so just call teardown
self._teardown_network_on_host(context, network)

# Commit the reservations
if reservations:
Expand Down

0 comments on commit 383ca6c

Please sign in to comment.