Don't immediately restart in DHCP agent on port change
Now that the agent will receive port update events for all port changes[1], we need to avoid immediately restarting when the subnets on the agent's port changes. Otherwise the restart may request ports on a subnet which is in the process of being deleted. While the server is equipped to handle this, it makes subnet deletion much more contentious than it needs to be. This alters the logic to schedule a resync for later if the agent's port has had its subnets changed rather than restarting right away. Then by the time the agent eventually syncs the server should have finished deleting the subnet. Even if it hasn't, it spaces out the request from the agent for the network far enough that the operation will be much less frequent to avoid racing with the server. 1. I607635601caff0322fd0c80c9023f5c4f663ca25 Partial-Bug: #1622616 Change-Id: I98761a7e3f4bce8d5485c885f03c6bfdde246802
This commit is contained in:
parent
70907b3e55
commit
673abd56c9
|
@ -387,7 +387,20 @@ class DhcpAgent(manager.Manager):
|
|||
orig = orig or {'fixed_ips': []}
|
||||
old_ips = {i['ip_address'] for i in orig['fixed_ips'] or []}
|
||||
new_ips = {i['ip_address'] for i in updated_port['fixed_ips']}
|
||||
if old_ips != new_ips:
|
||||
old_subs = {i['subnet_id'] for i in orig['fixed_ips'] or []}
|
||||
new_subs = {i['subnet_id'] for i in updated_port['fixed_ips']}
|
||||
if new_subs != old_subs:
|
||||
# subnets being serviced by port have changed, this could
|
||||
# indicate a subnet_delete is in progress. schedule a
|
||||
# resync rather than an immediate restart so we don't
|
||||
# attempt to re-allocate IPs at the same time the server
|
||||
# is deleting them.
|
||||
self.schedule_resync("Agent port was modified",
|
||||
updated_port.network_id)
|
||||
return
|
||||
elif old_ips != new_ips:
|
||||
LOG.debug("Agent IPs on network %s changed from %s to %s",
|
||||
network.id, old_ips, new_ips)
|
||||
driver_action = 'restart'
|
||||
self.cache.put_port(updated_port)
|
||||
self.call_driver(driver_action, network)
|
||||
|
|
|
@ -1040,6 +1040,17 @@ class TestDhcpAgentEventHandler(base.BaseTestCase):
|
|||
self.call_driver.assert_has_calls(
|
||||
[mock.call.call_driver('reload_allocations', fake_network)])
|
||||
|
||||
def test_port_update_change_subnet_on_dhcp_agents_port(self):
|
||||
self.cache.get_network_by_id.return_value = fake_network
|
||||
self.cache.get_port_by_id.return_value = fake_port1
|
||||
payload = dict(port=copy.deepcopy(fake_port1))
|
||||
device_id = utils.get_dhcp_agent_device_id(
|
||||
payload['port']['network_id'], self.dhcp.conf.host)
|
||||
payload['port']['fixed_ips'][0]['subnet_id'] = '77777-7777'
|
||||
payload['port']['device_id'] = device_id
|
||||
self.dhcp.port_update_end(None, payload)
|
||||
self.assertFalse(self.call_driver.called)
|
||||
|
||||
def test_port_update_change_ip_on_dhcp_agents_port(self):
|
||||
self.cache.get_network_by_id.return_value = fake_network
|
||||
self.cache.get_port_by_id.return_value = fake_port1
|
||||
|
@ -1061,8 +1072,8 @@ class TestDhcpAgentEventHandler(base.BaseTestCase):
|
|||
payload['port']['fixed_ips'][0]['ip_address'] = '172.9.9.99'
|
||||
payload['port']['device_id'] = device_id
|
||||
self.dhcp.port_update_end(None, payload)
|
||||
self.call_driver.assert_has_calls(
|
||||
[mock.call.call_driver('restart', fake_network)])
|
||||
self.schedule_resync.assert_called_once_with(mock.ANY,
|
||||
fake_port1.network_id)
|
||||
|
||||
def test_port_update_on_dhcp_agents_port_no_ip_change(self):
|
||||
self.cache.get_network_by_id.return_value = fake_network
|
||||
|
|
Loading…
Reference in New Issue