[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