{"id":2223301,"url":"http://patchwork.ozlabs.org/api/1.1/patches/2223301/?format=json","web_url":"http://patchwork.ozlabs.org/project/ovn/patch/20260414232958.189990-1-tiago.reis@luizalabs.com/","project":{"id":68,"url":"http://patchwork.ozlabs.org/api/1.1/projects/68/?format=json","name":"Open Virtual Network development","link_name":"ovn","list_id":"ovs-dev.openvswitch.org","list_email":"ovs-dev@openvswitch.org","web_url":"http://openvswitch.org/","scm_url":"","webscm_url":""},"msgid":"<20260414232958.189990-1-tiago.reis@luizalabs.com>","date":"2026-04-14T23:29:58","name":"[ovs-dev,v4] ovn-ic: Use dual IC-SB connections to prevent constraint violations.","commit_ref":null,"pull_url":null,"state":"new","archived":false,"hash":"072a26772e5bbd4b3bf724da59c20cfccf3331dd","submitter":{"id":92676,"url":"http://patchwork.ozlabs.org/api/1.1/people/92676/?format=json","name":"Tiago Matos","email":"tiago.reis@luizalabs.com"},"delegate":null,"mbox":"http://patchwork.ozlabs.org/project/ovn/patch/20260414232958.189990-1-tiago.reis@luizalabs.com/mbox/","series":[{"id":499901,"url":"http://patchwork.ozlabs.org/api/1.1/series/499901/?format=json","web_url":"http://patchwork.ozlabs.org/project/ovn/list/?series=499901","date":"2026-04-14T23:29:58","name":"[ovs-dev,v4] ovn-ic: Use dual IC-SB connections to prevent constraint violations.","version":4,"mbox":"http://patchwork.ozlabs.org/series/499901/mbox/"}],"comments":"http://patchwork.ozlabs.org/api/patches/2223301/comments/","check":"warning","checks":"http://patchwork.ozlabs.org/api/patches/2223301/checks/","tags":{},"headers":{"Return-Path":"<ovs-dev-bounces@openvswitch.org>","X-Original-To":["incoming@patchwork.ozlabs.org","dev@openvswitch.org"],"Delivered-To":["patchwork-incoming@legolas.ozlabs.org","ovs-dev@lists.linuxfoundation.org"],"Authentication-Results":["legolas.ozlabs.org;\n\tdkim=fail reason=\"signature verification failed\" (1024-bit key;\n unprotected) header.d=luizalabs.com header.i=@luizalabs.com\n header.a=rsa-sha256 header.s=google header.b=BHa+D88z;\n\tdkim-atps=neutral","legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org\n (client-ip=2605:bc80:3010::136; helo=smtp3.osuosl.org;\n envelope-from=ovs-dev-bounces@openvswitch.org; receiver=patchwork.ozlabs.org)","smtp3.osuosl.org;\n\tdkim=fail reason=\"signature verification failed\" (1024-bit key,\n unprotected) header.d=luizalabs.com header.i=@luizalabs.com\n header.a=rsa-sha256 header.s=google header.b=BHa+D88z","smtp1.osuosl.org; dmarc=pass (p=quarantine dis=none)\n header.from=luizalabs.com","smtp1.osuosl.org; dkim=pass (1024-bit key,\n unprotected) header.d=luizalabs.com header.i=@luizalabs.com\n header.a=rsa-sha256 header.s=google header.b=BHa+D88z"],"Received":["from smtp3.osuosl.org (smtp3.osuosl.org [IPv6:2605:bc80:3010::136])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519 server-signature ECDSA (secp384r1) server-digest SHA384)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4fwL9b3T86z1yHc\n\tfor <incoming@patchwork.ozlabs.org>; Wed, 15 Apr 2026 09:30:25 +1000 (AEST)","from localhost (localhost [127.0.0.1])\n\tby smtp3.osuosl.org (Postfix) with ESMTP id D35106080A;\n\tTue, 14 Apr 2026 23:30:22 +0000 (UTC)","from smtp3.osuosl.org ([127.0.0.1])\n by localhost (smtp3.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP\n id SkI3G-MVzig1; Tue, 14 Apr 2026 23:30:20 +0000 (UTC)","from lists.linuxfoundation.org (lf-lists.osuosl.org\n [IPv6:2605:bc80:3010:104::8cd3:938])\n\tby smtp3.osuosl.org (Postfix) with ESMTPS id B92B3607E4;\n\tTue, 14 Apr 2026 23:30:20 +0000 (UTC)","from lf-lists.osuosl.org (localhost [127.0.0.1])\n\tby lists.linuxfoundation.org (Postfix) with ESMTP id 91093C054A;\n\tTue, 14 Apr 2026 23:30:20 +0000 (UTC)","from smtp1.osuosl.org (smtp1.osuosl.org [140.211.166.138])\n by lists.linuxfoundation.org (Postfix) with ESMTP id 15AF6C0549\n for <dev@openvswitch.org>; Tue, 14 Apr 2026 23:30:19 +0000 (UTC)","from localhost (localhost [127.0.0.1])\n by smtp1.osuosl.org (Postfix) with ESMTP id EA73482F31\n for <dev@openvswitch.org>; Tue, 14 Apr 2026 23:30:18 +0000 (UTC)","from smtp1.osuosl.org ([127.0.0.1])\n by localhost (smtp1.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP\n id 4iczOZAryJuR for <dev@openvswitch.org>;\n Tue, 14 Apr 2026 23:30:17 +0000 (UTC)","from mail-vk1-xa42.google.com (mail-vk1-xa42.google.com\n [IPv6:2607:f8b0:4864:20::a42])\n by smtp1.osuosl.org (Postfix) with ESMTPS id 5224880BD3\n for <dev@openvswitch.org>; Tue, 14 Apr 2026 23:30:17 +0000 (UTC)","by mail-vk1-xa42.google.com with SMTP id\n 71dfb90a1353d-56a86f0a23bso6217436e0c.0\n for <dev@openvswitch.org>; Tue, 14 Apr 2026 16:30:17 -0700 (PDT)","from state ([2804:10dc:d35d:f00:3256:fff:fe0d:5e27])\n by smtp.gmail.com with ESMTPSA id\n 71dfb90a1353d-56f89fa7bf7sm107015e0c.12.2026.04.14.16.30.13\n (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n Tue, 14 Apr 2026 16:30:14 -0700 (PDT)"],"X-Virus-Scanned":["amavis at osuosl.org","amavis at osuosl.org"],"X-Comment":"SPF check N/A for local connections -\n client-ip=2605:bc80:3010:104::8cd3:938; helo=lists.linuxfoundation.org;\n envelope-from=ovs-dev-bounces@openvswitch.org; receiver=<UNKNOWN> ","DKIM-Filter":["OpenDKIM Filter v2.11.0 smtp3.osuosl.org B92B3607E4","OpenDKIM Filter v2.11.0 smtp1.osuosl.org 5224880BD3"],"Received-SPF":"Pass (mailfrom) identity=mailfrom;\n client-ip=2607:f8b0:4864:20::a42; helo=mail-vk1-xa42.google.com;\n envelope-from=tiago.reis@luizalabs.com; receiver=<UNKNOWN>","DMARC-Filter":"OpenDMARC Filter v1.4.2 smtp1.osuosl.org 5224880BD3","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=luizalabs.com; s=google; t=1776209416; x=1776814216; darn=openvswitch.org;\n h=content-transfer-encoding:mime-version:message-id:date:subject:cc\n :to:from:from:to:cc:subject:date:message-id:reply-to;\n bh=p05KmroYhce3cn72zzAwtjaRQI2afV1aKROP3xtnyNo=;\n b=BHa+D88zV5Qf7NxRtZ0adRsrLKrqHC9Wg6t7EEZzSUT7cYRJRt5CnO0lt6IiL0Q2+h\n L1fkMrjGtZBfOeNYCvZaNz5w+2HpA1nn9jr0RgjN3+sg6R5gEY+cFBM4mWp+mBoF6IV0\n LRbVEEPBaj3oX0wAA8P7WjCdbSNkwMFC6sVwQ=","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=1e100.net; s=20251104; t=1776209416; x=1776814216;\n h=content-transfer-encoding:mime-version:message-id:date:subject:cc\n :to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date\n :message-id:reply-to;\n bh=p05KmroYhce3cn72zzAwtjaRQI2afV1aKROP3xtnyNo=;\n b=UDL1u9VqhrE8jCnMk+v7FEycmOZj5ta1I8LcBHXksRswC9wWxJhVO9iHT2uzbT9qS0\n 2GTL7nR1ZyYLudmzW8ol3q8HMP2WGHxdvWvGa8N3SFqsp+dIFkxMcy2cKW9coICgVUdJ\n Fw1FPk8aZ+R5kgddj3H3dHFtzsGZHbCwJKASMDKucEYwxTya6AvA+NuFRIVIIcJHqfyR\n T///2PZn+Yxxo4rlr4qf50NqDND14O2G+COuHzQ2WwEUuDmcUZxBpl9wOur/UZR2sRZD\n woXVnlx+JDClnNNpq0L4Nic4qKEI0vjKvpB7WjZBJeody+zAU83lA2MKm0VICGpf6bf0\n k0YA==","X-Gm-Message-State":"AOJu0Yw3bdj900A0ChnAHQLduTOdTnsFlJYbK/VVwmEWko3PG5xl/M9s\n eq2FalMbsCuyKS3l0qD5yh3rvxNls1SdIfL32gcK6TCPPX0GRQi7MjkoQydmFeKeQnj9wHMc9sf\n NuB9wakw4eLfBfKQLD4/UN0HDpiSUhY5xC33MRNg5iS1Sfv5LRcAjlxL/5aC43Qwn5BHO","X-Gm-Gg":"AeBDieswbSlJUONdm09vwG5YMXqnemdAY6nXSkV2Q3Mn+2LLAOsAPrhhDjusxwVy2ow\n RfzBMSyelA7ct2MGgzsW1BivmNwVcd/Mdgjhu0xfReyM/6zhMMscCrUbPQowqq7uNHv+BqGwHlt\n eIBAy4cCs03P8F8vpY4ze61fpYrql9DMXzd7gW5noZezii/RbWatMtlp2VI2CcbQvNeUD13myvF\n 6nPsIE4cDQeJWQex5ysQIDjBvR9srLVlM3nUHzxW7zWl7G0UqPTKZ/lNxXmxniOZj9lqOirOMmL\n r/Xp2YYJasyZEiFDovkJ6iQS9+8fd6DPPzAeCgqZwYX/FAMlOpb+K1fGndocQ/tU9mcdMijpw6D\n 0UGM8uYWdNQXXxVkpTqjdFhhgM29E3TvIhWXurnv/94rl/0n/0Jm660PERQfQrj12NJeU377Umy\n rn7yGs2xHyG1Ce1l+JacMBF5Re8IhtabPyPA==","X-Received":"by 2002:a05:6122:4594:b0:56f:8f5:b135 with SMTP id\n 71dfb90a1353d-56f3bcf7b11mr9896164e0c.14.1776209415523;\n Tue, 14 Apr 2026 16:30:15 -0700 (PDT)","To":"dev@openvswitch.org","Date":"Tue, 14 Apr 2026 20:29:58 -0300","Message-ID":"<20260414232958.189990-1-tiago.reis@luizalabs.com>","X-Mailer":"git-send-email 2.53.0","MIME-Version":"1.0","Subject":"[ovs-dev] [PATCH ovn v4] ovn-ic: Use dual IC-SB connections to\n prevent constraint violations.","X-BeenThere":"ovs-dev@openvswitch.org","X-Mailman-Version":"2.1.30","Precedence":"list","List-Id":"<ovs-dev.openvswitch.org>","List-Unsubscribe":"<https://mail.openvswitch.org/mailman/options/ovs-dev>,\n <mailto:ovs-dev-request@openvswitch.org?subject=unsubscribe>","List-Archive":"<http://mail.openvswitch.org/pipermail/ovs-dev/>","List-Post":"<mailto:ovs-dev@openvswitch.org>","List-Help":"<mailto:ovs-dev-request@openvswitch.org?subject=help>","List-Subscribe":"<https://mail.openvswitch.org/mailman/listinfo/ovs-dev>,\n <mailto:ovs-dev-request@openvswitch.org?subject=subscribe>","From":"Tiago Matos via dev <ovs-dev@openvswitch.org>","Reply-To":"Tiago Matos <tiago.reis@luizalabs.com>","Content-Type":"text/plain; charset=\"iso-8859-1\"","Content-Transfer-Encoding":"quoted-printable","Errors-To":"ovs-dev-bounces@openvswitch.org","Sender":"\"dev\" <ovs-dev-bounces@openvswitch.org>"},"content":"When multiple Availability Zones (AZs) are connected via OVN-IC,\ncertain events trigger all AZs to attempt writing the same data to the\nIC-SB simultaneously. This race condition leads to constraint\nviolations, causing transaction failures and forcing expensive full\nrecomputes.\n\nTo mitigate this, this patch introduces a write-segregation mechanism\nemploying two distinct connections to IC-SB:\n1. Locked Connection: Acquires a lock to handle data that only a\n   single AZ should write (e.g., creating a new datapath_binding for a\n   transit switch/router).\n\n2. Lockless Connections: Used for data that multiple AZs can safely\n   insert concurrently (e.g., creating a new port_binding).\n\nSigned-off-by: Tiago Matos <tiago.reis@luizalabs.com>\n---\n ic/inc-proc-ic.c |   6 +-\n ic/inc-proc-ic.h |   1 +\n ic/ovn-ic.c      | 197 ++++++++++++++++++++++++++++++++++++-----------\n ic/ovn-ic.h      |   2 +\n tests/ovn-ic.at  |  44 +++++++++++\n 5 files changed, 201 insertions(+), 49 deletions(-)","diff":"diff --git a/ic/inc-proc-ic.c b/ic/inc-proc-ic.c\nindex 995f23433..2c0420292 100644\n--- a/ic/inc-proc-ic.c\n+++ b/ic/inc-proc-ic.c\n@@ -27,6 +27,7 @@\n #include \"openvswitch/vlog.h\"\n #include \"inc-proc-ic.h\"\n #include \"en-ic.h\"\n+#include \"ovn-util.h\"\n #include \"unixctl.h\"\n #include \"util.h\"\n \n@@ -214,7 +215,7 @@ inc_proc_ic_run(struct ic_context *ctx,\n                 struct ic_engine_context *ic_eng_ctx)\n {\n     ovs_assert(ctx->ovnnb_txn && ctx->ovnsb_txn &&\n-               ctx->ovninb_txn && ctx->ovnisb_txn);\n+               ctx->ovninb_txn && ctx->ovnisb_unlocked_txn);\n \n     int64_t start = time_msec();\n     engine_init_run();\n@@ -262,7 +263,8 @@ inc_proc_ic_can_run(struct ic_engine_context *ctx)\n         ctx->nb_idl_duration_ms >= IDL_LOOP_MAX_DURATION_MS ||\n         ctx->sb_idl_duration_ms >= IDL_LOOP_MAX_DURATION_MS ||\n         ctx->inb_idl_duration_ms >= IDL_LOOP_MAX_DURATION_MS ||\n-        ctx->isb_idl_duration_ms >= IDL_LOOP_MAX_DURATION_MS) {\n+        ctx->isb_idl_duration_ms >= IDL_LOOP_MAX_DURATION_MS ||\n+        ctx->isb_unlock_idl_duration_ms >= IDL_LOOP_MAX_DURATION_MS) {\n         return true;\n     }\n \ndiff --git a/ic/inc-proc-ic.h b/ic/inc-proc-ic.h\nindex 9af147fb3..36464564d 100644\n--- a/ic/inc-proc-ic.h\n+++ b/ic/inc-proc-ic.h\n@@ -13,6 +13,7 @@ struct ic_engine_context {\n     uint64_t sb_idl_duration_ms;\n     uint64_t inb_idl_duration_ms;\n     uint64_t isb_idl_duration_ms;\n+    uint64_t isb_unlock_idl_duration_ms;\n     uint32_t backoff_ms;\n };\n \ndiff --git a/ic/ovn-ic.c b/ic/ovn-ic.c\nindex 17feeb4af..8b163fbf7 100644\n--- a/ic/ovn-ic.c\n+++ b/ic/ovn-ic.c\n@@ -115,8 +115,9 @@ az_run(struct ic_context *ctx)\n      * \"ovn-ic-sbctl destroy avail <az>\". */\n     static char *az_name;\n     const struct icsbrec_availability_zone *az;\n-    if (ctx->ovnisb_txn && az_name && strcmp(az_name, nb_global->name)) {\n-        ICSBREC_AVAILABILITY_ZONE_FOR_EACH (az, ctx->ovnisb_idl) {\n+    if (ctx->ovnisb_unlocked_txn && az_name\n+        && strcmp(az_name, nb_global->name)) {\n+        ICSBREC_AVAILABILITY_ZONE_FOR_EACH (az, ctx->ovnisb_unlocked_idl) {\n             /* AZ name update locally need to update az in ISB. */\n             if (nb_global->name[0] && !strcmp(az->name, az_name)) {\n                 icsbrec_availability_zone_set_name(az, nb_global->name);\n@@ -138,11 +139,11 @@ az_run(struct ic_context *ctx)\n         az_name = xstrdup(nb_global->name);\n     }\n \n-    if (ctx->ovnisb_txn) {\n-        ovsdb_idl_txn_add_comment(ctx->ovnisb_txn, \"AZ %s\", az_name);\n+    if (ctx->ovnisb_unlocked_txn) {\n+        ovsdb_idl_txn_add_comment(ctx->ovnisb_unlocked_txn, \"AZ %s\", az_name);\n     }\n \n-    ICSBREC_AVAILABILITY_ZONE_FOR_EACH (az, ctx->ovnisb_idl) {\n+    ICSBREC_AVAILABILITY_ZONE_FOR_EACH (az, ctx->ovnisb_unlocked_idl) {\n         if (!strcmp(az->name, az_name)) {\n             ctx->runned_az = az;\n             return az;\n@@ -150,9 +151,9 @@ az_run(struct ic_context *ctx)\n     }\n \n     /* Create AZ in ISB */\n-    if (ctx->ovnisb_txn) {\n+    if (ctx->ovnisb_unlocked_txn) {\n         VLOG_INFO(\"Register AZ %s to interconnection DB.\", az_name);\n-        az = icsbrec_availability_zone_insert(ctx->ovnisb_txn);\n+        az = icsbrec_availability_zone_insert(ctx->ovnisb_unlocked_txn);\n         icsbrec_availability_zone_set_name(az, az_name);\n         ctx->runned_az = az;\n         return az;\n@@ -195,7 +196,7 @@ enumerate_datapaths(struct ic_context *ctx, struct hmap *dp_tnlids,\n                     struct shash *isb_ts_dps, struct shash *isb_tr_dps)\n {\n     const struct icsbrec_datapath_binding *isb_dp;\n-    ICSBREC_DATAPATH_BINDING_FOR_EACH (isb_dp, ctx->ovnisb_idl) {\n+    ICSBREC_DATAPATH_BINDING_FOR_EACH (isb_dp, ctx->ovnisb_unlocked_idl) {\n         ovn_add_tnlid(dp_tnlids, isb_dp->tunnel_key);\n \n         enum ic_datapath_type dp_type = ic_dp_get_type(isb_dp);\n@@ -209,6 +210,16 @@ enumerate_datapaths(struct ic_context *ctx, struct hmap *dp_tnlids,\n     }\n }\n \n+/*\n+ * Check if the AZ is the leader by checking the lock.\n+ */\n+static bool\n+is_az_leader(struct ovsdb_idl_txn *txn)\n+{\n+    struct ovsdb_idl *idl = ovsdb_idl_txn_get_idl(txn);\n+    return idl && ovsdb_idl_has_lock(idl);\n+}\n+\n static void\n ts_run(struct ic_context *ctx, struct hmap *dp_tnlids,\n        struct shash *isb_ts_dps)\n@@ -219,9 +230,14 @@ ts_run(struct ic_context *ctx, struct hmap *dp_tnlids,\n     const struct icnbrec_ic_nb_global *ic_nb =\n         icnbrec_ic_nb_global_first(ctx->ovninb_idl);\n \n+    /*\n+     * Warning: ovnisb_unlocked should not be used to insert data on IC_SB which\n+     * can cause a constraint violation, as an example, inserting data to\n+     * IC-SB datapath_binding.\n+     */\n     if (ic_nb && smap_get_bool(&ic_nb->options, \"vxlan_mode\", false)) {\n         const struct icsbrec_encap *encap;\n-        ICSBREC_ENCAP_FOR_EACH (encap, ctx->ovnisb_idl) {\n+        ICSBREC_ENCAP_FOR_EACH (encap, ctx->ovnisb_unlocked_idl) {\n             if (!strcmp(encap->type, \"vxlan\")) {\n                 vxlan_mode = true;\n                 break;\n@@ -294,7 +310,8 @@ ts_run(struct ic_context *ctx, struct hmap *dp_tnlids,\n     /* Sync TS between INB and ISB.  This is performed after syncing with AZ\n      * SB, to avoid uncommitted ISB datapath tunnel key to be synced back to\n      * AZ. */\n-    if (ctx->ovnisb_txn) {\n+    if (ctx->ovnisb_txn &&\n+        is_az_leader(ctx->ovnisb_txn)) {\n         /* Create ISB Datapath_Binding */\n         ICNBREC_TRANSIT_SWITCH_FOR_EACH (ts, ctx->ovninb_idl) {\n             const struct icsbrec_datapath_binding *isb_dp =\n@@ -340,6 +357,11 @@ static void\n tr_run(struct ic_context *ctx, struct hmap *dp_tnlids,\n        struct shash *isb_tr_dps)\n {\n+    /*\n+     * Warning: ovnisb_unlocked should not be used to insert data on IC_SB which\n+     * can cause a constraint violation, as an example, inserting data to\n+     * IC-SB datapath_binding.\n+     */\n     const struct nbrec_logical_router *lr;\n \n     if (ctx->ovnnb_txn) {\n@@ -383,7 +405,8 @@ tr_run(struct ic_context *ctx, struct hmap *dp_tnlids,\n     /* Sync TR between INB and ISB.  This is performed after syncing with AZ\n      * SB, to avoid uncommitted ISB datapath tunnel key to be synced back to\n      * AZ. */\n-    if (ctx->ovnisb_txn) {\n+    if (ctx->ovnisb_txn &&\n+        is_az_leader(ctx->ovnisb_txn)) {\n         /* Create ISB Datapath_Binding */\n         const struct icnbrec_transit_router *tr;\n         ICNBREC_TRANSIT_ROUTER_FOR_EACH (tr, ctx->ovninb_idl) {\n@@ -488,7 +511,7 @@ sync_sb_gw_to_isb(struct ic_context *ctx,\n     struct icsbrec_encap **isb_encaps =\n         xmalloc(chassis->n_encaps * sizeof *isb_encaps);\n     for (int i = 0; i < chassis->n_encaps; i++) {\n-        isb_encap = icsbrec_encap_insert(ctx->ovnisb_txn);\n+        isb_encap = icsbrec_encap_insert(ctx->ovnisb_unlocked_txn);\n         icsbrec_encap_set_gateway_name(isb_encap,\n                                       chassis->name);\n         icsbrec_encap_set_ip(isb_encap, chassis->encaps[i]->ip);\n@@ -506,14 +529,14 @@ sync_sb_gw_to_isb(struct ic_context *ctx,\n static void\n gateway_run(struct ic_context *ctx)\n {\n-    if (!ctx->ovnisb_txn || !ctx->ovnsb_txn) {\n+    if (!ctx->ovnisb_unlocked_txn || !ctx->ovnsb_txn) {\n         return;\n     }\n \n     struct shash local_gws = SHASH_INITIALIZER(&local_gws);\n     struct shash remote_gws = SHASH_INITIALIZER(&remote_gws);\n     const struct icsbrec_gateway *gw;\n-    ICSBREC_GATEWAY_FOR_EACH (gw, ctx->ovnisb_idl) {\n+    ICSBREC_GATEWAY_FOR_EACH (gw, ctx->ovnisb_unlocked_idl) {\n         if (gw->availability_zone == ctx->runned_az) {\n             shash_add(&local_gws, gw->name, gw);\n         } else {\n@@ -526,7 +549,7 @@ gateway_run(struct ic_context *ctx)\n         if (smap_get_bool(&chassis->other_config, \"is-interconn\", false)) {\n             gw = shash_find_and_delete(&local_gws, chassis->name);\n             if (!gw) {\n-                gw = icsbrec_gateway_insert(ctx->ovnisb_txn);\n+                gw = icsbrec_gateway_insert(ctx->ovnisb_unlocked_txn);\n                 icsbrec_gateway_set_availability_zone(gw, ctx->runned_az);\n                 icsbrec_gateway_set_name(gw, chassis->name);\n                 sync_sb_gw_to_isb(ctx, chassis, gw);\n@@ -980,7 +1003,7 @@ create_isb_pb(struct ic_context *ctx, const char *logical_port,\n     }\n \n     const struct icsbrec_port_binding *isb_pb =\n-        icsbrec_port_binding_insert(ctx->ovnisb_txn);\n+        icsbrec_port_binding_insert(ctx->ovnisb_unlocked_txn);\n     icsbrec_port_binding_set_availability_zone(isb_pb, az);\n     icsbrec_port_binding_set_transit_switch(isb_pb, ts_name);\n     icsbrec_port_binding_set_logical_port(isb_pb, logical_port);\n@@ -1068,7 +1091,7 @@ find_lsp_in_sb(struct ic_context *ctx,\n static void\n port_binding_run(struct ic_context *ctx)\n {\n-    if (!ctx->ovnisb_txn || !ctx->ovnnb_txn || !ctx->ovnsb_txn) {\n+    if (!ctx->ovnisb_unlocked_txn || !ctx->ovnnb_txn || !ctx->ovnsb_txn) {\n         return;\n     }\n \n@@ -2256,7 +2279,7 @@ advertise_routes(struct ic_context *ctx,\n                  const char *ts_name,\n                  struct hmap *routes_ad)\n {\n-    ovs_assert(ctx->ovnisb_txn);\n+    ovs_assert(ctx->ovnisb_unlocked_txn);\n     const struct icsbrec_route *isb_route;\n     const struct icsbrec_route *isb_route_key =\n         icsbrec_route_index_init_row(ctx->icsbrec_route_by_ts_az);\n@@ -2298,7 +2321,7 @@ advertise_routes(struct ic_context *ctx,\n     /* Create the missing routes in IC-SB */\n     struct ic_route_info *route_adv;\n     HMAP_FOR_EACH_SAFE (route_adv, node, routes_ad) {\n-        isb_route = icsbrec_route_insert(ctx->ovnisb_txn);\n+        isb_route = icsbrec_route_insert(ctx->ovnisb_unlocked_txn);\n         icsbrec_route_set_transit_switch(isb_route, ts_name);\n         icsbrec_route_set_availability_zone(isb_route, az);\n \n@@ -2531,7 +2554,7 @@ delete_orphan_ic_routes(struct ic_context *ctx,\n static void\n route_run(struct ic_context *ctx)\n {\n-    if (!ctx->ovnisb_txn || !ctx->ovnnb_txn || !ctx->ovnsb_txn) {\n+    if (!ctx->ovnisb_unlocked_txn || !ctx->ovnnb_txn || !ctx->ovnsb_txn) {\n         return;\n     }\n \n@@ -2963,7 +2986,7 @@ destroy_service_monitor_data(struct sync_service_monitor_data *sync_data)\n static void\n sync_service_monitor(struct ic_context *ctx)\n {\n-    if (!ctx->ovnisb_txn || !ctx->ovnsb_txn) {\n+    if (!ctx->ovnisb_unlocked_txn || !ctx->ovnsb_txn) {\n         return;\n     }\n \n@@ -2985,7 +3008,7 @@ sync_service_monitor(struct ic_context *ctx)\n         if (ic_rec) {\n             sbrec_service_monitor_set_status(db_rec, ic_rec->status);\n         } else {\n-            ic_rec = icsbrec_service_monitor_insert(ctx->ovnisb_txn);\n+            ic_rec = icsbrec_service_monitor_insert(ctx->ovnisb_unlocked_txn);\n             icsbrec_service_monitor_set_type(ic_rec, db_rec->type);\n             icsbrec_service_monitor_set_ip(ic_rec, db_rec->ip);\n             icsbrec_service_monitor_set_port(ic_rec, db_rec->port);\n@@ -3090,7 +3113,7 @@ static void\n update_sequence_numbers(struct ic_context *ctx,\n                         struct ovsdb_idl_loop *ic_sb_loop)\n {\n-    if (!ctx->ovnisb_txn || !ctx->ovninb_txn) {\n+    if (!ctx->ovnisb_unlocked_txn || !ctx->ovninb_txn) {\n         return;\n     }\n \n@@ -3100,9 +3123,9 @@ update_sequence_numbers(struct ic_context *ctx,\n         ic_nb = icnbrec_ic_nb_global_insert(ctx->ovninb_txn);\n     }\n     const struct icsbrec_ic_sb_global *ic_sb = icsbrec_ic_sb_global_first(\n-                                               ctx->ovnisb_idl);\n+                                               ctx->ovnisb_unlocked_idl);\n     if (!ic_sb) {\n-        ic_sb = icsbrec_ic_sb_global_insert(ctx->ovnisb_txn);\n+        ic_sb = icsbrec_ic_sb_global_insert(ctx->ovnisb_unlocked_txn);\n     }\n \n     if ((ic_nb->nb_ic_cfg != ic_sb->nb_ic_cfg) &&\n@@ -3112,7 +3135,8 @@ update_sequence_numbers(struct ic_context *ctx,\n             icsbrec_availability_zone_set_nb_ic_cfg(ctx->runned_az, 0);\n         }\n         ic_sb_loop->next_cfg = ic_nb->nb_ic_cfg;\n-        ovsdb_idl_txn_increment(ctx->ovnisb_txn, &ctx->runned_az->header_,\n+        ovsdb_idl_txn_increment(ctx->ovnisb_unlocked_txn,\n+                                &ctx->runned_az->header_,\n             &icsbrec_availability_zone_col_nb_ic_cfg, true);\n         return;\n     }\n@@ -3127,7 +3151,7 @@ update_sequence_numbers(struct ic_context *ctx,\n     }\n \n     const struct icsbrec_availability_zone *other_az;\n-    ICSBREC_AVAILABILITY_ZONE_FOR_EACH (other_az, ctx->ovnisb_idl) {\n+    ICSBREC_AVAILABILITY_ZONE_FOR_EACH (other_az, ctx->ovnisb_unlocked_idl) {\n         if (other_az->nb_ic_cfg != ctx->runned_az->nb_ic_cfg) {\n             return;\n         }\n@@ -3336,6 +3360,7 @@ static void\n update_idl_probe_interval(struct ovsdb_idl *ovn_sb_idl,\n                           struct ovsdb_idl *ovn_nb_idl,\n                           struct ovsdb_idl *ovn_icsb_idl,\n+                          struct ovsdb_idl *ovn_icsb_unlocked_idl,\n                           struct ovsdb_idl *ovn_icnb_idl)\n {\n     const struct nbrec_nb_global *nb = nbrec_nb_global_first(ovn_nb_idl);\n@@ -3354,6 +3379,7 @@ update_idl_probe_interval(struct ovsdb_idl *ovn_sb_idl,\n                                    ic_interval);\n     }\n     set_idl_probe_interval(ovn_icsb_idl, ovn_ic_sb_db, ic_interval);\n+    set_idl_probe_interval(ovn_icsb_unlocked_idl, ovn_ic_sb_db, ic_interval);\n     set_idl_probe_interval(ovn_icnb_idl, ovn_ic_nb_db, ic_interval);\n }\n \n@@ -3394,7 +3420,27 @@ main(int argc, char *argv[])\n         ovsdb_idl_create(ovn_ic_nb_db, &icnbrec_idl_class, true, true));\n     ovsdb_idl_track_add_all(ovninb_idl_loop.idl);\n \n-    /* ovn-ic-sb db. */\n+    /*\n+     * Each ovn-ic instance maintains two connections to the IC-SB database:\n+     * 1. Locked Connection: Competes for a global lock on IC-SB. Used for\n+     * writes that must be performed by only one active instance\n+     * (e.g., inserting a datapath_binding for a transit switch/router).\n+     *\n+     * 2. Unlocked Connection: Does not hold a lock. Used for writes that\n+     * can be safely performed by multiple instances simultaneously\n+     * (e.g., inserting a port_binding).\n+     *\n+     * This segregation prevents constraint violations and a full recompute\n+     * when writing to IC-SB.\n+     */\n+    /* ovn-ic-sb db without lock. */\n+    struct ovsdb_idl_loop ovnisb_unlocked_idl_loop =\n+        OVSDB_IDL_LOOP_INITIALIZER(ovsdb_idl_create(ovn_ic_sb_db,\n+                                                    &icsbrec_idl_class,\n+                                                    true, true));\n+    ovsdb_idl_track_add_all(ovnisb_unlocked_idl_loop.idl);\n+\n+    /* ovn-ic-sb db with lock. */\n     struct ovsdb_idl_loop ovnisb_idl_loop = OVSDB_IDL_LOOP_INITIALIZER(\n         ovsdb_idl_create(ovn_ic_sb_db, &icsbrec_idl_class, true, true));\n     ovsdb_idl_track_add_all(ovnisb_idl_loop.idl);\n@@ -3619,41 +3665,41 @@ main(int argc, char *argv[])\n                                   &icnbrec_transit_switch_col_name);\n \n     struct ovsdb_idl_index *icsbrec_port_binding_by_az\n-        = ovsdb_idl_index_create1(ovnisb_idl_loop.idl,\n+        = ovsdb_idl_index_create1(ovnisb_unlocked_idl_loop.idl,\n                                   &icsbrec_port_binding_col_availability_zone);\n \n     struct ovsdb_idl_index *icsbrec_port_binding_by_ts\n-        = ovsdb_idl_index_create1(ovnisb_idl_loop.idl,\n+        = ovsdb_idl_index_create1(ovnisb_unlocked_idl_loop.idl,\n                                   &icsbrec_port_binding_col_transit_switch);\n \n     struct ovsdb_idl_index *icsbrec_port_binding_by_ts_az\n-        = ovsdb_idl_index_create2(ovnisb_idl_loop.idl,\n+        = ovsdb_idl_index_create2(ovnisb_unlocked_idl_loop.idl,\n                                   &icsbrec_port_binding_col_transit_switch,\n                                   &icsbrec_port_binding_col_availability_zone);\n \n     struct ovsdb_idl_index *icsbrec_route_by_az\n-        = ovsdb_idl_index_create1(ovnisb_idl_loop.idl,\n+        = ovsdb_idl_index_create1(ovnisb_unlocked_idl_loop.idl,\n                                   &icsbrec_route_col_availability_zone);\n \n     struct ovsdb_idl_index *icsbrec_route_by_ts\n-        = ovsdb_idl_index_create1(ovnisb_idl_loop.idl,\n+        = ovsdb_idl_index_create1(ovnisb_unlocked_idl_loop.idl,\n                                   &icsbrec_route_col_transit_switch);\n \n     struct ovsdb_idl_index *icsbrec_route_by_ts_az\n-        = ovsdb_idl_index_create2(ovnisb_idl_loop.idl,\n+        = ovsdb_idl_index_create2(ovnisb_unlocked_idl_loop.idl,\n                                   &icsbrec_route_col_transit_switch,\n                                   &icsbrec_route_col_availability_zone);\n \n     struct ovsdb_idl_index *icsbrec_service_monitor_by_source_az\n-        = ovsdb_idl_index_create1(ovnisb_idl_loop.idl,\n+        = ovsdb_idl_index_create1(ovnisb_unlocked_idl_loop.idl,\n             &icsbrec_service_monitor_col_source_availability_zone);\n \n     struct ovsdb_idl_index *icsbrec_service_monitor_by_target_az\n-        = ovsdb_idl_index_create1(ovnisb_idl_loop.idl,\n+        = ovsdb_idl_index_create1(ovnisb_unlocked_idl_loop.idl,\n             &icsbrec_service_monitor_col_target_availability_zone);\n \n     struct ovsdb_idl_index *icsbrec_service_monitor_by_target_az_logical_port\n-        = ovsdb_idl_index_create2(ovnisb_idl_loop.idl,\n+        = ovsdb_idl_index_create2(ovnisb_unlocked_idl_loop.idl,\n             &icsbrec_service_monitor_col_target_availability_zone,\n             &icsbrec_service_monitor_col_logical_port);\n \n@@ -3668,12 +3714,13 @@ main(int argc, char *argv[])\n \n     /* Initialize incremental processing engine for ovn-northd */\n     inc_proc_ic_init(&ovnnb_idl_loop, &ovnsb_idl_loop,\n-                     &ovninb_idl_loop, &ovnisb_idl_loop);\n+                     &ovninb_idl_loop, &ovnisb_unlocked_idl_loop);\n \n     unsigned int ovnnb_cond_seqno = UINT_MAX;\n     unsigned int ovnsb_cond_seqno = UINT_MAX;\n     unsigned int ovninb_cond_seqno = UINT_MAX;\n     unsigned int ovnisb_cond_seqno = UINT_MAX;\n+    unsigned int ovnisb_unlocked_cond_seqno = UINT_MAX;\n \n     /* Main loop. */\n     struct ic_engine_context  eng_ctx = {0};\n@@ -3685,7 +3732,9 @@ main(int argc, char *argv[])\n     while (!exiting) {\n         update_ssl_config();\n         update_idl_probe_interval(ovnsb_idl_loop.idl, ovnnb_idl_loop.idl,\n-                                  ovnisb_idl_loop.idl, ovninb_idl_loop.idl);\n+                                  ovnisb_idl_loop.idl,\n+                                  ovnisb_unlocked_idl_loop.idl,\n+                                  ovninb_idl_loop.idl);\n         memory_run();\n         if (memory_should_report()) {\n             struct simap usage = SIMAP_INITIALIZER(&usage);\n@@ -3707,6 +3756,17 @@ main(int argc, char *argv[])\n                 ovsdb_idl_set_lock(ovnsb_idl_loop.idl, \"ovn_ic\");\n             }\n \n+            if (!ovsdb_idl_has_lock(ovnisb_idl_loop.idl) &&\n+                !ovsdb_idl_is_lock_contended(ovnisb_idl_loop.idl)) {\n+                /*\n+                 * Ensure that only a single ovn-ic has the permission to\n+                 * write to IC-SB.\n+                 */\n+                VLOG_INFO(\"OVN ISB lock acquired. \"\n+                          \"This ovn-ic instance is now active.\");\n+                ovsdb_idl_set_lock(ovnisb_idl_loop.idl, \"ovn_ic_sb\");\n+            }\n+\n             struct ovsdb_idl_txn *ovnnb_txn =\n                 run_idl_loop(&ovnnb_idl_loop, \"OVN_Northbound\",\n                              &eng_ctx.nb_idl_duration_ms);\n@@ -3759,6 +3819,20 @@ main(int argc, char *argv[])\n                 ovnisb_cond_seqno = new_ovnisb_cond_seqno;\n             }\n \n+            struct ovsdb_idl_txn *ovnisb_unlocked_txn =\n+                run_idl_loop(&ovnisb_unlocked_idl_loop, \"OVN_IC_Southbound\",\n+                             &eng_ctx.isb_unlock_idl_duration_ms);\n+            unsigned int new_ovnisb_unlocked_cond_seqno =\n+                ovsdb_idl_get_condition_seqno(ovnisb_unlocked_idl_loop.idl);\n+            if (new_ovnisb_unlocked_cond_seqno != ovnisb_unlocked_cond_seqno) {\n+                if (!new_ovnisb_unlocked_cond_seqno) {\n+                    VLOG_INFO(\"OVN ISB IDL Unlocked reconnected, \"\n+                              \"force recompute.\");\n+                    inc_proc_ic_force_recompute();\n+                }\n+                ovnisb_unlocked_cond_seqno = new_ovnisb_unlocked_cond_seqno;\n+            }\n+\n             struct ic_context ctx = {\n                 .ovnnb_idl = ovnnb_idl_loop.idl,\n                 .ovnnb_txn = ovnnb_txn,\n@@ -3768,6 +3842,8 @@ main(int argc, char *argv[])\n                 .ovninb_txn = ovninb_txn,\n                 .ovnisb_idl = ovnisb_idl_loop.idl,\n                 .ovnisb_txn = ovnisb_txn,\n+                .ovnisb_unlocked_idl = ovnisb_unlocked_idl_loop.idl,\n+                .ovnisb_unlocked_txn = ovnisb_unlocked_txn,\n                 .nbrec_ls_by_name = nbrec_ls_by_name,\n                 .nbrec_lr_by_name = nbrec_lr_by_name,\n                 .nbrec_lrp_by_name = nbrec_lrp_by_name,\n@@ -3815,15 +3891,17 @@ main(int argc, char *argv[])\n                 ovsdb_idl_has_ever_connected(ctx.ovnnb_idl) &&\n                 ovsdb_idl_has_ever_connected(ctx.ovnsb_idl) &&\n                 ovsdb_idl_has_ever_connected(ctx.ovninb_idl) &&\n-                ovsdb_idl_has_ever_connected(ctx.ovnisb_idl)) {\n+                ovsdb_idl_has_ever_connected(ctx.ovnisb_idl) &&\n+                ovsdb_idl_has_ever_connected(ctx.ovnisb_unlocked_idl)) {\n                 if (ctx.ovnnb_txn && ctx.ovnsb_txn && ctx.ovninb_txn &&\n-                    ctx.ovnisb_txn && inc_proc_ic_can_run(&eng_ctx)) {\n+                    ctx.ovnisb_unlocked_txn && inc_proc_ic_can_run(&eng_ctx)) {\n                     ctx.runned_az = az_run(&ctx);\n                     VLOG_DBG(\"Availability zone: %s\", ctx.runned_az ?\n                              ctx.runned_az->name : \"not created yet.\");\n                     if (ctx.runned_az) {\n                         (void) inc_proc_ic_run(&ctx, &eng_ctx);\n-                        update_sequence_numbers(&ctx, &ovnisb_idl_loop);\n+                        update_sequence_numbers(&ctx,\n+                                                &ovnisb_unlocked_idl_loop);\n                     }\n                 } else if (!inc_proc_ic_get_force_recompute()) {\n                     clear_idl_track = false;\n@@ -3847,10 +3925,21 @@ main(int argc, char *argv[])\n                                 \"force recompute next time.\");\n                     inc_proc_ic_force_recompute_immediate();\n                 }\n+                if (!ovsdb_idl_loop_commit_and_wait(\n+                                          &ovnisb_unlocked_idl_loop)) {\n+                    VLOG_INFO(\"OVNISB Unlocked commit failed, \"\n+                                \"force recompute next time.\");\n+                    inc_proc_ic_force_recompute_immediate();\n+                }\n \n-                if (!ovsdb_idl_loop_commit_and_wait(&ovnisb_idl_loop)) {\n+                /*\n+                 * ovn-ic will only try to recompute a failed transaction from\n+                 * the locked connection IF the AZ has the lock.\n+                 */\n+                if (!ovsdb_idl_loop_commit_and_wait(&ovnisb_idl_loop) &&\n+                    ovsdb_idl_has_lock(ovnisb_idl_loop.idl)) {\n                     VLOG_INFO(\"OVNISB commit failed, \"\n-                                \"force recompute next time.\");\n+                              \"force recompute next time.\");\n                     inc_proc_ic_force_recompute_immediate();\n                 }\n             } else {\n@@ -3859,10 +3948,13 @@ main(int argc, char *argv[])\n                 int rc2 = ovsdb_idl_loop_commit_and_wait(&ovnsb_idl_loop);\n                 int rc3 = ovsdb_idl_loop_commit_and_wait(&ovninb_idl_loop);\n                 int rc4 = ovsdb_idl_loop_commit_and_wait(&ovnisb_idl_loop);\n-                if (!rc1 || !rc2 || !rc3 || !rc4) {\n-                    VLOG_DBG(\" a transaction failed in: %s %s %s %s\",\n+                int rc5 =\n+                    ovsdb_idl_loop_commit_and_wait(&ovnisb_unlocked_idl_loop);\n+                if (!rc1 || !rc2 || !rc3 || !rc4 || !rc5) {\n+                    VLOG_DBG(\" a transaction failed in: %s %s %s %s %s\",\n                             !rc1 ? \"nb\" : \"\", !rc2 ? \"sb\" : \"\",\n-                            !rc3 ? \"ic_nb\" : \"\", !rc4 ? \"ic_sb\" : \"\");\n+                             !rc3 ? \"ic_nb\" : \"\", !rc4 ? \"ic_sb\" : \"\",\n+                             !rc5 ? \"ic_sb_unlocked\" : \"\");\n                     /* A transaction failed. Wake up immediately to give\n                     * opportunity to send the proper transaction\n                     */\n@@ -3877,6 +3969,13 @@ main(int argc, char *argv[])\n              *      copy will be out of sync.\n              *    - but we don't want to create any txns.\n              * */\n+            if (ovsdb_idl_has_lock(ovnisb_idl_loop.idl))\n+            {\n+                VLOG_INFO(\"This ovn-ic instance is now paused. \"\n+                          \"Removing IC-SB lock.\");\n+                ovsdb_idl_set_lock(ovnisb_idl_loop.idl, NULL);\n+            }\n+\n             if (ovsdb_idl_has_lock(ovnsb_idl_loop.idl) ||\n                 ovsdb_idl_is_lock_contended(ovnsb_idl_loop.idl))\n             {\n@@ -3890,10 +3989,12 @@ main(int argc, char *argv[])\n             ovsdb_idl_run(ovnsb_idl_loop.idl);\n             ovsdb_idl_run(ovninb_idl_loop.idl);\n             ovsdb_idl_run(ovnisb_idl_loop.idl);\n+            ovsdb_idl_run(ovnisb_unlocked_idl_loop.idl);\n             ovsdb_idl_wait(ovnnb_idl_loop.idl);\n             ovsdb_idl_wait(ovnsb_idl_loop.idl);\n             ovsdb_idl_wait(ovninb_idl_loop.idl);\n             ovsdb_idl_wait(ovnisb_idl_loop.idl);\n+            ovsdb_idl_wait(ovnisb_unlocked_idl_loop.idl);\n \n             /* Force a full recompute next time we become active. */\n             inc_proc_ic_force_recompute_immediate();\n@@ -3904,6 +4005,7 @@ main(int argc, char *argv[])\n             ovsdb_idl_track_clear(ovnsb_idl_loop.idl);\n             ovsdb_idl_track_clear(ovninb_idl_loop.idl);\n             ovsdb_idl_track_clear(ovnisb_idl_loop.idl);\n+            ovsdb_idl_track_clear(ovnisb_unlocked_idl_loop.idl);\n         }\n \n         unixctl_server_run(unixctl);\n@@ -3925,6 +4027,7 @@ main(int argc, char *argv[])\n     ovsdb_idl_loop_destroy(&ovnsb_idl_loop);\n     ovsdb_idl_loop_destroy(&ovninb_idl_loop);\n     ovsdb_idl_loop_destroy(&ovnisb_idl_loop);\n+    ovsdb_idl_loop_destroy(&ovnisb_unlocked_idl_loop);\n     service_stop();\n \n     exit(res);\ndiff --git a/ic/ovn-ic.h b/ic/ovn-ic.h\nindex 7391a19d4..9f52bb0f9 100644\n--- a/ic/ovn-ic.h\n+++ b/ic/ovn-ic.h\n@@ -22,10 +22,12 @@ struct ic_context {\n     struct ovsdb_idl *ovnsb_idl;\n     struct ovsdb_idl *ovninb_idl;\n     struct ovsdb_idl *ovnisb_idl;\n+    struct ovsdb_idl *ovnisb_unlocked_idl;\n     struct ovsdb_idl_txn *ovnnb_txn;\n     struct ovsdb_idl_txn *ovnsb_txn;\n     struct ovsdb_idl_txn *ovninb_txn;\n     struct ovsdb_idl_txn *ovnisb_txn;\n+    struct ovsdb_idl_txn *ovnisb_unlocked_txn;\n     const struct icsbrec_availability_zone *runned_az;\n     struct ovsdb_idl_index *nbrec_ls_by_name;\n     struct ovsdb_idl_index *nbrec_lr_by_name;\ndiff --git a/tests/ovn-ic.at b/tests/ovn-ic.at\nindex 50270fdda..68adc480c 100644\n--- a/tests/ovn-ic.at\n+++ b/tests/ovn-ic.at\n@@ -4793,3 +4793,47 @@ OVN_CLEANUP_IC([az1], [az2])\n \n AT_CLEANUP\n ])\n+\n+OVN_FOR_EACH_NORTHD([\n+AT_SETUP([ovn-ic - IC-SB lock acquisition and transit switch creation])\n+\n+ovn_init_ic_db\n+ovn_start az1\n+ovn_start az2\n+\n+wait_row_count ic-sb:Availability_Zone 2\n+\n+ovn_as az1\n+check ovn-ic-nbctl ts-add ts1\n+\n+wait_row_count ic-sb:Datapath_Binding 1 transit_switch=ts1\n+as az1 check ovn-appctl -t ic/ovn-ic pause\n+\n+ovn_as az2\n+check ovn-ic-nbctl ts-add ts2\n+wait_row_count ic-sb:Datapath_Binding 1 transit_switch=ts2\n+\n+check_row_count ic-sb:Datapath_Binding 2\n+check_column \"ts1 ts2\" ic-sb:Datapath_Binding transit_switch\n+\n+as az1 check ovn-appctl -t ic/ovn-ic resume\n+\n+as az2 check ovn-appctl -t ic/ovn-ic pause\n+\n+ovn_as az1\n+check ovn-ic-nbctl ts-add ts3\n+\n+wait_row_count ic-sb:Datapath_Binding 1 transit_switch=ts3\n+check_row_count ic-sb:Datapath_Binding 3\n+check_column \"ts1 ts2 ts3\" ic-sb:Datapath_Binding transit_switch\n+\n+as az2 check ovn-appctl -t ic/ovn-ic resume\n+\n+for i in 1 2; do\n+    az=az$i\n+    ovn_as $az\n+    OVN_CLEANUP_AZ([$az])\n+done\n+\n+AT_CLEANUP\n+])\n\\ No newline at end of file\n","prefixes":["ovs-dev","v4"]}