[ovs-dev] [PATCH v2] ovsdb-idl: improve error handling when schema is not available

Lance Richardson lrichard at redhat.com
Wed Feb 24 15:48:34 UTC 2016


A common error scenario with OVN is to attempt to use ovn-nbctl when
the OVN databases have not been created in ovsdb-server:
   1. ovn-nbctl sends a "get_schema" request for the OVN db to ovsdb-server.
   2. ovsdb-server fails to find requested db, sends error response
      to ovn-nbctl.
   3. ovn-nbctl receives the error response in ovsdb_idl_run(), but
      takes no specific action.
   4. ovn-nbctl hangs forever in IDL_S_SCHEMA_REQUESTED state (assuming
      a timeout wasn't requested on the command line).

This commit adds a new IDL state, IDL_S_NO_SCHEMA, which is entered
when a negative response to a schema request is received. When in
this state, ovsdb_idl_is_alive() now returns 'false', allowing clients
(currently ovn-nbctl, ovn-sbctl, vtep-ctl, and ovs-vsctl) to detect this
condition and exit with an appropriate error message.

Signed-off-by: Lance Richardson <lrichard at redhat.com>
---
 v2: changed ovsdb_idl_get_last_error() to better preserve the original
     semantics (per comments from Ben Pfaff).

 lib/ovsdb-idl.c | 29 +++++++++++++++++++++++------
 1 file changed, 23 insertions(+), 6 deletions(-)

diff --git a/lib/ovsdb-idl.c b/lib/ovsdb-idl.c
index 4cb1c81..2a109a9 100644
--- a/lib/ovsdb-idl.c
+++ b/lib/ovsdb-idl.c
@@ -80,7 +80,8 @@ enum ovsdb_idl_state {
     IDL_S_MONITOR_REQUESTED,
     IDL_S_MONITORING,
     IDL_S_MONITOR2_REQUESTED,
-    IDL_S_MONITORING2
+    IDL_S_MONITORING2,
+    IDL_S_NO_SCHEMA
 };
 
 struct ovsdb_idl {
@@ -417,6 +418,7 @@ ovsdb_idl_run(struct ovsdb_idl *idl)
 
             case IDL_S_MONITORING:
             case IDL_S_MONITORING2:
+            case IDL_S_NO_SCHEMA:
             default:
                 OVS_NOT_REACHED();
             }
@@ -461,6 +463,7 @@ ovsdb_idl_run(struct ovsdb_idl *idl)
                 idl->request_id = NULL;
                 VLOG_ERR("%s: requested schema not found",
                          jsonrpc_session_get_name(idl->session));
+                idl->state = IDL_S_NO_SCHEMA;
         } else if ((msg->type == JSONRPC_ERROR
                     || msg->type == JSONRPC_REPLY)
                    && ovsdb_idl_txn_process_reply(idl, msg)) {
@@ -550,20 +553,34 @@ ovsdb_idl_verify_write_only(struct ovsdb_idl *idl)
     idl->verify_write_only = true;
 }
 
-/* Returns true if 'idl' is currently connected or trying to connect. */
+/* Returns true if 'idl' is currently connected or trying to connect
+ * and a negative response to a schema request has not been received */
 bool
 ovsdb_idl_is_alive(const struct ovsdb_idl *idl)
 {
-    return jsonrpc_session_is_alive(idl->session);
+    return jsonrpc_session_is_alive(idl->session) &&
+           idl->state != IDL_S_NO_SCHEMA;
 }
 
 /* Returns the last error reported on a connection by 'idl'.  The return value
- * is 0 only if no connection made by 'idl' has ever encountered an error.  See
- * jsonrpc_get_status() for return value interpretation. */
+ * is 0 only if no connection made by 'idl' has ever encountered an error and
+ * a negative response to a schema request has never been received. See
+ * jsonrpc_get_status() for jsonrpc_session_get_last_error() return value
+ * interpretation. */
 int
 ovsdb_idl_get_last_error(const struct ovsdb_idl *idl)
 {
-    return jsonrpc_session_get_last_error(idl->session);
+    int err;
+
+    err = jsonrpc_session_get_last_error(idl->session);
+
+    if (err) {
+        return err;
+    } else if (idl->state == IDL_S_NO_SCHEMA) {
+        return ENOENT;
+    } else {
+        return 0;
+    }
 }
 
 static unsigned char *
-- 
2.5.0




More information about the dev mailing list