Occasionally in the unit tests the following race can happen:
1. ovs-vsctl updates database
2. ovs-vswitchd reconfigures, notifies ovs-vsctl that it is complete
3. ovs-appctl ofproto/trace fails to see newly added port
4. ovs-vswitchd main loop calls ofproto's ->type_run(), making the
new port visible to translation.
This race may be seen in the failures of tests 5 and 624 here:
https://launchpadlibrarian.net/151884888/buildlog_ubuntu-precise-amd64.openvswitch_2.0~201309300804-1ppa1~precise_FAILEDTOBUILD.txt.gz
Reported-by: Vasiliy Tolstov <[email protected]>
Signed-off-by: Ben Pfaff <[email protected]>
---
AUTHORS | 1 +
vswitchd/bridge.c | 46 ++++++++++++++++++++++++++++++++--------------
2 files changed, 33 insertions(+), 14 deletions(-)
diff --git a/AUTHORS b/AUTHORS
index af34bfe..29f44e2 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -214,6 +214,7 @@ Takayuki HAMA [email protected]
Teemu Koponen [email protected]
Timothy Chen [email protected]
Valentin Bud [email protected]
+Vasiliy Tolstov [email protected]
Vishal Swarankar [email protected]
Vjekoslav Brajkovic [email protected]
Voravit T. [email protected]
diff --git a/vswitchd/bridge.c b/vswitchd/bridge.c
index b3ca42b..11a9408 100644
--- a/vswitchd/bridge.c
+++ b/vswitchd/bridge.c
@@ -186,6 +186,7 @@ static long long int iface_stats_timer = LLONG_MIN;
static bool reconfiguring = false;
static void add_del_bridges(const struct ovsrec_open_vswitch *);
+static void bridge_run__(void);
static void bridge_update_ofprotos(void);
static void bridge_create(const struct ovsrec_bridge *);
static void bridge_destroy(struct bridge *);
@@ -645,6 +646,15 @@ bridge_reconfigure_continue(const struct
ovsrec_open_vswitch *ovs_cfg)
}
free(managers);
+ /* The ofproto-dpif provider does some final reconfiguration in its
+ * ->type_run() function. We have to call it before notifying the database
+ * client that reconfiguration is complete, otherwise there is a very
+ * narrow race window in which e.g. ofproto/trace will not recognize the
+ * new configuration (sometimes this causes unit test failures). */
+ if (done) {
+ bridge_run__();
+ }
+
return done;
}
@@ -2315,14 +2325,33 @@ bridge_run_fast(void)
}
}
+static void
+bridge_run__(void)
+{
+ struct bridge *br;
+ struct sset types;
+ const char *type;
+
+ /* Let each datapath type do the work that it needs to do. */
+ sset_init(&types);
+ ofproto_enumerate_types(&types);
+ SSET_FOR_EACH (type, &types) {
+ ofproto_type_run(type);
+ }
+ sset_destroy(&types);
+
+ /* Let each bridge do the work that it needs to do. */
+ HMAP_FOR_EACH (br, node, &all_bridges) {
+ ofproto_run(br->ofproto);
+ }
+}
+
void
bridge_run(void)
{
static struct ovsrec_open_vswitch null_cfg;
const struct ovsrec_open_vswitch *cfg;
struct ovsdb_idl_txn *reconf_txn = NULL;
- struct sset types;
- const char *type;
bool vlan_splinters_changed;
struct bridge *br;
@@ -2368,18 +2397,7 @@ bridge_run(void)
"flow-restore-wait", false));
}
- /* Let each datapath type do the work that it needs to do. */
- sset_init(&types);
- ofproto_enumerate_types(&types);
- SSET_FOR_EACH (type, &types) {
- ofproto_type_run(type);
- }
- sset_destroy(&types);
-
- /* Let each bridge do the work that it needs to do. */
- HMAP_FOR_EACH (br, node, &all_bridges) {
- ofproto_run(br->ofproto);
- }
+ bridge_run__();
/* Re-configure SSL. We do this on every trip through the main loop,
* instead of just when the database changes, because the contents of the
--
1.7.10.4
_______________________________________________
dev mailing list
[email protected]
http://openvswitch.org/mailman/listinfo/dev