mirror of
https://github.com/openvswitch/ovs
synced 2025-09-01 06:45:17 +00:00
ovsdb-idl: New function ovsdb_idl_create_unconnected().
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@ovn.org>
This commit is contained in:
118
lib/ovsdb-idl.c
118
lib/ovsdb-idl.c
@@ -233,6 +233,7 @@ struct ovsdb_idl {
|
|||||||
* function currently returns then the session has reconnected and the
|
* function currently returns then the session has reconnected and the
|
||||||
* state machine must restart. */
|
* state machine must restart. */
|
||||||
struct jsonrpc_session *session; /* Connection to the server. */
|
struct jsonrpc_session *session; /* Connection to the server. */
|
||||||
|
char *remote; /* 'session' remote name. */
|
||||||
enum ovsdb_idl_state state; /* Current session state. */
|
enum ovsdb_idl_state state; /* Current session state. */
|
||||||
unsigned int state_seqno; /* See above. */
|
unsigned int state_seqno; /* See above. */
|
||||||
struct json *request_id; /* JSON ID for request awaiting reply. */
|
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_add_to_indexes(const struct ovsdb_idl_row *);
|
||||||
static void ovsdb_idl_remove_from_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
|
static void
|
||||||
ovsdb_idl_db_init(struct ovsdb_idl_db *db, const struct ovsdb_idl_class *class,
|
ovsdb_idl_db_init(struct ovsdb_idl_db *db, const struct ovsdb_idl_class *class,
|
||||||
struct ovsdb_idl *parent, bool monitor_everything_by_default)
|
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 *
|
struct ovsdb_idl *
|
||||||
ovsdb_idl_create(const char *remote, const struct ovsdb_idl_class *class,
|
ovsdb_idl_create(const char *remote, const struct ovsdb_idl_class *class,
|
||||||
bool monitor_everything_by_default, bool retry)
|
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;
|
struct ovsdb_idl *idl;
|
||||||
|
|
||||||
idl = xzalloc(sizeof *idl);
|
idl = xzalloc(sizeof *idl);
|
||||||
ovsdb_idl_db_init(&idl->server, &serverrec_idl_class, idl, true);
|
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_db_init(&idl->data, class, idl, monitor_everything_by_default);
|
||||||
ovsdb_idl_open_session(idl, remote, retry);
|
|
||||||
idl->state_seqno = UINT_MAX;
|
idl->state_seqno = UINT_MAX;
|
||||||
idl->request_id = NULL;
|
idl->request_id = NULL;
|
||||||
idl->leader_only = true;
|
idl->leader_only = true;
|
||||||
@@ -471,14 +485,38 @@ ovsdb_idl_create(const char *remote, const struct ovsdb_idl_class *class,
|
|||||||
return idl;
|
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
|
void
|
||||||
ovsdb_idl_set_remote(struct ovsdb_idl *idl, const char *remote,
|
ovsdb_idl_set_remote(struct ovsdb_idl *idl, const char *remote, bool retry)
|
||||||
bool retry)
|
|
||||||
{
|
{
|
||||||
if (idl) {
|
if (idl
|
||||||
ovsdb_idl_open_session(idl, remote, retry);
|
&& ((remote != NULL) != (idl->remote != NULL)
|
||||||
idl->state_seqno = UINT_MAX;
|
|| (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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -584,7 +622,7 @@ ovsdb_idl_state_to_string(enum ovsdb_idl_state state)
|
|||||||
static void
|
static void
|
||||||
ovsdb_idl_retry_at(struct ovsdb_idl *idl, const char *where)
|
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_force_reconnect(idl);
|
||||||
ovsdb_idl_transition_at(idl, IDL_S_RETRY, where);
|
ovsdb_idl_transition_at(idl, IDL_S_RETRY, where);
|
||||||
} else {
|
} else {
|
||||||
@@ -597,7 +635,7 @@ ovsdb_idl_transition_at(struct ovsdb_idl *idl, enum ovsdb_idl_state new_state,
|
|||||||
const char *where)
|
const char *where)
|
||||||
{
|
{
|
||||||
VLOG_DBG("%s: %s -> %s at %s",
|
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(idl->state),
|
||||||
ovsdb_idl_state_to_string(new_state),
|
ovsdb_idl_state_to_string(new_state),
|
||||||
where);
|
where);
|
||||||
@@ -615,7 +653,9 @@ ovsdb_idl_send_request(struct ovsdb_idl *idl, struct jsonrpc_msg *request)
|
|||||||
{
|
{
|
||||||
json_destroy(idl->request_id);
|
json_destroy(idl->request_id);
|
||||||
idl->request_id = json_clone(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
|
static void
|
||||||
@@ -783,6 +823,11 @@ ovsdb_idl_process_msg(struct ovsdb_idl *idl, struct jsonrpc_msg *msg)
|
|||||||
void
|
void
|
||||||
ovsdb_idl_run(struct ovsdb_idl *idl)
|
ovsdb_idl_run(struct ovsdb_idl *idl)
|
||||||
{
|
{
|
||||||
|
if (!idl->session) {
|
||||||
|
ovsdb_idl_txn_abort_all(idl);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
ovs_assert(!idl->data.txn);
|
ovs_assert(!idl->data.txn);
|
||||||
@@ -822,6 +867,9 @@ ovsdb_idl_run(struct ovsdb_idl *idl)
|
|||||||
void
|
void
|
||||||
ovsdb_idl_wait(struct ovsdb_idl *idl)
|
ovsdb_idl_wait(struct ovsdb_idl *idl)
|
||||||
{
|
{
|
||||||
|
if (!idl->session) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
jsonrpc_session_wait(idl->session);
|
jsonrpc_session_wait(idl->session);
|
||||||
jsonrpc_session_recv_wait(idl->session);
|
jsonrpc_session_recv_wait(idl->session);
|
||||||
}
|
}
|
||||||
@@ -888,7 +936,9 @@ ovsdb_idl_has_ever_connected(const struct ovsdb_idl *idl)
|
|||||||
void
|
void
|
||||||
ovsdb_idl_enable_reconnect(struct ovsdb_idl *idl)
|
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
|
/* Forces 'idl' to drop its connection to the database and reconnect. In the
|
||||||
@@ -896,7 +946,9 @@ ovsdb_idl_enable_reconnect(struct ovsdb_idl *idl)
|
|||||||
void
|
void
|
||||||
ovsdb_idl_force_reconnect(struct ovsdb_idl *idl)
|
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,
|
/* Some IDL users should only write to write-only columns. Furthermore,
|
||||||
@@ -914,7 +966,7 @@ ovsdb_idl_verify_write_only(struct ovsdb_idl *idl)
|
|||||||
bool
|
bool
|
||||||
ovsdb_idl_is_alive(const struct ovsdb_idl *idl)
|
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;
|
idl->state != IDL_S_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -932,10 +984,7 @@ ovsdb_idl_is_connected(const struct ovsdb_idl *idl)
|
|||||||
int
|
int
|
||||||
ovsdb_idl_get_last_error(const struct ovsdb_idl *idl)
|
ovsdb_idl_get_last_error(const struct ovsdb_idl *idl)
|
||||||
{
|
{
|
||||||
int err;
|
int err = idl->session ? jsonrpc_session_get_last_error(idl->session) : 0;
|
||||||
|
|
||||||
err = jsonrpc_session_get_last_error(idl->session);
|
|
||||||
|
|
||||||
if (err) {
|
if (err) {
|
||||||
return err;
|
return err;
|
||||||
} else if (idl->state == IDL_S_ERROR) {
|
} else if (idl->state == IDL_S_ERROR) {
|
||||||
@@ -951,7 +1000,9 @@ ovsdb_idl_get_last_error(const struct ovsdb_idl *idl)
|
|||||||
void
|
void
|
||||||
ovsdb_idl_set_probe_interval(const struct ovsdb_idl *idl, int probe_interval)
|
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
|
static size_t
|
||||||
@@ -4045,7 +4096,8 @@ ovsdb_idl_txn_commit(struct ovsdb_idl_txn *txn)
|
|||||||
if (!any_updates) {
|
if (!any_updates) {
|
||||||
txn->status = TXN_UNCHANGED;
|
txn->status = TXN_UNCHANGED;
|
||||||
json_destroy(operations);
|
json_destroy(operations);
|
||||||
} else if (!jsonrpc_session_send(
|
} else if (txn->db->idl->session
|
||||||
|
&& !jsonrpc_session_send(
|
||||||
txn->db->idl->session,
|
txn->db->idl->session,
|
||||||
jsonrpc_create_request(
|
jsonrpc_create_request(
|
||||||
"transact", operations, &txn->request_id))) {
|
"transact", operations, &txn->request_id))) {
|
||||||
@@ -4745,7 +4797,9 @@ ovsdb_idl_set_lock(struct ovsdb_idl *idl, const char *lock_name)
|
|||||||
if (!msg) {
|
if (!msg) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
jsonrpc_session_send(idl->session, msg);
|
if (idl->session) {
|
||||||
|
jsonrpc_session_send(idl->session, msg);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -60,6 +60,8 @@ struct ovsdb_idl *ovsdb_idl_create(const char *remote,
|
|||||||
const struct ovsdb_idl_class *,
|
const struct ovsdb_idl_class *,
|
||||||
bool monitor_everything_by_default,
|
bool monitor_everything_by_default,
|
||||||
bool retry);
|
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_set_remote(struct ovsdb_idl *, const char *, bool);
|
||||||
void ovsdb_idl_destroy(struct ovsdb_idl *);
|
void ovsdb_idl_destroy(struct ovsdb_idl *);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user