Datapath sync can delete one logical datapath and create another in the
same engine run. In that case the synced datapath layer may reuse the
freed sparse-array index for the new datapath before northd has removed
the old datapath from its local datapath array.
The northd incremental LS/LR handlers process new datapaths before
deleted datapaths. If the reused index is still occupied locally,
ods_assign_array_index() asserts when adding the new datapath.
Detect this case before creating the new northd datapath and fall back
to a full recompute instead. The recompute path rebuilds the datapath
arrays from the synced datapath state and avoids the ordering conflict.
Add a regression test that deletes one logical switch/router and creates
another in the same transaction.
Fixes: 6b1b16469185 ("northd: Base ovn_datapath index on synced_datapath
index.")
Assisted-by: OpenAI Codex
Signed-off-by: Tim Rozet <[email protected]>
---
northd/northd.c | 6 ++++++
tests/ovn-northd.at | 20 ++++++++++++++++++++
2 files changed, 26 insertions(+)
diff --git a/northd/northd.c b/northd/northd.c
index 0ea7c1b95..edec652d4 100644
--- a/northd/northd.c
+++ b/northd/northd.c
@@ -5126,6 +5126,9 @@ northd_handle_ls_changes(struct ovsdb_idl_txn
*ovnsb_idl_txn,
goto fail;
}
+ if (sparse_array_get(&nd->ls_datapaths.dps, synced->sdp->index)) {
+ goto fail;
+ }
struct ovn_datapath *od = ovn_datapath_create(
&nd->ls_datapaths.datapaths, &new_ls->header_.uuid, new_ls,
NULL, synced->sdp);
@@ -5458,6 +5461,9 @@ northd_handle_lr_changes(const struct northd_input *ni,
if (new_lr->copp || (new_lr->n_ports > 0)) {
goto fail;
}
+ if (sparse_array_get(&nd->lr_datapaths.dps, synced->sdp->index)) {
+ goto fail;
+ }
struct ovn_datapath *od = ovn_datapath_create(
&nd->lr_datapaths.datapaths, &new_lr->header_.uuid,
NULL, new_lr, synced->sdp);
diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at
index 26a19bd96..a6e90fbaa 100644
--- a/tests/ovn-northd.at
+++ b/tests/ovn-northd.at
@@ -18770,6 +18770,26 @@ OVN_CLEANUP_NORTHD
AT_CLEANUP
])
+OVN_FOR_EACH_NORTHD_NO_HV([
+AT_SETUP([Datapath incremental processing index reuse])
+ovn_start
+
+check ovn-nbctl --wait=sb ls-add sw-old
+check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats
+check ovn-nbctl --wait=sb ls-del sw-old -- ls-add sw-new
+check_engine_compute northd recompute
+CHECK_NO_CHANGE_AFTER_RECOMPUTE
+
+check ovn-nbctl --wait=sb lr-add lr-old
+check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats
+check ovn-nbctl --wait=sb lr-del lr-old -- lr-add lr-new
+check_engine_compute northd recompute
+CHECK_NO_CHANGE_AFTER_RECOMPUTE
+
+OVN_CLEANUP_NORTHD
+AT_CLEANUP
+])
+
OVN_FOR_EACH_NORTHD_NO_HV([
AT_SETUP([Synced logical switch and router incremental procesesing])
ovn_start
--
2.53.0
_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev