From 01d0612a3a1b50cdadf633d5e5b9bad1cfe662fd Mon Sep 17 00:00:00 2001 From: LIU Yulong Date: Thu, 31 Oct 2019 19:17:36 +0800 Subject: [PATCH] Do not initialize snat-ns twice If the DVR+HA router has external gateway, the snat-namespace will be initialized twice during agent restart. And that ns initialization function will run many external resource processing actions which will definitely increase the starting time of L3 agent. This patch addresses this issue. Change-Id: I7719491275fa1ebfa7e881366e5cb066e3d4185c Closes-Bug: #1850779 (cherry picked from commit 7a9d6d26419defa148764166600bc4ac6b50c109) --- neutron/agent/l3/dvr_edge_ha_router.py | 4 ---- neutron/agent/l3/dvr_edge_router.py | 10 +++++++--- .../unit/agent/l3/test_dvr_local_router.py | 17 +++++++++++++++++ 3 files changed, 24 insertions(+), 7 deletions(-) diff --git a/neutron/agent/l3/dvr_edge_ha_router.py b/neutron/agent/l3/dvr_edge_ha_router.py index 553863e392b..b92f70b70f4 100644 --- a/neutron/agent/l3/dvr_edge_ha_router.py +++ b/neutron/agent/l3/dvr_edge_ha_router.py @@ -112,10 +112,6 @@ class DvrEdgeHaRouter(dvr_edge_router.DvrEdgeRouter, ha_router.HaRouter.external_gateway_updated(self, ex_gw_port, interface_name) - def initialize(self, process_monitor): - self._create_snat_namespace() - super(DvrEdgeHaRouter, self).initialize(process_monitor) - def _external_gateway_added(self, ex_gw_port, interface_name, ns_name, preserve_ips): self._plug_external_gateway(ex_gw_port, interface_name, ns_name) diff --git a/neutron/agent/l3/dvr_edge_router.py b/neutron/agent/l3/dvr_edge_router.py index 20b59dc33eb..b37768e5fc6 100644 --- a/neutron/agent/l3/dvr_edge_router.py +++ b/neutron/agent/l3/dvr_edge_router.py @@ -156,15 +156,19 @@ class DvrEdgeRouter(dvr_local_router.DvrLocalRouter): lib_constants.SNAT_INT_DEV_PREFIX, mtu=port.get('mtu')) + def initialize(self, process_monitor): + self._create_snat_namespace() + super(DvrEdgeRouter, self).initialize(process_monitor) + def _create_dvr_gateway(self, ex_gw_port, gw_interface_name): - snat_ns = self._create_snat_namespace() # connect snat_ports to br_int from SNAT namespace for port in self.get_snat_interfaces(): self._plug_snat_port(port) self._external_gateway_added(ex_gw_port, gw_interface_name, - snat_ns.name, preserve_ips=[]) + self.snat_namespace.name, + preserve_ips=[]) self.snat_iptables_manager = iptables_manager.IptablesManager( - namespace=snat_ns.name, + namespace=self.snat_namespace.name, use_ipv6=self.use_ipv6) self._initialize_address_scope_iptables(self.snat_iptables_manager) diff --git a/neutron/tests/unit/agent/l3/test_dvr_local_router.py b/neutron/tests/unit/agent/l3/test_dvr_local_router.py index 487b389eb60..adb58ffe05c 100644 --- a/neutron/tests/unit/agent/l3/test_dvr_local_router.py +++ b/neutron/tests/unit/agent/l3/test_dvr_local_router.py @@ -888,3 +888,20 @@ class TestDvrRouterOperations(base.BaseTestCase): ri1.remove_centralized_floatingip(fip_cidr) ri1._remove_vip.assert_called_once_with(fip_cidr) super_remove_centralized_floatingip.assert_called_once_with(fip_cidr) + + def test_initialize_dvr_ha_router_snat_ns_once(self): + agent = l3_agent.L3NATAgent(HOSTNAME, self.conf) + agent.conf.agent_mode = lib_constants.L3_AGENT_MODE_DVR_SNAT + router = l3_test_common.prepare_router_data( + num_internal_ports=2, enable_ha=True) + router['gw_port_host'] = HOSTNAME + router[lib_constants.HA_INTERFACE_KEY]['status'] = 'ACTIVE' + self.mock_driver.unplug.reset_mock() + self._set_ri_kwargs(agent, router['id'], router) + ri = dvr_edge_ha_rtr.DvrEdgeHaRouter(HOSTNAME, [], **self.ri_kwargs) + ri._create_snat_namespace = mock.Mock() + ri.update_initial_state = mock.Mock() + ri._plug_external_gateway = mock.Mock() + ri.initialize(mock.Mock()) + ri._create_dvr_gateway(mock.Mock(), mock.Mock()) + ri._create_snat_namespace.assert_called_once_with()