]> review.fuel-infra Code Review - openstack-build/neutron-build.git/commitdiff
Optimize router delete execution
authorRyan Moats <rmoats@us.ibm.com>
Mon, 2 Nov 2015 19:30:26 +0000 (13:30 -0600)
committerRyan Moats <rmoats@us.ibm.com>
Tue, 24 Nov 2015 05:50:02 +0000 (23:50 -0600)
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 <rmoats@us.ibm.com>
Closes-Bug: 1512450

neutron/agent/l3/dvr_edge_ha_router.py
neutron/agent/l3/dvr_edge_router.py
neutron/agent/l3/dvr_local_router.py
neutron/agent/l3/dvr_router_base.py
neutron/agent/l3/ha_router.py
neutron/agent/l3/router_info.py
neutron/agent/metadata/driver.py

index 5e254d65dd84788116fd9a03f8c780095d5aed34..ecd7a0e638fb40ad20dabaac11c01b29be14573c 100644 (file)
@@ -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)
 
index 72534d35ca237c5d8097a31da18b47256a4d2c57..d2424096d13ab92788ee21a3f51b953bcd1ad43e 100644 (file)
@@ -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()
index f412f94bb4c2e9cde6e48f9524b28172de898d28..52bb49cca01617fd7d49824a7b31fb222b4ec4a6 100644 (file)
@@ -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)
index 704be6ce6e0d16f1ce4ef4e8abdfa409943932c2..ec519ef93fb584207d9e484dc01d3d7a4cd71650 100644 (file)
@@ -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()
 
index d3ef8a68f3a9ebb6cbccb3703f236a78777c861b..e0e96f86e913421f6a3fde02cd41196cc0248676 100644 (file)
@@ -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()
index af3ae7c6e9bc416fa0e70aa55dbdf81030f5024d..e2c9907a84e0cd899b0059de97350df87d0a2a33 100644 (file)
@@ -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()
 
index 16002d2c2393f06648fd691c21a273f9b01a7102..f25c28c54420893e525522f51dd091c9176f12ab 100644 (file)
@@ -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'],