[ovs-dev] [PATCH 4/4] ovsdb-server: Correct malformed error replies to certain JSON-RPC requests.
Ben Pfaff
blp at nicira.com
Fri Mar 20 06:52:36 UTC 2015
I realized that this bug existed only a few weeks ago, but it has been
there since the earliest ovsdb-server code.
Signed-off-by: Ben Pfaff <blp at nicira.com>
---
ovsdb/jsonrpc-server.c | 26 ++++++++++++++------------
ovsdb/ovsdb-server.1.in | 29 ++++++++++++++++++++++++++++-
tests/ovsdb-server.at | 2 +-
3 files changed, 43 insertions(+), 14 deletions(-)
diff --git a/ovsdb/jsonrpc-server.c b/ovsdb/jsonrpc-server.c
index 2ba5ddd..95b4995 100644
--- a/ovsdb/jsonrpc-server.c
+++ b/ovsdb/jsonrpc-server.c
@@ -78,8 +78,9 @@ static void ovsdb_jsonrpc_trigger_complete_done(
struct ovsdb_jsonrpc_session *);
/* Monitors. */
-static struct json *ovsdb_jsonrpc_monitor_create(
- struct ovsdb_jsonrpc_session *, struct ovsdb *, struct json *params);
+static struct jsonrpc_msg *ovsdb_jsonrpc_monitor_create(
+ struct ovsdb_jsonrpc_session *, struct ovsdb *, struct json *params,
+ const struct json *request_id);
static struct jsonrpc_msg *ovsdb_jsonrpc_monitor_cancel(
struct ovsdb_jsonrpc_session *,
struct json_array *params,
@@ -674,7 +675,7 @@ ovsdb_jsonrpc_lookup_db(const struct ovsdb_jsonrpc_session *s,
return db;
error:
- *replyp = jsonrpc_create_reply(ovsdb_error_to_json(error), request->id);
+ *replyp = jsonrpc_create_error(ovsdb_error_to_json(error), request->id);
ovsdb_error_destroy(error);
return NULL;
}
@@ -752,7 +753,7 @@ ovsdb_jsonrpc_session_lock(struct ovsdb_jsonrpc_session *s,
return jsonrpc_create_reply(result, request->id);
error:
- reply = jsonrpc_create_reply(ovsdb_error_to_json(error), request->id);
+ reply = jsonrpc_create_error(ovsdb_error_to_json(error), request->id);
ovsdb_error_destroy(error);
return reply;
}
@@ -812,7 +813,7 @@ ovsdb_jsonrpc_session_unlock(struct ovsdb_jsonrpc_session *s,
return jsonrpc_create_reply(json_object_create(), request->id);
error:
- reply = jsonrpc_create_reply(ovsdb_error_to_json(error), request->id);
+ reply = jsonrpc_create_error(ovsdb_error_to_json(error), request->id);
ovsdb_error_destroy(error);
return reply;
}
@@ -842,9 +843,8 @@ ovsdb_jsonrpc_session_got_request(struct ovsdb_jsonrpc_session *s,
} else if (!strcmp(request->method, "monitor")) {
struct ovsdb *db = ovsdb_jsonrpc_lookup_db(s, request, &reply);
if (!reply) {
- reply = jsonrpc_create_reply(
- ovsdb_jsonrpc_monitor_create(s, db, request->params),
- request->id);
+ reply = ovsdb_jsonrpc_monitor_create(s, db, request->params,
+ request->id);
}
} else if (!strcmp(request->method, "monitor_cancel")) {
reply = ovsdb_jsonrpc_monitor_cancel(s, json_array(request->params),
@@ -1221,9 +1221,10 @@ ovsdb_jsonrpc_parse_monitor_request(struct ovsdb_jsonrpc_monitor_table *mt,
return NULL;
}
-static struct json *
+static struct jsonrpc_msg *
ovsdb_jsonrpc_monitor_create(struct ovsdb_jsonrpc_session *s, struct ovsdb *db,
- struct json *params)
+ struct json *params,
+ const struct json *request_id)
{
struct ovsdb_jsonrpc_monitor *m = NULL;
struct json *monitor_id, *monitor_requests;
@@ -1310,7 +1311,8 @@ ovsdb_jsonrpc_monitor_create(struct ovsdb_jsonrpc_session *s, struct ovsdb *db,
}
}
- return ovsdb_jsonrpc_monitor_get_initial(m);
+ return jsonrpc_create_reply(ovsdb_jsonrpc_monitor_get_initial(m),
+ request_id);
error:
if (m) {
@@ -1319,7 +1321,7 @@ error:
json = ovsdb_error_to_json(error);
ovsdb_error_destroy(error);
- return json;
+ return jsonrpc_create_error(json, request_id);
}
static struct jsonrpc_msg *
diff --git a/ovsdb/ovsdb-server.1.in b/ovsdb/ovsdb-server.1.in
index 0fafc49..e33d718 100644
--- a/ovsdb/ovsdb-server.1.in
+++ b/ovsdb/ovsdb-server.1.in
@@ -251,7 +251,34 @@ vSwitch 2.4 and later extend <condition> to allow the use of \fB<\fR,
of 0 or 1 integer'' and ``set of 0 or 1 real''. These conditions
evaluate to false when the column is empty, and otherwise as described
in RFC 7047 for integer and real types.
-
+.
+.SH "BUGS"
+.
+In Open vSwitch before version 2.4, when \fBovsdb\-server\fR sent
+JSON-RPC error responses to some requests, it incorrectly formulated
+them with the \fBresult\fR and \fBerror\fR swapped, so that the
+response appeared to indicate success (with a nonsensical result)
+rather than an error. The requests that suffered from this problem
+were:
+.
+.IP \fBtransact\fR
+.IQ \fBget_schema\fR
+Only if the request names a nonexistent database.
+.IP \fBmonitor\fR
+.IQ \fBlock\fR
+.IQ \fBunlock\fR
+In all error cases.
+.
+.PP
+Of these cases, the only error that a well-written application is
+likely to encounter in practice is \fBmonitor\fR of tables or columns
+that do not exist, in an situation where the application has been
+upgraded but the old database schema is still temporarily in use. To
+handle this situation gracefully, we recommend that clients should
+treat a \fBmonitor\fR response with a \fBresult\fR that contains an
+\fBerror\fR key-value pair as an error (assuming that the database
+being monitored does not contain a table named \fBerror\fR).
+.
.SH "SEE ALSO"
.
.BR ovsdb\-tool (1).
diff --git a/tests/ovsdb-server.at b/tests/ovsdb-server.at
index 35f0d11..c9ce4b1 100644
--- a/tests/ovsdb-server.at
+++ b/tests/ovsdb-server.at
@@ -163,7 +163,7 @@ ordinals
], [ignore], [test ! -e pid || kill `cat pid`])
AT_CHECK(
[[ovstest test-jsonrpc request unix:socket get_schema [\"nonexistent\"]]], [0],
- [[{"error":null,"id":0,"result":{"details":"get_schema request specifies unknown database nonexistent","error":"unknown database","syntax":"[\"nonexistent\"]"}}
+ [[{"error":{"details":"get_schema request specifies unknown database nonexistent","error":"unknown database","syntax":"[\"nonexistent\"]"},"id":0,"result":null}
]], [], [test ! -e pid || kill `cat pid`])
OVSDB_SERVER_SHUTDOWN
AT_CLEANUP
--
2.1.3
More information about the dev
mailing list