[ovs-dev] [PATCH v2 1/2] ovsdb-idl: New function ovsdb_idl_create_unconnected().

Mark Michelson mmichels at redhat.com
Thu Jul 26 20:56:32 UTC 2018


Better late than never

Acked-by: Mark Michelson <mmichels at redhat.com>

On 06/18/2018 02:36 PM, Ben Pfaff wrote:
> This new function makes it possible to create an instance of the IDL
> without connecting it to a remote OVSDB server.  The caller can then
> connect and disconnect using ovsdb_idl_set_remote(); the ability to
> disconnect is a new feature.
> 
> With this patch, the ovsdb_idl 'session' member can be null whereas
> previously it was always nonnull.  The scattered changes throughout
> ovsdb-idl are to cope with this new possibility.
> 
> An upcoming patch will introduce the first user of this new feature.
> 
> Signed-off-by: Ben Pfaff <blp at ovn.org>
> ---
> v1->v2: No change.
> 
>   lib/ovsdb-idl.c | 118 +++++++++++++++++++++++++++++++++++++++++---------------
>   lib/ovsdb-idl.h |   2 +
>   2 files changed, 88 insertions(+), 32 deletions(-)
> 
> diff --git a/lib/ovsdb-idl.c b/lib/ovsdb-idl.c
> index e0991f940f79..86e28d810603 100644
> --- a/lib/ovsdb-idl.c
> +++ b/lib/ovsdb-idl.c
> @@ -233,6 +233,7 @@ struct ovsdb_idl {
>        * function currently returns then the session has reconnected and the
>        * state machine must restart.  */
>       struct jsonrpc_session *session; /* Connection to the server. */
> +    char *remote;                    /* 'session' remote name. */
>       enum ovsdb_idl_state state;      /* Current session state. */
>       unsigned int state_seqno;        /* See above. */
>       struct json *request_id;         /* JSON ID for request awaiting reply. */
> @@ -365,18 +366,6 @@ static void ovsdb_idl_destroy_indexes(struct ovsdb_idl_table *);
>   static void ovsdb_idl_add_to_indexes(const struct ovsdb_idl_row *);
>   static void ovsdb_idl_remove_from_indexes(const struct ovsdb_idl_row *);
>   
> -static void
> -ovsdb_idl_open_session(struct ovsdb_idl *idl, const char *remote, bool retry)
> -{
> -    ovs_assert(!idl->data.txn);
> -    jsonrpc_session_close(idl->session);
> -
> -    struct svec remotes = SVEC_EMPTY_INITIALIZER;
> -    ovsdb_session_parse_remote(remote, &remotes, &idl->cid);
> -    idl->session = jsonrpc_session_open_multiple(&remotes, retry);
> -    svec_destroy(&remotes);
> -}
> -
>   static void
>   ovsdb_idl_db_init(struct ovsdb_idl_db *db, const struct ovsdb_idl_class *class,
>                     struct ovsdb_idl *parent, bool monitor_everything_by_default)
> @@ -443,13 +432,38 @@ ovsdb_idl_db_init(struct ovsdb_idl_db *db, const struct ovsdb_idl_class *class,
>   struct ovsdb_idl *
>   ovsdb_idl_create(const char *remote, const struct ovsdb_idl_class *class,
>                    bool monitor_everything_by_default, bool retry)
> +{
> +    struct ovsdb_idl *idl = ovsdb_idl_create_unconnected(
> +        class, monitor_everything_by_default);
> +    ovsdb_idl_set_remote(idl, remote, retry);
> +    return idl;
> +}
> +
> +/* Creates and returns a connection to an in-memory replica of the remote
> + * database whose schema is described by 'class'.  (Ordinarily 'class' is
> + * compiled from an OVSDB schema automatically by ovsdb-idlc.)
> + *
> + * Use ovsdb_idl_set_remote() to configure the database to which to connect.
> + * Until a remote is configured, no data can be retrieved.
> + *
> + * If 'monitor_everything_by_default' is true, then everything in the remote
> + * database will be replicated by default.  ovsdb_idl_omit() and
> + * ovsdb_idl_omit_alert() may be used to selectively drop some columns from
> + * monitoring.
> + *
> + * If 'monitor_everything_by_default' is false, then no columns or tables will
> + * be replicated by default.  ovsdb_idl_add_column() and ovsdb_idl_add_table()
> + * must be used to choose some columns or tables to replicate.
> + */
> +struct ovsdb_idl *
> +ovsdb_idl_create_unconnected(const struct ovsdb_idl_class *class,
> +                             bool monitor_everything_by_default)
>   {
>       struct ovsdb_idl *idl;
>   
>       idl = xzalloc(sizeof *idl);
>       ovsdb_idl_db_init(&idl->server, &serverrec_idl_class, idl, true);
>       ovsdb_idl_db_init(&idl->data, class, idl, monitor_everything_by_default);
> -    ovsdb_idl_open_session(idl, remote, retry);
>       idl->state_seqno = UINT_MAX;
>       idl->request_id = NULL;
>       idl->leader_only = true;
> @@ -471,14 +485,38 @@ ovsdb_idl_create(const char *remote, const struct ovsdb_idl_class *class,
>       return idl;
>   }
>   
> -/* Changes the remote and creates a new session. */
> +/* Changes the remote and creates a new session.
> + *
> + * If 'retry' is true, the connection to the remote will automatically retry
> + * when it fails.  If 'retry' is false, the connection is one-time. */
>   void
> -ovsdb_idl_set_remote(struct ovsdb_idl *idl, const char *remote,
> -                     bool retry)
> +ovsdb_idl_set_remote(struct ovsdb_idl *idl, const char *remote, bool retry)
>   {
> -    if (idl) {
> -        ovsdb_idl_open_session(idl, remote, retry);
> -        idl->state_seqno = UINT_MAX;
> +    if (idl
> +        && ((remote != NULL) != (idl->remote != NULL)
> +            || (remote && idl->remote && strcmp(remote, idl->remote)))) {
> +        ovs_assert(!idl->data.txn);
> +
> +        /* Close the old session, if any. */
> +        if (idl->session) {
> +            jsonrpc_session_close(idl->session);
> +            idl->session = NULL;
> +
> +            free(idl->remote);
> +            idl->remote = NULL;
> +        }
> +
> +        /* Open new session, if any. */
> +        if (remote) {
> +            struct svec remotes = SVEC_EMPTY_INITIALIZER;
> +            ovsdb_session_parse_remote(remote, &remotes, &idl->cid);
> +            idl->session = jsonrpc_session_open_multiple(&remotes, retry);
> +            svec_destroy(&remotes);
> +
> +            idl->state_seqno = UINT_MAX;
> +
> +            idl->remote = xstrdup(remote);
> +        }
>       }
>   }
>   
> @@ -588,7 +626,7 @@ ovsdb_idl_state_to_string(enum ovsdb_idl_state state)
>   static void
>   ovsdb_idl_retry_at(struct ovsdb_idl *idl, const char *where)
>   {
> -    if (jsonrpc_session_get_n_remotes(idl->session) > 1) {
> +    if (idl->session && jsonrpc_session_get_n_remotes(idl->session) > 1) {
>           ovsdb_idl_force_reconnect(idl);
>           ovsdb_idl_transition_at(idl, IDL_S_RETRY, where);
>       } else {
> @@ -601,7 +639,7 @@ ovsdb_idl_transition_at(struct ovsdb_idl *idl, enum ovsdb_idl_state new_state,
>                           const char *where)
>   {
>       VLOG_DBG("%s: %s -> %s at %s",
> -             jsonrpc_session_get_name(idl->session),
> +             idl->session ? jsonrpc_session_get_name(idl->session) : "void",
>                ovsdb_idl_state_to_string(idl->state),
>                ovsdb_idl_state_to_string(new_state),
>                where);
> @@ -619,7 +657,9 @@ ovsdb_idl_send_request(struct ovsdb_idl *idl, struct jsonrpc_msg *request)
>   {
>       json_destroy(idl->request_id);
>       idl->request_id = json_clone(request->id);
> -    jsonrpc_session_send(idl->session, request);
> +    if (idl->session) {
> +        jsonrpc_session_send(idl->session, request);
> +    }
>   }
>   
>   static void
> @@ -787,6 +827,11 @@ ovsdb_idl_process_msg(struct ovsdb_idl *idl, struct jsonrpc_msg *msg)
>   void
>   ovsdb_idl_run(struct ovsdb_idl *idl)
>   {
> +    if (!idl->session) {
> +        ovsdb_idl_txn_abort_all(idl);
> +        return;
> +    }
> +
>       int i;
>   
>       ovs_assert(!idl->data.txn);
> @@ -826,6 +871,9 @@ ovsdb_idl_run(struct ovsdb_idl *idl)
>   void
>   ovsdb_idl_wait(struct ovsdb_idl *idl)
>   {
> +    if (!idl->session) {
> +        return;
> +    }
>       jsonrpc_session_wait(idl->session);
>       jsonrpc_session_recv_wait(idl->session);
>   }
> @@ -892,7 +940,9 @@ ovsdb_idl_has_ever_connected(const struct ovsdb_idl *idl)
>   void
>   ovsdb_idl_enable_reconnect(struct ovsdb_idl *idl)
>   {
> -    jsonrpc_session_enable_reconnect(idl->session);
> +    if (idl->session) {
> +        jsonrpc_session_enable_reconnect(idl->session);
> +    }
>   }
>   
>   /* Forces 'idl' to drop its connection to the database and reconnect.  In the
> @@ -900,7 +950,9 @@ ovsdb_idl_enable_reconnect(struct ovsdb_idl *idl)
>   void
>   ovsdb_idl_force_reconnect(struct ovsdb_idl *idl)
>   {
> -    jsonrpc_session_force_reconnect(idl->session);
> +    if (idl->session) {
> +        jsonrpc_session_force_reconnect(idl->session);
> +    }
>   }
>   
>   /* Some IDL users should only write to write-only columns.  Furthermore,
> @@ -918,7 +970,7 @@ ovsdb_idl_verify_write_only(struct ovsdb_idl *idl)
>   bool
>   ovsdb_idl_is_alive(const struct ovsdb_idl *idl)
>   {
> -    return jsonrpc_session_is_alive(idl->session) &&
> +    return idl->session && jsonrpc_session_is_alive(idl->session) &&
>              idl->state != IDL_S_ERROR;
>   }
>   
> @@ -930,10 +982,7 @@ ovsdb_idl_is_alive(const struct ovsdb_idl *idl)
>   int
>   ovsdb_idl_get_last_error(const struct ovsdb_idl *idl)
>   {
> -    int err;
> -
> -    err = jsonrpc_session_get_last_error(idl->session);
> -
> +    int err = idl->session ? jsonrpc_session_get_last_error(idl->session) : 0;
>       if (err) {
>           return err;
>       } else if (idl->state == IDL_S_ERROR) {
> @@ -949,7 +998,9 @@ ovsdb_idl_get_last_error(const struct ovsdb_idl *idl)
>   void
>   ovsdb_idl_set_probe_interval(const struct ovsdb_idl *idl, int probe_interval)
>   {
> -    jsonrpc_session_set_probe_interval(idl->session, probe_interval);
> +    if (idl->session) {
> +        jsonrpc_session_set_probe_interval(idl->session, probe_interval);
> +    }
>   }
>   
>   static size_t
> @@ -4006,7 +4057,8 @@ ovsdb_idl_txn_commit(struct ovsdb_idl_txn *txn)
>       if (!any_updates) {
>           txn->status = TXN_UNCHANGED;
>           json_destroy(operations);
> -    } else if (!jsonrpc_session_send(
> +    } else if (txn->db->idl->session
> +               && !jsonrpc_session_send(
>                      txn->db->idl->session,
>                      jsonrpc_create_request(
>                          "transact", operations, &txn->request_id))) {
> @@ -4696,7 +4748,9 @@ ovsdb_idl_set_lock(struct ovsdb_idl *idl, const char *lock_name)
>           if (!msg) {
>               break;
>           }
> -        jsonrpc_session_send(idl->session, msg);
> +        if (idl->session) {
> +            jsonrpc_session_send(idl->session, msg);
> +        }
>       }
>   }
>   
> diff --git a/lib/ovsdb-idl.h b/lib/ovsdb-idl.h
> index ea18b22f5480..382981cb44c6 100644
> --- a/lib/ovsdb-idl.h
> +++ b/lib/ovsdb-idl.h
> @@ -60,6 +60,8 @@ struct ovsdb_idl *ovsdb_idl_create(const char *remote,
>                                      const struct ovsdb_idl_class *,
>                                      bool monitor_everything_by_default,
>                                      bool retry);
> +struct ovsdb_idl *ovsdb_idl_create_unconnected(
> +    const struct ovsdb_idl_class *, bool monitor_everything_by_default);
>   void ovsdb_idl_set_remote(struct ovsdb_idl *, const char *, bool);
>   void ovsdb_idl_destroy(struct ovsdb_idl *);
>   
> 



More information about the dev mailing list