From 544597c6ef9fb297693dbeb0f2d7dc22f3a1b25d Mon Sep 17 00:00:00 2001 From: Ihar Hrachyshka Date: Thu, 12 Apr 2018 20:30:20 +0000 Subject: [PATCH] ovs: survive errors from check_ovs_status Instead of allowing an error to bubble up and exit from rpc_loop, catch it and assume the switch is dead which will make the agent to wait until the switch is back without failing the service. Change-Id: Ic3095dd42b386f56b1f75ebb6a125606f295551b Closes-Bug: #1731494 --- .../ml2/drivers/openvswitch/agent/ovs_neutron_agent.py | 8 ++++++-- .../drivers/openvswitch/agent/test_ovs_neutron_agent.py | 8 ++++++++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/neutron/plugins/ml2/drivers/openvswitch/agent/ovs_neutron_agent.py b/neutron/plugins/ml2/drivers/openvswitch/agent/ovs_neutron_agent.py index 945c89b3ba6..2773f01ae8b 100644 --- a/neutron/plugins/ml2/drivers/openvswitch/agent/ovs_neutron_agent.py +++ b/neutron/plugins/ml2/drivers/openvswitch/agent/ovs_neutron_agent.py @@ -1778,8 +1778,12 @@ class OVSNeutronAgent(l2population_rpc.L2populationRpcCallBackTunnelMixin, port_info.get('updated')) def check_ovs_status(self): - # Check for the canary flow - status = self.int_br.check_canary_table() + try: + # Check for the canary flow + status = self.int_br.check_canary_table() + except Exception: + LOG.exception("Failure while checking for the canary flow") + status = constants.OVS_DEAD if status == constants.OVS_RESTARTED: LOG.warning("OVS is restarted. OVSNeutronAgent will reset " "bridges and recover ports.") 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 177fee05d17..94fba6f67a5 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 @@ -3514,6 +3514,14 @@ class TestOvsDvrNeutronAgent(object): pass self.assertTrue(all([x.called for x in reset_mocks])) + def test_rpc_loop_survives_error_in_check_canary_table(self): + with mock.patch.object(self.agent.int_br, + 'check_canary_table', + side_effect=TypeError('borked')),\ + mock.patch.object(self.agent, '_check_and_handle_signal', + side_effect=[True, False]): + self.agent.rpc_loop(polling_manager=mock.Mock()) + def _test_scan_ports_failure(self, scan_method_name): with mock.patch.object(self.agent, 'check_ovs_status',