Bridge, port and interface status changes are not sent to the
database if the connectivity and netdev sequence numbers have not
changed. However, if the previous database transaction fails, then
status changes will not be updated in the database until the
connectivity and netdev sequence numbers change again. This could
leave the database in an incorrect state for a long period of time.

This patch always sends status changes to the database if the last
transaction was not successful.

Signed-off-by: Ryan Wilson <wr...@nicira.com>

---
v2: Addressed Alex's comments, edited commit message to be more
accurate
---
 vswitchd/bridge.c |   25 ++++++++++++++++++++++---
 1 file changed, 22 insertions(+), 3 deletions(-)

diff --git a/vswitchd/bridge.c b/vswitchd/bridge.c
index 9764c1f..9101b54 100644
--- a/vswitchd/bridge.c
+++ b/vswitchd/bridge.c
@@ -172,9 +172,15 @@ static uint64_t connectivity_seqno = LLONG_MIN;
  * we check the return status of each update transaction and do not start new
  * update if the previous transaction status is 'TXN_INCOMPLETE'.
  *
- * 'statux_txn' is NULL if there is no ongoing status update.
+ * 'status_txn' is NULL if there is no ongoing status update.
+ *
+ * If the previous database transaction fails (is not 'TXN_SUCCESS',
+ * 'TXN_UNCHANGED' or 'TXN_INCOMPLETE'), 'force_status_update' is set to true.
+ * This means the database must be updated next iteration of bridge_run()
+ * even if the connectivity or netdev sequence numbers do not change.
  */
 static struct ovsdb_idl_txn *status_txn;
+bool force_status_update = true;
 
 /* When the status update transaction returns 'TXN_INCOMPLETE', should 
register a
  * timeout in 'STATUS_CHECK_AGAIN_MSEC' to check again. */
@@ -1820,7 +1826,8 @@ iface_refresh_netdev_status(struct iface *iface)
         return;
     }
 
-    if (iface->change_seq == netdev_get_change_seq(iface->netdev)) {
+    if (iface->change_seq == netdev_get_change_seq(iface->netdev)
+        && !force_status_update) {
         return;
     }
 
@@ -2420,7 +2427,7 @@ bridge_run(void)
 
         /* Check the need to update status. */
         seq = seq_read(connectivity_seq_get());
-        if (seq != connectivity_seqno) {
+        if (seq != connectivity_seqno || force_status_update) {
             connectivity_seqno = seq;
             status_txn = ovsdb_idl_txn_create(idl);
             HMAP_FOR_EACH (br, node, &all_bridges) {
@@ -2444,6 +2451,18 @@ bridge_run(void)
         enum ovsdb_idl_txn_status status;
 
         status = ovsdb_idl_txn_commit(status_txn);
+
+        /* If the transaction fails, 'status_txn' needs to be
+         * updated next iteration of bridge_run() even if
+         * connectivity or netdev sequence numbers do not change. */
+        if (status == TXN_SUCCESS || status == TXN_UNCHANGED
+            || status == TXN_INCOMPLETE)
+        {
+            force_status_update = false;
+        } else {
+            force_status_update = true;
+        }
+
         /* Do not destroy "status_txn" if the transaction is
          * "TXN_INCOMPLETE". */
         if (status != TXN_INCOMPLETE) {
-- 
1.7.9.5

_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to