@@ -84,8 +84,9 @@ OVS_NO_RETURN static void usage(void);
static void parse_options(int argc, char *argv[], struct shash *local_options);
static void run_prerequisites(struct ctl_command[], size_t n_commands,
struct ovsdb_idl *);
-static void do_nbctl(const char *args, struct ctl_command *, size_t n,
- struct ovsdb_idl *, bool *retry);
+static char * OVS_WARN_UNUSED_RESULT do_nbctl(const char *args,
+ struct ctl_command *, size_t n,
+ struct ovsdb_idl *, bool *retry);
static const struct nbrec_dhcp_options *dhcp_options_get(
struct ctl_context *ctx, const char *id, bool must_exist);
static void main_loop(const char *args, struct ctl_command *commands,
@@ -166,7 +167,10 @@ main_loop(const char *args, struct ctl_command *commands, size_t n_commands,
seqno = ovsdb_idl_get_seqno(idl);
bool retry;
- do_nbctl(args, commands, n_commands, idl, &retry);
+ char *error = do_nbctl(args, commands, n_commands, idl, &retry);
+ if (error) {
+ ctl_fatal("%s", error);
+ }
if (!retry) {
return;
}
@@ -4137,7 +4141,7 @@ run_prerequisites(struct ctl_command *commands, size_t n_commands,
}
}
-static void
+static char *
do_nbctl(const char *args, struct ctl_command *commands, size_t n_commands,
struct ovsdb_idl *idl, bool *retry)
{
@@ -4148,6 +4152,7 @@ do_nbctl(const char *args, struct ctl_command *commands, size_t n_commands,
struct ctl_command *c;
struct shash_node *node;
int64_t next_cfg = 0;
+ char *error = NULL;
ovs_assert(retry);
@@ -4181,7 +4186,9 @@ do_nbctl(const char *args, struct ctl_command *commands, size_t n_commands,
(c->syntax->run)(&ctx);
}
if (ctx.error) {
- ctl_fatal("%s", ctx.error);
+ error = xstrdup(ctx.error);
+ ctl_context_done(&ctx, c);
+ goto out_error;
}
ctl_context_done_command(&ctx, c);
@@ -4195,9 +4202,10 @@ do_nbctl(const char *args, struct ctl_command *commands, size_t n_commands,
SHASH_FOR_EACH (node, &symtab->sh) {
struct ovsdb_symbol *symbol = node->data;
if (!symbol->created) {
- ctl_fatal("row id \"%s\" is referenced but never created (e.g. "
- "with \"-- --id=%s create ...\")",
- node->name, node->name);
+ error = xasprintf("row id \"%s\" is referenced but never created "
+ "(e.g. with \"-- --id=%s create ...\")",
+ node->name, node->name);
+ goto out_error;
}
if (!symbol->strong_ref) {
if (!symbol->weak_ref) {
@@ -4222,7 +4230,9 @@ do_nbctl(const char *args, struct ctl_command *commands, size_t n_commands,
ctl_context_init(&ctx, c, idl, txn, symtab, NULL);
(c->syntax->postprocess)(&ctx);
if (ctx.error) {
- ctl_fatal("%s", ctx.error);
+ error = xstrdup(ctx.error);
+ ctl_context_done(&ctx, c);
+ goto out_error;
}
ctl_context_done(&ctx, c);
}
@@ -4236,7 +4246,8 @@ do_nbctl(const char *args, struct ctl_command *commands, size_t n_commands,
case TXN_ABORTED:
/* Should not happen--we never call ovsdb_idl_txn_abort(). */
- ctl_fatal("transaction aborted");
+ error = xstrdup("transaction aborted");
+ goto out_error;
case TXN_UNCHANGED:
case TXN_SUCCESS:
@@ -4246,11 +4257,14 @@ do_nbctl(const char *args, struct ctl_command *commands, size_t n_commands,
goto try_again;
case TXN_ERROR:
- ctl_fatal("transaction error: %s", ovsdb_idl_txn_get_error(txn));
+ error = xasprintf("transaction error: %s",
+ ovsdb_idl_txn_get_error(txn));
+ goto out_error;
case TXN_NOT_LOCKED:
/* Should not happen--we never call ovsdb_idl_set_lock(). */
- ctl_fatal("database not locked");
+ error = xstrdup("database not locked");
+ goto out_error;
default:
OVS_NOT_REACHED();
@@ -4309,11 +4323,14 @@ do_nbctl(const char *args, struct ctl_command *commands, size_t n_commands,
ovsdb_idl_txn_destroy(txn);
*retry = false;
- return;
+ return NULL;
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. */
+ *retry = true;
+
+out_error:
ovsdb_idl_txn_abort(txn);
ovsdb_idl_txn_destroy(txn);
the_idl_txn = NULL;
@@ -4324,7 +4341,8 @@ do_nbctl(const char *args, struct ctl_command *commands, size_t n_commands,
table_destroy(c->table);
free(c->table);
}
- *retry = true;
+
+ return error;
}
/* Frees the current transaction and the underlying IDL and then calls
Instead of terminating the process, return the error to the caller. This will allow us to reuse the main loop in daemon mode. Signed-off-by: Jakub Sitnicki <jkbs@redhat.com> --- ovn/utilities/ovn-nbctl.c | 46 ++++++++++++++++++++++++++++++++-------------- 1 file changed, 32 insertions(+), 14 deletions(-)