Names that begin with "_" are reserved, but ovsdb-server didn't previously
enforce this.

At the same time, make ovsdb-client ignore databases with reserved names
for the purpose of selecting a default database to work on.

This is in preparation for ovsdb-server starting to serve a new database,
full of meta-information, called _Server.

Signed-off-by: Ben Pfaff <[email protected]>
---
 ovsdb/execution.c    | 17 ++++++++++++-----
 ovsdb/ovsdb-client.c | 19 ++++++++++++++-----
 ovsdb/ovsdb-server.c | 51 ++++++++++++++++++++++++++++++++++++++-------------
 3 files changed, 64 insertions(+), 23 deletions(-)

diff --git a/ovsdb/execution.c b/ovsdb/execution.c
index 016b9c68767c..1794fcf66e43 100644
--- a/ovsdb/execution.c
+++ b/ovsdb/execution.c
@@ -175,11 +175,18 @@ ovsdb_execute(struct ovsdb *db, const struct 
ovsdb_session *session,
             error = parse_error;
         }
         /* Create read-only violation error if there is one. */
-        if (!error && read_only && !ro) {
-            error = ovsdb_error("not allowed",
-                                "%s operation not allowed when "
-                                "database server is in read only mode",
-                                op_name);
+        if (!ro && !error) {
+            if (read_only) {
+                error = ovsdb_error("not allowed",
+                                    "%s operation not allowed when "
+                                    "database server is in read only mode",
+                                    op_name);
+            } else if (db->schema->name[0] == '_') {
+                error = ovsdb_error("not allowed",
+                                    "%s operation not allowed on "
+                                    "table in reserved database %s",
+                                    op_name, db->schema->name);
+            }
         }
         if (error) {
             json_destroy(result);
diff --git a/ovsdb/ovsdb-client.c b/ovsdb/ovsdb-client.c
index 7d90183843ee..e4f2ce2ba0b5 100644
--- a/ovsdb/ovsdb-client.c
+++ b/ovsdb/ovsdb-client.c
@@ -131,14 +131,23 @@ main(int argc, char *argv[])
         if (argc - optind > command->min_args
             && svec_contains(&dbs, argv[optind])) {
             database = xstrdup(argv[optind++]);
-        } else if (dbs.n == 1) {
-            database = xstrdup(dbs.names[0]);
         } else if (svec_contains(&dbs, "Open_vSwitch")) {
             database = xstrdup("Open_vSwitch");
         } else {
-            jsonrpc_close(rpc);
-            ovs_fatal(0, "no default database for `%s' command, please "
-                      "specify a database name", command->name);
+            size_t n = 0;
+            const char *best = NULL;
+            for (size_t i = 0; i < dbs.n; i++) {
+                if (dbs.names[i][0] != '_') {
+                    best = dbs.names[i];
+                    n++;
+                }
+            }
+            if (n != 1) {
+                jsonrpc_close(rpc);
+                ovs_fatal(0, "no default database for `%s' command, please "
+                          "specify a database name", command->name);
+            }
+            database = xstrdup(best);
         }
         svec_destroy(&dbs);
     } else {
diff --git a/ovsdb/ovsdb-server.c b/ovsdb/ovsdb-server.c
index 1e0c20486e38..19cea99d3741 100644
--- a/ovsdb/ovsdb-server.c
+++ b/ovsdb/ovsdb-server.c
@@ -146,7 +146,9 @@ ovsdb_replication_init(const char *sync_from, const char 
*exclude,
     struct shash_node *node;
     SHASH_FOR_EACH (node, all_dbs) {
         struct db *db = node->data;
-        replication_add_local_db(node->name, db->db);
+        if (node->name[0] != '_' && db->db) {
+            replication_add_local_db(node->name, db->db);
+        }
     }
 }
 
@@ -518,6 +520,9 @@ open_db(struct server_config *config, const char *filename)
     db_error = ovsdb_file_open(db->filename, false, &db->db, &db->file);
     if (db_error) {
         error = ovsdb_error_to_string(db_error);
+    } else if (db->db->schema->name[0] == '_') {
+        error = xasprintf("%s: names beginning with \"_\" are reserved",
+                          db->db->schema->name);
     } else if (!ovsdb_jsonrpc_server_add_db(config->jsonrpc, db->db)) {
         error = xasprintf("%s: duplicate database name", db->db->schema->name);
     } else {
@@ -1147,10 +1152,17 @@ ovsdb_server_compact(struct unixctl_conn *conn, int 
argc,
     struct shash_node *node;
     int n = 0;
 
+    if (argc > 2 && argv[1][0] == '_') {
+        unixctl_command_reply_error(conn, "cannot compact built-in databases");
+        return;
+    }
+
     ds_init(&reply);
     SHASH_FOR_EACH(node, all_dbs) {
         db = node->data;
-        if (argc < 2 || !strcmp(argv[1], node->name)) {
+        if (argc < 2
+            ? node->name[0] != '_'
+            : !strcmp(argv[1], node->name)) {
             struct ovsdb_error *error;
 
             VLOG_INFO("compacting %s database by user request", node->name);
@@ -1286,21 +1298,12 @@ ovsdb_server_add_database(struct unixctl_conn *conn, 
int argc OVS_UNUSED,
 }
 
 static void
-ovsdb_server_remove_database(struct unixctl_conn *conn, int argc OVS_UNUSED,
-                             const char *argv[], void *config_)
+remove_db(struct server_config *config, struct shash_node *node)
 {
-    struct server_config *config = config_;
-    struct shash_node *node;
     struct db *db;
     bool ok;
 
-    node = shash_find(config->all_dbs, argv[1]);
-    if (!node)  {
-        unixctl_command_reply_error(conn, "Failed to find the database.");
-        return;
-    }
     db = node->data;
-
     ok = ovsdb_jsonrpc_server_remove_db(config->jsonrpc, db->db);
     ovs_assert(ok);
 
@@ -1314,6 +1317,26 @@ ovsdb_server_remove_database(struct unixctl_conn *conn, 
int argc OVS_UNUSED,
         ovsdb_replication_init(*config->sync_from, *config->sync_exclude,
                                config->all_dbs, server_uuid);
     }
+}
+
+static void
+ovsdb_server_remove_database(struct unixctl_conn *conn, int argc OVS_UNUSED,
+                             const char *argv[], void *config_)
+{
+    struct server_config *config = config_;
+    struct shash_node *node;
+
+    node = shash_find(config->all_dbs, argv[1]);
+    if (!node) {
+        unixctl_command_reply_error(conn, "Failed to find the database.");
+        return;
+    }
+    if (node->name[0] == '_') {
+        unixctl_command_reply_error(conn, "Cannot remove reserved database.");
+        return;
+    }
+
+    remove_db(config, node);
     unixctl_command_reply(conn, NULL);
 }
 
@@ -1573,7 +1596,9 @@ save_config(struct server_config *config)
     sset_init(&db_filenames);
     SHASH_FOR_EACH (node, config->all_dbs) {
         struct db *db = node->data;
-        sset_add(&db_filenames, db->filename);
+        if (node->name[0] != '_') {
+            sset_add(&db_filenames, db->filename);
+        }
     }
 
     save_config__(config->config_tmpfile, config->remotes, &db_filenames,
-- 
2.10.2

_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to