Great. Thanks Andy and Thomas, I applied these two patches to master. I added a NEWS item:
- ovs-vsctl now reports when ovs-vswitchd fails to create a new port or bridge. On Fri, Mar 28, 2014 at 12:13:45AM -0700, Andy Zhou wrote: > Not sure if I suppose to ack this patch since I am one of authors. > > I did review v4 in detail and tested it . > > Just in case it is useful, here is my ack. > > Acked-by: Andy Zhou <az...@nicira.com> > > On Thu, Mar 27, 2014 at 9:02 PM, Ben Pfaff <b...@nicira.com> wrote: > > From: Andy Zhou <az...@nicira.com> > > > > ovs-vsctl is a command-line interface to the Open vSwitch database, > > and as such it just modifies the desired Open vSwitch configuration in > > the database. ovs-vswitchd, on the other hand, monitors the database > > and implements the actual configuration specified in the database. > > This can lead to surprises when the user makes a change to the > > database, with ovs-vsctl, that ovs-vswitchd cannot actually > > implement. In such a case, the ovs-vsctl command silently succeeds > > (because the database was successfully updated) but its desired > > effects don't actually take place. One good example of such a change > > is attempting to add a port with a misspelled name (e.g. ``ovs-vsctl > > add-port br0 fth0'', where fth0 should be eth0); another is creating > > a bridge or a port whose name is longer than supported > > (e.g. ``ovs-vsctl add-br'' with a 16-character bridge name on > > Linux). It can take users a long time to realize the error, because it > > requires looking through the ovs-vswitchd log. > > > > The patch improves the situation by checking whether operations that > > ovs executes succeed and report an error when > > they do not. This patch only report add-br and add-port > > operation errors by examining the `ofport' value that > > ovs-vswitchd stores into the database record for the newly created > > interface. Until ovs-vswitchd finishes implementing the new > > configuration, this column is empty, and after it finishes it is > > either -1 (on failure) or a positive number (on success). > > > > Signed-off-by: Andy Zhou <az...@nicira.com> > > Co-authored-by: Thomas Graf <tg...@redhat.com> > > Signed-off-by: Thomas Graf <tg...@redhat.com> > > Co-authored-by: Ben Pfaff <b...@nicira.com> > > Signed-off-by: Ben Pfaff <b...@nicira.com> > > --- > > v3->v4: See http://openvswitch.org/pipermail/dev/2014-March/038164.html for > > changes. > > > > tests/ovs-vsctl.at | 8 +++-- > > utilities/ovs-vsctl.c | 87 > > ++++++++++++++++++++++++++++++++++++++++++++++++--- > > 2 files changed, 88 insertions(+), 7 deletions(-) > > > > diff --git a/tests/ovs-vsctl.at b/tests/ovs-vsctl.at > > index 851e4d8..440bf1a 100644 > > --- a/tests/ovs-vsctl.at > > +++ b/tests/ovs-vsctl.at > > @@ -1209,7 +1209,9 @@ m4_foreach( > > [vxlan_system]], > > [ > > # Try creating the port > > -AT_CHECK([ovs-vsctl add-port br0 reserved_name], [0], [], []) > > +AT_CHECK([ovs-vsctl add-port br0 reserved_name], [0], [], [dnl > > +ovs-vsctl: Error detected while setting up 'reserved_name'. See > > ovs-vswitchd log for details. > > +]) > > # Detect the warning log message > > AT_CHECK([sed -n "s/^.*\(|bridge|WARN|.*\)$/\1/p" ovs-vswitchd.log], [0], > > [dnl > > |bridge|WARN|could not create interface reserved_name, name is reserved > > @@ -1242,7 +1244,9 @@ m4_foreach( > > [vxlan_system]], > > [ > > # Try creating the port > > -AT_CHECK([ovs-vsctl add-port br0 reserved_name], [0], [], []) > > +AT_CHECK([ovs-vsctl add-port br0 reserved_name], [0], [], [dnl > > +ovs-vsctl: Error detected while setting up 'reserved_name'. See > > ovs-vswitchd log for details. > > +]) > > # Detect the warning log message > > AT_CHECK([sed -n "s/^.*\(|bridge|WARN|.*\)$/\1/p" ovs-vswitchd.log], [0], > > [dnl > > |bridge|WARN|could not create interface reserved_name, name is reserved > > diff --git a/utilities/ovs-vsctl.c b/utilities/ovs-vsctl.c > > index 21ac777..4fcee77 100644 > > --- a/utilities/ovs-vsctl.c > > +++ b/utilities/ovs-vsctl.c > > @@ -1,5 +1,5 @@ > > /* > > - * Copyright (c) 2009, 2010, 2011, 2012, 2013 Nicira, Inc. > > + * Copyright (c) 2009, 2010, 2011, 2012, 2013, 2014 Nicira, Inc. > > * > > * Licensed under the Apache License, Version 2.0 (the "License"); > > * you may not use this file except in compliance with the License. > > @@ -165,6 +165,34 @@ static bool is_condition_satisfied(const struct > > vsctl_table_class *, > > const char *arg, > > struct ovsdb_symbol_table *); > > > > +/* Post_db_reload_check frame work is to allow ovs-vsctl to do additional > > + * checks after OVSDB transactions are successfully recorded and reload by > > + * ovs-vswitchd. > > + * > > + * For example, When a new interface is added to OVSDB, ovs-vswitchd will > > + * either store a positive values on successful implementing the new > > + * interface, or -1 on failure. > > + * > > + * Unless -no-wait command line option is specified, > > + * post_db_reload_do_checks() is called right after any configuration > > + * changes is picked up (i.e. reload) by ovs-vswitchd. Any error detected > > + * post OVSDB reload is reported as ovs-vsctl errors. OVS-vswitchd logs > > + * more detailed messages about those errors. > > + * > > + * Current implementation only check for Post OVSDB reload failures on new > > + * interface additions with 'add-br' and 'add-port' commands. > > + * > > + * post_db_reload_expect_iface() > > + * > > + * keep track of interfaces to be checked post OVSDB reload. */ > > +static void post_db_reload_check_init(void); > > +static void post_db_reload_do_checks(const struct vsctl_context *); > > +static void post_db_reload_expect_iface(const struct ovsrec_interface *); > > + > > +static struct uuid *neoteric_ifaces; > > +static size_t n_neoteric_ifaces; > > +static size_t allocated_neoteric_ifaces; > > + > > int > > main(int argc, char *argv[]) > > { > > @@ -1004,6 +1032,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 > > @@ -1561,6 +1590,7 @@ cmd_add_br(struct vsctl_context *ctx) > > { > > bool may_exist = shash_find(&ctx->options, "--may-exist") != NULL; > > const char *br_name, *parent_name; > > + struct ovsrec_interface *iface; > > int vlan; > > > > br_name = ctx->argv[1]; > > @@ -1614,7 +1644,6 @@ cmd_add_br(struct vsctl_context *ctx) > > > > if (!parent_name) { > > struct ovsrec_port *port; > > - struct ovsrec_interface *iface; > > struct ovsrec_bridge *br; > > > > iface = ovsrec_interface_insert(ctx->txn); > > @@ -1633,7 +1662,6 @@ cmd_add_br(struct vsctl_context *ctx) > > } else { > > struct vsctl_bridge *parent; > > struct ovsrec_port *port; > > - struct ovsrec_interface *iface; > > struct ovsrec_bridge *br; > > int64_t tag = vlan; > > > > @@ -1659,6 +1687,7 @@ cmd_add_br(struct vsctl_context *ctx) > > bridge_insert_port(br, port); > > } > > > > + post_db_reload_expect_iface(iface); > > vsctl_context_invalidate_cache(ctx); > > } > > > > @@ -1952,6 +1981,7 @@ add_port(struct vsctl_context *ctx, > > for (i = 0; i < n_ifaces; i++) { > > ifaces[i] = ovsrec_interface_insert(ctx->txn); > > ovsrec_interface_set_name(ifaces[i], iface_names[i]); > > + post_db_reload_expect_iface(ifaces[i]); > > } > > > > port = ovsrec_port_insert(ctx->txn); > > @@ -3644,6 +3674,52 @@ post_create(struct vsctl_context *ctx) > > } > > > > static void > > +post_db_reload_check_init(void) > > +{ > > + n_neoteric_ifaces = 0; > > +} > > + > > +static void > > +post_db_reload_expect_iface(const struct ovsrec_interface *iface) > > +{ > > + if (n_neoteric_ifaces >= allocated_neoteric_ifaces) { > > + neoteric_ifaces = x2nrealloc(neoteric_ifaces, > > + &allocated_neoteric_ifaces, > > + sizeof *neoteric_ifaces); > > + } > > + neoteric_ifaces[n_neoteric_ifaces++] = iface->header_.uuid; > > +} > > + > > +static void > > +post_db_reload_do_checks(const struct vsctl_context *ctx) > > +{ > > + struct ds dead_ifaces = DS_EMPTY_INITIALIZER; > > + size_t i; > > + > > + for (i = 0; i < n_neoteric_ifaces; i++) { > > + const struct uuid *uuid; > > + > > + uuid = ovsdb_idl_txn_get_insert_uuid(ctx->txn, > > &neoteric_ifaces[i]); > > + if (uuid) { > > + const struct ovsrec_interface *iface; > > + > > + iface = ovsrec_interface_get_for_uuid(ctx->idl, uuid); > > + if (iface && (!iface->ofport || *iface->ofport == -1)) { > > + ds_put_format(&dead_ifaces, "'%s', ", iface->name); > > + } > > + } > > + } > > + > > + if (dead_ifaces.length) { > > + dead_ifaces.length -= 2; /* Strip off trailing comma and space. */ > > + ovs_error(0, "Error detected while setting up %s. See > > ovs-vswitchd " > > + "log for details.", ds_cstr(&dead_ifaces)); > > + } > > + > > + ds_destroy(&dead_ifaces); > > +} > > + > > +static void > > pre_cmd_destroy(struct vsctl_context *ctx) > > { > > const char *table_name = ctx->argv[1]; > > @@ -3999,6 +4075,7 @@ do_vsctl(const char *args, struct vsctl_command > > *commands, size_t n_commands, > > &ovsrec_open_vswitch_col_next_cfg); > > } > > > > + post_db_reload_check_init(); > > symtab = ovsdb_symbol_table_create(); > > for (c = commands; c < &commands[n_commands]; c++) { > > ds_init(&c->output); > > @@ -4055,8 +4132,6 @@ do_vsctl(const char *args, struct vsctl_command > > *commands, size_t n_commands, > > } > > } > > error = xstrdup(ovsdb_idl_txn_get_error(txn)); > > - ovsdb_idl_txn_destroy(txn); > > - txn = the_idl_txn = NULL; > > > > switch (status) { > > case TXN_UNCOMMITTED: > > @@ -4134,6 +4209,7 @@ do_vsctl(const char *args, struct vsctl_command > > *commands, size_t n_commands, > > ovsdb_idl_run(idl); > > OVSREC_OPEN_VSWITCH_FOR_EACH (ovs, idl) { > > if (ovs->cur_cfg >= next_cfg) { > > + post_db_reload_do_checks(&ctx); > > goto done; > > } > > } > > @@ -4142,6 +4218,7 @@ do_vsctl(const char *args, struct vsctl_command > > *commands, size_t n_commands, > > } > > done: ; > > } > > + ovsdb_idl_txn_destroy(txn); > > ovsdb_idl_destroy(idl); > > > > exit(EXIT_SUCCESS); > > -- > > 1.8.5.3 > > _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev