@@ -1506,10 +1506,15 @@ ovsdb_idl_reparse_refs_to_inserted(struct ovsdb_idl *db)
struct ovsdb_idl_row *row;
LIST_FOR_EACH_POP (row, reparse_node, &db->rows_to_reparse) {
+ ovs_list_init(&row->reparse_node);
+
+ /* Skip rows that have been deleted in the meantime. */
+ if (ovsdb_idl_row_is_orphan(row)) {
+ continue;
+ }
ovsdb_idl_row_unparse(row);
ovsdb_idl_row_clear_arcs(row, false);
ovsdb_idl_row_parse(row);
- ovs_list_init(&row->reparse_node);
}
}
@@ -1540,6 +1540,32 @@ OVSDB_CHECK_IDL([simple idl, initially populated, strong references, conditional
006: done
]])
+dnl This test checks that deleting a row that refers to a row that was inserted
+dnl in the current IDL run works properly.
+OVSDB_CHECK_IDL_TRACK([track, simple idl, initially empty, strong references, insert and delete],
+ [],
+ [['["idltest",
+ {"op": "insert",
+ "table": "link1",
+ "uuid-name": "uuid_l1",
+ "row": {"i": 1, "k": ["named-uuid", "uuid_l1"]}},
+ {"op": "insert",
+ "table": "link2",
+ "row": {"i": 2, "l1": ["set", [["named-uuid", "uuid_l1"]]]}}
+ ]' \
+ '+["idltest",
+ {"op": "delete",
+ "table": "link2",
+ "where": [["i", "==", 2]]}]'
+ ]],
+ [[000: empty
+001: {"error":null,"result":[{"uuid":["uuid","<0>"]},{"uuid":["uuid","<1>"]}]}
+002: {"error":null,"result":[{"count":1}]}
+003: table link1: inserted row: i=1 k=1 ka=[] l2= uuid=<0>
+003: table link1: updated columns: i k
+004: done
+]])
+
OVSDB_CHECK_IDL_TRACK([track, simple idl, initially empty, various ops],
[],
[['["idltest",
Rows that refer to rows that were inserted in the current IDL run should only be reparsed if they don't get deleted (become orphan) in the current IDL run. Fixes: 7b8aeadd60c8 ("ovsdb-idl: Re-parse backrefs of inserted rows only once.") Reported-by: Ilya Maximets <i.maximets@ovn.org> Signed-off-by: Dumitru Ceara <dceara@redhat.com> --- lib/ovsdb-idl.c | 7 ++++++- tests/ovsdb-idl.at | 26 ++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-)