Allow ovsdb-tool to accept a schema-list, a list of schema files, in
addition to a single schema file, for all applicable options.

There is no limit on how many schemas can be joined together, but
they can not have a shared schema name and they have to be compatible
for joining. Compatible basically means overlapping tables and columns
have to be of the same type.

A single joined schema, formed by joining schemas from the schema-list,
is used for DB operations.

See man page changes for more details.

Signed-off-by: Andy Zhou <az...@nicira.com>
---
 ovsdb/file.c          |  41 -----------
 ovsdb/file.h          |   9 ---
 ovsdb/ovsdb-tool.1.in |  77 +++++++++++---------
 ovsdb/ovsdb-tool.c    | 193 +++++++++++++++++++++++++++++++++++++++-----------
 ovsdb/ovsdb.c         |   6 +-
 ovsdb/ovsdb.h         |   7 --
 6 files changed, 198 insertions(+), 135 deletions(-)

diff --git a/ovsdb/file.c b/ovsdb/file.c
index 7709047..74e0c09 100644
--- a/ovsdb/file.c
+++ b/ovsdb/file.c
@@ -117,26 +117,6 @@ ovsdb_file_open_as_schemas(const char *file_name,
     return ovsdb_file_open__(file_name, schemas, true, dbp, NULL);
 }
 
-struct ovsdb_error *
-ovsdb_file_open_as_schema(const char *file_name,
-                          const struct ovsdb_schema *schema,
-                          struct ovsdb **dbp)
-{
-    struct shash *schemas;
-    struct ovsdb_error *err;
-
-    schemas = xmalloc(sizeof *schemas);
-    shash_init(schemas);
-    shash_add(schemas, schema->name, ovsdb_schema_clone(schema));
-
-    err = ovsdb_file_open__(file_name, schemas, true, dbp, NULL);
-    if (err) {
-        ovsdb_schemas_destroy(schemas);
-    }
-
-    return err;
-}
-
 static struct ovsdb_error *
 ovsdb_file_open_log(const char *file_name, enum ovsdb_log_open_mode open_mode,
                     struct ovsdb_log **logp, struct shash **schemasp)
@@ -527,27 +507,6 @@ ovsdb_file_read_schemas(const char *file_name, struct 
shash **schemasp)
     return ovsdb_file_open_log(file_name, OVSDB_LOG_READ_ONLY, NULL, schemasp);
 }
 
-struct ovsdb_error *
-ovsdb_file_read_schema(const char *file_name, struct ovsdb_schema **schemap)
-{
-    struct shash *schemas = NULL;
-    struct ovsdb_schema *schema = NULL;
-    struct ovsdb_error *err;
-
-    ovs_assert(schemap != NULL);
-    err = ovsdb_file_read_schemas(file_name, &schemas);
-    if (err) {
-        goto error;
-    }
-
-    err = ovsdb_schemas_join(schemas, &schema);
-    ovsdb_schemas_destroy(schemas);
-
-error:
-    *schemap = schema;
-    return err;
-}
-
 
 /* Replica implementation. */
 
diff --git a/ovsdb/file.h b/ovsdb/file.h
index 799c915..f40c2df 100644
--- a/ovsdb/file.h
+++ b/ovsdb/file.h
@@ -29,11 +29,6 @@ struct ovsdb_error *ovsdb_file_open(const char *file_name, 
bool read_only,
                                     struct ovsdb **, struct ovsdb_file **)
     OVS_WARN_UNUSED_RESULT;
 
-struct ovsdb_error *ovsdb_file_open_as_schema(const char *file_name,
-                                              const struct ovsdb_schema *,
-                                              struct ovsdb **)
-    OVS_WARN_UNUSED_RESULT;
-
 struct ovsdb_error *ovsdb_file_open_as_schemas(const char *file_name,
                                                const struct shash *,
                                                struct ovsdb **)
@@ -46,10 +41,6 @@ struct ovsdb_error *ovsdb_file_save_copy(const char 
*file_name, int locking,
 
 struct ovsdb_error *ovsdb_file_compact(struct ovsdb_file *);
 
-struct ovsdb_error *ovsdb_file_read_schema(const char *file_name,
-                                           struct ovsdb_schema **)
-    OVS_WARN_UNUSED_RESULT;
-
 struct ovsdb_error *ovsdb_file_read_schemas(const char *file_name,
                                            struct shash **)
     OVS_WARN_UNUSED_RESULT;
diff --git a/ovsdb/ovsdb-tool.1.in b/ovsdb/ovsdb-tool.1.in
index a2f1f22..e6c04c9 100644
--- a/ovsdb/ovsdb-tool.1.in
+++ b/ovsdb/ovsdb-tool.1.in
@@ -12,22 +12,22 @@
 ovsdb\-tool \- Open vSwitch database management utility
 .
 .SH SYNOPSIS
-\fBovsdb\-tool \fR[\fIoptions\fR] \fBcreate \fR[\fIdb\fR [\fIschema\fR]]
+\fBovsdb\-tool \fR[\fIoptions\fR] \fBcreate \fR[\fIdb\fR [\fIschema-list\fR]]
 .br
 \fBovsdb\-tool \fR[\fIoptions\fR] \fBcompact \fR[\fIdb\fR [\fItarget\fR]]
 .br
-\fBovsdb\-tool \fR[\fIoptions\fR] \fBconvert \fR[\fIdb\fR [\fIschema
+\fBovsdb\-tool \fR[\fIoptions\fR] \fBconvert \fR[\fIdb\fR [\fIschema-list
 \fR[\fItarget\fR]]]
 .br
-\fBovsdb\-tool \fR[\fIoptions\fR] \fBneeds\-conversion \fR[\fIdb\fR 
[\fIschema\fR]]
+\fBovsdb\-tool \fR[\fIoptions\fR] \fBneeds\-conversion \fR[\fIdb\fR 
[\fIschema-list\fR]]
 .br
 \fBovsdb\-tool \fR[\fIoptions\fR] \fBdb\-version \fR[\fIdb\fR]
 .br
-\fBovsdb\-tool \fR[\fIoptions\fR] \fBschema\-version \fR[\fIschema\fR]
+\fBovsdb\-tool \fR[\fIoptions\fR] \fBschema\-version \fR[\fIschema-list\fR]
 .br
 \fBovsdb\-tool \fR[\fIoptions\fR] \fBdb\-cksum \fR[\fIdb\fR]
 .br
-\fBovsdb\-tool \fR[\fIoptions\fR] \fBschema\-cksum \fR[\fIschema\fR]
+\fBovsdb\-tool \fR[\fIoptions\fR] \fBschema\-cksum \fR[\fIschema-list\fR]
 .br
 \fBovsdb\-tool \fR[\fIoptions\fR] \fBquery \fR[\fIdb\fR] \fItransaction\fR
 .br
@@ -44,16 +44,22 @@ The \fBovsdb\-tool\fR program is a command-line tool for 
managing Open
 vSwitch database (OVSDB) files.  It does not interact directly with
 running Open vSwitch database servers (instead, use
 \fBovsdb\-client\fR).
-.
+
 .SS "Basic Commands"
-.IP "\fBcreate\fI db schema\fR"
-Reads an OVSDB schema from the file named \fIschema\fR and creates a
-new OVSDB database file named \fIdb\fR using that schema.  The new
+.IP "\fBcreate\fI db schema-list\fR"
+Reads OVSDB schemas from the files listed in \fIschema-list\fR and creates a
+new OVSDB database file named \fIdb\fR using those schemas.  The new
 database is initially empty.  This command will not overwrite an
 existing \fIdb\fR.
+
 .IP
-\fIschema\fR must contain an OVSDB schema in JSON format.  Refer to
-the OVSDB specification for details.
+The \fIschema-list\fR argument accepts either a single file name, or a
+comma seperated list of file names. Quating is usually required for them
+to appear as a single argument to ovsdb-tool. Schemas can not share
+the same name.
+
+Each \fBschema\fR must containan OVSDB schema in JSON format. 
+Refer to the OVSDB specification for details.
 .
 .IP "\fBcompact\fI db \fR[\fItarget\fR]"
 Reads \fIdb\fR and writes a compacted version.  If \fItarget\fR is
@@ -62,47 +68,52 @@ specified, the compacted version is written as a new file 
named
 omitted, then the compacted version of the database replaces \fIdb\fR
 in-place.
 .
-.IP "\fBconvert\fI db schema \fR[\fItarget\fR]"
-Reads \fIdb\fR, translating it into to the schema specified in
-\fIschema\fR, and writes out the new interpretation.  If \fItarget\fR
+.IP "\fBconvert\fI db schema-list \fR[\fItarget\fR]"
+Reads \fIdb\fR, translating it into to the schemas specified in
+\fIschema-list\fR, and writes out the new interpretation.  If \fItarget\fR
 is specified, the translated version is written as a new file named
 \fItarget\fR, which must not already exist.  If \fItarget\fR is
 omitted, then the translated version of the database replaces \fIdb\fR
 in-place.
 .IP
 This command can do simple ``upgrades'' and ``downgrades'' on a
-database's schema.  The data in \fIdb\fR must be valid when
-interpreted under \fIschema\fR, with only one exception: data in
-\fIdb\fR for tables and columns that do not exist in \fIschema\fR are
-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
+database's schemas.  The data in \fIdb\fR must be valid when
+interpreted under \fIschema-list\fR, with only one exception: data in
+\fIdb\fR for tables and columns that do not exist in \fIschema-list\fR are
+ignored.  Columns that exist in \fIschema-list\fR but not in \fIdb\fR are
+set to their default values.  All of \fIschema-list\fR's constraints apply
 in full.
 .
-.IP "\fBneeds\-conversion\fI db schema\fR"
-Reads the schema embedded in \fIdb\fR and the standalone schema in
-\fIschema\fR and compares them.  If the schemas are the same, prints
+.IP "\fBneeds\-conversion\fI db schema-list\fR"
+Reads the schemas embedded in \fIdb\fR and the standalone schemas in
+\fIschema-list\fR and compares them.  If the schemas are the same, prints
 \fBno\fR on stdout; if they differ, print \fByes\fR.
 .
 .IP "\fBdb\-version\fI db\fR"
-.IQ "\fBschema\-version\fI schema\fR"
-Prints the version number in the schema embedded within the database
-\fIdb\fR or in the standalone schema \fIschema\fR on stdout.  A schema
-version number has the form \fIx\fB.\fIy\fB.\fIz\fR.  See
-\fBovs\-vswitchd.conf.db\fR(5) for details.
+.IQ "\fBschema\-version\fI schema-list\fR"
+Prints the version number in the schemas embedded within the database
+\fIdb\fR or in the standalone schemas \fIschema-list\fR on stdout.  A single
+schema version number has the form \fIx\fB.\fIy\fB.\fIz\fR. 
+Multiple schemas have the form \fIschema-name\fB:\fIx\fB.\fIy\fB.\fIz\fR.
+One line per schema.  See \fBovs\-vswitchd.conf.db\fR(5) for details.
+
 .IP
 Schema version numbers and Open vSwitch version numbers are
 independent.
 .IP
-If \fIschema\fR or \fIdb\fR was created before schema versioning was
+If \fIschema-list\fR or \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 "\fBdb\-cksum\fI db\fR"
-.IQ "\fBschema\-cksum\fI schema\fR"
-Prints the checksum in the schema embedded within the database
-\fIdb\fR or of the standalone schema \fIschema\fR on stdout.
+.IQ "\fBschema\-cksum\fI schema-list\fR"
+Prints the checksum in the schemas embedded within the database
+\fIdb\fR or of the standalone schemas \fIschema-list\fR on stdout.
+Multiple schemas output are prefixed with \fIschema-name\fB:\fR. 
+One line per schema.
+
 .IP
-If \fIschema\fR or \fIdb\fR was created before schema checksums were
+If \fIschema-list\fR or \fIdb\fR was created before schema checksums were
 introduced, then it will not have a checksum and this command
 will print a blank line.
 .
@@ -149,7 +160,7 @@ record.
 .so lib/common.man
 .SH "FILES"
 The default \fIdb\fR is \fB@DBDIR@/conf.db\fR.  The
-default \fIschema\fR is \fB@pkgdatadir@/vswitch.ovsschema\fR.  The
+default \fIschema-list\fR is \fB@pkgdatadir@/vswitch.ovsschema\fR.  The
 \fBhelp\fR command also displays these defaults.
 .SH "SEE ALSO"
 .
diff --git a/ovsdb/ovsdb-tool.c b/ovsdb/ovsdb-tool.c
index 32883e2..49a4cbe 100644
--- a/ovsdb/ovsdb-tool.c
+++ b/ovsdb/ovsdb-tool.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2010, 2011, 2012, 2013 Nicira, Inc.
+ * Copyright (c) 2009, 2010, 2011, 2012, 2013, 2015 Nicira, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -35,7 +35,9 @@
 #include "ovsdb.h"
 #include "ovsdb-data.h"
 #include "ovsdb-error.h"
+#include "shash.h"
 #include "socket-util.h"
+#include "sset.h"
 #include "table.h"
 #include "timeval.h"
 #include "util.h"
@@ -188,20 +190,33 @@ check_ovsdb_error(struct ovsdb_error *error)
         ovs_fatal(0, "%s", ovsdb_error_to_string(error));
     }
 }
+
+static void
+parse_schema_file_names(const char *file_names, struct sset *names)
+{
+   ovsdb_parse_schema_file_names(file_names, names, default_schema());
+   ovs_assert(!sset_is_empty(names));
+}
+
 
 static void
 do_create(struct ovs_cmdl_context *ctx)
 {
     const char *db_file_name = ctx->argc >= 2 ? ctx->argv[1] : default_db();
-    const char *schema_file_name = ctx->argc >= 3 ? ctx->argv[2] : 
default_schema();
-    struct ovsdb_schema *schema;
+    const char *schema_file_name = ctx->argc >= 3 ? ctx->argv[2] : NULL;
     struct ovsdb_log *log;
     struct json *json;
+    struct shash *schemas;
+    struct sset schema_names = SSET_INITIALIZER(&schema_names);
 
-    /* Read schema from file and convert to JSON. */
-    check_ovsdb_error(ovsdb_schema_from_file(schema_file_name, &schema));
-    json = ovsdb_schema_to_json(schema);
-    ovsdb_schema_destroy(schema);
+    /* Read schema from file(s) and convert to JSON. */
+    parse_schema_file_names(schema_file_name, &schema_names);
+
+    check_ovsdb_error(ovsdb_schemas_from_files(&schema_names, &schemas));
+    sset_destroy(&schema_names);
+
+    json = ovsdb_schemas_to_json(schemas);
+    ovsdb_schemas_destroy(schemas);
 
     /* Create database file. */
     check_ovsdb_error(ovsdb_log_open(db_file_name, OVSDB_LOG_CREATE,
@@ -215,7 +230,7 @@ do_create(struct ovs_cmdl_context *ctx)
 
 static void
 compact_or_convert(const char *src_name_, const char *dst_name_,
-                   const struct ovsdb_schema *new_schema,
+                   struct shash *new_schemas,
                    const char *comment)
 {
     char *src_name, *dst_name;
@@ -249,8 +264,8 @@ compact_or_convert(const char *src_name_, const char 
*dst_name_,
     }
 
     /* Save a copy. */
-    check_ovsdb_error(new_schema
-                      ? ovsdb_file_open_as_schema(src_name, new_schema, &db)
+    check_ovsdb_error(new_schemas
+                      ? ovsdb_file_open_as_schemas(src_name, new_schemas, &db)
                       : ovsdb_file_open(src_name, true, &db, NULL));
     check_ovsdb_error(ovsdb_file_save_copy(dst_name, false, comment, db));
     ovsdb_destroy(db);
@@ -287,72 +302,158 @@ static void
 do_convert(struct ovs_cmdl_context *ctx)
 {
     const char *db = ctx->argc >= 2 ? ctx->argv[1] : default_db();
-    const char *schema = ctx->argc >= 3 ? ctx->argv[2] : default_schema();
+    const char *schema_file_name = ctx->argc >= 3 ? ctx->argv[2] : NULL;
     const char *target = ctx->argc >= 4 ? ctx->argv[3] : NULL;
-    struct ovsdb_schema *new_schema;
+    struct shash *schemas;
+    struct sset schema_names = SSET_INITIALIZER(&schema_names);
+
+    parse_schema_file_names(schema_file_name, &schema_names);
+    check_ovsdb_error(ovsdb_schemas_from_files(&schema_names, &schemas));
+    sset_destroy(&schema_names);
 
-    check_ovsdb_error(ovsdb_schema_from_file(schema, &new_schema));
-    compact_or_convert(db, target, new_schema,
+    compact_or_convert(db, target, schemas,
                        "converted by ovsdb-tool "VERSION);
-    ovsdb_schema_destroy(new_schema);
+    ovsdb_schemas_destroy(schemas);
 }
 
 static void
 do_needs_conversion(struct ovs_cmdl_context *ctx)
 {
     const char *db_file_name = ctx->argc >= 2 ? ctx->argv[1] : default_db();
-    const char *schema_file_name = ctx->argc >= 3 ? ctx->argv[2] : 
default_schema();
-    struct ovsdb_schema *schema1, *schema2;
-
-    check_ovsdb_error(ovsdb_file_read_schema(db_file_name, &schema1));
-    check_ovsdb_error(ovsdb_schema_from_file(schema_file_name, &schema2));
-    puts(ovsdb_schema_equal(schema1, schema2) ? "no" : "yes");
-    ovsdb_schema_destroy(schema1);
-    ovsdb_schema_destroy(schema2);
+    const char *schema_file_name = ctx->argc >= 3 ? ctx->argv[2] : NULL;
+    struct sset schema_names = SSET_INITIALIZER(&schema_names);
+    struct shash *schemas1;
+    struct shash *schemas2;
+    struct shash_node *node1, *node2;
+
+    /* Read schema from file(s) and convert to JSON. */
+    parse_schema_file_names(schema_file_name, &schema_names);
+    check_ovsdb_error(ovsdb_schemas_from_files(&schema_names, &schemas1));
+    sset_destroy(&schema_names);
+
+    check_ovsdb_error(ovsdb_file_read_schemas(db_file_name, &schemas2));
+
+    if (shash_count(schemas1) == shash_count(schemas2)) {
+        SHASH_FOR_EACH (node1, schemas1) {
+            struct ovsdb_schema *schema1 = node1->data, *schema2;
+
+            node2 = shash_find(schemas2, schema1->name);
+            if (!node2) {
+                /* Schmea names do not overlap. Conversion is necessary.  */
+                puts("yes");
+                goto done;
+            }
+
+            schema2 = node2->data;
+            if(!ovsdb_schema_equal(schema1, schema2)) {
+                /* Schemas that have the same name are not equivalent.
+                 * Conversion is necessary.  */
+                puts("yes");
+                goto done;
+            }
+        }
+        /* All schemas are identical, No conversion is necessary */
+        puts("no");
+    }
+
+done:
+    ovsdb_schemas_destroy(schemas1);
+    ovsdb_schemas_destroy(schemas2);
 }
 
 static void
 do_db_version(struct ovs_cmdl_context *ctx)
 {
     const char *db_file_name = ctx->argc >= 2 ? ctx->argv[1] : default_db();
+    struct shash *schemas;
     struct ovsdb_schema *schema;
 
-    check_ovsdb_error(ovsdb_file_read_schema(db_file_name, &schema));
-    puts(schema->version);
-    ovsdb_schema_destroy(schema);
+    check_ovsdb_error(ovsdb_file_read_schemas(db_file_name, &schemas));
+
+    if (shash_count(schemas) == 1) {
+        schema = shash_first(schemas)->data;
+        puts(schema->version);
+    } else {
+        struct shash_node *node;
+        SHASH_FOR_EACH (node, schemas) {
+            schema = node->data;
+            printf("%s:%s\n", schema->name, schema->version);
+        }
+    }
+
+    ovsdb_schemas_destroy(schemas);
 }
 
 static void
 do_db_cksum(struct ovs_cmdl_context *ctx)
 {
     const char *db_file_name = ctx->argc >= 2 ? ctx->argv[1] : default_db();
+    struct shash *schemas;
     struct ovsdb_schema *schema;
 
-    check_ovsdb_error(ovsdb_file_read_schema(db_file_name, &schema));
-    puts(schema->cksum);
-    ovsdb_schema_destroy(schema);
+    check_ovsdb_error(ovsdb_file_read_schemas(db_file_name, &schemas));
+
+    if (shash_count(schemas) == 1) {
+        schema = shash_first(schemas)->data;
+        puts(schema->cksum);
+    } else {
+        struct shash_node *node;
+        SHASH_FOR_EACH (node, schemas) {
+            schema = node->data;
+            printf("%s:%s\n", schema->name, schema->cksum);
+        }
+    }
+    ovsdb_schemas_destroy(schemas);
 }
 
 static void
 do_schema_version(struct ovs_cmdl_context *ctx)
 {
     const char *schema_file_name = ctx->argc >= 2 ? ctx->argv[1] : 
default_schema();
+    struct shash *schemas;
     struct ovsdb_schema *schema;
-
-    check_ovsdb_error(ovsdb_schema_from_file(schema_file_name, &schema));
-    puts(schema->version);
-    ovsdb_schema_destroy(schema);
+    struct sset schema_names = SSET_INITIALIZER(&schema_names);
+
+    parse_schema_file_names(schema_file_name, &schema_names);
+    check_ovsdb_error(ovsdb_schemas_from_files(&schema_names, &schemas));
+    sset_destroy(&schema_names);
+
+    if (shash_count(schemas) == 1) {
+        schema = shash_first(schemas)->data;
+        puts(schema->version);
+    } else {
+        struct shash_node *node;
+        SHASH_FOR_EACH (node, schemas) {
+            schema = node->data;
+            printf("%s:%s\n", schema->name, schema->version);
+        }
+    }
+    ovsdb_schemas_destroy(schemas);
 }
 
 static void
 do_schema_cksum(struct ovs_cmdl_context *ctx)
 {
-    const char *schema_file_name = ctx->argc >= 2 ? ctx->argv[1] : 
default_schema();
+    const char *schema_file_name = ctx->argc >= 2 ? ctx->argv[1] : NULL;
+    struct shash *schemas;
     struct ovsdb_schema *schema;
-
-    check_ovsdb_error(ovsdb_schema_from_file(schema_file_name, &schema));
-    puts(schema->cksum);
-    ovsdb_schema_destroy(schema);
+    struct sset schema_names = SSET_INITIALIZER(&schema_names);
+
+    parse_schema_file_names(schema_file_name, &schema_names);
+    check_ovsdb_error(ovsdb_schemas_from_files(&schema_names, &schemas));
+    sset_destroy(&schema_names);
+
+    if (shash_count(schemas) == 1) {
+        schema = shash_first(schemas)->data;
+        puts(schema->cksum);
+    } else {
+        struct shash_node *node;
+        SHASH_FOR_EACH (node, schemas) {
+            schema = node->data;
+            printf("%s:%s\n", schema->name, schema->cksum);
+        }
+    }
+    ovsdb_schemas_destroy(schemas);
 }
 
 static void
@@ -503,13 +604,13 @@ do_show_log(struct ovs_cmdl_context *ctx)
     const char *db_file_name = ctx->argc >= 2 ? ctx->argv[1] : default_db();
     struct shash names;
     struct ovsdb_log *log;
+    struct shash *schemas;
     struct ovsdb_schema *schema;
     unsigned int i;
 
     check_ovsdb_error(ovsdb_log_open(db_file_name, OVSDB_LOG_READ_ONLY,
                                      -1, &log));
     shash_init(&names);
-    schema = NULL;
     for (i = 0; ; i++) {
         struct json *json;
 
@@ -520,9 +621,16 @@ do_show_log(struct ovs_cmdl_context *ctx)
 
         printf("record %u:", i);
         if (i == 0) {
-            check_ovsdb_error(ovsdb_schema_from_json(json, &schema));
-            printf(" \"%s\" schema, version=\"%s\", cksum=\"%s\"\n",
-                   schema->name, schema->version, schema->cksum);
+            struct shash_node *node;
+
+            check_ovsdb_error(ovsdb_schemas_from_json(json, &schemas));
+            SHASH_FOR_EACH (node, schemas) {
+                struct ovsdb_schema *schema = node->data;
+
+                printf(" \"%s\" schema, version=\"%s\", cksum=\"%s\"\n",
+                       schema->name, schema->version, schema->cksum);
+            }
+            check_ovsdb_error(ovsdb_schemas_join(schemas, &schema));
         } else if (json->type == JSON_OBJECT) {
             struct json *date, *comment;
 
@@ -556,6 +664,7 @@ do_show_log(struct ovs_cmdl_context *ctx)
     }
 
     ovsdb_log_close(log);
+    ovsdb_schemas_destroy(schemas);
     ovsdb_schema_destroy(schema);
     /* XXX free 'names'. */
 }
diff --git a/ovsdb/ovsdb.c b/ovsdb/ovsdb.c
index 5305360..287b839 100644
--- a/ovsdb/ovsdb.c
+++ b/ovsdb/ovsdb.c
@@ -28,7 +28,7 @@
 #include "table.h"
 #include "transaction.h"
 
-struct ovsdb_schema *
+static struct ovsdb_schema *
 ovsdb_schema_create(const char *name, const char *version, const char *cksum)
 {
     struct ovsdb_schema *schema;
@@ -42,7 +42,7 @@ ovsdb_schema_create(const char *name, const char *version, 
const char *cksum)
     return schema;
 }
 
-struct ovsdb_schema *
+static struct ovsdb_schema *
 ovsdb_schema_clone(const struct ovsdb_schema *old)
 {
     struct ovsdb_schema *new;
@@ -115,7 +115,7 @@ ovsdb_schema_join(struct ovsdb_schema *dst, const struct 
ovsdb_schema *src)
     return NULL;
 }
 
-struct ovsdb_error *
+static struct ovsdb_error *
 ovsdb_schema_from_file(const char *file_name, struct ovsdb_schema **schemap)
 {
     struct ovsdb_schema *schema;
diff --git a/ovsdb/ovsdb.h b/ovsdb/ovsdb.h
index b61b6ba..4af6cab 100644
--- a/ovsdb/ovsdb.h
+++ b/ovsdb/ovsdb.h
@@ -37,15 +37,8 @@ struct ovsdb_schema {
     struct shash tables;        /* Contains "struct ovsdb_table_schema *"s. */
 };
 
-struct ovsdb_schema *ovsdb_schema_create(const char *name,
-                                         const char *version,
-                                         const char *cksum);
-struct ovsdb_schema *ovsdb_schema_clone(const struct ovsdb_schema *);
 void ovsdb_schema_destroy(struct ovsdb_schema *);
 
-struct ovsdb_error *ovsdb_schema_from_file(const char *file_name,
-                                           struct ovsdb_schema **)
-    OVS_WARN_UNUSED_RESULT;
 struct ovsdb_error *ovsdb_schema_from_json(struct json *,
                                            struct ovsdb_schema **)
     OVS_WARN_UNUSED_RESULT;
-- 
1.9.1

_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to