From patchwork Tue Dec 15 17:03:15 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Han Zhou X-Patchwork-Id: 557280 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from archives.nicira.com (li376-54.members.linode.com [96.126.127.54]) by ozlabs.org (Postfix) with ESMTP id C93D51402D9 for ; Wed, 16 Dec 2015 13:32:07 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b=zvKWghSW; dkim-atps=neutral Received: from archives.nicira.com (localhost [127.0.0.1]) by archives.nicira.com (Postfix) with ESMTP id 446EF10285; Tue, 15 Dec 2015 18:32:06 -0800 (PST) X-Original-To: dev@openvswitch.org Delivered-To: dev@openvswitch.org Received: from mx1e4.cudamail.com (mx1.cudamail.com [69.90.118.67]) by archives.nicira.com (Postfix) with ESMTPS id 7DC0C10229 for ; Tue, 15 Dec 2015 18:32:05 -0800 (PST) Received: from bar2.cudamail.com (unknown [192.168.21.12]) by mx1e4.cudamail.com (Postfix) with ESMTPS id 8E0AD1E007F for ; Tue, 15 Dec 2015 19:32:04 -0700 (MST) X-ASG-Debug-ID: 1450233123-03dc530f7272ee70001-byXFYA Received: from mx1-pf1.cudamail.com ([192.168.24.1]) by bar2.cudamail.com with ESMTP id BvvglO6GKSCnlvTN (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Tue, 15 Dec 2015 19:32:03 -0700 (MST) X-Barracuda-Envelope-From: zhouhan@gmail.com X-Barracuda-RBL-Trusted-Forwarder: 192.168.24.1 Received: from unknown (HELO mail-pa0-f43.google.com) (209.85.220.43) by mx1-pf1.cudamail.com with ESMTPS (RC4-SHA encrypted); 16 Dec 2015 02:32:02 -0000 Received-SPF: pass (mx1-pf1.cudamail.com: SPF record at _netblocks.google.com designates 209.85.220.43 as permitted sender) X-Barracuda-RBL-Trusted-Forwarder: 209.85.220.43 Received: by mail-pa0-f43.google.com with SMTP id hk6so15260717pad.2 for ; Tue, 15 Dec 2015 18:32:02 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id; bh=GWkQPqPnMhq00y0uV3IaI2fx4va93e/Nlf9/9Lpg5KI=; b=zvKWghSWyq0TsEcrfF3MpY0kVk9j9aIa9wSwHxKV9vdQB0cJ1RB1ezUXUNDzKadwVB kV6aIbRgCYKNa1SRqZBqwh3+grvvAG0oi2JDkqxGApvOTCW6QIWelSGmU1H9r4NF+50Q vdfiqB9m6qGMZiraXWyUSexeMYvcJVF1uIdrcD4eN9Ubp4S9xMYq9c4OySbGE1X4I+sp 0wwPwfS5exYDawgmsEs4+DEs3GgiHUjvo6ZIicopdAdEN7iJrqSrZy3s0ywrIdHqzPrK 19HzVSzL/183xYBHFlpFBatUzCMND4l08z+8FkvfDrBthhSev1XQAOJCr3WI8ulY/a/s a7GA== X-Received: by 10.66.227.102 with SMTP id rz6mr59218598pac.4.1450233121314; Tue, 15 Dec 2015 18:32:01 -0800 (PST) Received: from localhost.localdomain.localdomain ([216.113.160.70]) by smtp.gmail.com with ESMTPSA id o9sm784155pfi.86.2015.12.15.18.32.00 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 15 Dec 2015 18:32:00 -0800 (PST) X-CudaMail-Envelope-Sender: zhouhan@gmail.com X-Barracuda-Apparent-Source-IP: 216.113.160.70 From: Han Zhou To: dev@openvswitch.org X-CudaMail-MID: CM-E1-1214115063 X-CudaMail-DTE: 121515 X-CudaMail-Originating-IP: 209.85.220.43 Date: Tue, 15 Dec 2015 09:03:15 -0800 X-ASG-Orig-Subj: [##CM-E1-1214115063##][PATCH] ovsdb: separate json cache for different monitor versions Message-Id: <1450198995-20413-1-git-send-email-zhouhan@gmail.com> X-Mailer: git-send-email 2.1.0 X-GBUdb-Analysis: 0, 209.85.220.43, Ugly c=0.44763 p=-0.272727 Source Normal X-MessageSniffer-Rules: 0-0-0-12365-c X-Barracuda-Connect: UNKNOWN[192.168.24.1] X-Barracuda-Start-Time: 1450233123 X-Barracuda-Encrypted: DHE-RSA-AES256-SHA X-Barracuda-URL: https://web.cudamail.com:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at cudamail.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 1.71 X-Barracuda-Spam-Status: No, SCORE=1.71 using per-user scores of TAG_LEVEL=3.5 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=4.0 tests=BSF_SC5_MJ1963, DATE_IN_PAST_06_12, DATE_IN_PAST_06_12_2, DKIM_SIGNED, RDNS_NONE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.25299 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.01 DATE_IN_PAST_06_12 Date: is 6 to 12 hours before Received: date 0.00 DKIM_SIGNED Domain Keys Identified Mail: message has a signature 0.10 RDNS_NONE Delivered to trusted network by a host with no rDNS 1.10 DATE_IN_PAST_06_12_2 DATE_IN_PAST_06_12_2 0.50 BSF_SC5_MJ1963 Custom Rule MJ1963 Subject: [ovs-dev] [PATCH] ovsdb: separate json cache for different monitor versions X-BeenThere: dev@openvswitch.org X-Mailman-Version: 2.1.16 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: dev-bounces@openvswitch.org Sender: "dev" Cached json objects were reused when sending notifications to clients. This created a problem when there were different versions of monitors coexiting. E.g. clients expecting version2 notification would receive messages with method == "update2" but payload in version1 format, which end up failure of processing the updates. http://openvswitch.org/pipermail/dev/2015-December/063406.html This patch fixes the issue by using dedicated cache for each version. Signed-off-by: Han Zhou --- ovsdb/monitor.c | 40 +++++++++++++++++++++++++++------------- 1 file changed, 27 insertions(+), 13 deletions(-) diff --git a/ovsdb/monitor.c b/ovsdb/monitor.c index f08607a..31f26e7 100644 --- a/ovsdb/monitor.c +++ b/ovsdb/monitor.c @@ -54,7 +54,9 @@ struct ovsdb_monitor { struct ovsdb *db; uint64_t n_transactions; /* Count number of committed transactions. */ struct hmap_node hmap_node; /* Elements within ovsdb_monitors. */ - struct hmap json_cache; /* Contains "ovsdb_monitor_json_cache_node"s.*/ + struct hmap json_cache[OVSDB_MONITOR_VERSION_MAX]; /* Array of caches, one + for each ovsdb monitor version, contains + "ovsdb_monitor_json_cache_node"s. */ }; /* A json object of updates between 'from_txn' and 'dbmon->n_transactions' @@ -136,12 +138,14 @@ static void ovsdb_monitor_table_track_changes(struct ovsdb_monitor_table *mt, static struct ovsdb_monitor_json_cache_node * ovsdb_monitor_json_cache_search(const struct ovsdb_monitor *dbmon, - uint64_t from_txn) + uint64_t from_txn, + enum ovsdb_monitor_version version) { struct ovsdb_monitor_json_cache_node *node; uint32_t hash = hash_uint64(from_txn); - HMAP_FOR_EACH_WITH_HASH(node, hmap_node, hash, &dbmon->json_cache) { + HMAP_FOR_EACH_WITH_HASH(node, hmap_node, hash, + &dbmon->json_cache[version]) { if (node->from_txn == from_txn) { return node; } @@ -152,7 +156,8 @@ ovsdb_monitor_json_cache_search(const struct ovsdb_monitor *dbmon, static void ovsdb_monitor_json_cache_insert(struct ovsdb_monitor *dbmon, - uint64_t from_txn, struct json *json) + uint64_t from_txn, struct json *json, + enum ovsdb_monitor_version version) { struct ovsdb_monitor_json_cache_node *node; uint32_t hash; @@ -163,7 +168,7 @@ ovsdb_monitor_json_cache_insert(struct ovsdb_monitor *dbmon, node->from_txn = from_txn; node->json = json ? json_clone(json) : NULL; - hmap_insert(&dbmon->json_cache, &node->hmap_node, hash); + hmap_insert(&dbmon->json_cache[version], &node->hmap_node, hash); } static void @@ -171,10 +176,13 @@ ovsdb_monitor_json_cache_flush(struct ovsdb_monitor *dbmon) { struct ovsdb_monitor_json_cache_node *node, *next; - HMAP_FOR_EACH_SAFE(node, next, hmap_node, &dbmon->json_cache) { - hmap_remove(&dbmon->json_cache, &node->hmap_node); - json_destroy(node->json); - free(node); + enum ovsdb_monitor_version v; + for (v = OVSDB_MONITOR_V1; v < OVSDB_MONITOR_VERSION_MAX; v++) { + HMAP_FOR_EACH_SAFE(node, next, hmap_node, &dbmon->json_cache[v]) { + hmap_remove(&dbmon->json_cache[v], &node->hmap_node); + json_destroy(node->json); + free(node); + } } } @@ -307,6 +315,7 @@ ovsdb_monitor_create(struct ovsdb *db, struct ovsdb_jsonrpc_monitor *jsonrpc_monitor) { struct ovsdb_monitor *dbmon; + enum ovsdb_monitor_version v; dbmon = xzalloc(sizeof *dbmon); @@ -317,7 +326,9 @@ ovsdb_monitor_create(struct ovsdb *db, dbmon->n_transactions = 0; shash_init(&dbmon->tables); hmap_node_nullify(&dbmon->hmap_node); - hmap_init(&dbmon->json_cache); + for (v = OVSDB_MONITOR_V1; v < OVSDB_MONITOR_VERSION_MAX; v++) { + hmap_init(&dbmon->json_cache[v]); + } ovsdb_monitor_add_jsonrpc_monitor(dbmon, jsonrpc_monitor); return dbmon; @@ -721,7 +732,7 @@ ovsdb_monitor_get_update(struct ovsdb_monitor *dbmon, /* Return a clone of cached json if one exists. Otherwise, * generate a new one and add it to the cache. */ - cache_node = ovsdb_monitor_json_cache_search(dbmon, prev_txn); + cache_node = ovsdb_monitor_json_cache_search(dbmon, prev_txn, version); if (cache_node) { json = cache_node->json ? json_clone(cache_node->json) : NULL; } else { @@ -733,7 +744,7 @@ ovsdb_monitor_get_update(struct ovsdb_monitor *dbmon, json = ovsdb_monitor_compose_update(dbmon, initial, prev_txn, ovsdb_monitor_compose_row_update2); } - ovsdb_monitor_json_cache_insert(dbmon, prev_txn, json); + ovsdb_monitor_json_cache_insert(dbmon, prev_txn, json, version); } /* Maintain transaction id of 'changes'. */ @@ -1072,6 +1083,7 @@ static void ovsdb_monitor_destroy(struct ovsdb_monitor *dbmon) { struct shash_node *node; + enum ovsdb_monitor_version v; list_remove(&dbmon->replica.node); @@ -1080,7 +1092,9 @@ ovsdb_monitor_destroy(struct ovsdb_monitor *dbmon) } ovsdb_monitor_json_cache_flush(dbmon); - hmap_destroy(&dbmon->json_cache); + for (v = OVSDB_MONITOR_V1; v < OVSDB_MONITOR_VERSION_MAX; v++) { + hmap_destroy(&dbmon->json_cache[v]); + } SHASH_FOR_EACH (node, &dbmon->tables) { struct ovsdb_monitor_table *mt = node->data;