From patchwork Tue Apr 7 14:43:33 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lorenzo Bianconi X-Patchwork-Id: 2220575 X-Patchwork-Delegate: i.maximets@samsung.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=frCRi/Gk; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=140.211.166.138; helo=smtp1.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=patchwork.ozlabs.org) Received: from smtp1.osuosl.org (smtp1.osuosl.org [140.211.166.138]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4fqpqL08Pxz1xtJ for ; Wed, 08 Apr 2026 00:43:56 +1000 (AEST) Received: from localhost (localhost [127.0.0.1]) by smtp1.osuosl.org (Postfix) with ESMTP id CA4B580B09; Tue, 7 Apr 2026 14:43:52 +0000 (UTC) X-Virus-Scanned: amavis at osuosl.org Received: from smtp1.osuosl.org ([127.0.0.1]) by localhost (smtp1.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP id iEYkwrbnGY8D; Tue, 7 Apr 2026 14:43:51 +0000 (UTC) X-Comment: SPF check N/A for local connections - client-ip=140.211.9.56; helo=lists.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver= DKIM-Filter: OpenDKIM Filter v2.11.0 smtp1.osuosl.org 8A12480B3F Authentication-Results: smtp1.osuosl.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=frCRi/Gk Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by smtp1.osuosl.org (Postfix) with ESMTPS id 8A12480B3F; Tue, 7 Apr 2026 14:43:51 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 4E80CC04FB; Tue, 7 Apr 2026 14:43:51 +0000 (UTC) X-Original-To: ovs-dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from smtp4.osuosl.org (smtp4.osuosl.org [IPv6:2605:bc80:3010::137]) by lists.linuxfoundation.org (Postfix) with ESMTP id 526CEC04FA for ; Tue, 7 Apr 2026 14:43:50 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp4.osuosl.org (Postfix) with ESMTP id 33059406DB for ; Tue, 7 Apr 2026 14:43:50 +0000 (UTC) X-Virus-Scanned: amavis at osuosl.org Received: from smtp4.osuosl.org ([127.0.0.1]) by localhost (smtp4.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP id DwDJk-50yI3l for ; Tue, 7 Apr 2026 14:43:49 +0000 (UTC) Received-SPF: Pass (mailfrom) identity=mailfrom; client-ip=170.10.129.124; helo=us-smtp-delivery-124.mimecast.com; envelope-from=lorenzo.bianconi@redhat.com; receiver= DMARC-Filter: OpenDMARC Filter v1.4.2 smtp4.osuosl.org DF545406AA Authentication-Results: smtp4.osuosl.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 smtp4.osuosl.org DF545406AA Authentication-Results: smtp4.osuosl.org; dkim=pass (1024-bit key, unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=frCRi/Gk Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by smtp4.osuosl.org (Postfix) with ESMTPS id DF545406AA for ; Tue, 7 Apr 2026 14:43:48 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1775573027; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=gFdMrxIlI9DcgeJ3jKQ0/9bJQsXpKosdF7xltSKEttI=; b=frCRi/Gkzg8jugYEtwE8oI7hjdh2SKxRZkuLVlN97ei0fTw21cmThe0O5cvqThUGYzxHS5 E+9nuS+Fh4/KuT7jCSZvQ10Iop00ScPPHWQ2NlgWCbJmX9JGLGSaetWSoDtj9Lju1os0eR lZl+wqkKvSbNdPNCk8bTRGap0HfZVX4= Received: from mail-wm1-f70.google.com (mail-wm1-f70.google.com [209.85.128.70]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-685-HbZg8zAuPMCjIsazHc5uqQ-1; Tue, 07 Apr 2026 10:43:45 -0400 X-MC-Unique: HbZg8zAuPMCjIsazHc5uqQ-1 X-Mimecast-MFC-AGG-ID: HbZg8zAuPMCjIsazHc5uqQ_1775573025 Received: by mail-wm1-f70.google.com with SMTP id 5b1f17b1804b1-4889e505136so19706715e9.0 for ; Tue, 07 Apr 2026 07:43:45 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1775573024; x=1776177824; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=gFdMrxIlI9DcgeJ3jKQ0/9bJQsXpKosdF7xltSKEttI=; b=VoPIsNs5pcjy1Bic4CqYMVd3svuFnfoZncvw94H/NkGXx7tA2jtRKEQuvjTQwar5vq Y0GiY6imTPnachTEd0BpgbQjGO+2E+nFnrm6wzMnH0JNEHCStLS+30nSffOf/DnU6M6c ZrTEZ8/BfKzYLse89zTV/rPcbZJvJq5KD+UcIBjQSU7MGqfjRAGOC5QNHeW3pUe29KxT G4ux9EqX8bB2vA4msRiUwi6syldjJRTxWbpyvXm8/lG/uJsRHVixyArdvbxbI2PHIaEy 0hdKxQ5FknvD655scRrlU/vwB3LYiAaeR0QY7j5QFE3I4tHsJK5SJkPAUCicB6cOss1N h7Qw== X-Gm-Message-State: AOJu0Yw92cRLcH38SRpxKx4zqdfKiN12IaiA/WaQ0MyznmSroIcSbRfs GLWRLIU7GJPVT38DxI5DUbCU2pd2E8iDE3luz5BoKzXoiUnq0Ihe5sf5zXjqzilV4PsoVhxqHXH M1KT6JEIyN8vdOOhyhJU+EJYqPaHD6xs4opEtmytlONLKq1w87ldAHcnx6ItiRJlXiIPnr+XAMI 9upBWhpf37lVuRny7mESn2RclaVE5itDt3Mr+b0xQs0qh7hxLaDm9Smw== X-Gm-Gg: AeBDiesfYSxKFRD4luhJE2CxeIjlY8ZvVGv8Bl5lEZASRPxBZUZYKQOUXwt0le7VGG/ VFPtC8oq5/MmkznvsGNQg8mv2OMOviRlcbz+vS3GteRWomDoZNEnbl77KuxFFjx0Z++gzZt/8zZ GGFUdX4Rf9wizx2TUQFXKFVp0yvGz6jxmPhesEgCGkMFUggFyZjvXroH+AEUFsYMaenFEi/r46t Jw0d3zRjLd6akGDYLJiCy/izRME03NQdX3ohLo3zVv3lfpCTDkMED9xSEIHXmgZ6demGaDNx/8r tCS9xLJSuF9Msk1iejmxmvOIAWGrJlV6slu2DxRJYlq25kftw+gf7xHl6eHCkl/FPmoe98YaXWa nE6LnAbCTCMWC77UXaT/y5fTpfnQrId1NN54z9sZUIVMH1NsTvgapYSpou1tGZm3X1pa/Cw== X-Received: by 2002:a05:600c:c16f:b0:488:c239:d498 with SMTP id 5b1f17b1804b1-488c239d786mr16595595e9.8.1775573023643; Tue, 07 Apr 2026 07:43:43 -0700 (PDT) X-Received: by 2002:a05:600c:c16f:b0:488:c239:d498 with SMTP id 5b1f17b1804b1-488c239d786mr16595155e9.8.1775573022926; Tue, 07 Apr 2026 07:43:42 -0700 (PDT) Received: from localhost (net-37-119-153-93.cust.vodafonedsl.it. [37.119.153.93]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-488c13811ccsm17168515e9.8.2026.04.07.07.43.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 07 Apr 2026 07:43:42 -0700 (PDT) To: ovs-dev@openvswitch.org Cc: dceara@redhat.com, i.maximets@ovn.org Date: Tue, 7 Apr 2026 16:43:33 +0200 Message-ID: <813574e5fdcf2408b2d3a0c41c1d39abc3c5bf97.1775572218.git.lorenzo.bianconi@redhat.com> X-Mailer: git-send-email 2.53.0 MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: Qq3pUchsYiY_pKZEMRySNAypiYg8VYc-IpkuslmTh-E_1775573025 X-Mimecast-Originator: redhat.com Subject: [ovs-dev] [PATCH v2] ovsdb: Save user monitor condition request in ovsdb_idl_table struct. X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Lorenzo Bianconi via dev From: Lorenzo Bianconi Reply-To: Lorenzo Bianconi Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" Store the user monitor condition request in pre-json format in ovsdb_idl_table in order to use it in ovsdb_idl_compose_monitor_request routine and create a monitor condition request based on the tables/columns available in db-schema. Reported-at: https://issues.redhat.com/browse/FDP-3114 Signed-off-by: Lorenzo Bianconi --- Changes in v2: - Add missing unit-test. - squash with patch 'ovsdb: Add ovsdb_cs_clear_condition routine to remove stable ovsdb_cs_db_table entries.'. - fix the error condition reported by Ilya. - Remove unnecessary ovsdb_cs_db_sync_condition() in ovsdb_cs_send_monitor_request(). - cosmetics. --- lib/ovsdb-cs.c | 35 ++++++++++--- lib/ovsdb-cs.h | 1 + lib/ovsdb-idl-provider.h | 3 ++ lib/ovsdb-idl.c | 104 +++++++++++++++++++++++++++++++++++++-- tests/ovsdb-idl.at | 3 ++ tests/test-ovsdb.c | 8 +++ 6 files changed, 145 insertions(+), 9 deletions(-) diff --git a/lib/ovsdb-cs.c b/lib/ovsdb-cs.c index df33a835d..09796f37a 100644 --- a/lib/ovsdb-cs.c +++ b/lib/ovsdb-cs.c @@ -912,17 +912,40 @@ ovsdb_cs_db_get_table(struct ovsdb_cs_db *db, const char *table) return t; } +static void +ovsdb_cs_db_destroy_table(struct ovsdb_cs_db_table *table, + struct ovsdb_cs_db *db) +{ + json_destroy(table->ack_cond); + json_destroy(table->req_cond); + json_destroy(table->new_cond); + hmap_remove(&db->tables, &table->hmap_node); + free(table->name); + free(table); +} + +/* Destroy a given ovsdb_cs_db_table according to the table name. */ +void +ovsdb_cs_clear_condition(struct ovsdb_cs *cs, const char *table) +{ + uint32_t hash = hash_string(table, 0); + struct ovsdb_cs_db *db = &cs->data; + + struct ovsdb_cs_db_table *t; + HMAP_FOR_EACH_WITH_HASH (t, hmap_node, hash, &db->tables) { + if (!strcmp(t->name, table)) { + ovsdb_cs_db_destroy_table(t, db); + return; + } + } +} + static void ovsdb_cs_db_destroy_tables(struct ovsdb_cs_db *db) { struct ovsdb_cs_db_table *table; HMAP_FOR_EACH_SAFE (table, hmap_node, &db->tables) { - json_destroy(table->ack_cond); - json_destroy(table->req_cond); - json_destroy(table->new_cond); - hmap_remove(&db->tables, &table->hmap_node); - free(table->name); - free(table); + ovsdb_cs_db_destroy_table(table, db); } hmap_destroy(&db->tables); } diff --git a/lib/ovsdb-cs.h b/lib/ovsdb-cs.h index bcc3dcd71..0ac691352 100644 --- a/lib/ovsdb-cs.h +++ b/lib/ovsdb-cs.h @@ -144,6 +144,7 @@ void ovsdb_cs_set_probe_interval(const struct ovsdb_cs *, int probe_interval); unsigned int ovsdb_cs_set_condition(struct ovsdb_cs *, const char *table, const struct json *condition); unsigned int ovsdb_cs_get_condition_seqno(const struct ovsdb_cs *); +void ovsdb_cs_clear_condition(struct ovsdb_cs *, const char *table); /* Database change awareness. */ void ovsdb_cs_set_db_change_aware(struct ovsdb_cs *, bool set_db_change_aware); diff --git a/lib/ovsdb-idl-provider.h b/lib/ovsdb-idl-provider.h index 6cf32fb50..9244bbcd5 100644 --- a/lib/ovsdb-idl-provider.h +++ b/lib/ovsdb-idl-provider.h @@ -130,6 +130,9 @@ struct ovsdb_idl_table { * or not. */ struct ovs_list indexes; /* Contains "struct ovsdb_idl_index"s */ struct ovs_list track_list; /* Tracked rows (ovsdb_idl_row.track_node). */ + + struct ovsdb_idl_condition req_cond; /* User requested monitor + * condition. */ }; struct ovsdb_idl_class { diff --git a/lib/ovsdb-idl.c b/lib/ovsdb-idl.c index fe90deda7..0bd77cffd 100644 --- a/lib/ovsdb-idl.c +++ b/lib/ovsdb-idl.c @@ -99,6 +99,7 @@ struct ovsdb_idl { struct ovs_list rows_to_reparse; /* Stores rows that might need to be * re-parsed due to insertion of a * referenced row. */ + bool server_schema_received; }; static struct ovsdb_cs_ops ovsdb_idl_cs_ops; @@ -205,6 +206,19 @@ static void ovsdb_idl_add_to_indexes(const struct ovsdb_idl_row *); static void ovsdb_idl_remove_from_indexes(const struct ovsdb_idl_row *); static int ovsdb_idl_try_commit_loop_txn(struct ovsdb_idl_loop *loop, bool *may_need_wakeup); +static void +ovsdb_idl_condition_clone(struct ovsdb_idl_condition *dest, + const struct ovsdb_idl_condition *source); +static void +ovsdb_idl_create_req_condition(struct ovsdb_idl *, + const struct ovsdb_idl_table_class *, + const struct ovsdb_idl_condition *); +static void ovsdb_idl_destroy_req_condition(struct ovsdb_idl_table *); +static bool ovsdb_idl_condition_is_set(struct ovsdb_idl_condition *); +static unsigned int +ovsdb_idl_set_condition__(struct ovsdb_idl *, + const struct ovsdb_idl_table_class *, + const struct ovsdb_idl_condition *); static void add_tracked_change_for_references(struct ovsdb_idl_row *); @@ -266,6 +280,7 @@ ovsdb_idl_create_unconnected(const struct ovsdb_idl_class *class, .txn = NULL, .outstanding_txns = HMAP_INITIALIZER(&idl->outstanding_txns), .verify_write_only = false, + .server_schema_received = false, .deleted_untracked_rows = OVS_LIST_INITIALIZER(&idl->deleted_untracked_rows), .rows_to_reparse @@ -298,6 +313,7 @@ ovsdb_idl_create_unconnected(const struct ovsdb_idl_class *class, = table->change_seqno[OVSDB_IDL_CHANGE_DELETE] = 0; table->idl = idl; table->in_server_schema = false; + ovsdb_idl_condition_init(&table->req_cond); shash_init(&table->schema_columns); } @@ -311,6 +327,7 @@ ovsdb_idl_create_unconnected(const struct ovsdb_idl_class *class, void ovsdb_idl_set_remote(struct ovsdb_idl *idl, const char *remote, bool retry) { + idl->server_schema_received = false; ovsdb_cs_set_remote(idl->cs, remote, retry); } @@ -372,6 +389,7 @@ ovsdb_idl_destroy(struct ovsdb_idl *idl) ovsdb_idl_schema_columns_clear(&table->schema_columns); shash_destroy(&table->schema_columns); + ovsdb_idl_destroy_req_condition(table); hmap_destroy(&table->rows); free(table->modes); @@ -784,6 +802,7 @@ static struct json * ovsdb_idl_compose_monitor_request(const struct json *schema_json, void *idl_) { struct ovsdb_idl *idl = idl_; + idl->server_schema_received = true; struct shash *schema = ovsdb_cs_parse_schema(schema_json); struct json *monitor_requests = json_object_create(); @@ -842,6 +861,7 @@ ovsdb_idl_compose_monitor_request(const struct json *schema_json, void *idl_) idl->class_->database, table->class_->name); json_destroy(columns); table->in_server_schema = false; + ovsdb_cs_clear_condition(idl->cs, table->class_->name); continue; } else if (schema && table_schema) { table->in_server_schema = true; @@ -852,6 +872,14 @@ ovsdb_idl_compose_monitor_request(const struct json *schema_json, void *idl_) json_object_put(monitor_requests, tc->name, json_array_create_1(monitor_request)); } + + if (!table->in_server_schema) { + ovsdb_cs_clear_condition(idl->cs, table->class_->name); + } else if (ovsdb_idl_condition_is_set(&table->req_cond)) { + /* Update the monitor condition request according to the + * db schema. */ + ovsdb_idl_set_condition__(idl, tc, &table->req_cond); + } } ovsdb_cs_free_schema(schema); @@ -1156,6 +1184,45 @@ ovsdb_idl_condition_add_clause__(struct ovsdb_idl_condition *condition, hmap_insert(&condition->clauses, &clause->hmap_node, hash); } +static void +ovsdb_idl_destroy_req_condition(struct ovsdb_idl_table *table) +{ + ovsdb_idl_condition_destroy(&table->req_cond); +} + +static bool +ovsdb_idl_condition_is_set(struct ovsdb_idl_condition *condition) +{ + return !hmap_is_empty(&condition->clauses) || condition->is_true; +} + +static void +ovsdb_idl_condition_clone(struct ovsdb_idl_condition *dest, + const struct ovsdb_idl_condition *source) +{ + ovsdb_idl_condition_init(dest); + + struct ovsdb_idl_clause *clause; + HMAP_FOR_EACH (clause, hmap_node, &source->clauses) { + uint32_t hash = ovsdb_idl_clause_hash(clause); + ovsdb_idl_condition_add_clause__(dest, clause, hash); + } + dest->is_true = source->is_true; +} + +static void +ovsdb_idl_create_req_condition(struct ovsdb_idl *idl, + const struct ovsdb_idl_table_class *tc, + const struct ovsdb_idl_condition *condition) +{ + struct ovsdb_idl_table *table = shash_find_data(&idl->table_by_name, + tc->name); + if (table) { + ovsdb_idl_destroy_req_condition(table); + ovsdb_idl_condition_clone(&table->req_cond, condition); + } +} + /* Adds a clause to the condition for replicating the table with class 'tc' in * 'idl'. * @@ -1234,6 +1301,17 @@ ovsdb_idl_condition_to_json(const struct ovsdb_idl_condition *cnd) return json_array_create(clauses, n); } +static unsigned int +ovsdb_idl_set_condition__(struct ovsdb_idl *idl, + const struct ovsdb_idl_table_class *tc, + const struct ovsdb_idl_condition *condition) +{ + struct json *cond_json = ovsdb_idl_condition_to_json(condition); + unsigned int seqno = ovsdb_cs_set_condition(idl->cs, tc->name, cond_json); + json_destroy(cond_json); + return seqno; +} + /* Sets the replication condition for 'tc' in 'idl' to 'condition' and * arranges to send the new condition to the database server. * @@ -1245,9 +1323,29 @@ ovsdb_idl_set_condition(struct ovsdb_idl *idl, const struct ovsdb_idl_table_class *tc, const struct ovsdb_idl_condition *condition) { - struct json *cond_json = ovsdb_idl_condition_to_json(condition); - unsigned int seqno = ovsdb_cs_set_condition(idl->cs, tc->name, cond_json); - json_destroy(cond_json); + struct ovsdb_idl_condition filter_cond = + OVSDB_IDL_CONDITION_INIT(&filter_cond); + + if (idl->server_schema_received && hmap_count(&condition->clauses)) { + struct ovsdb_idl_clause *clause; + HMAP_FOR_EACH (clause, hmap_node, &condition->clauses) { + if (ovsdb_idl_server_has_column(idl, clause->column)) { + uint32_t hash = ovsdb_idl_clause_hash(clause); + ovsdb_idl_condition_add_clause__(&filter_cond, clause, hash); + } + } + if (hmap_is_empty(&filter_cond.clauses)) { + return 0; /* FIXME */ + } + condition = &filter_cond; + } + + unsigned int seqno = ovsdb_idl_set_condition__(idl, tc, condition); + ovsdb_idl_create_req_condition(idl, tc, &filter_cond); + if (hmap_count(&filter_cond.clauses)) { + ovsdb_idl_condition_destroy(&filter_cond); + } + return seqno; } diff --git a/tests/ovsdb-idl.at b/tests/ovsdb-idl.at index 728d761d4..194afef13 100644 --- a/tests/ovsdb-idl.at +++ b/tests/ovsdb-idl.at @@ -2722,6 +2722,9 @@ unix:socket2 remote has col id in table simple7, type: string --- remote unix:socket2 done --- ], [stderr]) +# Check we do not have any errors related to conditional monitoring. +AT_CHECK([grep -q "received error, error={\"details\":\"no table named link2\",\"error\":\"syntax error\"}" stderr], [1]) + OVSDB_SERVER_SHUTDOWN AT_CLEANUP diff --git a/tests/test-ovsdb.c b/tests/test-ovsdb.c index 95290ae78..037a78743 100644 --- a/tests/test-ovsdb.c +++ b/tests/test-ovsdb.c @@ -3596,6 +3596,12 @@ do_idl_table_column_check(struct ovs_cmdl_context *ctx) ovsdb_idl_set_remote(idl, ctx->argv[r], true); ovsdb_idl_force_reconnect(idl); + struct ovsdb_idl_condition cond_link2 = + OVSDB_IDL_CONDITION_INIT(&cond_link2); + idltest_link2_add_clause_i(&cond_link2, OVSDB_F_EQ, 1); + + idltest_link2_set_condition(idl, &cond_link2); + /* Wait for update. */ for (;;) { ovsdb_idl_run(idl); @@ -3661,6 +3667,8 @@ do_idl_table_column_check(struct ovs_cmdl_context *ctx) type ? ", type: " : "", type ? type_s : ""); free(type_s); + ovsdb_idl_condition_destroy(&cond_link2); + printf("--- remote %s done ---\n", ctx->argv[r]); }