From 87b23a01ed618392a14538db136fb06e00f4bdbf Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Thu, 24 Jun 2010 11:01:53 -0700 Subject: [PATCH] ovs-vsctl: Allow commands to tell ovs-vsctl to try again later. 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 file changed, 27 insertions(+), 12 deletions(-) diff --git a/utilities/ovs-vsctl.c b/utilities/ovs-vsctl.c index 2f78a53bc..4c0a20051 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 { @@ -2608,6 +2607,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 @@ -2649,13 +2650,19 @@ 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); @@ -2682,7 +2689,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: @@ -2697,11 +2703,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); @@ -2711,6 +2713,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; @@ -2765,6 +2769,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[] = { -- 2.43.0