[ovs-dev] [PATCH RFC] ovsdb-server: Preserve remotes across crash and restart.

Gurucharan Shetty shettyg at nicira.com
Thu Jun 13 15:50:42 UTC 2013


On Thu, Jun 13, 2013 at 8:29 AM, Gurucharan Shetty <shettyg at nicira.com>wrote:

> On Wed, Jun 12, 2013 at 5:10 PM, Ben Pfaff <blp at 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.
>
This concern is probably invalid. I don't think there is a possibility that
a second file with the same name will be created if the first one is
deleted.


> * 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 at openvswitch.org
>> http://openvswitch.org/mailman/listinfo/dev
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.openvswitch.org/pipermail/ovs-dev/attachments/20130613/12147dc6/attachment-0003.html>


More information about the dev mailing list