@@ -95,6 +95,13 @@ static unixctl_cb_func ovsdb_server_get_sync_exclude_tables;
static unixctl_cb_func ovsdb_server_get_sync_status;
static unixctl_cb_func ovsdb_server_get_db_storage_status;
+/* Holds the name of the configuration file passed via --config-file.
+ * Mutually exclusive with command-line and unixctl configuration
+ * that can otherwise be done via configuration file. */
+static char *config_file_path = NULL;
+/* UnixCtl command to reload configuration from a configuration file. */
+static unixctl_cb_func ovsdb_server_reload;
+
#define SERVICE_MODELS \
SERVICE_MODEL(UNDEFINED, undefined) \
SERVICE_MODEL(STANDALONE, standalone) \
@@ -639,6 +646,8 @@ main(int argc, char *argv[])
ovsdb_server_memory_trim_on_compaction, NULL);
unixctl_command_register("ovsdb-server/reconnect", "", 0, 0,
ovsdb_server_reconnect, jsonrpc);
+ unixctl_command_register("ovsdb-server/reload", "", 0, 0,
+ ovsdb_server_reload, &server_config);
unixctl_command_register("ovsdb-server/add-remote", "REMOTE", 1, 1,
ovsdb_server_add_remote, &server_config);
@@ -714,6 +723,7 @@ main(int argc, char *argv[])
free(sync_exclude);
unixctl_server_destroy(unixctl);
replication_destroy();
+ free(config_file_path);
if (run_process && process_exited(run_process)) {
int status = process_status(run_process);
@@ -1626,6 +1636,23 @@ report_error_if_changed(char *error, char **last_errorp)
}
}
+static bool
+check_config_file_on_unixctl(struct unixctl_conn *conn)
+{
+ struct ds ds = DS_EMPTY_INITIALIZER;
+
+ if (!config_file_path) {
+ return false;
+ }
+
+ ds_put_format(&ds, "Update the %s and use ovsdb-server/reload instead",
+ config_file_path);
+ unixctl_command_reply_error(conn, ds_cstr(&ds));
+ ds_destroy(&ds);
+
+ return true;
+}
+
static void
ovsdb_server_set_active_ovsdb_server(struct unixctl_conn *conn,
int argc OVS_UNUSED, const char *argv[],
@@ -1634,6 +1661,10 @@ ovsdb_server_set_active_ovsdb_server(struct unixctl_conn *conn,
struct server_config *config = config_;
struct shash_node *node;
+ if (check_config_file_on_unixctl(conn)) {
+ return;
+ }
+
free(*config->sync_from);
*config->sync_from = xstrdup(argv[1]);
@@ -1672,6 +1703,10 @@ ovsdb_server_connect_active_ovsdb_server(struct unixctl_conn *conn,
struct shash_node *node;
char *msg = NULL;
+ if (check_config_file_on_unixctl(conn)) {
+ return;
+ }
+
if (!*config->sync_from) {
msg = "Unable to connect: active server is not specified.\n";
} else {
@@ -1715,6 +1750,10 @@ ovsdb_server_disconnect_active_ovsdb_server(struct unixctl_conn *conn,
struct server_config *config = config_;
struct shash_node *node;
+ if (check_config_file_on_unixctl(conn)) {
+ return;
+ }
+
SHASH_FOR_EACH (node, config->all_dbs) {
struct db *db = node->data;
struct db_config *conf = db->config;
@@ -1738,6 +1777,10 @@ ovsdb_server_set_active_ovsdb_server_probe_interval(struct unixctl_conn *conn,
struct shash_node *node;
int probe_interval;
+ if (check_config_file_on_unixctl(conn)) {
+ return;
+ }
+
if (!str_to_int(argv[1], 10, &probe_interval)) {
unixctl_command_reply_error(
conn, "Invalid probe interval, integer value expected");
@@ -1776,6 +1819,10 @@ ovsdb_server_set_relay_source_interval(struct unixctl_conn *conn,
struct shash_node *node;
int probe_interval;
+ if (check_config_file_on_unixctl(conn)) {
+ return;
+ }
+
if (!str_to_int(argv[1], 10, &probe_interval)) {
unixctl_command_reply_error(
conn, "Invalid probe interval, integer value expected");
@@ -1808,6 +1855,10 @@ ovsdb_server_set_sync_exclude_tables(struct unixctl_conn *conn,
struct server_config *config = config_;
struct shash_node *node;
+ if (check_config_file_on_unixctl(conn)) {
+ return;
+ }
+
char *err = parse_excluded_tables(argv[1]);
if (err) {
goto exit;
@@ -2002,6 +2053,21 @@ ovsdb_server_reconnect(struct unixctl_conn *conn, int argc OVS_UNUSED,
unixctl_command_reply(conn, NULL);
}
+/* "ovsdb-server/reload": makes ovsdb-server open a configuration file on
+ * 'config_file_path', read it and sync the runtime configuration with it. */
+static void
+ovsdb_server_reload(struct unixctl_conn *conn, int argc OVS_UNUSED,
+ const char *argv[] OVS_UNUSED, void *config_ OVS_UNUSED)
+{
+ if (!config_file_path) {
+ unixctl_command_reply_error(conn,
+ "Configuration file was not specified on command line");
+ } else {
+ unixctl_command_reply_error(conn,
+ "Configuration file support is not implemented yet");
+ }
+}
+
/* "ovsdb-server/add-remote REMOTE": adds REMOTE to the set of remotes that
* ovsdb-server services. */
static void
@@ -2016,6 +2082,10 @@ ovsdb_server_add_remote(struct unixctl_conn *conn, int argc OVS_UNUSED,
const struct db *db;
char *retval;
+ if (check_config_file_on_unixctl(conn)) {
+ return;
+ }
+
retval = (strncmp("db:", remote, 3)
? NULL
: parse_db_column(config->all_dbs, remote,
@@ -2040,6 +2110,10 @@ ovsdb_server_remove_remote(struct unixctl_conn *conn, int argc OVS_UNUSED,
struct server_config *config = config_;
struct ovsdb_jsonrpc_options *options;
+ if (check_config_file_on_unixctl(conn)) {
+ return;
+ }
+
options = shash_find_and_delete(config->remotes, argv[1]);
if (options) {
free(options->role);
@@ -2083,6 +2157,10 @@ ovsdb_server_add_database(struct unixctl_conn *conn, int argc OVS_UNUSED,
const struct shash_node *node;
struct shash db_conf;
+ if (check_config_file_on_unixctl(conn)) {
+ return;
+ }
+
shash_init(&db_conf);
add_database_config(&db_conf, filename, *config->sync_from,
*config->sync_exclude, !config->is_backup);
@@ -2120,6 +2198,10 @@ ovsdb_server_remove_database(struct unixctl_conn *conn, int argc OVS_UNUSED,
struct server_config *config = config_;
struct shash_node *node;
+ if (check_config_file_on_unixctl(conn)) {
+ return;
+ }
+
node = shash_find(config->all_dbs, argv[1]);
if (!node) {
unixctl_command_reply_error(conn, "Failed to find the database.");
@@ -2333,6 +2415,7 @@ parse_options(int argc, char *argv[],
OPT_NO_DBS,
OPT_FILE_COLUMN_DIFF,
OPT_FILE_NO_DATA_CONVERSION,
+ OPT_CONFIG_FILE,
VLOG_OPTION_ENUMS,
DAEMON_OPTION_ENUMS,
SSL_OPTION_ENUMS,
@@ -2360,6 +2443,7 @@ parse_options(int argc, char *argv[],
{"disable-file-column-diff", no_argument, NULL, OPT_FILE_COLUMN_DIFF},
{"disable-file-no-data-conversion", no_argument, NULL,
OPT_FILE_NO_DATA_CONVERSION},
+ {"config-file", required_argument, NULL, OPT_CONFIG_FILE},
{NULL, 0, NULL, 0},
};
char *short_options = ovs_cmdl_long_options_to_short_options(long_options);
@@ -2460,6 +2544,11 @@ parse_options(int argc, char *argv[],
ovsdb_no_data_conversion_disable();
break;
+ case OPT_CONFIG_FILE:
+ config_file_path = abs_file_name(ovs_dbdir(), optarg);
+ add_default_db = false;
+ break;
+
case '?':
exit(EXIT_FAILURE);
@@ -2471,7 +2560,19 @@ parse_options(int argc, char *argv[],
argc -= optind;
argv += optind;
- if (argc > 0) {
+
+ if (config_file_path) {
+ if (*sync_from || *sync_exclude || *active) {
+ ovs_fatal(0, "--config-file is mutually exclusive with "
+ "--sync-from, --sync-exclude and --active");
+ }
+ if (shash_count(remotes)) {
+ ovs_fatal(0, "--config-file is mutually exclusive with --remote");
+ }
+ if (argc > 0) {
+ ovs_fatal(0, "Databases should be specified in a config file");
+ }
+ } else if (argc > 0) {
for (int i = 0; i < argc; i++) {
add_database_config(db_conf, argv[i], *sync_from, *sync_exclude,
*active);
@@ -2496,6 +2597,12 @@ usage(void)
printf("\nJSON-RPC options (may be specified any number of times):\n"
" --remote=REMOTE connect or listen to REMOTE\n");
stream_usage("JSON-RPC", true, true, true);
+ printf("\nConfiguration file:\n"
+ " --config-file PATH Use configuration file as a source of\n"
+ " database and JSON-RPC configuration.\n"
+ " Mutually exclusive with the DATABASE,\n"
+ " JSON-RPC and Syncing options.\n"
+ " Assumes --no-dbs.\n");
daemon_usage();
vlog_usage();
replication_usage();
@@ -2503,6 +2610,7 @@ usage(void)
printf("\nOther options:\n"
" --run COMMAND run COMMAND as subprocess then exit\n"
" --unixctl=SOCKET override default control socket name\n"
+ " --no-dbs do not add default database\n"
" --disable-file-column-diff\n"
" don't use column diff in database file\n"
" -h, --help display this help message\n"
Adding a --config-file option that will be used in the future to allow users to provide the database server configuration via a JSON file. For now, it does nothing useful, but we define it as mutually exclusive with all the command line options and UnixCtl commands that configure values that will be available via a config file. This will ensure that we don't have too many ways of configuring the same thing at the same time. New appctl command 'ovsdb-server/reload' is going to signal OVSDB server that it needs to re-read the configuration file. While at it, adding a missing 'usage' line for '--no-dbs'. This option is rarely used, so it doesn't seem to be worth a separate fix. Signed-off-by: Ilya Maximets <i.maximets@ovn.org> --- ovsdb/ovsdb-server.c | 110 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 109 insertions(+), 1 deletion(-)