On Wed, Jun 12, 2013 at 5:10 PM, Ben Pfaff <b...@nicira.com> wrote:

> ---
> This is unpolished but it shows the approach I have in mind.
> Sending out for comments on the approach.
>
I am fine with the approach. The two negatives I see with this:
* If /tmp is cleaned up routinely, we will loose the information. If we
decide to put this in /etc/openvswitch, it may look a little dirty when
program is abnormally terminated.
* If we have multiple run time data, (ex: add/remove databases) we may need
multiple files.

If you are fine with this, I am fine with it.



>
> diff --git a/ovsdb/ovsdb-server.c b/ovsdb/ovsdb-server.c
> index 20e1964..d87360a 100644
> --- a/ovsdb/ovsdb-server.c
> +++ b/ovsdb/ovsdb-server.c
> @@ -81,8 +81,14 @@ struct add_remote_aux {
>      struct sset *remotes;
>      struct db *dbs;
>      size_t n_dbs;
> +    FILE *config_tmpfile;
>  };
>  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;
>
> @@ -99,6 +105,9 @@ static void update_remote_status(const struct
> ovsdb_jsonrpc_server *jsonrpc,
>                                   const struct sset *remotes,
>                                   struct db dbs[], size_t n_dbs);
>
> +static void save_config(FILE *config_file, const struct sset *);
> +static void load_config(FILE *config_file, struct sset *);
> +
>  int
>  main(int argc, char *argv[])
>  {
> @@ -112,6 +121,8 @@ main(int argc, char *argv[])
>      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 db *dbs;
>      int n_dbs;
> @@ -125,7 +136,14 @@ main(int argc, char *argv[])
>
>      parse_options(&argc, &argv, &remotes, &unixctl_path, &run_command);
>
> +    config_tmpfile = tmpfile();
> +    if (!config_tmpfile) {
> +        ovs_fatal(errno, "failed to create temporary file");
> +    }
> +
> +    save_config(config_tmpfile, &remotes);
>      daemonize_start();
> +    load_config(config_tmpfile, &remotes);
>
>      n_dbs = MAX(1, argc);
>      dbs = xcalloc(n_dbs + 1, sizeof *dbs);
> @@ -195,10 +213,13 @@ main(int argc, char *argv[])
>      add_remote_aux.remotes = &remotes;
>      add_remote_aux.dbs = dbs;
>      add_remote_aux.n_dbs = n_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;
>      unixctl_command_register("ovsdb-server/remove-remote", "REMOTE", 1, 1,
> -                             ovsdb_server_remove_remote, &remotes);
> +                             ovsdb_server_remove_remote,
> &remove_remote_aux);
>      unixctl_command_register("ovsdb-server/list-remotes", "", 0, 0,
>                               ovsdb_server_list_remotes, &remotes);
>
> @@ -922,7 +943,9 @@ ovsdb_server_add_remote(struct unixctl_conn *conn, int
> argc OVS_UNUSED,
>                : parse_db_column(aux->dbs, aux->n_dbs, remote,
>                                  &db, &table, &column));
>      if (!retval) {
> -        sset_add(aux->remotes, remote);
> +        if (sset_add(aux->remotes, remote)) {
> +            save_config(aux->config_tmpfile, aux->remotes);
> +        }
>          unixctl_command_reply(conn, NULL);
>      } else {
>          unixctl_command_reply_error(conn, retval);
> @@ -934,14 +957,15 @@ ovsdb_server_add_remote(struct unixctl_conn *conn,
> int argc OVS_UNUSED,
>   * that ovsdb-server services. */
>  static void
>  ovsdb_server_remove_remote(struct unixctl_conn *conn, int argc OVS_UNUSED,
> -                           const char *argv[], void *remotes_)
> +                           const char *argv[], void *aux_)
>  {
> -    struct sset *remotes = remotes_;
> +    struct remove_remote_aux *aux = aux_;
>      struct sset_node *node;
>
> -    node = sset_find(remotes, argv[1]);
> +    node = sset_find(aux->remotes, argv[1]);
>      if (node) {
> -        sset_delete(remotes, node);
> +        sset_delete(aux->remotes, node);
> +        save_config(aux->config_tmpfile, aux->remotes);
>          unixctl_command_reply(conn, NULL);
>      } else {
>          unixctl_command_reply_error(conn, "no such remote");
> @@ -1092,3 +1116,48 @@ usage(void)
>      leak_checker_usage();
>      exit(EXIT_SUCCESS);
>  }
> +
> +static void
> +save_config(FILE *config_file, const struct sset *remotes)
> +{
> +    const char *remote;
> +    struct json *json;
> +    char *s;
> +
> +    if (ftruncate(fileno(config_file), 0) == -1) {
> +        ovs_fatal(errno, "truncate failed");
> +    }
> +
> +    json = json_array_create_empty();
> +    SSET_FOR_EACH (remote, remotes) {
> +        json_array_add(json, json_string_create(remote));
> +    }
> +    s = json_to_string(json, 0);
> +    json_destroy(json);
> +
> +    if (fputs(s, config_file) == EOF || fflush(config_file) == EOF) {
> +        ovs_fatal(errno, "write failed");
> +    }
> +    free(s);
> +}
> +
> +static void
> +load_config(FILE *config_file, struct sset *remotes)
> +{
> +    struct json *json;
> +    size_t i;
> +
> +    sset_clear(remotes);
> +
> +    rewind(config_file);
> +    json = json_from_stream(config_file);
> +    if (json->type == JSON_STRING) {
> +        ovs_fatal(0, "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));
> +    }
> +    json_destroy(json);
> +}
> --
> 1.7.2.5
>
> _______________________________________________
> dev mailing list
> dev@openvswitch.org
> http://openvswitch.org/mailman/listinfo/dev
>
_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to