Prepare for the command handlers (pre_cmd_*() cmd_*() functions) to report errors by storing them in the context.
Signed-off-by: Jakub Sitnicki <[email protected]> --- lib/db-ctl-base.c | 22 ++++++++++++++++++++++ lib/db-ctl-base.h | 3 +++ ovn/utilities/ovn-nbctl.c | 9 +++++++++ ovn/utilities/ovn-sbctl.c | 9 +++++++++ utilities/ovs-vsctl.c | 9 +++++++++ vtep/vtep-ctl.c | 9 +++++++++ 6 files changed, 61 insertions(+) diff --git a/lib/db-ctl-base.c b/lib/db-ctl-base.c index 033011c15..14cdff6eb 100644 --- a/lib/db-ctl-base.c +++ b/lib/db-ctl-base.c @@ -2191,6 +2191,25 @@ ctl_might_write_to_db(const struct ctl_command *commands, size_t n) return false; } +/* Report an error while running in the command context. Caller should return + * to its caller immediately after reporting the error. */ +void +ctl_error(struct ctl_context *ctx, const char *format, ...) +{ + va_list args; + + ovs_assert(ctx); + + if (ctx->error) { + VLOG_ERR("Discarding unhandled error: %s", ctx->error); + free(ctx->error); + } + + va_start(args, format); + ctx->error = xvasprintf(format, args); + va_end(args); +} + void ctl_fatal(const char *format, ...) { @@ -2376,6 +2395,7 @@ ctl_context_init_command(struct ctl_context *ctx, ds_swap(&ctx->output, &command->output); ctx->table = command->table; ctx->try_again = false; + ctx->error = NULL; } /* Initializes the entire 'ctx'. */ @@ -2401,6 +2421,8 @@ ctl_context_done_command(struct ctl_context *ctx, { ds_swap(&ctx->output, &command->output); command->table = ctx->table; + free(ctx->error); + ctx->error = NULL; } /* Finishes up with 'ctx'. diff --git a/lib/db-ctl-base.h b/lib/db-ctl-base.h index 8c6ac19a3..5d325d8e7 100644 --- a/lib/db-ctl-base.h +++ b/lib/db-ctl-base.h @@ -59,6 +59,8 @@ void ctl_init__(const struct ovsdb_idl_class *, const struct ctl_table_class *, const struct cmd_show_table *cmd_show_tables, void (*ctl_exit_func)(int status)); char *ctl_default_db(void); +void ctl_error(struct ctl_context *, const char *, ...) +OVS_PRINTF_FORMAT(2, 3); OVS_NO_RETURN void ctl_fatal(const char *, ...) OVS_PRINTF_FORMAT(1, 2); /* *ctl command syntax structure, to be defined by each command implementation. @@ -225,6 +227,7 @@ struct ctl_context { struct shash options; /* Modifiable state. */ + char *error; struct ds output; struct table *table; struct ovsdb_idl *idl; diff --git a/ovn/utilities/ovn-nbctl.c b/ovn/utilities/ovn-nbctl.c index 798f6bef4..63d41660b 100644 --- a/ovn/utilities/ovn-nbctl.c +++ b/ovn/utilities/ovn-nbctl.c @@ -3788,6 +3788,9 @@ run_prerequisites(struct ctl_command *commands, size_t n_commands, ctl_context_init(&ctx, c, idl, NULL, NULL, NULL); (c->syntax->prerequisites)(&ctx); + if (ctx.error) { + ctl_fatal("%s", ctx.error); + } ctl_context_done(&ctx, c); ovs_assert(!c->output.string); @@ -3837,6 +3840,9 @@ do_nbctl(const char *args, struct ctl_command *commands, size_t n_commands, if (c->syntax->run) { (c->syntax->run)(&ctx); } + if (ctx.error) { + ctl_fatal("%s", error); + } ctl_context_done_command(&ctx, c); if (ctx.try_again) { @@ -3875,6 +3881,9 @@ do_nbctl(const char *args, struct ctl_command *commands, size_t n_commands, if (c->syntax->postprocess) { ctl_context_init(&ctx, c, idl, txn, symtab, NULL); (c->syntax->postprocess)(&ctx); + if (ctx.error) { + ctl_fatal("%s", ctx.error); + } ctl_context_done(&ctx, c); } } diff --git a/ovn/utilities/ovn-sbctl.c b/ovn/utilities/ovn-sbctl.c index 0e2c67c08..441b2dac6 100644 --- a/ovn/utilities/ovn-sbctl.c +++ b/ovn/utilities/ovn-sbctl.c @@ -1238,6 +1238,9 @@ run_prerequisites(struct ctl_command *commands, size_t n_commands, sbctl_context_init(&sbctl_ctx, c, idl, NULL, NULL); (c->syntax->prerequisites)(&sbctl_ctx.base); + if (sbctl_ctx.base.error) { + ctl_fatal("%s", sbctl_ctx.base.error); + } sbctl_context_done(&sbctl_ctx, c); ovs_assert(!c->output.string); @@ -1281,6 +1284,9 @@ do_sbctl(const char *args, struct ctl_command *commands, size_t n_commands, if (c->syntax->run) { (c->syntax->run)(&sbctl_ctx.base); } + if (sbctl_ctx.base.error) { + ctl_fatal("%s", sbctl_ctx.base.error); + } sbctl_context_done_command(&sbctl_ctx, c); if (sbctl_ctx.base.try_again) { @@ -1316,6 +1322,9 @@ do_sbctl(const char *args, struct ctl_command *commands, size_t n_commands, if (c->syntax->postprocess) { sbctl_context_init(&sbctl_ctx, c, idl, txn, symtab); (c->syntax->postprocess)(&sbctl_ctx.base); + if (sbctl_ctx.base.error) { + ctl_fatal("%s", sbctl_ctx.base.error); + } sbctl_context_done(&sbctl_ctx, c); } } diff --git a/utilities/ovs-vsctl.c b/utilities/ovs-vsctl.c index 6a9637a20..e845634c2 100644 --- a/utilities/ovs-vsctl.c +++ b/utilities/ovs-vsctl.c @@ -2527,6 +2527,9 @@ run_prerequisites(struct ctl_command *commands, size_t n_commands, vsctl_context_init(&vsctl_ctx, c, idl, NULL, NULL, NULL); (c->syntax->prerequisites)(&vsctl_ctx.base); + if (vsctl_ctx.base.error) { + ctl_fatal("%s", vsctl_ctx.base.error); + } vsctl_context_done(&vsctl_ctx, c); ovs_assert(!c->output.string); @@ -2621,6 +2624,9 @@ do_vsctl(const char *args, struct ctl_command *commands, size_t n_commands, if (c->syntax->run) { (c->syntax->run)(&vsctl_ctx.base); } + if (vsctl_ctx.base.error) { + ctl_fatal("%s", vsctl_ctx.base.error); + } vsctl_context_done_command(&vsctl_ctx, c); if (vsctl_ctx.base.try_again) { @@ -2659,6 +2665,9 @@ do_vsctl(const char *args, struct ctl_command *commands, size_t n_commands, if (c->syntax->postprocess) { vsctl_context_init(&vsctl_ctx, c, idl, txn, ovs, symtab); (c->syntax->postprocess)(&vsctl_ctx.base); + if (vsctl_ctx.base.error) { + ctl_fatal("%s", vsctl_ctx.base.error); + } vsctl_context_done(&vsctl_ctx, c); } } diff --git a/vtep/vtep-ctl.c b/vtep/vtep-ctl.c index 678323fae..e0d5121a3 100644 --- a/vtep/vtep-ctl.c +++ b/vtep/vtep-ctl.c @@ -2260,6 +2260,9 @@ run_prerequisites(struct ctl_command *commands, size_t n_commands, vtep_ctl_context_init(&vtepctl_ctx, c, idl, NULL, NULL, NULL); (c->syntax->prerequisites)(&vtepctl_ctx.base); + if (vtepctl_ctx.base.error) { + ctl_fatal("%s", vtepctl_ctx.base.error); + } vtep_ctl_context_done(&vtepctl_ctx, c); ovs_assert(!c->output.string); @@ -2304,6 +2307,9 @@ do_vtep_ctl(const char *args, struct ctl_command *commands, if (c->syntax->run) { (c->syntax->run)(&vtepctl_ctx.base); } + if (vtepctl_ctx.base.error) { + ctl_fatal("%s", vtepctl_ctx.base.error); + } vtep_ctl_context_done_command(&vtepctl_ctx, c); if (vtepctl_ctx.base.try_again) { @@ -2339,6 +2345,9 @@ do_vtep_ctl(const char *args, struct ctl_command *commands, if (c->syntax->postprocess) { vtep_ctl_context_init(&vtepctl_ctx, c, idl, txn, vtep_global, symtab); (c->syntax->postprocess)(&vtepctl_ctx.base); + if (vtepctl_ctx.base.error) { + ctl_fatal("%s", vtepctl_ctx.base.error); + } vtep_ctl_context_done(&vtepctl_ctx, c); } } -- 2.14.4 _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
