Ensure dnsmasq is down before enabling it in restart method

Dnsmasq driver used by dhcp agent has restart() method which is
calling disable() and then enable() dnsmasq process again.
What can be observed in functional tests from time to time it may
happen that start dnsmasq process will be called before old process
is really down. That leads to error that IP address to which
dnsmasq wants to bind is already in use and it fails to start.

This patch adds possibility to call disable() method with block flag
set to True. In such case driver will ensure in disable() method that
process is really not active.
This blocking disable() is used in restart() method now.

Change-Id: I419a451633badbc3d32edcee1945fca3e3d9f6be
Closes-Bug: #1811126
This commit is contained in:
Slawek Kaplonski 2019-02-01 11:04:56 +01:00
parent f3810d0da3
commit d471a85931
2 changed files with 10 additions and 7 deletions

View File

@ -140,12 +140,12 @@ class DhcpBase(object):
"""Enables DHCP for this network."""
@abc.abstractmethod
def disable(self, retain_port=False):
def disable(self, retain_port=False, block=False):
"""Disable dhcp for this network."""
def restart(self):
"""Restart the dhcp service for the network."""
self.disable(retain_port=True)
self.disable(retain_port=True, block=True)
self.enable()
@abc.abstractproperty
@ -233,10 +233,13 @@ class DhcpLocalProcess(DhcpBase):
pid_file=self.get_conf_file_name('pid'),
run_as_root=True)
def disable(self, retain_port=False):
def disable(self, retain_port=False, block=False):
"""Disable DHCP for this network by killing the local process."""
self.process_monitor.unregister(self.network.id, DNSMASQ_SERVICE_NAME)
self._get_process_manager().disable()
pm = self._get_process_manager()
pm.disable()
if block:
common_utils.wait_until_true(lambda: not pm.active)
if not retain_port:
self._destroy_namespace_and_port()
self._remove_config_files()

View File

@ -1094,8 +1094,8 @@ class TestDhcpBase(TestBase):
def enable(self):
self.called.append('enable')
def disable(self, retain_port=False):
self.called.append('disable %s' % retain_port)
def disable(self, retain_port=False, block=False):
self.called.append('disable %s %s' % (retain_port, block))
def reload_allocations(self):
pass
@ -1106,7 +1106,7 @@ class TestDhcpBase(TestBase):
c = SubClass()
c.restart()
self.assertEqual(c.called, ['disable True', 'enable'])
self.assertEqual(c.called, ['disable True True', 'enable'])
class TestDhcpLocalProcess(TestBase):