From: Alex Wang Date: Tue, 4 Aug 2015 16:52:26 +0000 (-0700) Subject: idl-loop: Move idl-loop into ovsdb-idl library. X-Git-Tag: v2.5.0~759 X-Git-Url: http://git.cascardo.eti.br/?a=commitdiff_plain;h=a548a764b89ac6421c9c8bbb5c683aff0d5ddd88;p=cascardo%2Fovs.git idl-loop: Move idl-loop into ovsdb-idl library. 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 Acked-by: Russell Bryant --- diff --git a/lib/ovsdb-idl.c b/lib/ovsdb-idl.c index 4ec703240..f0d5d9ca0 100644 --- a/lib/ovsdb-idl.c +++ b/lib/ovsdb-idl.c @@ -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); +} diff --git a/lib/ovsdb-idl.h b/lib/ovsdb-idl.h index a49f84fb6..519412231 100644 --- a/lib/ovsdb-idl.h +++ b/lib/ovsdb-idl.h @@ -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 */ diff --git a/ovn/controller/ovn-controller.c b/ovn/controller/ovn-controller.c index 2c4248f8c..bb2b840d1 100644 --- a/ovn/controller/ovn-controller.c +++ b/ovn/controller/ovn-controller.c @@ -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[]) { @@ -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, @@ -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); @@ -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); @@ -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(); @@ -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); @@ -329,8 +245,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); poll_block(); } @@ -338,8 +254,8 @@ main(int argc, char *argv[]) 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);