On Tue, 2021-04-13 at 20:50 -0500, Dan Williams wrote:
> After creating the new cluster database write a raft entry that
> sets the desired election timer. This allows CMSes to set the
> election timer at cluster start and avoid an error-prone
> election timer modification process after the cluster is up.
> 
> Reported-at: https://bugzilla.redhat.com/1831778

Anyone have thoughts on this or a better approach?

Thanks,
Dan

> 
> Signed-off-by: Dan Williams <[email protected]>
> ---
>  ovsdb/ovsdb-tool.c | 30 +++++++++++++++++++++++++++++-
>  ovsdb/raft.c       |  2 +-
>  ovsdb/raft.h       |  8 ++++++++
>  3 files changed, 38 insertions(+), 2 deletions(-)
> 
> diff --git a/ovsdb/ovsdb-tool.c b/ovsdb/ovsdb-tool.c
> index b8560f850cd08..8d029cef56df6 100644
> --- a/ovsdb/ovsdb-tool.c
> +++ b/ovsdb/ovsdb-tool.c
> @@ -276,10 +276,22 @@ do_create_cluster(struct ovs_cmdl_context *ctx)
>      const char *db_file_name = ctx->argv[1];
>      const char *src_file_name = ctx->argv[2];
>      const char *local = ctx->argv[3];
> +    uint64_t election_timer = 0;
>  
>      struct ovsdb_schema *schema;
>      struct json *data;
>  
> +    if (ctx->argc >= 5) {
> +        election_timer = atoll(ctx->argv[4]);
> +        /* Election timer smaller than 100ms or bigger than 10min
> doesn't make
> +         * sense. */
> +        if (election_timer < 100 || election_timer > 600000) {
> +            ovs_fatal(0, "election timer must be between 100 and
> 600000, "
> +                      "in msec.");
> +            return;
> +        }
> +    }
> +
>      struct ovsdb_error *error =
> ovsdb_schema_from_file(src_file_name, &schema);
>      if (!error) {
>          /* It's just a schema file. */
> @@ -306,6 +318,21 @@ do_create_cluster(struct ovs_cmdl_context *ctx)
>                                            local, snapshot));
>      ovsdb_schema_destroy(schema);
>      json_destroy(snapshot);
> +
> +    if (election_timer > 0) {
> +        struct ovsdb_log *log = NULL;
> +        struct raft *raft = NULL;
> +
> +        check_ovsdb_error(ovsdb_log_open(db_file_name, RAFT_MAGIC,
> +                                         OVSDB_LOG_READ_WRITE, -1,
> &log));
> +        check_ovsdb_error(raft_open(log, &raft));
> +        /* Use term=1 since raft_open() triggers leader election and
> sets
> +         * the term to 1. */
> +        check_ovsdb_error(raft_write_entry(raft, 1,
> json_nullable_clone(NULL),
> +                                           NULL,
> json_nullable_clone(NULL),
> +                                           election_timer));
> +        raft_close(raft);
> +    }
>  }
>  
>  static void
> @@ -1675,7 +1702,8 @@ do_list_commands(struct ovs_cmdl_context *ctx
> OVS_UNUSED)
>  
>  static const struct ovs_cmdl_command all_commands[] = {
>      { "create", "[db [schema]]", 0, 2, do_create, OVS_RW },
> -    { "create-cluster", "db contents local", 3, 3,
> do_create_cluster, OVS_RW },
> +    { "create-cluster", "db contents local [election timer ms]", 3,
> 4,
> +      do_create_cluster, OVS_RW },
>      { "join-cluster", "db name local remote...", 4, INT_MAX,
> do_join_cluster,
>        OVS_RW },
>      { "compact", "[db [dst]]", 0, 2, do_compact, OVS_RW },
> diff --git a/ovsdb/raft.c b/ovsdb/raft.c
> index d2ff643b27379..4e2a508033ce0 100644
> --- a/ovsdb/raft.c
> +++ b/ovsdb/raft.c
> @@ -697,7 +697,7 @@ raft_add_entry(struct raft *raft,
>  
>  /* Writes a RAFT_REC_ENTRY record for 'term', 'data', 'eid',
> 'servers',
>   * 'election_timer' to * 'raft''s log and returns an error
> indication. */
> -static struct ovsdb_error * OVS_WARN_UNUSED_RESULT
> +struct ovsdb_error * OVS_WARN_UNUSED_RESULT
>  raft_write_entry(struct raft *raft, uint64_t term, struct json
> *data,
>                   const struct uuid *eid, struct json *servers,
>                   uint64_t election_timer)
> diff --git a/ovsdb/raft.h b/ovsdb/raft.h
> index 99d5307e54684..92b1c7741ed96 100644
> --- a/ovsdb/raft.h
> +++ b/ovsdb/raft.h
> @@ -170,6 +170,14 @@ uint64_t raft_command_get_commit_index(const
> struct raft_command *);
>  void raft_command_unref(struct raft_command *);
>  void raft_command_wait(const struct raft_command *);
>  
> +struct ovsdb_error *raft_write_entry(struct raft *raft,
> +                                     uint64_t term,
> +                                     struct json *data,
> +                                     const struct uuid *eid,
> +                                     struct json *servers,
> +                                     uint64_t election_timer)
> +    OVS_WARN_UNUSED_RESULT;
> +
>  /* Replacing the local log by a snapshot. */
>  bool raft_grew_lots(const struct raft *);
>  uint64_t raft_get_log_length(const struct raft *);


_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to