When adding a new port or bond, save the port name and check the "ofport" column of that port after the database has been reloaded. It will contain OFPP_NONE (-1) if the addition process failed inside the bridge. Print an error message and exit ovs-vsctl with -EFAULT in that case.
Note that this is not 100% reliable. Another user may have modified the database which may have caused the port addition to fail. Cc: Ben Pfaff <b...@nicira.com> Signed-off-by: Thomas Graf <tg...@redhat.com> --- utilities/ovs-vsctl.c | 58 +++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 56 insertions(+), 2 deletions(-) diff --git a/utilities/ovs-vsctl.c b/utilities/ovs-vsctl.c index bccb2c9..ead635b 100644 --- a/utilities/ovs-vsctl.c +++ b/utilities/ovs-vsctl.c @@ -733,6 +733,11 @@ struct vsctl_context { /* 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; + + /* A command may set this member to a port name to trigger checking the + * "ofport" column after the database reload for OFPP_NONE and indicate + * an error. */ + char *check_ofport; }; struct vsctl_bridge { @@ -981,6 +986,7 @@ pre_get_info(struct vsctl_context *ctx) ovsdb_idl_add_column(ctx->idl, &ovsrec_port_col_interfaces); ovsdb_idl_add_column(ctx->idl, &ovsrec_interface_col_name); + ovsdb_idl_add_column(ctx->idl, &ovsrec_interface_col_ofport); } static void @@ -1934,6 +1940,8 @@ add_port(struct vsctl_context *ctx, add_iface_to_cache(ctx, vsctl_port, ifaces[i]); } free(ifaces); + + ctx->check_ofport = xstrdup(port_name); } static void @@ -3880,6 +3888,50 @@ run_prerequisites(struct vsctl_command *commands, size_t n_commands, } } +static struct ovsrec_interface * +find_failed_interface(const struct ovsrec_open_vswitch *ovs, const char *name) +{ + int i, j, k; + + for (i = 0; i < ovs->n_bridges; i++) { + struct ovsrec_bridge *br = ovs->bridges[i]; + + for (j = 0; j < br->n_ports; j++) { + struct ovsrec_port *port = br->ports[j]; + + if (strcmp(port->name, name)) + continue; + + for (k = 0; k < port->n_interfaces; k++) { + struct ovsrec_interface *iface = port->interfaces[k]; + + if (iface->n_ofport && + *((uint16_t *) iface->ofport) == OFPP_NONE) + return iface; + } + } + } + + return NULL; +} + +static int +post_db_reload_checks(struct vsctl_context *ctx) +{ + int err = EXIT_SUCCESS; + + if (ctx->check_ofport) { + if (find_failed_interface(ctx->ovs, ctx->check_ofport)) { + vsctl_fatal("Unable to add port '%s'", ctx->check_ofport); + err = -EFAULT; + } + } + + free(ctx->check_ofport); + + return err; +} + static void do_vsctl(const char *args, struct vsctl_command *commands, size_t n_commands, struct ovsdb_idl *idl) @@ -3893,6 +3945,7 @@ do_vsctl(const char *args, struct vsctl_command *commands, size_t n_commands, struct shash_node *node; int64_t next_cfg = 0; char *error = NULL; + int ret = EXIT_SUCCESS; txn = the_idl_txn = ovsdb_idl_txn_create(idl); if (dry_run) { @@ -4048,11 +4101,12 @@ do_vsctl(const char *args, struct vsctl_command *commands, size_t n_commands, ovsdb_idl_wait(idl); poll_block(); } - done: ; + done: + ret = post_db_reload_checks(&ctx); } ovsdb_idl_destroy(idl); - exit(EXIT_SUCCESS); + exit(ret); try_again: /* Our transaction needs to be rerun, or a prerequisite was not met. Free -- 1.7.11.7 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev