Skip to content

Commit

Permalink
idl-loop: Move idl-loop into ovsdb-idl library.
Browse files Browse the repository at this point in the history
idl-loop is needed in implementing other controller (i.e., vtep controller).
So, this commit moves the logic into ovsdb-idl library module.

Signed-off-by: Alex Wang <[email protected]>
Acked-by: Russell Bryant <[email protected]>
  • Loading branch information
yew011 committed Aug 8, 2015
1 parent bf4afb5 commit a548a76
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 96 deletions.
72 changes: 72 additions & 0 deletions lib/ovsdb-idl.c
Original file line number Diff line number Diff line change
Expand Up @@ -2632,3 +2632,75 @@ ovsdb_idl_parse_lock_notify(struct ovsdb_idl *idl,
}
}
}

void
ovsdb_idl_loop_destroy(struct ovsdb_idl_loop *loop)
{
if (loop) {
ovsdb_idl_destroy(loop->idl);
}
}

struct ovsdb_idl_txn *
ovsdb_idl_loop_run(struct ovsdb_idl_loop *loop)
{
ovsdb_idl_run(loop->idl);
loop->open_txn = (loop->committing_txn
|| ovsdb_idl_get_seqno(loop->idl) == loop->skip_seqno
? NULL
: ovsdb_idl_txn_create(loop->idl));
return loop->open_txn;
}

void
ovsdb_idl_loop_commit_and_wait(struct ovsdb_idl_loop *loop)
{
if (loop->open_txn) {
loop->committing_txn = loop->open_txn;
loop->open_txn = NULL;

loop->precommit_seqno = ovsdb_idl_get_seqno(loop->idl);
}

struct ovsdb_idl_txn *txn = loop->committing_txn;
if (txn) {
enum ovsdb_idl_txn_status status = ovsdb_idl_txn_commit(txn);
if (status != TXN_INCOMPLETE) {
switch (status) {
case TXN_TRY_AGAIN:
/* We want to re-evaluate the database when it's changed from
* the contents that it had when we started the commit. (That
* might have already happened.) */
loop->skip_seqno = loop->precommit_seqno;
if (ovsdb_idl_get_seqno(loop->idl) != loop->skip_seqno) {
poll_immediate_wake();
}
break;

case TXN_SUCCESS:
/* If the database has already changed since we started the
* commit, re-evaluate it immediately to avoid missing a change
* for a while. */
if (ovsdb_idl_get_seqno(loop->idl) != loop->precommit_seqno) {
poll_immediate_wake();
}
break;

case TXN_UNCHANGED:
case TXN_ABORTED:
case TXN_NOT_LOCKED:
case TXN_ERROR:
break;

case TXN_UNCOMMITTED:
case TXN_INCOMPLETE:
OVS_NOT_REACHED();

}
ovsdb_idl_txn_destroy(txn);
loop->committing_txn = NULL;
}
}

ovsdb_idl_wait(loop->idl);
}
19 changes: 19 additions & 0 deletions lib/ovsdb-idl.h
Original file line number Diff line number Diff line change
Expand Up @@ -222,5 +222,24 @@ const struct ovsdb_idl_row *ovsdb_idl_txn_insert(
const struct uuid *);

struct ovsdb_idl *ovsdb_idl_txn_get_idl (struct ovsdb_idl_txn *);


/* ovsdb_idl_loop provides an easy way to manage the transactions related
* to 'idl' and to cope with different status during transaction. */
struct ovsdb_idl_loop {
struct ovsdb_idl *idl;
unsigned int skip_seqno;

struct ovsdb_idl_txn *committing_txn;
unsigned int precommit_seqno;

struct ovsdb_idl_txn *open_txn;
};

#define OVSDB_IDL_LOOP_INITIALIZER(IDL) { .idl = (IDL) }

void ovsdb_idl_loop_destroy(struct ovsdb_idl_loop *);
struct ovsdb_idl_txn *ovsdb_idl_loop_run(struct ovsdb_idl_loop *);
void ovsdb_idl_loop_commit_and_wait(struct ovsdb_idl_loop *);

#endif /* ovsdb-idl.h */
108 changes: 12 additions & 96 deletions ovn/controller/ovn-controller.c
Original file line number Diff line number Diff line change
Expand Up @@ -128,90 +128,6 @@ get_ovnsb_remote(struct ovsdb_idl *ovs_idl)
}
}

struct idl_loop {
struct ovsdb_idl *idl;
unsigned int skip_seqno;

struct ovsdb_idl_txn *committing_txn;
unsigned int precommit_seqno;

struct ovsdb_idl_txn *open_txn;
};

#define IDL_LOOP_INITIALIZER(IDL) { .idl = (IDL) }

static void
idl_loop_destroy(struct idl_loop *loop)
{
if (loop) {
ovsdb_idl_destroy(loop->idl);
}
}

static struct ovsdb_idl_txn *
idl_loop_run(struct idl_loop *loop)
{
ovsdb_idl_run(loop->idl);
loop->open_txn = (loop->committing_txn
|| ovsdb_idl_get_seqno(loop->idl) == loop->skip_seqno
? NULL
: ovsdb_idl_txn_create(loop->idl));
return loop->open_txn;
}

static void
idl_loop_commit_and_wait(struct idl_loop *loop)
{
if (loop->open_txn) {
loop->committing_txn = loop->open_txn;
loop->open_txn = NULL;

loop->precommit_seqno = ovsdb_idl_get_seqno(loop->idl);
}

struct ovsdb_idl_txn *txn = loop->committing_txn;
if (txn) {
enum ovsdb_idl_txn_status status = ovsdb_idl_txn_commit(txn);
if (status != TXN_INCOMPLETE) {
switch (status) {
case TXN_TRY_AGAIN:
/* We want to re-evaluate the database when it's changed from
* the contents that it had when we started the commit. (That
* might have already happened.) */
loop->skip_seqno = loop->precommit_seqno;
if (ovsdb_idl_get_seqno(loop->idl) != loop->skip_seqno) {
poll_immediate_wake();
}
break;

case TXN_SUCCESS:
/* If the database has already changed since we started the
* commit, re-evaluate it immediately to avoid missing a change
* for a while. */
if (ovsdb_idl_get_seqno(loop->idl) != loop->precommit_seqno) {
poll_immediate_wake();
}
break;

case TXN_UNCHANGED:
case TXN_ABORTED:
case TXN_NOT_LOCKED:
case TXN_ERROR:
break;

case TXN_UNCOMMITTED:
case TXN_INCOMPLETE:
OVS_NOT_REACHED();

}
ovsdb_idl_txn_destroy(txn);
loop->committing_txn = NULL;
}
}

ovsdb_idl_wait(loop->idl);
}

int
main(int argc, char *argv[])
{
Expand Down Expand Up @@ -242,7 +158,7 @@ main(int argc, char *argv[])

/* Connect to OVS OVSDB instance. We do not monitor all tables by
* default, so modules must register their interest explicitly. */
struct idl_loop ovs_idl_loop = IDL_LOOP_INITIALIZER(
struct ovsdb_idl_loop ovs_idl_loop = OVSDB_IDL_LOOP_INITIALIZER(
ovsdb_idl_create(ovs_remote, &ovsrec_idl_class, false, true));
ovsdb_idl_add_table(ovs_idl_loop.idl, &ovsrec_table_open_vswitch);
ovsdb_idl_add_column(ovs_idl_loop.idl,
Expand All @@ -255,7 +171,7 @@ main(int argc, char *argv[])

/* Connect to OVN SB database. */
char *ovnsb_remote = get_ovnsb_remote(ovs_idl_loop.idl);
struct idl_loop ovnsb_idl_loop = IDL_LOOP_INITIALIZER(
struct ovsdb_idl_loop ovnsb_idl_loop = OVSDB_IDL_LOOP_INITIALIZER(
ovsdb_idl_create(ovnsb_remote, &sbrec_idl_class, true, true));
get_initial_snapshot(ovnsb_idl_loop.idl);

Expand All @@ -264,9 +180,9 @@ main(int argc, char *argv[])
while (!exiting) {
struct controller_ctx ctx = {
.ovs_idl = ovs_idl_loop.idl,
.ovs_idl_txn = idl_loop_run(&ovs_idl_loop),
.ovs_idl_txn = ovsdb_idl_loop_run(&ovs_idl_loop),
.ovnsb_idl = ovnsb_idl_loop.idl,
.ovnsb_idl_txn = idl_loop_run(&ovnsb_idl_loop),
.ovnsb_idl_txn = ovsdb_idl_loop_run(&ovnsb_idl_loop),
};

const struct ovsrec_bridge *br_int = get_br_int(ctx.ovs_idl);
Expand Down Expand Up @@ -298,8 +214,8 @@ main(int argc, char *argv[])
poll_immediate_wake();
}

idl_loop_commit_and_wait(&ovnsb_idl_loop);
idl_loop_commit_and_wait(&ovs_idl_loop);
ovsdb_idl_loop_commit_and_wait(&ovnsb_idl_loop);
ovsdb_idl_loop_commit_and_wait(&ovs_idl_loop);

if (br_int) {
ofctrl_wait();
Expand All @@ -312,9 +228,9 @@ main(int argc, char *argv[])
while (!done) {
struct controller_ctx ctx = {
.ovs_idl = ovs_idl_loop.idl,
.ovs_idl_txn = idl_loop_run(&ovs_idl_loop),
.ovs_idl_txn = ovsdb_idl_loop_run(&ovs_idl_loop),
.ovnsb_idl = ovnsb_idl_loop.idl,
.ovnsb_idl_txn = idl_loop_run(&ovnsb_idl_loop),
.ovnsb_idl_txn = ovsdb_idl_loop_run(&ovnsb_idl_loop),
};

const struct ovsrec_bridge *br_int = get_br_int(ctx.ovs_idl);
Expand All @@ -329,17 +245,17 @@ main(int argc, char *argv[])
poll_immediate_wake();
}

idl_loop_commit_and_wait(&ovnsb_idl_loop);
idl_loop_commit_and_wait(&ovs_idl_loop);
ovsdb_idl_loop_commit_and_wait(&ovnsb_idl_loop);
ovsdb_idl_loop_commit_and_wait(&ovs_idl_loop);
poll_block();
}

unixctl_server_destroy(unixctl);
lflow_destroy();
ofctrl_destroy();

idl_loop_destroy(&ovs_idl_loop);
idl_loop_destroy(&ovnsb_idl_loop);
ovsdb_idl_loop_destroy(&ovs_idl_loop);
ovsdb_idl_loop_destroy(&ovnsb_idl_loop);

free(ovnsb_remote);
free(ovs_remote);
Expand Down

0 comments on commit a548a76

Please sign in to comment.