From b421d2af0ab5049a91fa5ba4a423dd4b7d30b0d8 Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Wed, 10 Apr 2013 09:34:49 -0700 Subject: [PATCH] ovsdb-server: Add commands for adding and removing remotes at runtime. This will make it possible, in later commits, to make ovsdb-server connect to OVS managers only after ovs-vswitchd has completed its initial configuration. Signed-off-by: Ben Pfaff Acked-by: Ansis Atteka --- ovsdb/ovsdb-server.1.in | 28 ++++++++++++ ovsdb/ovsdb-server.c | 94 ++++++++++++++++++++++++++++++++++++++++- tests/ovsdb-server.at | 42 ++++++++++++++++++ 3 files changed, 162 insertions(+), 2 deletions(-) diff --git a/ovsdb/ovsdb-server.1.in b/ovsdb/ovsdb-server.1.in index 9d424715f..82dd9c627 100644 --- a/ovsdb/ovsdb-server.1.in +++ b/ovsdb/ovsdb-server.1.in @@ -1,4 +1,9 @@ .\" -*- nroff -*- +.de IQ +. br +. ns +. IP "\\$1" +.. .TH ovsdb\-server 1 "@VERSION@" "Open vSwitch" "Open vSwitch Manual" .\" This program's name: .ds PN ovsdb\-server @@ -124,6 +129,29 @@ connections to database clients and reconnect. This command might be useful for debugging issues with database clients. . +.IP "\fBovsdb\-server/add\-remote \fIremote\fR" +Adds a remote, as if \fB\-\-remote=\fIremote\fR had been specified on +the \fBovsdb\-server\fR command line. (If \fIremote\fR is already a +remote, this command succeeds without changing the configuration.) +. +.IP "\fBovsdb\-server/remove\-remote \fIremote\fR" +Removes the specified \fIremote\fR from the configuration, failing +with an error if \fIremote\fR is not configured as a remote. This +command only works with remotes that were named on \fB\-\-remote\fR or +\fBovsdb\-server/add\-remote\fR, that is, it will not remove remotes +added indirectly because they were read from the database by +configuring a \fBdb:\fR[\fIdb\fB,\fR]\fItable\fB,\fIcolumn\fR remote. +(You can remove a database source with \fBovsdb\-server/remove\-remote +\fBdb:\fR[\fIdb\fB,\fR]\fItable\fB,\fIcolumn\fR, but not individual +remotes found indirectly through the database.) +. +.IP "\fBovsdb\-server/list\-remotes" +Outputs a list of the currently configured remotes named on +\fB\-\-remote\fR or \fBovsdb\-server/add\-remote\fR, that is, it does +not list remotes added indirectly because they were read from the +database by configuring a +\fBdb:\fR[\fIdb\fB,\fR]\fItable\fB,\fIcolumn\fR remote. +. .so lib/vlog-unixctl.man .so lib/memory-unixctl.man .so lib/coverage-unixctl.man diff --git a/ovsdb/ovsdb-server.c b/ovsdb/ovsdb-server.c index 40fc36c6d..61095e29b 100644 --- a/ovsdb/ovsdb-server.c +++ b/ovsdb/ovsdb-server.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2009, 2010, 2011, 2012 Nicira, Inc. +/* Copyright (c) 2009, 2010, 2011, 2012, 2013 Nicira, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -76,6 +76,15 @@ static unixctl_cb_func ovsdb_server_exit; static unixctl_cb_func ovsdb_server_compact; static unixctl_cb_func ovsdb_server_reconnect; +struct add_remote_aux { + struct sset *remotes; + struct db *dbs; + size_t n_dbs; +}; +static unixctl_cb_func ovsdb_server_add_remote; +static unixctl_cb_func ovsdb_server_remove_remote; +static unixctl_cb_func ovsdb_server_list_remotes; + static void parse_options(int *argc, char **argvp[], struct sset *remotes, char **unixctl_pathp, char **run_command); @@ -101,6 +110,7 @@ main(int argc, char *argv[]) bool exiting; int retval; long long int status_timer = LLONG_MIN; + struct add_remote_aux add_remote_aux; struct db *dbs; int n_dbs; @@ -181,6 +191,16 @@ main(int argc, char *argv[]) unixctl_command_register("ovsdb-server/reconnect", "", 0, 0, ovsdb_server_reconnect, jsonrpc); + add_remote_aux.remotes = &remotes; + add_remote_aux.dbs = dbs; + add_remote_aux.n_dbs = n_dbs; + unixctl_command_register("ovsdb-server/add-remote", "REMOTE", 1, 1, + ovsdb_server_add_remote, &add_remote_aux); + unixctl_command_register("ovsdb-server/remove-remote", "REMOTE", 1, 1, + ovsdb_server_remove_remote, &remotes); + unixctl_command_register("ovsdb-server/list-remotes", "", 0, 0, + ovsdb_server_list_remotes, &remotes); + exiting = false; while (!exiting) { int i; @@ -198,9 +218,13 @@ main(int argc, char *argv[]) simap_destroy(&usage); } + /* Run unixctl_server_run() before reconfigure_from_db() because + * ovsdb-server/add-remote and ovsdb-server/remove-remote can change + * the set of remotes that reconfigure_from_db() uses. */ + unixctl_server_run(unixctl); + reconfigure_from_db(jsonrpc, dbs, n_dbs, &remotes); ovsdb_jsonrpc_server_run(jsonrpc); - unixctl_server_run(unixctl); for (i = 0; i < n_dbs; i++) { ovsdb_trigger_run(dbs[i].db, time_msec()); @@ -871,6 +895,72 @@ ovsdb_server_reconnect(struct unixctl_conn *conn, int argc OVS_UNUSED, unixctl_command_reply(conn, NULL); } +/* "ovsdb-server/add-remote REMOTE": adds REMOTE to the set of remotes that + * ovsdb-server services. */ +static void +ovsdb_server_add_remote(struct unixctl_conn *conn, int argc OVS_UNUSED, + const char *argv[], void *aux_) +{ + struct add_remote_aux *aux = aux_; + const char *remote = argv[1]; + + const struct ovsdb_column *column; + const struct ovsdb_table *table; + const struct db *db; + char *retval; + + retval = (strncmp("db:", remote, 3) + ? NULL + : parse_db_column(aux->dbs, aux->n_dbs, remote, + &db, &table, &column)); + if (!retval) { + sset_add(aux->remotes, remote); + unixctl_command_reply(conn, NULL); + } else { + unixctl_command_reply_error(conn, retval); + free(retval); + } +} + +/* "ovsdb-server/remove-remote REMOTE": removes REMOTE frmo the set of remotes + * that ovsdb-server services. */ +static void +ovsdb_server_remove_remote(struct unixctl_conn *conn, int argc OVS_UNUSED, + const char *argv[], void *remotes_) +{ + struct sset *remotes = remotes_; + struct sset_node *node; + + node = sset_find(remotes, argv[1]); + if (node) { + sset_delete(remotes, node); + unixctl_command_reply(conn, NULL); + } else { + unixctl_command_reply_error(conn, "no such remote"); + } +} + +/* "ovsdb-server/list-remotes": outputs a list of configured rmeotes. */ +static void +ovsdb_server_list_remotes(struct unixctl_conn *conn, int argc OVS_UNUSED, + const char *argv[] OVS_UNUSED, void *remotes_) +{ + struct sset *remotes = remotes_; + const char **list, **p; + struct ds s; + + ds_init(&s); + + list = sset_sort(remotes); + for (p = list; *p; p++) { + ds_put_format(&s, "%s\n", *p); + } + free(list); + + unixctl_command_reply(conn, ds_cstr(&s)); + ds_destroy(&s); +} + static void parse_options(int *argcp, char **argvp[], struct sset *remotes, char **unixctl_pathp, char **run_command) diff --git a/tests/ovsdb-server.at b/tests/ovsdb-server.at index 62eae3824..50f95bda2 100644 --- a/tests/ovsdb-server.at +++ b/tests/ovsdb-server.at @@ -229,6 +229,48 @@ AT_CHECK( [ignore]) AT_CLEANUP +AT_SETUP([ovsdb-server/add-remote and remove-remote]) +AT_KEYWORDS([ovsdb server positive]) +OVS_RUNDIR=`pwd`; export OVS_RUNDIR +OVS_LOGDIR=`pwd`; export OVS_LOGDIR +ordinal_schema > schema +AT_CHECK([ovsdb-tool create db schema], [0], [ignore], [ignore]) +ON_EXIT([kill `cat *.pid`]) +AT_CHECK([ovsdb-server --detach --no-chdir --pidfile db]) + +AT_CHECK([test ! -e socket1]) +AT_CHECK([ovs-appctl -t ovsdb-server ovsdb-server/add-remote punix:socket1]) +OVS_WAIT_UNTIL([test -S socket1]) +AT_CHECK([ovs-appctl -t ovsdb-server ovsdb-server/list-remotes], + [0], [punix:socket1 +]) + +AT_CHECK([test ! -e socket2]) +AT_CHECK([ovs-appctl -t ovsdb-server ovsdb-server/add-remote punix:socket2]) +OVS_WAIT_UNTIL([test -S socket2]) +AT_CHECK([ovs-appctl -t ovsdb-server ovsdb-server/list-remotes], + [0], [punix:socket1 +punix:socket2 +]) + +AT_CHECK([ovs-appctl -t ovsdb-server ovsdb-server/add-remote db:x,y,z], [2], + [], ["db:x,y,z": no database named x +ovs-appctl: ovsdb-server: server returned an error +]) + +AT_CHECK([ovs-appctl -t ovsdb-server ovsdb-server/remove-remote punix:socket1]) +OVS_WAIT_UNTIL([test ! -e socket1]) +AT_CHECK([test -S socket2]) +AT_CHECK([ovs-appctl -t ovsdb-server ovsdb-server/list-remotes], + [0], [punix:socket2 +]) + +AT_CHECK([ovs-appctl -t ovsdb-server ovsdb-server/remove-remote punix:socket2]) +OVS_WAIT_UNTIL([test ! -e socket2]) +AT_CHECK([test ! -e socket1]) +AT_CHECK([ovs-appctl -t ovsdb-server ovsdb-server/list-remotes]) +AT_CLEANUP + AT_SETUP([SSL db: implementation]) AT_KEYWORDS([ovsdb server positive ssl $5]) AT_SKIP_IF([test "$HAVE_OPENSSL" = no]) -- 2.43.0