From: Ben Pfaff Date: Thu, 27 Feb 2014 19:06:30 +0000 (-0800) Subject: rconn: Discover errors in rconn_run() even if rconn_recv() is never called. X-Git-Tag: sliver-openvswitch-2.2.90-1~9^2~20 X-Git-Url: http://git.onelab.eu/?a=commitdiff_plain;h=accaecc419cc57d;p=sliver-openvswitch.git rconn: Discover errors in rconn_run() even if rconn_recv() is never called. rconn_recv() calls vconn_recv(), which will report a connection error and cause rconn_recv() to disconnect the rconn. Most rconn users regularly call rconn_recv(), so that disconnection happens promptly. However, the lswitch code only calls rconn_recv() after the connection negotiates an OpenFlow version, so a connection that failed before negotiation would never be detected as failed. This commit fixes the problem by making rconn_run() also detect and handle connection errors. The lswitch code is only used by the test-controller program, so this is not an important bug fix. Reported-by: Vasu Dasari Signed-off-by: Ben Pfaff --- diff --git a/lib/rconn.c b/lib/rconn.c index d339365b2..72688ba8d 100644 --- a/lib/rconn.c +++ b/lib/rconn.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013 Nicira, Inc. + * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014 Nicira, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -592,7 +592,15 @@ rconn_run(struct rconn *rc) ovs_mutex_lock(&rc->mutex); if (rc->vconn) { + int error; + vconn_run(rc->vconn); + + error = vconn_get_status(rc->vconn); + if (error) { + report_error(rc, error); + disconnect(rc, error); + } } for (i = 0; i < rc->n_monitors; ) { struct ofpbuf *msg; diff --git a/lib/vconn.c b/lib/vconn.c index f0549d5da..c1485f037 100644 --- a/lib/vconn.c +++ b/lib/vconn.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013 Nicira, Inc. + * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014 Nicira, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -293,6 +293,15 @@ vconn_run_wait(struct vconn *vconn) } } +/* Returns 0 if 'vconn' is healthy (connecting or connected), a positive errno + * value if the connection died abnormally (connection failed or aborted), or + * EOF if the connection was closed in a normal way. */ +int +vconn_get_status(const struct vconn *vconn) +{ + return vconn->error; +} + int vconn_open_block(const char *name, uint32_t allowed_versions, uint8_t dscp, struct vconn **vconnp) diff --git a/lib/vconn.h b/lib/vconn.h index 86785818e..f6ba95531 100644 --- a/lib/vconn.h +++ b/lib/vconn.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013 Nicira, Inc. + * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014 Nicira, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -57,6 +57,8 @@ int vconn_transact_multiple_noreply(struct vconn *, struct list *requests, void vconn_run(struct vconn *); void vconn_run_wait(struct vconn *); +int vconn_get_status(const struct vconn *); + int vconn_open_block(const char *name, uint32_t allowed_versions, uint8_t dscp, struct vconn **); int vconn_connect_block(struct vconn *);