quantum_adapter: race between ovs port deletion and plugin port deletion

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 <yamahata@valinux.co.jp>
Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
This commit is contained in:
Isaku Yamahata 2013-07-10 18:35:11 +09:00 committed by FUJITA Tomonori
parent 2f9b932d5d
commit 55c8f9e165

View File

@ -14,6 +14,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import traceback
from oslo.config import cfg
try:
@ -36,6 +37,7 @@ from ryu.controller import (conf_switch,
dpset,
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
@ -189,6 +191,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:
@ -200,7 +207,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:
@ -232,12 +243,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,