The ovn-ic instance holding the IC-SB lock writes, among others, the
transit switch and router Datapath_Bindings through the locked IC-SB
connection. Its transaction isn't available while the previous one is
being committed, but ovn-ic runs the engine anyway. The nodes then skip
their IC-SB writes: the en_tunnel_key handlers fall back to a recompute,
which skips them as well, and the tracked changes are cleared, so e.g.
the Datapath_Binding of a deleted transit switch isn't garbage collected
until a later recompute.
Postpone the engine run while the locked IC-SB transaction isn't
available, keeping the tracked changes, as is already done for the other
connections.
Also, ignore the IC-SB Datapath_Binding deletions whose IC-NB transit
switch or router is gone in en_tunnel_key. They are the echo of its own
garbage collection and there is nothing to reconcile for them.
Both made the "transit switch handler scoping" test flaky, as deleting
a transit switch could trigger a recompute of en_tunnel_key.
Fixes: 0ad737079717 ("ic: Add the en_tunnel_key node.")
Signed-off-by: Paulo Guilherme Silva <[email protected]>
---
ic/en-tunnel-key.c | 30 ++++++++++++++++++++++++++----
ic/ovn-ic.c | 11 ++++++++++-
2 files changed, 36 insertions(+), 5 deletions(-)
diff --git a/ic/en-tunnel-key.c b/ic/en-tunnel-key.c
index 0a63a6c90..834c2143e 100644
--- a/ic/en-tunnel-key.c
+++ b/ic/en-tunnel-key.c
@@ -377,11 +377,28 @@ en_tunnel_key_icnb_transit_router_handler(struct
engine_node *node,
return ret;
}
+static bool
+icnb_transit_switch_exists(struct ic_context *ctx, const char *name)
+{
+ const struct icnbrec_transit_switch *key =
+ icnbrec_transit_switch_index_init_row(
+ ctx->icnbrec_transit_switch_by_name);
+ icnbrec_transit_switch_index_set_name(key, name);
+ const struct icnbrec_transit_switch *ts =
+ icnbrec_transit_switch_index_find(ctx->icnbrec_transit_switch_by_name,
+ key);
+ icnbrec_transit_switch_index_destroy_row(key);
+ return ts != NULL;
+}
+
/* IC-SB Datapath_Binding: react only to a binding *deletion* by re-creating it
* for the still-present IC-NB entity (self-healing after an out-of-band
- * delete). Inserts and modifies are this node's own writes (or already
- * consistent), so they are a no-op here - the requested-tnl-key follow-up is
- * driven by en_ts/en_tr's own handlers on this same table. */
+ * delete). The deletion of a binding whose IC-NB entity is gone is the echo
+ * of this node's own garbage collection and needs nothing, so it must not
+ * depend on the IC-SB transaction being available. Inserts and modifies are
+ * this node's own writes (or already consistent), so they are a no-op here -
+ * the requested-tnl-key follow-up is driven by en_ts/en_tr's own handlers on
+ * this same table. */
enum engine_input_handler_result
en_tunnel_key_icsb_datapath_binding_handler(struct engine_node *node,
void *data_)
@@ -402,10 +419,15 @@ en_tunnel_key_icsb_datapath_binding_handler(struct
engine_node *node,
/* Not inserted by ovn-ic: nothing to reconcile. */
continue;
}
+ if (!icnbrec_transit_router_get_for_uuid(ctx->ovninb_idl,
+ isb_dp->nb_ic_uuid)) {
+ continue;
+ }
char *uuid_str = uuid_to_string(isb_dp->nb_ic_uuid);
sset_add(&tr_scope, uuid_str);
free(uuid_str);
- } else {
+ } else if (icnb_transit_switch_exists(ctx,
+ isb_dp->transit_switch)) {
sset_add(&ts_scope, isb_dp->transit_switch);
}
}
diff --git a/ic/ovn-ic.c b/ic/ovn-ic.c
index 7e9b3139f..e65256577 100644
--- a/ic/ovn-ic.c
+++ b/ic/ovn-ic.c
@@ -1449,8 +1449,17 @@ main(int argc, char *argv[])
ovsdb_idl_has_ever_connected(ctx.ovninb_idl) &&
ovsdb_idl_has_ever_connected(ctx.ovnisb_idl) &&
ovsdb_idl_has_ever_connected(ctx.ovnisb_unlocked_idl)) {
+ /* The AZ holding the IC-SB lock writes through the locked
+ * connection, whose transaction isn't available while the
+ * previous one is being committed. Postpone the engine run
+ * in that case, keeping the tracked changes, as the nodes
+ * would otherwise skip their writes and the changes they
+ * handle incrementally would be lost. */
+ bool isb_txn_ready = ctx.ovnisb_txn ||
+ !ovsdb_idl_has_lock(ctx.ovnisb_idl);
if (ctx.ovnnb_txn && ctx.ovnsb_txn && ctx.ovninb_txn &&
- ctx.ovnisb_unlocked_txn && inc_proc_ic_can_run(&eng_ctx)) {
+ ctx.ovnisb_unlocked_txn && isb_txn_ready &&
+ inc_proc_ic_can_run(&eng_ctx)) {
/* The availability zone is now resolved by the en_az
* engine node. The subsystem nodes skip their work when
* there is no AZ; the sequence-number bookkeeping below
--
2.34.1
--
_'Esta mensagem é direcionada apenas para os endereços constantes no
cabeçalho inicial. Se você não está listado nos endereços constantes no
cabeçalho, pedimos-lhe que desconsidere completamente o conteúdo dessa
mensagem e cuja cópia, encaminhamento e/ou execução das ações citadas estão
imediatamente anuladas e proibidas'._
* **'Apesar do Magazine Luiza tomar
todas as precauções razoáveis para assegurar que nenhum vírus esteja
presente nesse e-mail, a empresa não poderá aceitar a responsabilidade por
quaisquer perdas ou danos causados por esse e-mail ou por seus anexos'.*
_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev