From a545da420cad0bbf6a150939af5e0b9c6c424c01 Mon Sep 17 00:00:00 2001 From: Gary Kotton Date: Sun, 15 Sep 2019 00:57:37 -0700 Subject: [PATCH] Enable bulk updates for the dnsmasq Instead of restarting the dnsmasq agent for every IP we do this in bulk. That is, if a network has N updates in X seconds then we will restart the process once with the ports configured in the X seconds and not N Times. A new configuration variable have been added: - bulk_reload_interval - time to wait between bulk reloads. This is 0 by default to ensure backwards compatibility. If the value is not 0 the new functionlay is invoked. Change-Id: Ieff5ce4506fd4e7fa427eb50c50fbe316f67103f --- neutron/agent/dhcp/agent.py | 17 +++++++++++++++++ neutron/conf/agent/dhcp.py | 8 +++++++- .../dhcp-bulk-updates-0150b764bb1b165f.yaml | 14 ++++++++++++++ 3 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 releasenotes/notes/dhcp-bulk-updates-0150b764bb1b165f.yaml diff --git a/neutron/agent/dhcp/agent.py b/neutron/agent/dhcp/agent.py index 0b2318d4ff9..9f3c1861363 100644 --- a/neutron/agent/dhcp/agent.py +++ b/neutron/agent/dhcp/agent.py @@ -115,6 +115,7 @@ class DhcpAgent(manager.Manager): self._pool_size = DHCP_PROCESS_GREENLET_MIN self._pool = eventlet.GreenPool(size=self._pool_size) self._queue = queue.ResourceProcessingQueue() + self._network_bulk_allocations = {} def init_host(self): self.sync_state() @@ -144,11 +145,27 @@ class DhcpAgent(manager.Manager): self.periodic_resync() self.start_ready_ports_loop() eventlet.spawn_n(self._process_loop) + if self.conf.bulk_reload_interval: + eventlet.spawn_n(self._reload_bulk_allocations) + + def _reload_bulk_allocations(self): + while True: + for network_id in self._network_bulk_allocations.keys(): + network = self.cache.get_network_by_id(network_id) + self.call_driver('bulk_reload_allocations', network) + del self._network_bulk_allocations[network_id] + eventlet.greenthread.sleep(self.conf.bulk_reload_interval) def call_driver(self, action, network, **action_kwargs): """Invoke an action on a DHCP driver instance.""" LOG.debug('Calling driver for network: %(net)s action: %(action)s', {'net': network.id, 'action': action}) + if self.conf.bulk_reload_interval and action == 'reload_allocations': + LOG.debug("Call deferred to bulk load") + self._network_bulk_allocations[network.id] = True + return True + if action == 'bulk_reload_allocations': + action = 'reload_allocations' try: # the Driver expects something that is duck typed similar to # the base models. diff --git a/neutron/conf/agent/dhcp.py b/neutron/conf/agent/dhcp.py index 9823dd1bd9a..e7254d1544c 100644 --- a/neutron/conf/agent/dhcp.py +++ b/neutron/conf/agent/dhcp.py @@ -68,7 +68,13 @@ DHCP_AGENT_OPTS = [ cfg.IntOpt('num_sync_threads', default=4, help=_('Number of threads to use during sync process. ' 'Should not exceed connection pool size configured on ' - 'server.')) + 'server.')), + cfg.IntOpt('bulk_reload_interval', default=0, min=0, + help=_('Time to sleep between reloading the DHCP allocations. ' + 'This will only be invoked if the value is not 0. ' + 'If a network has N updates in X seconds then ' + 'we will reload once with the port changes in the X ' + 'seconds and not N times.')), ] DHCP_OPTS = [ diff --git a/releasenotes/notes/dhcp-bulk-updates-0150b764bb1b165f.yaml b/releasenotes/notes/dhcp-bulk-updates-0150b764bb1b165f.yaml new file mode 100644 index 00000000000..98a4149aac9 --- /dev/null +++ b/releasenotes/notes/dhcp-bulk-updates-0150b764bb1b165f.yaml @@ -0,0 +1,14 @@ +--- +features: + - By default the dnsmasq agent is restarted for every + port created, deleted or updated. When there are + many port changes on the same network it can and will + take a very long time for all of the port changes to + be realised. This enhancement adds in a new + configuration variable that will enable bulk updates. + This means that the dnsmasq will only be restarted once + in a period and not N times. + The new option 'bulk_reload_interval' indicates how + often the agent should be reloaded. The default value + is 0 which means that the original functionality is the + default.