From 7b5ba5b35a2c793a21a1f2d336cc339e37eeee2f Mon Sep 17 00:00:00 2001 From: Hong Hui Xiao Date: Mon, 25 Jan 2016 06:20:49 -0500 Subject: [PATCH] Log warning message if get_subnet_for_dvr fails When subnet or gateway port has been deleted concurrently, rpc call to get_subnet_for_dvr will return an empty dict without any value. ovs_dvr_neutron_agent should be more gracefull and at least log warning message in that situation. Change the existing error log to warning, because it is not a server error, but a fact that should be noticed. Change-Id: Icb3a57553a8b0eb635c0d85e2c60e7ce519893f6 Closes-bug: #1454921 --- .../agent/ovs_dvr_neutron_agent.py | 13 ++++++++++-- .../agent/test_ovs_neutron_agent.py | 20 +++++++++++++++++++ 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/neutron/plugins/ml2/drivers/openvswitch/agent/ovs_dvr_neutron_agent.py b/neutron/plugins/ml2/drivers/openvswitch/agent/ovs_dvr_neutron_agent.py index a4158ff10a9..8cb65f6527b 100644 --- a/neutron/plugins/ml2/drivers/openvswitch/agent/ovs_dvr_neutron_agent.py +++ b/neutron/plugins/ml2/drivers/openvswitch/agent/ovs_dvr_neutron_agent.py @@ -377,8 +377,9 @@ class OVSDVRNeutronAgent(object): subnet_info = self.plugin_rpc.get_subnet_for_dvr( self.context, subnet_uuid, fixed_ips=fixed_ips) if not subnet_info: - LOG.error(_LE("DVR: Unable to retrieve subnet information " - "for subnet_id %s"), subnet_uuid) + LOG.warning(_LW("DVR: Unable to retrieve subnet information " + "for subnet_id %s. The subnet or the gateway " + "may have already been deleted"), subnet_uuid) return LOG.debug("get_subnet_for_dvr for subnet %(uuid)s " "returned with %(info)s", @@ -528,6 +529,14 @@ class OVSDVRNeutronAgent(object): # for this subnet subnet_info = self.plugin_rpc.get_subnet_for_dvr( self.context, subnet_uuid, fixed_ips=fixed_ips) + if not subnet_info: + LOG.warning(_LW("DVR: Unable to retrieve subnet information " + "for subnet_id %s. The subnet or the gateway " + "may have already been deleted"), subnet_uuid) + return + LOG.debug("get_subnet_for_dvr for subnet %(uuid)s " + "returned with %(info)s", + {"uuid": subnet_uuid, "info": subnet_info}) ldm = LocalDVRSubnetMapping(subnet_info, port.ofport) self.local_dvr_map[subnet_uuid] = ldm else: diff --git a/neutron/tests/unit/plugins/ml2/drivers/openvswitch/agent/test_ovs_neutron_agent.py b/neutron/tests/unit/plugins/ml2/drivers/openvswitch/agent/test_ovs_neutron_agent.py index f9aec4e685d..0869aba36fc 100644 --- a/neutron/tests/unit/plugins/ml2/drivers/openvswitch/agent/test_ovs_neutron_agent.py +++ b/neutron/tests/unit/plugins/ml2/drivers/openvswitch/agent/test_ovs_neutron_agent.py @@ -2350,6 +2350,26 @@ class TestOvsDvrNeutronAgent(object): ] self.assertEqual(expected_on_tun_br, tun_br.mock_calls) + def test_port_bound_for_dvr_with_csnat_ports_without_subnet(self): + self._setup_for_dvr_test() + int_br = mock.create_autospec(self.agent.int_br) + tun_br = mock.create_autospec(self.agent.tun_br) + + # get_subnet_for_dvr RPC returns {} on error + with mock.patch.object(self.agent.dvr_agent.plugin_rpc, + 'get_subnet_for_dvr', + return_value={}),\ + mock.patch.object(self.agent, 'int_br', new=int_br),\ + mock.patch.object(self.agent, 'tun_br', new=tun_br),\ + mock.patch.object(self.agent.dvr_agent, 'int_br', new=int_br),\ + mock.patch.object(self.agent.dvr_agent, 'tun_br', new=tun_br): + self.agent.port_bound( + self._port, self._net_uuid, 'vxlan', + None, None, self._fixed_ips, + n_const.DEVICE_OWNER_ROUTER_SNAT, + False) + self.assertFalse(int_br.install_dvr_to_src_mac.called) + def test_treat_devices_removed_for_dvr_interface(self): self._test_treat_devices_removed_for_dvr_interface() self._test_treat_devices_removed_for_dvr_interface(ip_version=6)