[ovs-dev] [PATCH] ovs-vsctl: Check "ofport" column after adding a new port
Thomas Graf
tgraf at redhat.com
Tue Dec 11 23:48:44 UTC 2012
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 <blp at nicira.com>
Signed-off-by: Thomas Graf <tgraf at 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
More information about the dev
mailing list