Adds a new "read_only" column for remote connections. Operations that would alter the state of the database are not permitted on connections for which the "read_only" column is set to "true".
Signed-off-by: Lance Richardson <lrich...@redhat.com> --- ovsdb/jsonrpc-server.c | 7 ++++-- ovsdb/jsonrpc-server.h | 1 + ovsdb/ovsdb-server.1.in | 2 ++ ovsdb/ovsdb-server.c | 15 +++++++++++ tests/ovsdb-server.at | 67 +++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 90 insertions(+), 2 deletions(-) diff --git a/ovsdb/jsonrpc-server.c b/ovsdb/jsonrpc-server.c index 87fc240..fa589b5 100644 --- a/ovsdb/jsonrpc-server.c +++ b/ovsdb/jsonrpc-server.c @@ -127,6 +127,7 @@ struct ovsdb_jsonrpc_remote { struct pstream *listener; /* Listener, if passive. */ struct ovs_list sessions; /* List of "struct ovsdb_jsonrpc_session"s. */ uint8_t dscp; + bool read_only; }; static struct ovsdb_jsonrpc_remote *ovsdb_jsonrpc_server_add_remote( @@ -268,11 +269,12 @@ ovsdb_jsonrpc_server_add_remote(struct ovsdb_jsonrpc_server *svr, remote->listener = listener; ovs_list_init(&remote->sessions); remote->dscp = options->dscp; + remote->read_only = options->read_only; shash_add(&svr->remotes, name, remote); if (!listener) { ovsdb_jsonrpc_session_create(remote, jsonrpc_session_open(name, true), - svr->read_only); + svr->read_only || remote->read_only); } return remote; } @@ -366,7 +368,8 @@ ovsdb_jsonrpc_server_run(struct ovsdb_jsonrpc_server *svr) struct jsonrpc_session *js; js = jsonrpc_session_open_unreliably(jsonrpc_open(stream), remote->dscp); - ovsdb_jsonrpc_session_create(remote, js, svr->read_only); + ovsdb_jsonrpc_session_create(remote, js, svr->read_only || + remote->read_only); } else if (error != EAGAIN) { VLOG_WARN_RL(&rl, "%s: accept failed: %s", pstream_get_name(remote->listener), diff --git a/ovsdb/jsonrpc-server.h b/ovsdb/jsonrpc-server.h index f04b1e9..f72f884 100644 --- a/ovsdb/jsonrpc-server.h +++ b/ovsdb/jsonrpc-server.h @@ -34,6 +34,7 @@ void ovsdb_jsonrpc_server_destroy(struct ovsdb_jsonrpc_server *); struct ovsdb_jsonrpc_options { int max_backoff; /* Maximum reconnection backoff, in msec. */ int probe_interval; /* Max idle time before probing, in msec. */ + bool read_only; /* Only read-only transactions are allowed. */ int dscp; /* Dscp value for manager connections */ }; struct ovsdb_jsonrpc_options * diff --git a/ovsdb/ovsdb-server.1.in b/ovsdb/ovsdb-server.1.in index e2e96ae..0faf844 100644 --- a/ovsdb/ovsdb-server.1.in +++ b/ovsdb/ovsdb-server.1.in @@ -86,6 +86,8 @@ Maximum number of milliseconds to wait between connection attempts. .IP "\fBinactivity_probe\fR (integer)" Maximum number of milliseconds of idle time on connection to client before sending an inactivity probe message. +.IP "\fBread_only\fR (boolean)" +If true, only read-only transactions are allowed on this connection. .RE .IP It is an error for \fIcolumn\fR to have another type. diff --git a/ovsdb/ovsdb-server.c b/ovsdb/ovsdb-server.c index 0e3f9ac..bc71fd1 100644 --- a/ovsdb/ovsdb-server.c +++ b/ovsdb/ovsdb-server.c @@ -781,6 +781,17 @@ read_string_column(const struct ovsdb_row *row, const char *column_name, return atom != NULL; } +static bool +read_bool_column(const struct ovsdb_row *row, const char *column_name, + bool *boolp) +{ + const union ovsdb_atom *atom; + + atom = read_column(row, column_name, OVSDB_TYPE_BOOLEAN); + *boolp = atom ? atom->boolean : false; + return atom != NULL; +} + static void write_bool_column(struct ovsdb_row *row, const char *column_name, bool value) { @@ -849,6 +860,7 @@ add_manager_options(struct shash *remotes, const struct ovsdb_row *row) static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1); struct ovsdb_jsonrpc_options *options; long long int max_backoff, probe_interval; + bool read_only; const char *target, *dscp_string; if (!read_string_column(row, "target", &target) || !target) { @@ -864,6 +876,9 @@ add_manager_options(struct shash *remotes, const struct ovsdb_row *row) if (read_integer_column(row, "inactivity_probe", &probe_interval)) { options->probe_interval = probe_interval; } + if (read_bool_column(row, "read_only", &read_only)) { + options->read_only = read_only; + } options->dscp = DSCP_DEFAULT; dscp_string = read_map_string_column(row, "other_config", "dscp"); diff --git a/tests/ovsdb-server.at b/tests/ovsdb-server.at index d04941b..ae1aab8 100644 --- a/tests/ovsdb-server.at +++ b/tests/ovsdb-server.at @@ -1367,3 +1367,70 @@ AT_CHECK([diff dump1 dump2]) dnl OVSDB_SERVER_SHUTDOWN dnl OVSDB_SERVER_SHUTDOWN2 AT_CLEANUP + +AT_SETUP([ovsdb-server/read-only db:ptcp connection]) +AT_KEYWORDS([ovsdb server read-only]) +AT_DATA([schema], + [[{"name": "mydb", + "tables": { + "Root": { + "columns": { + "managers": { + "type": { + "key": {"type": "uuid", "refTable": "Manager"}, + "min": 0, + "max": "unlimited"}}}}, + "Manager": { + "columns": { + "target": { + "type": "string"}, + "read_only": { + "type": { + "key": "boolean", + "min": 0, + "max": 1}}, + "is_connected": { + "type": { + "key": "boolean", + "min": 0, + "max": 1}}}}, + "ordinals": { + "columns": { + "number": {"type": "integer"}, + "name": {"type": "string"}}, + "indexes": [["number"]]} + }, + "version": "5.1.3", + "cksum": "12345678 9" +} +]]) +AT_CHECK([ovsdb-tool create db schema], [0], [ignore], [ignore]) +AT_CHECK( + [[ovsdb-tool transact db \ + '["mydb", + {"op": "insert", + "table": "Root", + "row": { + "managers": ["set", [["named-uuid", "x"]]]}}, + {"op": "insert", + "table": "Manager", + "uuid-name": "x", + "row": {"target": "ptcp:0:127.0.0.1", + "read_only": true}}]']], [0], [ignore], [ignore]) + +AT_CHECK([ovsdb-server --log-file --detach --no-chdir --pidfile --remote=db:mydb,Root,managers db], [0], [ignore], [ignore]) +PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT]) +AT_CHECK([ovsdb-client get-schema-version tcp:127.0.0.1:$TCP_PORT mydb], [0], [5.1.3 +]) + +AT_CHECK([ovsdb-client transact tcp:127.0.0.1:$TCP_PORT \ + ['["mydb", + {"op": "insert", + "table": "ordinals", + "row": {"name": "two", "number": '2'}} + ]']], [0], [stdout], [ignore]) +cat stdout >> output +AT_CHECK([${PERL} $srcdir/uuidfilt.pl output], [0], [[[{"details":"insert operation not allowed when database server is in read only mode","error":"not allowed"}]] +], [ignore]) +OVSDB_SERVER_SHUTDOWN +AT_CLEANUP -- 2.5.5 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev