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 v3: Remove iface_refresh_netdev_status() from iface_create() upon further discussion with Alex --- vswitchd/bridge.c | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/vswitchd/bridge.c b/vswitchd/bridge.c index 9764c1f..bda935c 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. */ @@ -1547,7 +1553,6 @@ iface_create(struct bridge *br, const struct ovsrec_interface *iface_cfg, /* Populate initial status in database. */ iface_refresh_stats(iface); - iface_refresh_netdev_status(iface); /* Add bond fake iface if necessary. */ if (port_is_bond_fake_iface(port)) { @@ -1820,7 +1825,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 +2426,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 +2450,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