[ovs-dev] [PATCH] rconn: Discover errors in rconn_run() even if rconn_recv() is never called.

Ben Pfaff blp at nicira.com
Thu Feb 27 19:07:07 UTC 2014


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 <vdasari at gmail.com>
Signed-off-by: Ben Pfaff <blp at nicira.com>
---
 lib/rconn.c |   10 +++++++++-
 lib/vconn.c |   11 ++++++++++-
 lib/vconn.h |    4 +++-
 3 files changed, 22 insertions(+), 3 deletions(-)

diff --git a/lib/rconn.c b/lib/rconn.c
index d339365..72688ba 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 f0549d5..c1485f0 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 8678581..f6ba955 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 *);
-- 
1.7.10.4




More information about the dev mailing list