The order between the notification of ovs port deletion via OVSDB protocol and
the notification network id/port deletion via REST from quantum plugin
isn't deterministic.
So when ovs port is deleted, the corresponding network id may or may not
exist.

The code wrongly assumed the order, so resulted in the following exception.
When ovs port is deleted and the corresponding network id isn't find,
just ignore the exception.

> (19257) accepted ('127.0.0.1', 36841)
> 127.0.0.1 - - [19/Jun/2013 11:24:25] "DELETE 
> /v1.0/tunnels/networks/8179bb70-a63f-4c74-a82e-a21f3c275c9a/key HTTP/1.1" 200 
> 115 0.000383
> hub: uncaught exception: Traceback (most recent call last):
>   File "/opt/stack/ryu/ryu/lib/hub.py", line 50, in _launch
>     func(*args, **kwargs)
>   File "/opt/stack/ryu/ryu/base/app_manager.py", line 104, in _event_loop
>     handler(ev)
>   File "/opt/stack/ryu/ryu/app/quantum_adapter.py", line 368, in
> port_del_handler
>     self._port_handler(ev.dp.id, port.port_no, name, False)
>   File "/opt/stack/ryu/ryu/app/quantum_adapter.py", line 336, in _port_handler
>     ovs_switch.update_port(port_no, port_name, add)
>   File "/opt/stack/ryu/ryu/app/quantum_adapter.py", line 279, in update_port
>     self._update_vif_port(old_port, add=False)
>   File "/opt/stack/ryu/ryu/app/quantum_adapter.py", line 194, in
> _update_vif_port
>     self.network_api.remove_port(network_id, self.dpid, port.ofport)
>   File "/opt/stack/ryu/ryu/controller/network.py", line 368, in remove_port
>     self.networks.remove(network_id, dpid, port_no)
>   File "/opt/stack/ryu/ryu/controller/network.py", line 119, in remove
>     raise NetworkNotFound(network_id=network_id)
> NetworkNotFound: no such network id 8179bb70-a63f-4c74-a82e-a21f3c275c9a

Signed-off-by: Isaku Yamahata <yamah...@valinux.co.jp>
---
Changes v1 -> v2:
- typo
  self.log -> self.logger
---
 ryu/app/quantum_adapter.py |   29 ++++++++++++++++++++++-------
 1 file changed, 22 insertions(+), 7 deletions(-)

diff --git a/ryu/app/quantum_adapter.py b/ryu/app/quantum_adapter.py
index eca1360..c362e4d 100644
--- a/ryu/app/quantum_adapter.py
+++ b/ryu/app/quantum_adapter.py
@@ -16,6 +16,7 @@
 
 from oslo.config import cfg
 import logging
+import traceback
 
 from quantumclient import client as q_client
 from quantumclient.common import exceptions as q_exc
@@ -29,6 +30,7 @@ from ryu.controller import (conf_switch,
                             event,
                             handler,
                             network)
+from ryu import exception as ryu_exc
 from ryu.lib import dpid as dpid_lib
 from ryu.lib import mac as mac_lib
 from ryu.lib import quantum_ifaces
@@ -182,6 +184,11 @@ class OVSSwitch(object):
                                          self.dpid, port.ofport)
 
     def _update_vif_port(self, port, add=True):
+        # When ovs port is updated, the corresponding network id may or
+        # may not exist because the order between the notification of
+        # ovs port deletion via OVSDB protocol and the notification
+        # network id/port deletion via REST from quantum plugin
+        # isn't deterministic.
         self.logger.debug("_update_vif_port: %s %s", port, add)
         iface_id = port.ext_ids.get('iface-id')
         if iface_id is None:
@@ -193,7 +200,11 @@ class OVSSwitch(object):
             return
 
         if not add:
-            self.network_api.remove_port(network_id, self.dpid, port.ofport)
+            try:
+                self.network_api.remove_port(network_id,
+                                             self.dpid, port.ofport)
+            except (network.NetworkNotFound, ryu_exc.PortNotFound) as e:
+                self.logger.debug('remove_port %s', traceback.format_exc())
             ports = self.ifaces.get_key(iface_id, QuantumIfaces.KEY_PORTS)
             other_ovs_ports = None
             for p in ports:
@@ -225,12 +236,16 @@ class OVSSwitch(object):
             return
 
         # update {network, port, mac}
-        self.network_api.update_network(network_id)
-        self.network_api.update_port(network_id, self.dpid, port.ofport)
-        mac = port.ext_ids.get('attached-mac')
-        if mac:
-            self.network_api.update_mac(network_id, self.dpid, port.ofport,
-                                        mac_lib.haddr_to_bin(mac))
+        try:
+            self.network_api.update_network(network_id)
+            self.network_api.update_port(network_id, self.dpid, port.ofport)
+            mac = port.ext_ids.get('attached-mac')
+            if mac:
+                self.network_api.update_mac(network_id, self.dpid, port.ofport,
+                                            mac_lib.haddr_to_bin(mac))
+        except (network.NetworkNotFound, ryu_exc.PortNotFound) as e:
+            self.logger.debug('update network/port/mac %s',
+                              traceback.format_exc())
 
     def update_port(self, port_no, port_name, add):
         self.logger.debug('update_port port_no %d %s %s', port_no, port_name,
-- 
1.7.10.4


------------------------------------------------------------------------------
See everything from the browser to the database with AppDynamics
Get end-to-end visibility with application monitoring from AppDynamics
Isolate bottlenecks and diagnose root cause in seconds.
Start your free trial of AppDynamics Pro today!
http://pubads.g.doubleclick.net/gampad/clk?id=48808831&iu=/4140/ostg.clktrk
_______________________________________________
Ryu-devel mailing list
Ryu-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ryu-devel

Reply via email to