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

Ben Pfaff blp at ovn.org
Thu Oct 4 20:29:26 UTC 2018


Thanks.  I applied this series to master.

On Thu, Jul 26, 2018 at 04:56:32PM -0400, Mark Michelson wrote:
> 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