diff --git a/etc/neutron/plugins/openvswitch/ovs_neutron_plugin.ini b/etc/neutron/plugins/openvswitch/ovs_neutron_plugin.ini index bb3caf3a58..2632a25aaf 100644 --- a/etc/neutron/plugins/openvswitch/ovs_neutron_plugin.ini +++ b/etc/neutron/plugins/openvswitch/ovs_neutron_plugin.ini @@ -90,6 +90,10 @@ # Minimize polling by monitoring ovsdb for interface changes # minimize_polling = False +# When minimize_polling = True, the number of seconds to wait before +# respawning the ovsdb monitor after losing communication with it +# ovsdb_monitor_respawn_interval = 30 + # (ListOpt) The types of tenant network tunnels supported by the agent. # Setting this will enable tunneling support in the agent. This can be set to # either 'gre' or 'vxlan'. If this is unset, it will default to [] and diff --git a/neutron/agent/linux/polling.py b/neutron/agent/linux/polling.py index 64ea2cebfd..8cce60be4d 100644 --- a/neutron/agent/linux/polling.py +++ b/neutron/agent/linux/polling.py @@ -19,12 +19,18 @@ import contextlib import eventlet from neutron.agent.linux import ovsdb_monitor +from neutron.plugins.openvswitch.common import constants @contextlib.contextmanager -def get_polling_manager(minimize_polling=False, root_helper=None): +def get_polling_manager(minimize_polling=False, + root_helper=None, + ovsdb_monitor_respawn_interval=( + constants.DEFAULT_OVSDBMON_RESPAWN)): if minimize_polling: - pm = InterfacePollingMinimizer(root_helper=root_helper) + pm = InterfacePollingMinimizer( + root_helper=root_helper, + ovsdb_monitor_respawn_interval=ovsdb_monitor_respawn_interval) pm.start() else: pm = AlwaysPoll() @@ -86,10 +92,14 @@ class AlwaysPoll(BasePollingManager): class InterfacePollingMinimizer(BasePollingManager): """Monitors ovsdb to determine when polling is required.""" - def __init__(self, root_helper=None): + def __init__(self, root_helper=None, + ovsdb_monitor_respawn_interval=( + constants.DEFAULT_OVSDBMON_RESPAWN)): + super(InterfacePollingMinimizer, self).__init__() self._monitor = ovsdb_monitor.SimpleInterfaceMonitor( - root_helper=root_helper) + root_helper=root_helper, + respawn_interval=ovsdb_monitor_respawn_interval) def start(self): self._monitor.start() diff --git a/neutron/plugins/openvswitch/agent/ovs_neutron_agent.py b/neutron/plugins/openvswitch/agent/ovs_neutron_agent.py index b093d0a2d3..ef7cda71ed 100644 --- a/neutron/plugins/openvswitch/agent/ovs_neutron_agent.py +++ b/neutron/plugins/openvswitch/agent/ovs_neutron_agent.py @@ -158,7 +158,9 @@ class OVSNeutronAgent(sg_rpc.SecurityGroupAgentRpcCallbackMixin, bridge_mappings, root_helper, polling_interval, tunnel_types=None, veth_mtu=None, l2_population=False, - minimize_polling=False): + minimize_polling=False, + ovsdb_monitor_respawn_interval=( + constants.DEFAULT_OVSDBMON_RESPAWN)): '''Constructor. :param integ_br: name of the integration bridge. @@ -173,6 +175,9 @@ class OVSNeutronAgent(sg_rpc.SecurityGroupAgentRpcCallbackMixin, :param veth_mtu: MTU size for veth interfaces. :param minimize_polling: Optional, whether to minimize polling by monitoring ovsdb for interface changes. + :param ovsdb_monitor_respawn_interval: Optional, when using polling + minimization, the number of seconds to wait before respawning + the ovsdb monitor. ''' self.veth_mtu = veth_mtu self.root_helper = root_helper @@ -204,6 +209,7 @@ class OVSNeutronAgent(sg_rpc.SecurityGroupAgentRpcCallbackMixin, self.polling_interval = polling_interval self.minimize_polling = minimize_polling + self.ovsdb_monitor_respawn_interval = ovsdb_monitor_respawn_interval if tunnel_types: self.enable_tunneling = True @@ -1115,8 +1121,11 @@ class OVSNeutronAgent(sg_rpc.SecurityGroupAgentRpcCallbackMixin, 'elapsed': elapsed}) def daemon_loop(self): - with polling.get_polling_manager(self.minimize_polling, - self.root_helper) as pm: + with polling.get_polling_manager( + self.minimize_polling, + self.root_helper, + self.ovsdb_monitor_respawn_interval) as pm: + self.rpc_loop(polling_manager=pm) diff --git a/neutron/plugins/openvswitch/common/config.py b/neutron/plugins/openvswitch/common/config.py index abd2a56fa4..4b473943bb 100644 --- a/neutron/plugins/openvswitch/common/config.py +++ b/neutron/plugins/openvswitch/common/config.py @@ -66,6 +66,10 @@ agent_opts = [ default=False, help=_("Minimize polling by monitoring ovsdb for interface " "changes.")), + cfg.IntOpt('ovsdb_monitor_respawn_interval', + default=constants.DEFAULT_OVSDBMON_RESPAWN, + help=_("The number of seconds to wait before respawning the " + "ovsdb monitor after losing communication with it")), cfg.ListOpt('tunnel_types', default=DEFAULT_TUNNEL_TYPES, help=_("Network types supported by the agent " "(gre and/or vxlan)")), diff --git a/neutron/plugins/openvswitch/common/constants.py b/neutron/plugins/openvswitch/common/constants.py index 01488b447e..9d1abd05fa 100644 --- a/neutron/plugins/openvswitch/common/constants.py +++ b/neutron/plugins/openvswitch/common/constants.py @@ -48,3 +48,6 @@ UCAST_TO_TUN = 20 FLOOD_TO_TUN = 21 # Map tunnel types to tables number TUN_TABLE = {TYPE_GRE: GRE_TUN_TO_LV, TYPE_VXLAN: VXLAN_TUN_TO_LV} + +# The default respawn interval for the ovsdb monitor +DEFAULT_OVSDBMON_RESPAWN = 30 diff --git a/neutron/tests/functional/agent/linux/test_ovsdb_monitor.py b/neutron/tests/functional/agent/linux/test_ovsdb_monitor.py index 51284c8ea7..602204bb50 100644 --- a/neutron/tests/functional/agent/linux/test_ovsdb_monitor.py +++ b/neutron/tests/functional/agent/linux/test_ovsdb_monitor.py @@ -120,8 +120,8 @@ class TestOvsdbMonitor(BaseMonitorTest): old_pid = self.monitor._process.pid output1 = self.collect_initial_output() pid = self.monitor._get_pid_to_kill() - self.monitor._reset_queues() self.monitor._kill_process(pid) + self.monitor._reset_queues() while (self.monitor._process.pid == old_pid): eventlet.sleep(0.01) output2 = self.collect_initial_output() diff --git a/neutron/tests/unit/openvswitch/test_ovs_neutron_agent.py b/neutron/tests/unit/openvswitch/test_ovs_neutron_agent.py index 874ef2011d..1ffa79e012 100644 --- a/neutron/tests/unit/openvswitch/test_ovs_neutron_agent.py +++ b/neutron/tests/unit/openvswitch/test_ovs_neutron_agent.py @@ -588,7 +588,8 @@ class TestOvsNeutronAgent(base.BaseTestCase): 'neutron.agent.linux.polling.get_polling_manager') as mock_get_pm: with mock.patch.object(self.agent, 'rpc_loop') as mock_loop: self.agent.daemon_loop() - mock_get_pm.assert_called_with(False, 'sudo') + mock_get_pm.assert_called_with(False, 'sudo', + constants.DEFAULT_OVSDBMON_RESPAWN) mock_loop.called_once() def test_setup_tunnel_port_error_negative(self):