diff --git a/SOURCES/openvswitch-2.16.0.patch b/SOURCES/openvswitch-2.16.0.patch index ac3a700..acde610 100644 --- a/SOURCES/openvswitch-2.16.0.patch +++ b/SOURCES/openvswitch-2.16.0.patch @@ -4243,7 +4243,7 @@ index e120094d7a..ff026b77fa 100644 const struct json *schema, const struct json *snapshot) diff --git a/ovsdb/transaction.c b/ovsdb/transaction.c -index 8ffefcf7c9..88e0528002 100644 +index 8ffefcf7c9..db86d847c3 100644 --- a/ovsdb/transaction.c +++ b/ovsdb/transaction.c @@ -41,6 +41,9 @@ struct ovsdb_txn { @@ -4736,7 +4736,7 @@ index 8ffefcf7c9..88e0528002 100644 if (old) { old->txn_row = txn_row; } -@@ -1423,12 +1592,18 @@ ovsdb_txn_history_run(struct ovsdb *db) +@@ -1423,12 +1592,20 @@ ovsdb_txn_history_run(struct ovsdb *db) if (!db->need_txn_history) { return; } @@ -4745,8 +4745,10 @@ index 8ffefcf7c9..88e0528002 100644 + /* Remove old histories to limit the size of the history. Removing until + * the number of ovsdb atoms in history becomes less than the number of + * atoms in the database, because it will be faster to just get a database -+ * snapshot than re-constructing changes from the history that big. */ -+ while (db->n_txn_history && ++ * snapshot than re-constructing changes from the history that big. ++ * Keeping at least one transaction to avoid sending UUID_ZERO as a last id ++ * if all entries got removed due to the size limit. */ ++ while (db->n_txn_history > 1 && + (db->n_txn_history > 100 || + db->n_txn_history_atoms > db->n_atoms)) { struct ovsdb_txn_history_node *txn_h_node = CONTAINER_OF( @@ -4757,7 +4759,7 @@ index 8ffefcf7c9..88e0528002 100644 ovsdb_txn_destroy_cloned(txn_h_node->txn); free(txn_h_node); db->n_txn_history--; -@@ -1440,6 +1615,7 @@ ovsdb_txn_history_init(struct ovsdb *db, bool need_txn_history) +@@ -1440,6 +1617,7 @@ ovsdb_txn_history_init(struct ovsdb *db, bool need_txn_history) { db->need_txn_history = need_txn_history; db->n_txn_history = 0; @@ -4765,7 +4767,7 @@ index 8ffefcf7c9..88e0528002 100644 ovs_list_init(&db->txn_history); } -@@ -1458,4 +1634,5 @@ ovsdb_txn_history_destroy(struct ovsdb *db) +@@ -1458,4 +1636,5 @@ ovsdb_txn_history_destroy(struct ovsdb *db) free(txn_h_node); } db->n_txn_history = 0; @@ -5462,10 +5464,10 @@ index 1386f13770..91d34d0de6 100644 008: table simple: i=1 r=2 b=true s= u=<0> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<2> 009: done diff --git a/tests/ovsdb-server.at b/tests/ovsdb-server.at -index ac243d6a79..2b742f78b0 100644 +index ac243d6a79..876cb836cd 100644 --- a/tests/ovsdb-server.at +++ b/tests/ovsdb-server.at -@@ -1228,6 +1228,69 @@ AT_CHECK([test $logged_updates -lt $logged_nonblock_updates]) +@@ -1228,6 +1228,71 @@ AT_CHECK([test $logged_updates -lt $logged_nonblock_updates]) AT_CHECK_UNQUOTED([ovs-vsctl get open_vswitch . system_version], [0], [xyzzy$counter ]) @@ -5491,10 +5493,11 @@ index ac243d6a79..2b742f78b0 100644 +dnl to hold all of them. +dnl +dnl The test verifies that the number of atoms in the transaction history -+dnl is always less than the number of atoms in the database. -+get_n_atoms () { ++dnl is always less than the number of atoms in the database, except for ++dnl a case where there is only one transaction in a history. ++get_memory_value () { + n=$(ovs-appctl -t ovsdb-server memory/show dnl -+ | tr ' ' '\n' | grep atoms | grep "^$1:" | cut -d ':' -f 2) ++ | tr ' ' '\n' | grep "^$1:" | cut -d ':' -f 2) + if test X"$n" == "X"; then + n=0 + fi @@ -5502,8 +5505,9 @@ index ac243d6a79..2b742f78b0 100644 +} + +check_atoms () { -+ n_db_atoms=$(get_n_atoms atoms) -+ n_txn_history_atoms=$(get_n_atoms txn-history-atoms) ++ if test $(get_memory_value txn-history) -eq 1; then return; fi ++ n_db_atoms=$(get_memory_value atoms) ++ n_txn_history_atoms=$(get_memory_value txn-history-atoms) + echo "n_db_atoms: $n_db_atoms" + echo "n_txn_history_atoms: $n_txn_history_atoms" + AT_CHECK([test $n_txn_history_atoms -le $n_db_atoms]) @@ -5515,7 +5519,7 @@ index ac243d6a79..2b742f78b0 100644 + done +} + -+initial_db_atoms=$(get_n_atoms atoms) ++initial_db_atoms=$(get_memory_value atoms) + +for i in $(seq 1 100); do + cmd=$(add_ports $i $(($i / 4 + 1))) @@ -5530,7 +5534,7 @@ index ac243d6a79..2b742f78b0 100644 + +dnl After removing all the bridges, the number of atoms in the database +dnl should return to its initial value. -+AT_CHECK([test $(get_n_atoms atoms) -eq $initial_db_atoms]) ++AT_CHECK([test $(get_memory_value atoms) -eq $initial_db_atoms]) + OVS_APP_EXIT_AND_WAIT([ovsdb-server]) AT_CLEANUP diff --git a/SPECS/openvswitch2.16.spec b/SPECS/openvswitch2.16.spec index 425ecd2..071e455 100644 --- a/SPECS/openvswitch2.16.spec +++ b/SPECS/openvswitch2.16.spec @@ -57,7 +57,7 @@ Summary: Open vSwitch Group: System Environment/Daemons daemon/database/utilities URL: http://www.openvswitch.org/ Version: 2.16.0 -Release: 44%{?dist} +Release: 45%{?dist} # Nearly all of openvswitch is ASL 2.0. The bugtool is LGPLv2+, and the # lib/sflow*.[ch] files are SISSL @@ -699,6 +699,45 @@ exit 0 %endif %changelog +* Tue Feb 01 2022 Ilya Maximets - 2.16.0-45 +- ovsdb: transaction: Keep one entry in the transaction history. [RH git: 7665f42d12] (#2044621) + commit 6e13565dd32fb2cf5517f51ca06956e2052c4bba + Author: Ilya Maximets + Date: Sun Dec 19 15:09:38 2021 +0100 + + ovsdb: transaction: Keep one entry in the transaction history. + + If a single transaction exceeds the size of the whole database (e.g., + a lot of rows got removed and new ones added), transaction history will + be drained. This leads to sending UUID_ZERO to the clients as the last + transaction id in the next monitor update, because monitor doesn't + know what was the actual last transaction id. In case of a re-connect + that will cause re-downloading of the whole database, since the + client's last_id will be out of sync. + + One solution would be to store the last transaction ID separately + from the actual transactions, but that will require a careful + management in cases where database gets reset and the history needs + to be cleared. Keeping the one last transaction instead to avoid + the problem. That should not be a big concern in terms of memory + consumption, because this last transaction will be removed from the + history once the next transaction appeared. This is also not a concern + for a fast re-sync, because this last transaction will not be used + for the monitor reply; it's either client already has it, so no need + to send, or it's a history miss. + + The test updated to not check the number of atoms if there is only + one transaction in the history. + + Fixes: 317b1bfd7dd3 ("ovsdb: Don't let transaction history grow larger than the database.") + Acked-by: Mike Pattrick + Acked-by: Han Zhou + Signed-off-by: Ilya Maximets + + Reported-at: https://bugzilla.redhat.com/2044621 + Signed-off-by: Ilya Maximets + + * Mon Jan 31 2022 Open vSwitch CI - 2.16.0-44 - Merging upstream branch-2.16 [RH git: d202cd6da1] Commit list: