[ovs-dev] [PATCH 3/3 v3] ovsdb-server: Add and remove databases during run time.

Gurucharan Shetty shettyg at nicira.com
Tue Jun 25 16:56:07 UTC 2013


Please ignore this. I will send it again.

On Tue, Jun 25, 2013 at 1:02 AM, Gurucharan Shetty <shettyg at nicira.com>wrote:

> The commit allows a user to add a database file to a
> ovsdb-server during run time. One can also remove a
> database file from ovsdb-server's control.
>
> Feature #14595.
> Signed-off-by: Gurucharan Shetty <gshetty at nicira.com>
> ---
>  ovsdb/jsonrpc-server.c  |    9 ++
>  ovsdb/jsonrpc-server.h  |    2 +
>  ovsdb/ovsdb-server.1.in |   24 ++++
>  ovsdb/ovsdb-server.c    |  295
> ++++++++++++++++++++++++++++++++++++++---------
>  ovsdb/ovsdb.c           |    3 +
>  ovsdb/server.c          |   13 +++
>  ovsdb/server.h          |    1 +
>  tests/ovsdb-server.at   |  118 +++++++++++++++++++
>  8 files changed, 410 insertions(+), 55 deletions(-)
>
> diff --git a/ovsdb/jsonrpc-server.c b/ovsdb/jsonrpc-server.c
> index 9f99d64..016dd33 100644
> --- a/ovsdb/jsonrpc-server.c
> +++ b/ovsdb/jsonrpc-server.c
> @@ -132,6 +132,15 @@ ovsdb_jsonrpc_server_add_db(struct
> ovsdb_jsonrpc_server *svr, struct ovsdb *db)
>      return ovsdb_server_add_db(&svr->up, db);
>  }
>
> +/* Removes 'db' from the set of databases served out by 'svr'.  Returns
> + * true if successful, false if there is no database associated with
> 'db'. */
> +bool
> +ovsdb_jsonrpc_server_remove_db(struct ovsdb_jsonrpc_server *svr,
> +                                struct ovsdb *db)
> +{
> +    return ovsdb_server_remove_db(&svr->up, db);
> +}
> +
>  void
>  ovsdb_jsonrpc_server_destroy(struct ovsdb_jsonrpc_server *svr)
>  {
> diff --git a/ovsdb/jsonrpc-server.h b/ovsdb/jsonrpc-server.h
> index f2395fc..e6a1642 100644
> --- a/ovsdb/jsonrpc-server.h
> +++ b/ovsdb/jsonrpc-server.h
> @@ -26,6 +26,8 @@ struct simap;
>  struct ovsdb_jsonrpc_server *ovsdb_jsonrpc_server_create(void);
>  bool ovsdb_jsonrpc_server_add_db(struct ovsdb_jsonrpc_server *,
>                                   struct ovsdb *);
> +bool ovsdb_jsonrpc_server_remove_db(struct ovsdb_jsonrpc_server *,
> +                                     struct ovsdb *);
>  void ovsdb_jsonrpc_server_destroy(struct ovsdb_jsonrpc_server *);
>
>  /* Options for a remote. */
> diff --git a/ovsdb/ovsdb-server.1.in b/ovsdb/ovsdb-server.1.in
> index ceefef5..4339620 100644
> --- a/ovsdb/ovsdb-server.1.in
> +++ b/ovsdb/ovsdb-server.1.in
> @@ -150,6 +150,30 @@ not list remotes added indirectly because they were
> read from the
>  database by configuring a
>  \fBdb:\fIdb\fB,\fItable\fB,\fIcolumn\fR remote.
>  .
> +.IP "\fBovsdb\-server/add\-db \fIdatabase\fR"
> +Adds the \fIdatabase\fR to the running \fBovsdb\-server\fR.  The database
> +file must already have been created and initialized using, for example,
> +\fBovsdb\-tool create\fR.
> +.
> +.IP "\fBovsdb\-server/remove\-db \fIdatabase\fR"
> +Removes \fIdatabase\fR from the running \fBovsdb\-server\fR.
>  \fIdatabase\fR
> +must be a database name as listed by \fBovsdb-server/list\-dbs\fR.
> +.IP
> +If a remote has been configured that points to the specified
> +\fIdatabase\fR (e.g. \fB\-\-remote=db:\fIdatabase\fB,\fR... on the
> +command line), then it is automatically removed.
> +.IP
> +Any public key infrastructure options specified through this database
> +(e.g. \fB\-\-private\-key=db:\fIdatabase,\fR... on the command line)
> +are no longer checked for new changes, but any files previously
> +configured are still used. (Adding \fIdatabase\fR back will cause the
> +public key infrastructure options specified through it to update
> +again.)
> +.
> +.IP "\fBovsdb\-server/list\-dbs"
> +Outputs a list of the currently configured databases added either through
> +the command line or through the \fBovsdb\-server/add\-db\fR command.
> +.
>  .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 72c13c6..670f13f 100644
> --- a/ovsdb/ovsdb-server.c
> +++ b/ovsdb/ovsdb-server.c
> @@ -73,25 +73,27 @@ static char *private_key_file;
>  static char *certificate_file;
>  static char *ca_cert_file;
>  static bool bootstrap_ca_cert;
> +static bool ssl_reconfigure = true;
>
>  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 load_config_aux {
>      struct sset *remotes;
> +    struct sset *dbnames;
>      struct shash *all_dbs;
>      FILE *config_tmpfile;
> +    struct ovsdb_jsonrpc_server *jsonrpc;
>  };
>  static unixctl_cb_func ovsdb_server_add_remote;
> -
> -struct remove_remote_aux {
> -    struct sset *remotes;
> -    FILE *config_tmpfile;
> -};
>  static unixctl_cb_func ovsdb_server_remove_remote;
>  static unixctl_cb_func ovsdb_server_list_remotes;
>
> +static unixctl_cb_func ovsdb_server_add_database;
> +static unixctl_cb_func ovsdb_server_remove_database;
> +static unixctl_cb_func ovsdb_server_list_databases;
> +
>  static void open_db(struct ovsdb_jsonrpc_server *jsonrpc,
>                      struct db *db, struct shash *all_dbs);
>
> @@ -108,8 +110,8 @@ static void update_remote_status(const struct
> ovsdb_jsonrpc_server *jsonrpc,
>                                   const struct sset *remotes,
>                                   struct shash *all_dbs);
>
> -static void save_config(FILE *config_file, const struct sset *);
> -static void load_config(FILE *config_file, struct sset *);
> +static void save_config(FILE *config_file, const struct load_config_aux
> *);
> +static void load_config(FILE *config_file, struct load_config_aux *);
>
>  int
>  main(int argc, char *argv[])
> @@ -118,15 +120,14 @@ main(int argc, char *argv[])
>      char *run_command = NULL;
>      struct unixctl_server *unixctl;
>      struct ovsdb_jsonrpc_server *jsonrpc;
> -    struct sset remotes;
> +    struct sset remotes, dbnames;
> +    const char *dbname;
>      struct process *run_process;
>      bool exiting;
>      int retval;
>      long long int status_timer = LLONG_MIN;
> -    struct add_remote_aux add_remote_aux;
> -    struct remove_remote_aux remove_remote_aux;
>      FILE *config_tmpfile;
> -
> +    struct load_config_aux load_config_aux;
>      struct db *db;
>      struct shash all_dbs;
>      struct shash_node *node;
> @@ -149,25 +150,36 @@ main(int argc, char *argv[])
>      if (!config_tmpfile) {
>          ovs_fatal(errno, "failed to create temporary file");
>      }
> -    save_config(config_tmpfile, &remotes);
> +
> +    sset_init(&dbnames);
> +    if (argc > 0) {
> +        for (i = 0; i < argc; i++) {
> +            sset_add(&dbnames, argv[i]);
> +         }
> +    } else {
> +        char *default_db = xasprintf("%s/conf.db", ovs_dbdir());
> +        sset_add(&dbnames, default_db);
> +        free(default_db);
> +    }
> +
> +    load_config_aux.remotes = &remotes;
> +    load_config_aux.dbnames = &dbnames;
> +    load_config_aux.config_tmpfile = config_tmpfile;
> +
> +    save_config(config_tmpfile, &load_config_aux);
>
>      daemonize_start();
>
>      /* Load the saved config. */
> -    load_config(config_tmpfile, &remotes);
> -
> -    shash_init(&all_dbs);
> +    load_config(config_tmpfile, &load_config_aux);
>      jsonrpc = ovsdb_jsonrpc_server_create();
>
> -    if (argc > 0) {
> -        for (i = 0; i < argc; i++) {
> -            db = xzalloc(sizeof *db);
> -            db->filename = argv[i];
> -            open_db(jsonrpc, db, &all_dbs);
> -         }
> -    } else {
> +    shash_init(&all_dbs);
> +    load_config_aux.all_dbs = &all_dbs;
> +    load_config_aux.jsonrpc = jsonrpc;
> +    SSET_FOR_EACH(dbname, &dbnames) {
>          db = xzalloc(sizeof *db);
> -        db->filename = xasprintf("%s/conf.db", ovs_dbdir());
> +        db->filename = strdup(dbname);
>          open_db(jsonrpc, db, &all_dbs);
>      }
>
> @@ -209,20 +221,20 @@ 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.all_dbs = &all_dbs;
> -    add_remote_aux.config_tmpfile = config_tmpfile;
>      unixctl_command_register("ovsdb-server/add-remote", "REMOTE", 1, 1,
> -                             ovsdb_server_add_remote, &add_remote_aux);
> -
> -    remove_remote_aux.remotes = &remotes;
> -    remove_remote_aux.config_tmpfile = config_tmpfile;
> +                             ovsdb_server_add_remote, &load_config_aux);
>      unixctl_command_register("ovsdb-server/remove-remote", "REMOTE", 1, 1,
> -                             ovsdb_server_remove_remote,
> &remove_remote_aux);
> -
> +                             ovsdb_server_remove_remote,
> &load_config_aux);
>      unixctl_command_register("ovsdb-server/list-remotes", "", 0, 0,
>                               ovsdb_server_list_remotes, &remotes);
>
> +    unixctl_command_register("ovsdb-server/add-db", "DB", 1, 1,
> +                             ovsdb_server_add_database, &load_config_aux);
> +    unixctl_command_register("ovsdb-server/remove-db", "DB", 1, 1,
> +                             ovsdb_server_remove_database,
> &load_config_aux);
> +    unixctl_command_register("ovsdb-server/list-dbs", "", 0, 0,
> +                             ovsdb_server_list_databases, &all_dbs);
> +
>      exiting = false;
>      while (!exiting) {
>          memory_run();
> @@ -874,6 +886,9 @@ reconfigure_from_db(struct ovsdb_jsonrpc_server
> *jsonrpc,
>      shash_destroy_free_data(&resolved_remotes);
>
>      /* Configure SSL. */
> +    if (!ssl_reconfigure) {
> +        return;
> +    }
>      stream_ssl_set_key_and_cert(query_db_string(all_dbs,
> private_key_file),
>                                  query_db_string(all_dbs,
> certificate_file));
>      stream_ssl_set_ca_cert_file(query_db_string(all_dbs, ca_cert_file),
> @@ -954,7 +969,7 @@ 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_;
> +    struct load_config_aux *aux = aux_;
>      const char *remote = argv[1];
>
>      const struct ovsdb_column *column;
> @@ -968,7 +983,7 @@ ovsdb_server_add_remote(struct unixctl_conn *conn, int
> argc OVS_UNUSED,
>                                  &db, &table, &column));
>      if (!retval) {
>          if (sset_add(aux->remotes, remote)) {
> -            save_config(aux->config_tmpfile, aux->remotes);
> +            save_config(aux->config_tmpfile, aux);
>          }
>          unixctl_command_reply(conn, NULL);
>      } else {
> @@ -983,13 +998,13 @@ static void
>  ovsdb_server_remove_remote(struct unixctl_conn *conn, int argc OVS_UNUSED,
>                             const char *argv[], void *aux_)
>  {
> -    struct remove_remote_aux *aux = aux_;
> +    struct load_config_aux *aux = aux_;
>      struct sset_node *node;
>
>      node = sset_find(aux->remotes, argv[1]);
>      if (node) {
>          sset_delete(aux->remotes, node);
> -        save_config(aux->config_tmpfile, aux->remotes);
> +        save_config(aux->config_tmpfile, aux);
>          unixctl_command_reply(conn, NULL);
>      } else {
>          unixctl_command_reply_error(conn, "no such remote");
> @@ -1017,6 +1032,155 @@ ovsdb_server_list_remotes(struct unixctl_conn
> *conn, int argc OVS_UNUSED,
>      ds_destroy(&s);
>  }
>
> +static bool
> +ssl_path_valid(struct shash *all_dbs, const char *config)
> +{
> +    const struct ovsdb_column *column;
> +    const struct ovsdb_table *table;
> +    char *retval;
> +    const struct db *db;
> +
> +    if (!config) {
> +        return true;
> +    }
> +
> +    retval = (strncmp("db:", config, 3)
> +              ? NULL
> +              : parse_db_column(all_dbs, config, &db, &table, &column));
> +    if (retval) {
> +        free(retval);
> +        return false;
> +    }
> +    return true;
> +}
> +
> +/* "ovsdb-server/add-db DB": adds the DB to ovsdb-server. */
> +static void
> +ovsdb_server_add_database(struct unixctl_conn *conn, int argc OVS_UNUSED,
> +                          const char *argv[], void *aux_)
> +{
> +    struct load_config_aux *aux = aux_;
> +    const char *filename = argv[1];
> +    struct db *db;
> +    struct ovsdb_error *error;
> +
> +    db = xzalloc(sizeof *db);
> +    db->filename = strdup(filename);
> +
> +    error = ovsdb_file_open(db->filename, false,
> +                            &db->db, &db->file);
> +    if (error) {
> +        VLOG_ERR("%s", ovsdb_error_to_string(error));
> +        free(db->filename);
> +        free(db);
> +        free(error);
> +        unixctl_command_reply_error(conn, "Failed to open the database
> file.");
> +        return;
> +    }
> +
> +    if (!ovsdb_jsonrpc_server_add_db(aux->jsonrpc, db->db)) {
> +        VLOG_ERR("%s: duplicate database name", db->db->schema->name);
> +        ovsdb_destroy(db->db);
> +        free(db->filename);
> +        free(db);
> +        unixctl_command_reply_error(conn, "Failed to open the database
> file.");
> +        return;
> +    }
> +
> +    shash_add_once(aux->all_dbs, db->filename, db);
> +    sset_add(aux->dbnames, filename);
> +    save_config(aux->config_tmpfile, aux);
> +
> +    /* Unflag SSL paths if it becomes valid with this db. */
> +    if (!ssl_reconfigure && ssl_path_valid(aux->all_dbs,
> private_key_file) &&
> +        ssl_path_valid(aux->all_dbs, certificate_file) &&
> +        ssl_path_valid(aux->all_dbs, ca_cert_file)) {
> +            ssl_reconfigure = true;
> +    }
> +
> +    unixctl_command_reply(conn, NULL);
> +}
> +
> +static void
> +ovsdb_server_remove_database(struct unixctl_conn *conn, int argc
> OVS_UNUSED,
> +                             const char *argv[], void *aux_)
> +{
> +    struct load_config_aux *aux = aux_;
> +    struct shash *all_dbs = aux->all_dbs;
> +    struct sset *remotes = aux->remotes;
> +    struct db *db;
> +    const struct db *dbp;
> +    struct shash_node *node;
> +    const char *remote, *next;
> +    const struct ovsdb_column *column;
> +    const struct ovsdb_table *table;
> +    char *retval;
> +
> +    node = shash_find(all_dbs, argv[1]);
> +    if (node) {
> +        if (!ovsdb_jsonrpc_server_remove_db(aux->jsonrpc,
> +                                           ((struct db
> *)node->data)->db)) {
> +            unixctl_command_reply_error(conn,
> +                                        "Database not in jsonrpc
> server.");
> +            return;
> +        }
> +
> +        /* Remove any remotes associated with the database. */
> +        SSET_FOR_EACH_SAFE(remote, next, remotes) {
> +            if (!strncmp("db:", remote, 3)) {
> +                retval =  parse_db_column(all_dbs, remote, &dbp, &table,
> +                                          &column);
> +                if (!retval && !strcmp(dbp->filename, argv[1])) {
> +                    sset_find_and_delete(remotes, remote);
> +                } else if (retval) {
> +                    free(retval);
> +                }
> +            }
> +        }
> +
> +        db = node->data;
> +        ovsdb_destroy(db->db);
> +        shash_delete(all_dbs, node);
> +        free(db->filename);
> +        free(db);
> +
> +        /* Flag any SSL paths provided by this database. */
> +        if (ssl_reconfigure) {
> +            if (!ssl_path_valid(all_dbs, private_key_file) || \
> +                !ssl_path_valid(all_dbs, certificate_file) || \
> +                !ssl_path_valid(all_dbs, ca_cert_file)) {
> +                ssl_reconfigure = false;
> +                VLOG_ERR("SSL paths no longer valid.");
> +            }
> +        }
> +    } else {
> +        unixctl_command_reply_error(conn, "Failed to find the database.");
> +        return;
> +    }
> +
> +    sset_find_and_delete(aux->dbnames, argv[1]);
> +    save_config(aux->config_tmpfile, aux);
> +    unixctl_command_reply(conn, NULL);
> +}
> +
> +static void
> +ovsdb_server_list_databases(struct unixctl_conn *conn, int argc
> OVS_UNUSED,
> +                            const char *argv[] OVS_UNUSED, void *all_dbs_)
> +{
> +    struct shash *all_dbs = all_dbs_;
> +    struct shash_node *node;
> +    struct ds s;
> +
> +    ds_init(&s);
> +
> +    SHASH_FOR_EACH(node, all_dbs) {
> +        ds_put_format(&s, "%s\n", node->name);
> +    }
> +
> +    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)
> @@ -1142,24 +1306,33 @@ usage(void)
>  }
>
>  /* Truncates and replaces the contents of 'config_file' by a
> representation
> - * of 'remotes'. */
> + * of 'aux->remotes' and 'aux->dbnames'. */
>  static void
> -save_config(FILE *config_file, const struct sset *remotes)
> +save_config(FILE *config_file, const struct load_config_aux *aux)
>  {
> -    const char *remote;
> -    struct json *json;
> +    const char *remote, *dbname;
> +    struct json *obj, *arr1, *arr2;
>      char *s;
>
>      if (ftruncate(fileno(config_file), 0) == -1) {
>          VLOG_FATAL("failed to truncate temporary file (%s)",
> strerror(errno));
>      }
>
> -    json = json_array_create_empty();
> -    SSET_FOR_EACH (remote, remotes) {
> -        json_array_add(json, json_string_create(remote));
> +    arr1 = json_array_create_empty();
> +    SSET_FOR_EACH (remote, aux->remotes) {
> +        json_array_add(arr1, json_string_create(remote));
>      }
> -    s = json_to_string(json, 0);
> -    json_destroy(json);
> +
> +    arr2 = json_array_create_empty();
> +    SSET_FOR_EACH (dbname, aux->dbnames) {
> +        json_array_add(arr2, json_string_create(dbname));
> +    }
> +
> +    obj = json_object_create();
> +    json_object_put(obj, "remotes", arr1);
> +    json_object_put(obj, "dbnames", arr2);
> +    s = json_to_string(obj, 0);
> +    json_destroy(obj);
>
>      if (fseek(config_file, 0, SEEK_SET) != 0
>          || fputs(s, config_file) == EOF
> @@ -1169,15 +1342,18 @@ save_config(FILE *config_file, const struct sset
> *remotes)
>      free(s);
>  }
>
> -/* Clears and replaces 'remotes' by a configuration read from
> 'config_file',
> - * which must have been previously written by save_config(). */
> +/* Clears and replaces 'aux->remotes' and 'aux->dbnames' by a
> configuration
> + * read from 'config_file', which must have been previously written by
> + * save_config(). */
>  static void
> -load_config(FILE *config_file, struct sset *remotes)
> +load_config(FILE *config_file, struct load_config_aux *aux)
>  {
> -    struct json *json;
> +    struct json *json, *json_arr;
>      size_t i;
> +    struct shash_node *node;
>
> -    sset_clear(remotes);
> +    sset_clear(aux->remotes);
> +    sset_clear(aux->dbnames);
>
>      if (fseek(config_file, 0, SEEK_SET) != 0) {
>          VLOG_FATAL("seek failed in temporary file (%s)", strerror(errno));
> @@ -1186,10 +1362,19 @@ load_config(FILE *config_file, struct sset
> *remotes)
>      if (json->type == JSON_STRING) {
>          VLOG_FATAL("reading json failed (%s)", json_string(json));
>      }
> -    ovs_assert(json->type == JSON_ARRAY);
> -    for (i = 0; i < json->u.array.n; i++) {
> -        const struct json *remote = json->u.array.elems[i];
> -        sset_add(remotes, json_string(remote));
> +    ovs_assert(json->type == JSON_OBJECT);
> +
> +    SHASH_FOR_EACH (node, json_object(json)) {
> +        json_arr = node->data;
> +        ovs_assert(json_arr->type == JSON_ARRAY);
> +        for (i = 0; i < json_arr->u.array.n; i++) {
> +            const struct json *elem = json_arr->u.array.elems[i];
> +            if (!strcmp(node->name, "remotes")) {
> +                sset_add(aux->remotes, json_string(elem));
> +            } else if (!strcmp(node->name, "dbnames")) {
> +                sset_add(aux->dbnames, json_string(elem));
> +            }
> +        }
>      }
>      json_destroy(json);
>  }
> diff --git a/ovsdb/ovsdb.c b/ovsdb/ovsdb.c
> index 6b53f4a..35e3153 100644
> --- a/ovsdb/ovsdb.c
> +++ b/ovsdb/ovsdb.c
> @@ -25,6 +25,9 @@
>  #include "simap.h"
>  #include "table.h"
>  #include "transaction.h"
> +#include "vlog.h"
> +
> +VLOG_DEFINE_THIS_MODULE(ovsdb);
>
>  struct ovsdb_schema *
>  ovsdb_schema_create(const char *name, const char *version, const char
> *cksum)
> diff --git a/ovsdb/server.c b/ovsdb/server.c
> index bf4ef3c..82f55cb 100644
> --- a/ovsdb/server.c
> +++ b/ovsdb/server.c
> @@ -132,6 +132,19 @@ ovsdb_server_add_db(struct ovsdb_server *server,
> struct ovsdb *db)
>      return shash_add_once(&server->dbs, db->schema->name, db);
>  }
>
> +/* Removes 'db' from the set of databases served out by 'server'.  Returns
> + * true if successful, false if there is no db associated with
> + * db->schema->name. */
> +bool
> +ovsdb_server_remove_db(struct ovsdb_server *server, struct ovsdb *db)
> +{
> +    void *data = shash_find_and_delete(&server->dbs, db->schema->name);
> +    if (data) {
> +        return true;
> +    }
> +    return false;
> +}
> +
>  /* Destroys 'server'. */
>  void
>  ovsdb_server_destroy(struct ovsdb_server *server)
> diff --git a/ovsdb/server.h b/ovsdb/server.h
> index 561f01e..047cbb7 100644
> --- a/ovsdb/server.h
> +++ b/ovsdb/server.h
> @@ -83,6 +83,7 @@ struct ovsdb_server {
>
>  void ovsdb_server_init(struct ovsdb_server *);
>  bool ovsdb_server_add_db(struct ovsdb_server *, struct ovsdb *);
> +bool ovsdb_server_remove_db(struct ovsdb_server *, struct ovsdb *);
>  void ovsdb_server_destroy(struct ovsdb_server *);
>
>  struct ovsdb_lock_waiter *ovsdb_server_lock(struct ovsdb_server *,
> diff --git a/tests/ovsdb-server.at b/tests/ovsdb-server.at
> index 2368cbc..d775aa7 100644
> --- a/tests/ovsdb-server.at
> +++ b/tests/ovsdb-server.at
> @@ -164,6 +164,124 @@ AT_CHECK(
>  OVSDB_SERVER_SHUTDOWN
>  AT_CLEANUP
>
> +AT_SETUP([ovsdb-server/add-db and remove-db])
> +AT_KEYWORDS([ovsdb server positive])
> +ON_EXIT([kill `cat ovsdb-server.pid`])
> +OVS_RUNDIR=`pwd`; export OVS_RUNDIR
> +OVS_LOGDIR=`pwd`; export OVS_LOGDIR
> +ordinal_schema > schema1
> +constraint_schema > schema2
> +AT_CHECK([ovsdb-tool create db1 schema1], [0], [ignore], [ignore])
> +AT_CHECK([ovsdb-tool create db2 schema2], [0], [ignore], [ignore])
> +
> +# Start ovsdb-server with just a single database - db1.
> +AT_CHECK([ovsdb-server --detach --no-chdir --pidfile
> --remote=punix:socket db1], [0])
> +AT_CHECK([ovs-appctl -t ovsdb-server ovsdb-server/list-dbs],
> +  [0], [db1
> +])
> +
> +# Add the second database.
> +AT_CHECK([ovs-appctl -t ovsdb-server ovsdb-server/add-db db2], [0])
> +AT_CHECK([ovs-appctl -t ovsdb-server ovsdb-server/list-dbs],
> +  [0], [db1
> +db2
> +])
> +
> +# The databases are responsive.
> +AT_CHECK([ovsdb-client list-tables unix:socket constraints], [0],
> [ignore], [ignore])
> +AT_CHECK([ovsdb-client list-tables unix:socket ordinals], [0], [ignore],
> [ignore])
> +
> +# Add an already added database.
> +AT_CHECK([ovs-appctl -t ovsdb-server ovsdb-server/add-db db2], [2],
> +  [], [Failed to open the database file.
> +ovs-appctl: ovsdb-server: server returned an error
> +])
> +
> +# Add a non-existing database.
> +AT_CHECK([ovs-appctl -t ovsdb-server ovsdb-server/add-db db3], [2],
> +  [], [Failed to open the database file.
> +ovs-appctl: ovsdb-server: server returned an error
> +])
> +
> +# Add a remote through a db path in db1.
> +AT_CHECK([ovs-appctl -t ovsdb-server ovsdb-server/add-remote
> db:ordinals,ordinals,name], [0])
> +AT_CHECK([ovs-appctl -t ovsdb-server ovsdb-server/list-remotes],
> +  [0], [db:ordinals,ordinals,name
> +punix:socket
> +])
> +
> +# Removing db1 should also remove the remote.
> +AT_CHECK([ovs-appctl -t ovsdb-server ovsdb-server/remove-db db1], [0])
> +AT_CHECK([ovs-appctl -t ovsdb-server ovsdb-server/list-dbs],
> +  [0], [db2
> +])
> +AT_CHECK([ovs-appctl -t ovsdb-server ovsdb-server/list-remotes],
> +  [0], [punix:socket
> +])
> +AT_CHECK([ovsdb-client list-tables unix:socket ordinals], [1], [ignore],
> [ignore])
> +
> +# Remove db2.
> +AT_CHECK([ovs-appctl -t ovsdb-server ovsdb-server/remove-db db2], [0])
> +AT_CHECK([ovs-appctl -t ovsdb-server ovsdb-server/list-dbs],
> +  [0], [])
> +AT_CHECK([ovsdb-client list-tables unix:socket constraints], [1],
> [ignore], [ignore])
> +
> +# Remove a non-existant database.
> +AT_CHECK([ovs-appctl -t ovsdb-server ovsdb-server/remove-db db1], [2],
> +  [], [Failed to find the database.
> +ovs-appctl: ovsdb-server: server returned an error
> +])
> +AT_CLEANUP
> +
> +AT_SETUP([ovsdb-server/add-db and remove-db with --monitor])
> +AT_KEYWORDS([ovsdb server positive])
> +# Start ovsdb-server, initially with one db.
> +OVS_RUNDIR=`pwd`; export OVS_RUNDIR
> +OVS_LOGDIR=`pwd`; export OVS_LOGDIR
> +ordinal_schema > schema
> +AT_CHECK([ovsdb-tool create db1 schema], [0], [ignore], [ignore])
> +ON_EXIT([kill `cat *.pid`])
> +AT_CHECK([ovsdb-server -v -vvlog:off --monitor --detach --no-chdir
> --pidfile --log-file db1])
> +
> +# Add the second database.
> +constraint_schema > schema2
> +AT_CHECK([ovsdb-tool create db2 schema2], [0], [ignore], [ignore])
> +AT_CHECK([ovs-appctl -t ovsdb-server ovsdb-server/add-db db2], [0])
> +AT_CHECK([ovs-appctl -t ovsdb-server ovsdb-server/list-dbs],
> +  [0], [db1
> +db2
> +])
> +
> +# Kill the daemon process, making it look like a segfault,
> +# and wait for a new daemon process to get spawned.
> +cp ovsdb-server.pid old.pid
> +AT_CHECK([kill -SEGV `cat ovsdb-server.pid`])
> +OVS_WAIT_WHILE([kill -0 `cat old.pid`])
> +OVS_WAIT_UNTIL(
> +  [test -s ovsdb-server.pid && test `cat ovsdb-server.pid` != `cat
> old.pid`])
> +AT_CHECK([ovs-appctl -t ovsdb-server ovsdb-server/list-dbs],
> +  [0], [db1
> +db2
> +])
> +
> +# Remove the recently added database.
> +AT_CHECK([ovs-appctl -t ovsdb-server ovsdb-server/remove-db db2])
> +AT_CHECK([ovs-appctl -t ovsdb-server ovsdb-server/list-dbs],
> +  [0], [db1
> +])
> +
> +# Kill the daemon process, making it look like a segfault,
> +# and wait for a new daemon process to get spawned.
> +cp ovsdb-server.pid old.pid
> +AT_CHECK([kill -SEGV `cat ovsdb-server.pid`])
> +OVS_WAIT_WHILE([kill -0 `cat old.pid`])
> +OVS_WAIT_UNTIL(
> +  [test -s ovsdb-server.pid && test `cat ovsdb-server.pid` != `cat
> old.pid`])
> +AT_CHECK([ovs-appctl -t ovsdb-server ovsdb-server/list-dbs],
> +  [0], [db1
> +])
> +AT_CLEANUP
> +
>  AT_SETUP([--remote=db: implementation])
>  AT_KEYWORDS([ovsdb server positive])
>  OVS_RUNDIR=`pwd`; export OVS_RUNDIR
> --
> 1.7.9.5
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.openvswitch.org/pipermail/ovs-dev/attachments/20130625/dfcb9b66/attachment-0003.html>


More information about the dev mailing list