]> review.fuel-infra Code Review - openstack-build/neutron-build.git/commitdiff
Delete DHCP port without DHCP server on a net node
authorStephen Ma <stephen.ma@hp.com>
Sun, 27 Oct 2013 15:14:21 +0000 (08:14 -0700)
committerStephen Ma <stephen.ma@hp.com>
Tue, 15 Apr 2014 20:35:01 +0000 (20:35 +0000)
A DHCP-network was deleted from one host using neutron
dhcp-agent-network-remove and then added to another host
using neutron dhcp-agent-network-add command. While the
dhcp-agent-network-remove command was in progress, the
host crashed.  As a result, the removal of the DHCP-network
was partially done. The network was disassociated from
the agent in mysql. However, the agent never made the
release_dhcp_port RPC call to delete the port -- even
after the agent restarted. The end result is that there
are two DHCP ports for the same network. One of these
is found on the host that is no longer hosting the
dhcp-server.

This fix make the DHCP agent invoke the release_dhcp_port
RPC call on a stale network whose dnsmasq process is not
running (not active). Before this change, the RPC call is
made on a stale network only when the dnsmasq process is
running.

Closes-Bug: #1244860
Change-Id: Ie0bafdac698810b5455550c306c6a75ddf91d9bb

neutron/agent/linux/dhcp.py
neutron/tests/unit/test_linux_dhcp.py

index 3a26dc263b98f1c0fd3d8774150db6e3975445ee..42dd7c2958cabde2beae79ed678411f8d9b3a1f6 100644 (file)
@@ -173,15 +173,17 @@ class DhcpLocalProcess(DhcpBase):
         """Disable DHCP for this network by killing the local process."""
         pid = self.pid
 
-        if self.active:
-            cmd = ['kill', '-9', pid]
-            utils.execute(cmd, self.root_helper)
+        if pid:
+            if self.active:
+                cmd = ['kill', '-9', pid]
+                utils.execute(cmd, self.root_helper)
+            else:
+                LOG.debug(_('DHCP for %(net_id)s is stale, pid %(pid)d '
+                            'does not exist, performing cleanup'),
+                          {'net_id': self.network.id, 'pid': pid})
             if not retain_port:
-                self.device_manager.destroy(self.network, self.interface_name)
-
-        elif pid:
-            LOG.debug(_('DHCP for %(net_id)s pid %(pid)d is stale, ignoring '
-                        'command'), {'net_id': self.network.id, 'pid': pid})
+                self.device_manager.destroy(self.network,
+                                            self.interface_name)
         else:
             LOG.debug(_('No DHCP started for %s'), self.network.id)
 
index 1a6723d0441c7c23b79a8a8508065943403b2a6a..e3c060763a7248d5e456194231d95b0c4dcc4e08 100644 (file)
@@ -539,10 +539,14 @@ class TestDhcpLocalProcess(TestBase):
             mocks['pid'].__get__ = mock.Mock(return_value=5)
             mocks['interface_name'].__get__ = mock.Mock(return_value='tap0')
             with mock.patch.object(dhcp.LOG, 'debug') as log:
-                lp = LocalChild(self.conf, FakeDualNetwork())
+                network = FakeDualNetwork()
+                lp = LocalChild(self.conf, network)
+                lp.device_manager = mock.Mock()
                 lp.disable()
                 msg = log.call_args[0][0]
-                self.assertIn('stale', msg)
+                self.assertIn('does not exist', msg)
+                lp.device_manager.destroy.assert_called_once_with(
+                    network, 'tap0')
 
     def test_disable_unknown_network(self):
         attrs_to_mock = dict([(a, mock.DEFAULT) for a in