[ovs-dev] [PATCH 2/2] unixctl: New JSON RPC back-end.

Ethan Jackson ethan at nicira.com
Tue Feb 21 07:42:15 UTC 2012


Here's an incremental.

---
 lib/unixctl.c          |   76 +++++++++++++++++++++--------------------------
 lib/vlog.c             |    2 +-
 utilities/ovs-appctl.c |    3 +-
 3 files changed, 36 insertions(+), 45 deletions(-)

diff --git a/lib/unixctl.c b/lib/unixctl.c
index c68b059..054ce49 100644
--- a/lib/unixctl.c
+++ b/lib/unixctl.c
@@ -48,10 +48,8 @@ struct unixctl_conn {
     struct jsonrpc *rpc;
 
     /* Only one request can be in progress at a time.  While the request is
-     * being processed, 'request_id' is populated.  Once a reply is ready
-     * 'reply' is populated. Once the reply is sent, both are NULL. */
+     * being processed, 'request_id' is populated, otherwise it is null. */
     struct json *request_id;   /* ID of the currently active request. */
-    struct jsonrpc_msg *reply; /* Reply to the currently active request. */
 };
 
 /* Server for control connection. */
@@ -132,10 +130,10 @@ unixctl_command_reply__(struct unixctl_conn *conn,
                         bool success, const char *body)
 {
     struct json *body_json;
+    struct jsonrpc_msg *reply;
 
     COVERAGE_INC(unixctl_replied);
     assert(conn->request_id);
-    assert(!conn->reply);
 
     if (!body) {
         body = "";
@@ -148,14 +146,22 @@ unixctl_command_reply__(struct unixctl_conn *conn,
     }
 
     if (success) {
-        conn->reply = jsonrpc_create_reply(body_json, conn->request_id);
+        reply = jsonrpc_create_reply(body_json, conn->request_id);
     } else {
-        conn->reply = jsonrpc_create_error(body_json, conn->request_id);
+        reply = jsonrpc_create_error(body_json, conn->request_id);
     }
+
+    /* If jsonrpc_send() returns an error, the run loop will take care of the
+     * problem eventually. */
+    jsonrpc_send(conn->rpc, reply);
+    json_destroy(conn->request_id);
+    conn->request_id = NULL;
 }
 
 /* Replies to the active unixctl connection 'conn'.  'result' is sent to the
- * client indicating the command was processed successfully. */
+ * client indicating the command was processed successfully.  Only one call to
+ * unixctl_command_reply() or unixctl_command_reply_error() may be made per
+ * request. */
 void
 unixctl_command_reply(struct unixctl_conn *conn, const char *result)
 {
@@ -163,7 +169,9 @@ unixctl_command_reply(struct unixctl_conn *conn, const char *result)
 }
 
 /* Replies to the active unixctl connection 'conn'. 'error' is sent to the
- * client indicating an error occured processing the command. */
+ * client indicating an error occured processing the command.  Only one call to
+ * unixctl_command_reply() or unixctl_command_reply_error() may be made per
+ * request. */
 void
 unixctl_command_reply_error(struct unixctl_conn *conn, const char *error)
 {
@@ -285,47 +293,35 @@ process_command(struct unixctl_conn *conn, struct jsonrpc_msg *request)
 static int
 run_connection(struct unixctl_conn *conn)
 {
-    bool event;
-    int error;
+    int error, i;
 
     jsonrpc_run(conn->rpc);
     error = jsonrpc_get_status(conn->rpc);
-    if (error) {
+    if (error || jsonrpc_get_backlog(conn->rpc)) {
         return error;
     }
 
-    do {
-        event = false;
-
-        if (conn->reply) {
-            event = true;
-
-            error = jsonrpc_send(conn->rpc, conn->reply);
-            conn->reply = NULL;
+    for (i = 0; i < 10; i++) {
+        struct jsonrpc_msg *msg;
 
-            json_destroy(conn->request_id);
-            conn->request_id = NULL;
+        if (error || conn->request_id) {
+            break;
         }
 
-        if (!error && !conn->request_id) {
-            struct jsonrpc_msg *msg;
-
-            error = jsonrpc_recv(conn->rpc, &msg);
-            if (msg) {
-                event = true;
-
-                if (msg->type == JSONRPC_REQUEST) {
-                    process_command(conn, msg);
-                } else {
-                    VLOG_WARN_RL(&rl, "%s: received unexpected %s message",
-                                 jsonrpc_get_name(conn->rpc),
-                                 jsonrpc_msg_type_to_string(msg->type));
-                    error = EINVAL;
-                }
-                jsonrpc_msg_destroy(msg);
+        jsonrpc_recv(conn->rpc, &msg);
+        if (msg) {
+            if (msg->type == JSONRPC_REQUEST) {
+                process_command(conn, msg);
+            } else {
+                VLOG_WARN_RL(&rl, "%s: received unexpected %s message",
+                             jsonrpc_get_name(conn->rpc),
+                             jsonrpc_msg_type_to_string(msg->type));
+                error = EINVAL;
             }
+            jsonrpc_msg_destroy(msg);
         }
-    } while (!error && event);
+        error = error ? error : jsonrpc_get_status(conn->rpc);
+    }
 
     return error;
 }
@@ -336,7 +332,6 @@ kill_connection(struct unixctl_conn *conn)
     list_remove(&conn->node);
     jsonrpc_close(conn->rpc);
     json_destroy(conn->request_id);
-    jsonrpc_msg_destroy(conn->reply);
     free(conn);
 }
 
@@ -391,9 +386,6 @@ unixctl_server_wait(struct unixctl_server *server)
         if (!jsonrpc_get_backlog(conn->rpc)) {
             jsonrpc_recv_wait(conn->rpc);
         }
-        if (conn->reply) {
-            poll_immediate_wake();
-        }
     }
 }
 
diff --git a/lib/vlog.c b/lib/vlog.c
index 87ef4eb..4c97ef4 100644
--- a/lib/vlog.c
+++ b/lib/vlog.c
@@ -452,7 +452,7 @@ vlog_unixctl_list(struct unixctl_conn *conn, int argc OVS_UNUSED,
                   const char *argv[] OVS_UNUSED, void *aux OVS_UNUSED)
 {
     char *msg = vlog_get_levels();
-    unixctl_command_reply(conn,  msg);
+    unixctl_command_reply(conn, msg);
     free(msg);
 }
 
diff --git a/utilities/ovs-appctl.c b/utilities/ovs-appctl.c
index 19acb94..241b6c0 100644
--- a/utilities/ovs-appctl.c
+++ b/utilities/ovs-appctl.c
@@ -69,8 +69,7 @@ main(int argc, char *argv[])
     } else if (cmd_result) {
         fputs(cmd_result, stdout);
     } else {
-        ovs_error(0, "%s: server did not return a result or an error", target);
-        exit(2);
+        NOT_REACHED();
     }
 
     jsonrpc_close(client);
-- 
1.7.9.1




More information about the dev mailing list