From: Ryan Moats Date: Mon, 2 Nov 2015 19:30:26 +0000 (-0600) Subject: Optimize router delete execution X-Git-Url: https://review.fuel-infra.org/gitweb?a=commitdiff_plain;h=526dac467ba869284dd096c7a9e8251fb1bd4e85;p=openstack-build%2Fneutron-build.git Optimize router delete execution Optimize the execution of router delete in the L3 agent by not performing operations in the router namespace that will be removed as the last step of the workflow. Comparing the slopes of the least squares fit of delete execution time shows that this optimization decreases that slope by over half. Change-Id: Ic425ab1f8c3afe882c9deaa72a814ac0d2053f3b Signed-off-by: Ryan Moats Closes-Bug: 1512450 --- diff --git a/neutron/agent/l3/dvr_edge_ha_router.py b/neutron/agent/l3/dvr_edge_ha_router.py index 5e254d65d..ecd7a0e63 100644 --- a/neutron/agent/l3/dvr_edge_ha_router.py +++ b/neutron/agent/l3/dvr_edge_ha_router.py @@ -92,16 +92,11 @@ class DvrEdgeHaRouter(DvrEdgeRouter, HaRouter): self._create_snat_namespace() super(DvrEdgeHaRouter, self).initialize(process_monitor) - def process(self, agent): - super(DvrEdgeHaRouter, self).process(agent) + def process(self, agent, delete=False): + super(DvrEdgeHaRouter, self).process(agent, delete) if self.ha_port: self.enable_keepalived() - def delete(self, agent): - super(DvrEdgeHaRouter, self).delete(agent) - if self.snat_namespace: - self.snat_namespace.delete() - def get_router_cidrs(self, device): return RouterInfo.get_router_cidrs(self, device) diff --git a/neutron/agent/l3/dvr_edge_router.py b/neutron/agent/l3/dvr_edge_router.py index 72534d35c..d2424096d 100644 --- a/neutron/agent/l3/dvr_edge_router.py +++ b/neutron/agent/l3/dvr_edge_router.py @@ -186,3 +186,8 @@ class DvrEdgeRouter(dvr_local_router.DvrLocalRouter): ns_name = dvr_snat_ns.SnatNamespace.get_snat_ns_name(self.router['id']) super(DvrEdgeRouter, self).update_routing_table(operation, route, namespace=ns_name) + + def delete(self, agent): + super(DvrEdgeRouter, self).delete(agent) + if self.snat_namespace: + self.snat_namespace.delete() diff --git a/neutron/agent/l3/dvr_local_router.py b/neutron/agent/l3/dvr_local_router.py index f412f94bb..52bb49cca 100644 --- a/neutron/agent/l3/dvr_local_router.py +++ b/neutron/agent/l3/dvr_local_router.py @@ -414,11 +414,11 @@ class DvrLocalRouter(dvr_router_base.DvrRouterBase): def _handle_router_snat_rules(self, ex_gw_port, interface_name): pass - def process_external(self, agent): + def process_external(self, agent, delete=False): ex_gw_port = self.get_ex_gw_port() if ex_gw_port: self.create_dvr_fip_interfaces(ex_gw_port) - super(DvrLocalRouter, self).process_external(agent) + super(DvrLocalRouter, self).process_external(agent, delete) def create_dvr_fip_interfaces(self, ex_gw_port): floating_ips = self.get_floating_ips() @@ -455,10 +455,10 @@ class DvrLocalRouter(dvr_router_base.DvrRouterBase): # configured self.agent.process_router_add(self) - def process(self, agent): + def process(self, agent, delete=False): ex_gw_port = self.get_ex_gw_port() if ex_gw_port: self.fip_ns = agent.get_fip_ns(ex_gw_port['network_id']) self.fip_ns.scan_fip_ports(self) - super(DvrLocalRouter, self).process(agent) + super(DvrLocalRouter, self).process(agent, delete) diff --git a/neutron/agent/l3/dvr_router_base.py b/neutron/agent/l3/dvr_router_base.py index 704be6ce6..ec519ef93 100644 --- a/neutron/agent/l3/dvr_router_base.py +++ b/neutron/agent/l3/dvr_router_base.py @@ -26,8 +26,8 @@ class DvrRouterBase(router.RouterInfo): self.agent = agent self.host = host - def process(self, agent): - super(DvrRouterBase, self).process(agent) + def process(self, agent, delete=False): + super(DvrRouterBase, self).process(agent, delete) # NOTE: Keep a copy of the interfaces around for when they are removed self.snat_ports = self.get_snat_interfaces() diff --git a/neutron/agent/l3/ha_router.py b/neutron/agent/l3/ha_router.py index d3ef8a68f..e0e96f86e 100644 --- a/neutron/agent/l3/ha_router.py +++ b/neutron/agent/l3/ha_router.py @@ -385,8 +385,8 @@ class HaRouter(router.RouterInfo): self.ha_network_removed() self.disable_keepalived() - def process(self, agent): - super(HaRouter, self).process(agent) + def process(self, agent, delete=False): + super(HaRouter, self).process(agent, delete) if self.ha_port: self.enable_keepalived() diff --git a/neutron/agent/l3/router_info.py b/neutron/agent/l3/router_info.py index af3ae7c6e..e2c9907a8 100644 --- a/neutron/agent/l3/router_info.py +++ b/neutron/agent/l3/router_info.py @@ -261,7 +261,7 @@ class RouterInfo(object): self.router['gw_port'] = None self.router[l3_constants.INTERFACE_KEY] = [] self.router[l3_constants.FLOATINGIP_KEY] = [] - self.process(agent) + self.process(agent, delete=True) self.disable_radvd() self.router_namespace.delete() @@ -646,31 +646,35 @@ class RouterInfo(object): self.iptables_manager, interface_name) - def process_external(self, agent): + def process_external(self, agent, delete=False): fip_statuses = {} - try: - with self.iptables_manager.defer_apply(): - ex_gw_port = self.get_ex_gw_port() - self._process_external_gateway(ex_gw_port, agent.pd) - if not ex_gw_port: - return - - # Process SNAT/DNAT rules and addresses for floating IPs - self.process_snat_dnat_for_fip() - - # Once NAT rules for floating IPs are safely in place - # configure their addresses on the external gateway port - interface_name = self.get_external_device_interface_name( - ex_gw_port) - fip_statuses = self.configure_fip_addresses(interface_name) - - except (n_exc.FloatingIpSetupException, - n_exc.IpTablesApplyException): - # All floating IPs must be put in error state - LOG.exception(_LE("Failed to process floating IPs.")) - fip_statuses = self.put_fips_in_error_state() - finally: - self.update_fip_statuses(agent, fip_statuses) + if not delete: + try: + with self.iptables_manager.defer_apply(): + ex_gw_port = self.get_ex_gw_port() + self._process_external_gateway(ex_gw_port, agent.pd) + if not ex_gw_port: + return + + # Process SNAT/DNAT rules and addresses for floating IPs + self.process_snat_dnat_for_fip() + + # Once NAT rules for floating IPs are safely in place + # configure their addresses on the external gateway port + interface_name = self.get_external_device_interface_name( + ex_gw_port) + fip_statuses = self.configure_fip_addresses(interface_name) + + except (n_exc.FloatingIpSetupException, + n_exc.IpTablesApplyException): + # All floating IPs must be put in error state + LOG.exception(_LE("Failed to process floating IPs.")) + fip_statuses = self.put_fips_in_error_state() + finally: + self.update_fip_statuses(agent, fip_statuses) + else: + ex_gw_port = self.get_ex_gw_port() + self._process_external_gateway(ex_gw_port, agent.pd) def update_fip_statuses(self, agent, fip_statuses): # Identify floating IPs which were disabled @@ -689,18 +693,19 @@ class RouterInfo(object): agent.context, self.router_id, fip_statuses) @common_utils.exception_logger() - def process(self, agent): + def process(self, agent, delete=False): """Process updates to this router This method is the point where the agent requests that updates be applied to this router. :param agent: Passes the agent in order to send RPC messages. + :param delete: Indicates whether this update is from a delete operation """ LOG.debug("process router updates") self._process_internal_ports(agent.pd) agent.pd.sync_router(self.router['id']) - self.process_external(agent) + self.process_external(agent, delete) # Process static routes for router self.routes_updated() diff --git a/neutron/agent/metadata/driver.py b/neutron/agent/metadata/driver.py index 16002d2c2..f25c28c54 100644 --- a/neutron/agent/metadata/driver.py +++ b/neutron/agent/metadata/driver.py @@ -167,14 +167,6 @@ def after_router_added(resource, event, l3_agent, **kwargs): def before_router_removed(resource, event, l3_agent, **kwargs): router = kwargs['router'] proxy = l3_agent.metadata_driver - for c, r in proxy.metadata_filter_rules(proxy.metadata_port, - proxy.metadata_access_mark): - router.iptables_manager.ipv4['filter'].remove_rule(c, r) - for c, r in proxy.metadata_mangle_rules(proxy.metadata_access_mark): - router.iptables_manager.ipv4['mangle'].remove_rule(c, r) - for c, r in proxy.metadata_nat_rules(proxy.metadata_port): - router.iptables_manager.ipv4['nat'].remove_rule(c, r) - router.iptables_manager.apply() proxy.destroy_monitored_metadata_proxy(l3_agent.process_monitor, router.router['id'],