summaryrefslogtreecommitdiff
path: root/ovsdb
diff options
context:
space:
mode:
authorBen Pfaff <blp@nicira.com>2010-12-27 14:26:47 -0800
committerBen Pfaff <blp@nicira.com>2010-12-27 14:26:47 -0800
commit8159b984dced44851670bd48e204b4e854941a24 (patch)
treefd1c2b8187747cece69b8fe5be114ef127a15773 /ovsdb
parent538c6dfab42ec72f916e80f916e858f988d1c48d (diff)
downloadopenvswitch-8159b984dced44851670bd48e204b4e854941a24.tar.gz
Implement database schema versioning.
As the database schema evolves, it might be useful to have an identifier for the particular version in use. This commit adds that feature.
Diffstat (limited to 'ovsdb')
-rw-r--r--ovsdb/SPECS12
-rw-r--r--ovsdb/ovsdb-client.1.in15
-rw-r--r--ovsdb/ovsdb-client.c12
-rw-r--r--ovsdb/ovsdb-tool.1.in29
-rw-r--r--ovsdb/ovsdb-tool.c26
-rw-r--r--ovsdb/ovsdb.c37
-rw-r--r--ovsdb/ovsdb.h4
7 files changed, 129 insertions, 6 deletions
diff --git a/ovsdb/SPECS b/ovsdb/SPECS
index 326293c71..97f988265 100644
--- a/ovsdb/SPECS
+++ b/ovsdb/SPECS
@@ -33,6 +33,11 @@ values. Additional notation is presented later.
<id>s that begin with _ are reserved to the implementation and may
not be used by the user.
+<version>
+
+ A JSON string that contains a version number that matches
+ [0-9]+\.[0-9]+\.[0-9]+
+
<boolean>
A JSON true or false value.
@@ -102,6 +107,7 @@ is represented by <database-schema>, as described below.
A JSON object with the following members:
"name": <id> required
+ "version": <version> required
"tables": {<id>: <table-schema>, ...} required
The "name" identifies the database as a whole. It must be
@@ -109,6 +115,12 @@ is represented by <database-schema>, as described below.
operated on. The value of "tables" is a JSON object whose names
are table names and whose values are <table-schema>s.
+ The "version" reports the version of the database schema. Because
+ this is a recent addition to the schema format, OVSDB permits it
+ to be omitted, but future versions of OVSDB will require it to be
+ present. Open vSwitch semantics for "version" are described in
+ ovs-vswitchd.conf.db(5).
+
<table-schema>
A JSON object with the following members:
diff --git a/ovsdb/ovsdb-client.1.in b/ovsdb/ovsdb-client.1.in
index 22b4e2322..725211d70 100644
--- a/ovsdb/ovsdb-client.1.in
+++ b/ovsdb/ovsdb-client.1.in
@@ -19,6 +19,8 @@ ovsdb\-client \- command-line interface to \fBovsdb-server\fR(1)
.br
\fBovsdb\-client \fR[\fIoptions\fR] \fBget\-schema\fI server database\fR
.br
+\fBovsdb\-client \fR[\fIoptions\fR] \fBget\-schema\-version\fI server database\fR
+.br
\fBovsdb\-client \fR[\fIoptions\fR] \fBlist\-tables\fI server database\fR
.br
\fBovsdb\-client \fR[\fIoptions\fR] \fBlist\-columns\fI server database \fR[\fItable\fR]
@@ -61,6 +63,19 @@ be used for \fIdatabase\fR in the following commands.
Connects to \fIserver\fR, retrieves the schema for \fIdatabase\fR, and
prints it in JSON format.
.
+.IP "\fBget\-schema\-version\fI server database\fR"
+Connects to \fIserver\fR, retrieves the schema for \fIdatabase\fR, and
+prints its version number on stdout. A schema version number has the form
+\fIx\fB.\fIy\fB.\fIz\fR. See \fBovs\-vswitchd.conf.db\fR(5) for
+details.
+.IP
+Schema version numbers and Open vSwitch version numbers are
+independent.
+.IP
+If \fIdatabase\fR was created before schema versioning was introduced,
+then it will not have a version number and this command will print a
+blank line.
+.
.IP "\fBlist\-tables\fI server database\fR"
Connects to \fIserver\fR, retrieves the schema for \fIdatabase\fR, and
prints a table listing the name of each table
diff --git a/ovsdb/ovsdb-client.c b/ovsdb/ovsdb-client.c
index 6d19e5df2..da6a6d6d7 100644
--- a/ovsdb/ovsdb-client.c
+++ b/ovsdb/ovsdb-client.c
@@ -182,6 +182,9 @@ usage(void)
" list databases available on SERVER\n"
"\n get-schema SERVER DATABASE\n"
" retrieve schema for DATABASE from SERVER\n"
+ "\n get-schema-version SERVER DATABASE\n"
+ " retrieve schema for DATABASE from SERVER and report only its\n"
+ " version number on stdout\n"
"\n list-tables SERVER DATABASE\n"
" list tables for DATABASE on SERVER\n"
"\n list-columns SERVER DATABASE [TABLE]\n"
@@ -782,6 +785,14 @@ do_get_schema(int argc OVS_UNUSED, char *argv[])
}
static void
+do_get_schema_version(int argc OVS_UNUSED, char *argv[])
+{
+ struct ovsdb_schema *schema = fetch_schema(argv[1], argv[2]);
+ puts(schema->version);
+ ovsdb_schema_destroy(schema);
+}
+
+static void
do_list_tables(int argc OVS_UNUSED, char *argv[])
{
struct ovsdb_schema *schema;
@@ -1344,6 +1355,7 @@ do_help(int argc OVS_UNUSED, char *argv[] OVS_UNUSED)
static const struct command all_commands[] = {
{ "list-dbs", 1, 1, do_list_dbs },
{ "get-schema", 2, 2, do_get_schema },
+ { "get-schema-version", 2, 2, do_get_schema_version },
{ "list-tables", 2, 2, do_list_tables },
{ "list-columns", 2, 3, do_list_columns },
{ "transact", 2, 2, do_transact },
diff --git a/ovsdb/ovsdb-tool.1.in b/ovsdb/ovsdb-tool.1.in
index b073f6d57..069ab1a4d 100644
--- a/ovsdb/ovsdb-tool.1.in
+++ b/ovsdb/ovsdb-tool.1.in
@@ -14,6 +14,15 @@ ovsdb\-tool \- Open vSwitch database management utility
.SH SYNOPSIS
\fBovsdb\-tool \fR[\fIoptions\fR] \fBcreate\fI db schema\fR
.br
+\fBovsdb\-tool \fR[\fIoptions\fR] \fBcompact \fIdb \fR[\fItarget\fR]
+.br
+\fBovsdb\-tool \fR[\fIoptions\fR] \fBconvert\fI db schema
+\fR[\fItarget\fR]
+.br
+\fBovsdb\-tool \fR[\fIoptions\fR] \fBdb\-version\fI db\fR
+.br
+\fBovsdb\-tool \fR[\fIoptions\fR] \fBschema\-version\fI schema\fR
+.br
\fBovsdb\-tool \fR[\fIoptions\fR] \fBquery\fI db transaction\fR
.br
\fBovsdb\-tool \fR[\fIoptions\fR] \fBtransact\fI db transaction\fR
@@ -63,6 +72,26 @@ ignored. Columns that exist in \fIschema\fR but not in \fIdb\fR are
set to their default values. All of \fIschema\fR's constraints apply
in full.
.
+.IP "\fBdb\-version\fI db\fR"
+Reads \fIdb\fR and prints the version number of the schema embedded
+within the database on stdout. A schema version number has the form
+\fIx\fB.\fIy\fB.\fIz\fR. See \fBovs\-vswitchd.conf.db\fR(5) for
+details.
+.IP
+Schema version numbers and Open vSwitch version numbers are
+independent.
+.IP
+If \fIdb\fR was created before schema versioning was introduced, then
+it will not have a version number and this command will print a blank
+line.
+.
+.IP "\fBschema\-version\fI schema\fR"
+Reads \fIschema\fR and prints the schema's version number on stdout.
+.IP
+If \fIschema\fR was created before versioning was introduced, then it
+does not have a version number and this command will print a blank
+line.
+.
.IP "\fBquery\fI db transaction\fR"
Opens \fIdb\fR, executes \fItransaction\fR on it, and prints the
results. The \fItransaction\fR must be a JSON array in the format of
diff --git a/ovsdb/ovsdb-tool.c b/ovsdb/ovsdb-tool.c
index 5eeb28fa4..130e73779 100644
--- a/ovsdb/ovsdb-tool.c
+++ b/ovsdb/ovsdb-tool.c
@@ -110,6 +110,8 @@ usage(void)
" create DB SCHEMA create DB with the given SCHEMA\n"
" compact DB [DST] compact DB in-place (or to DST)\n"
" convert DB SCHEMA [DST] convert DB to SCHEMA (to DST)\n"
+ " db-version DB report version of schema used by DB\n"
+ " schema-version SCHEMA report SCHEMA's schema version\n"
" query DB TRNS execute read-only transaction on DB\n"
" transact DB TRNS execute read/write transaction on DB\n"
" show-log DB prints information about DB's log entries\n",
@@ -240,6 +242,28 @@ do_convert(int argc OVS_UNUSED, char *argv[])
}
static void
+do_db_version(int argc OVS_UNUSED, char *argv[])
+{
+ const char *db_file_name = argv[1];
+ struct ovsdb *db;
+
+ check_ovsdb_error(ovsdb_file_open(db_file_name, true, &db, NULL));
+ puts(db->schema->version);
+ ovsdb_destroy(db);
+}
+
+static void
+do_schema_version(int argc OVS_UNUSED, char *argv[])
+{
+ const char *schema_file_name = argv[1];
+ struct ovsdb_schema *schema;
+
+ check_ovsdb_error(ovsdb_schema_from_file(schema_file_name, &schema));
+ puts(schema->version);
+ ovsdb_schema_destroy(schema);
+}
+
+static void
transact(bool read_only, const char *db_file_name, const char *transaction)
{
struct json *request, *result;
@@ -410,6 +434,8 @@ static const struct command all_commands[] = {
{ "create", 2, 2, do_create },
{ "compact", 1, 2, do_compact },
{ "convert", 2, 3, do_convert },
+ { "db-version", 1, 1, do_db_version },
+ { "schema-version", 1, 1, do_schema_version },
{ "query", 2, 2, do_query },
{ "transact", 2, 2, do_transact },
{ "show-log", 1, 1, do_show_log },
diff --git a/ovsdb/ovsdb.c b/ovsdb/ovsdb.c
index 45683766c..b767d3867 100644
--- a/ovsdb/ovsdb.c
+++ b/ovsdb/ovsdb.c
@@ -26,12 +26,13 @@
#include "transaction.h"
struct ovsdb_schema *
-ovsdb_schema_create(const char *name)
+ovsdb_schema_create(const char *name, const char *version)
{
struct ovsdb_schema *schema;
schema = xzalloc(sizeof *schema);
schema->name = xstrdup(name);
+ schema->version = xstrdup(version);
shash_init(&schema->tables);
return schema;
@@ -43,7 +44,7 @@ ovsdb_schema_clone(const struct ovsdb_schema *old)
struct ovsdb_schema *new;
struct shash_node *node;
- new = ovsdb_schema_create(old->name);
+ new = ovsdb_schema_create(old->name, old->version);
SHASH_FOR_EACH (node, &old->tables) {
const struct ovsdb_table_schema *ts = node->data;
@@ -52,7 +53,6 @@ ovsdb_schema_clone(const struct ovsdb_schema *old)
return new;
}
-
void
ovsdb_schema_destroy(struct ovsdb_schema *schema)
{
@@ -67,6 +67,7 @@ ovsdb_schema_destroy(struct ovsdb_schema *schema)
}
shash_destroy(&schema->tables);
free(schema->name);
+ free(schema->version);
free(schema);
}
@@ -116,26 +117,49 @@ ovsdb_schema_check_ref_table(const struct ovsdb_column *column,
}
}
+static bool
+is_valid_version(const char *s)
+{
+ int n = -1;
+ sscanf(s, "%*[0-9].%*[0-9].%*[0-9]%n", &n);
+ return n != -1 && s[n] == '\0';
+}
+
struct ovsdb_error *
ovsdb_schema_from_json(struct json *json, struct ovsdb_schema **schemap)
{
struct ovsdb_schema *schema;
- const struct json *name, *tables;
+ const struct json *name, *tables, *version_json;
struct ovsdb_error *error;
struct shash_node *node;
struct ovsdb_parser parser;
+ const char *version;
*schemap = NULL;
ovsdb_parser_init(&parser, json, "database schema");
name = ovsdb_parser_member(&parser, "name", OP_ID);
+ version_json = ovsdb_parser_member(&parser, "version",
+ OP_STRING | OP_OPTIONAL);
+ ovsdb_parser_member(&parser, "cksum", OP_STRING | OP_OPTIONAL);
tables = ovsdb_parser_member(&parser, "tables", OP_OBJECT);
error = ovsdb_parser_finish(&parser);
if (error) {
return error;
}
- schema = ovsdb_schema_create(json_string(name));
+ if (version_json) {
+ version = json_string(version_json);
+ if (!is_valid_version(version)) {
+ return ovsdb_syntax_error(json, NULL, "schema version \"%s\" not "
+ "in format x.y.z", version);
+ }
+ } else {
+ /* Backward compatibility with old databases. */
+ version = "";
+ }
+
+ schema = ovsdb_schema_create(json_string(name), version);
SHASH_FOR_EACH (node, json_object(tables)) {
struct ovsdb_table_schema *table;
@@ -190,6 +214,9 @@ ovsdb_schema_to_json(const struct ovsdb_schema *schema)
json = json_object_create();
json_object_put_string(json, "name", schema->name);
+ if (schema->version[0]) {
+ json_object_put_string(json, "version", schema->version);
+ }
tables = json_object_create();
diff --git a/ovsdb/ovsdb.h b/ovsdb/ovsdb.h
index a83412dcd..642f686f0 100644
--- a/ovsdb/ovsdb.h
+++ b/ovsdb/ovsdb.h
@@ -29,10 +29,12 @@ struct uuid;
/* Database schema. */
struct ovsdb_schema {
char *name;
+ char *version;
struct shash tables; /* Contains "struct ovsdb_table_schema *"s. */
};
-struct ovsdb_schema *ovsdb_schema_create(const char *name);
+struct ovsdb_schema *ovsdb_schema_create(const char *name,
+ const char *version);
struct ovsdb_schema *ovsdb_schema_clone(const struct ovsdb_schema *);
void ovsdb_schema_destroy(struct ovsdb_schema *);