Hi Ryu developers,
Could you please review the patch? At Fri, 29 Mar 2019 13:47:37 +0900, Atzm Watanabe wrote: > > When datapath reconnects/disconnects, waiting requests on old > datapath should be canceled. Otherwise, threads that sent > requests may fall into deadlock because replies possibly never > come. > > Signed-off-by: Atzm Watanabe <a...@iij.ad.jp> > --- > ryu/app/ofctl/service.py | 40 +++++++++++++++++++++++++++------------- > 1 file changed, 27 insertions(+), 13 deletions(-) > > diff --git a/ryu/app/ofctl/service.py b/ryu/app/ofctl/service.py > index 08ee75b..eed5177 100644 > --- a/ryu/app/ofctl/service.py > +++ b/ryu/app/ofctl/service.py > @@ -64,6 +64,22 @@ class OfctlService(app_manager.RyuApp): > self.unobserve_event(ev_cls) > self.logger.debug('ofctl: stop observing %s', ev_cls) > > + def _cancel(self, info, barrier_xid, exception): > + xid = info.barriers.pop(barrier_xid) > + req = info.xids.pop(xid) > + msg = req.msg > + datapath = msg.datapath > + parser = datapath.ofproto_parser > + is_barrier = isinstance(msg, parser.OFPBarrierRequest) > + > + info.results.pop(xid) > + > + if not is_barrier and req.reply_cls is not None: > + self._unobserve_msg(req.reply_cls) > + > + self.logger.error('failed to send message <%s>', req.msg) > + self.reply_to_request(req, event.Reply(exception=exception)) > + > @staticmethod > def _is_error(msg): > return (ofp_event.ofp_msg_to_ev_cls(type(msg)) == > @@ -81,6 +97,9 @@ class OfctlService(app_manager.RyuApp): > self._switches[id] = new_info > if old_info: > old_info.datapath.close() > + for xid in list(old_info.barriers): > + self._cancel( > + old_info, xid, exception.InvalidDatapath(result=id)) > > @set_ev_cls(ofp_event.EventOFPStateChange, DEAD_DISPATCHER) > def _handle_dead(self, ev): > @@ -96,6 +115,8 @@ class OfctlService(app_manager.RyuApp): > if info.datapath is datapath: > self.logger.debug('forget info %s', info) > self._switches.pop(id) > + for xid in list(info.barriers): > + self._cancel(info, xid, exception.InvalidDatapath(result=id)) > > @set_ev_cls(event.GetDatapathRequest, MAIN_DISPATCHER) > def _handle_get_datapath(self, req): > @@ -131,15 +152,6 @@ class OfctlService(app_manager.RyuApp): > si.xids[xid] = req > si.barriers[barrier_xid] = xid > > - def _cancel(barrier_xid, exc): > - xid = si.barriers.pop(barrier_xid) > - si.results.pop(xid) > - si.xids.pop(xid) > - if not is_barrier and req.reply_cls is not None: > - self._unobserve_msg(req.reply_cls) > - self.logger.error('failed to send message <%s>', msg) > - self.reply_to_request(req, event.Reply(exception=exc)) > - > if is_barrier: > barrier = msg > datapath.set_xid(barrier) > @@ -152,12 +164,14 @@ class OfctlService(app_manager.RyuApp): > datapath.set_xid(barrier) > _store_xid(msg.xid, barrier.xid) > if not datapath.send_msg(msg): > - return _cancel(barrier.xid, > - exception.InvalidDatapath(result=datapath.id)) > + return self._cancel( > + si, barrier.xid, > + exception.InvalidDatapath(result=datapath.id)) > > if not datapath.send_msg(barrier): > - return _cancel(barrier.xid, > - exception.InvalidDatapath(result=datapath.id)) > + return self._cancel( > + si, barrier.xid, > + exception.InvalidDatapath(result=datapath.id)) > > @set_ev_cls(ofp_event.EventOFPBarrierReply, MAIN_DISPATCHER) > def _handle_barrier(self, ev): > -- > 2.7.4 > > > > _______________________________________________ > Ryu-devel mailing list > Ryu-devel@lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/ryu-devel > _______________________________________________ Ryu-devel mailing list Ryu-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/ryu-devel