[ovs-dev] [PATCH 1/4] ovs-vsctl: Allow commands to tell ovs-vsctl to try again later.

Ben Pfaff blp at nicira.com
Thu Jun 24 18:41:27 UTC 2010


The "wait-until" command to be introduced in an upcoming commit needs to
be able to tell the ovs-vsctl main loop to try again later, since the
condition that it is looking for has not yet been satisfied.  This commit
adds the infrastructure for this.  (It's being broken out into a separate
commit because it modifies scattered code in ovs-vsctl.c and thus might
be easier to review this way.)
---
 utilities/ovs-vsctl.c |   39 +++++++++++++++++++++++++++------------
 1 files changed, 27 insertions(+), 12 deletions(-)

diff --git a/utilities/ovs-vsctl.c b/utilities/ovs-vsctl.c
index 9d34267..4aaebef 100644
--- a/utilities/ovs-vsctl.c
+++ b/utilities/ovs-vsctl.c
@@ -122,7 +122,6 @@ main(int argc, char *argv[])
     struct vsctl_command *commands;
     size_t n_commands;
     char *args;
-    int trials;
 
     set_program_name(argv[0]);
     signal(SIGPIPE, SIG_IGN);
@@ -146,12 +145,8 @@ main(int argc, char *argv[])
 
     /* Now execute the commands. */
     idl = the_idl = ovsdb_idl_create(db, &ovsrec_idl_class);
-    trials = 0;
     for (;;) {
         if (ovsdb_idl_run(idl)) {
-            if (++trials > 5) {
-                vsctl_fatal("too many database inconsistency failures");
-            }
             do_vsctl(args, commands, n_commands, idl);
         }
 
@@ -507,6 +502,10 @@ struct vsctl_context {
     struct ovsdb_idl_txn *txn;
     struct ovsdb_symbol_table *symtab;
     const struct ovsrec_open_vswitch *ovs;
+
+    /* A command may set this member to true if some prerequisite is not met
+     * and the caller should wait for something to change and then retry. */
+    bool try_again;
 };
 
 struct vsctl_bridge {
@@ -2599,6 +2598,8 @@ vsctl_context_init(struct vsctl_context *ctx, struct vsctl_command *command,
     ctx->txn = txn;
     ctx->ovs = ovs;
     ctx->symtab = symtab;
+
+    ctx->try_again = false;
 }
 
 static void
@@ -2641,12 +2642,18 @@ do_vsctl(const char *args, struct vsctl_command *commands, size_t n_commands,
 
     symtab = ovsdb_symbol_table_create();
     for (c = commands; c < &commands[n_commands]; c++) {
+        ds_init(&c->output);
+    }
+    for (c = commands; c < &commands[n_commands]; c++) {
         struct vsctl_context ctx;
 
-        ds_init(&c->output);
         vsctl_context_init(&ctx, c, idl, txn, ovs, symtab);
         (c->syntax->run)(&ctx);
         vsctl_context_done(&ctx, c);
+
+        if (ctx.try_again) {
+            goto try_again;
+        }
     }
 
     status = ovsdb_idl_txn_commit_block(txn);
@@ -2673,7 +2680,6 @@ do_vsctl(const char *args, struct vsctl_command *commands, size_t n_commands,
         vsctl_fatal("row id \"%s\" is referenced but never created (e.g. "
                     "with \"-- --id=%s create ...\")", unused, unused);
     }
-    ovsdb_symbol_table_destroy(symtab);
 
     switch (status) {
     case TXN_INCOMPLETE:
@@ -2688,11 +2694,7 @@ do_vsctl(const char *args, struct vsctl_command *commands, size_t n_commands,
         break;
 
     case TXN_TRY_AGAIN:
-        for (c = commands; c < &commands[n_commands]; c++) {
-            ds_destroy(&c->output);
-        }
-        free(error);
-        return;
+        goto try_again;
 
     case TXN_ERROR:
         vsctl_fatal("transaction error: %s", error);
@@ -2702,6 +2704,8 @@ do_vsctl(const char *args, struct vsctl_command *commands, size_t n_commands,
     }
     free(error);
 
+    ovsdb_symbol_table_destroy(symtab);
+
     for (c = commands; c < &commands[n_commands]; c++) {
         struct ds *ds = &c->output;
         struct shash_node *node;
@@ -2756,6 +2760,17 @@ do_vsctl(const char *args, struct vsctl_command *commands, size_t n_commands,
     ovsdb_idl_destroy(idl);
 
     exit(EXIT_SUCCESS);
+
+try_again:
+    /* Our transaction needs to be rerun, or a prerequisite was not met.  Free
+     * resources and return so that the caller can try again. */
+    ovsdb_idl_txn_abort(txn);
+    ovsdb_idl_txn_destroy(txn);
+    ovsdb_symbol_table_destroy(symtab);
+    for (c = commands; c < &commands[n_commands]; c++) {
+        ds_destroy(&c->output);
+    }
+    free(error);
 }
 
 static const struct vsctl_command_syntax all_commands[] = {
-- 
1.7.1





More information about the dev mailing list