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.

This patch fixes the issue by including version in cache node.

Signed-off-by: Han Zhou <zhou...@gmail.com>
---

Notes:
    v1 -> v2: add version to cache node and add it to hash key, according to
              suggestion by Andy Zhou

 ovsdb/monitor.c | 18 +++++++++++++-----
 1 file changed, 13 insertions(+), 5 deletions(-)

diff --git a/ovsdb/monitor.c b/ovsdb/monitor.c
index f08607a..76e93a9 100644
--- a/ovsdb/monitor.c
+++ b/ovsdb/monitor.c
@@ -61,6 +61,7 @@ struct ovsdb_monitor {
  * inclusive.  */
 struct ovsdb_monitor_json_cache_node {
     struct hmap_node hmap_node;   /* Elements in json cache. */
+    enum ovsdb_monitor_version version;
     uint64_t from_txn;
     struct json *json;            /* Null, or a cloned of json */
 };
@@ -136,13 +137,17 @@ 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,
+                                enum ovsdb_monitor_version version,
                                 uint64_t from_txn)
 {
     struct ovsdb_monitor_json_cache_node *node;
-    uint32_t hash = hash_uint64(from_txn);
+    uint32_t hash;
+
+    hash = hash_uint64(version);
+    hash = hash_uint64_basis(from_txn, hash);
 
     HMAP_FOR_EACH_WITH_HASH(node, hmap_node, hash, &dbmon->json_cache) {
-        if (node->from_txn == from_txn) {
+        if (node->from_txn == from_txn && node->version == version) {
             return node;
         }
     }
@@ -152,6 +157,7 @@ ovsdb_monitor_json_cache_search(const struct ovsdb_monitor 
*dbmon,
 
 static void
 ovsdb_monitor_json_cache_insert(struct ovsdb_monitor *dbmon,
+                                enum ovsdb_monitor_version version,
                                 uint64_t from_txn, struct json *json)
 {
     struct ovsdb_monitor_json_cache_node *node;
@@ -159,7 +165,9 @@ ovsdb_monitor_json_cache_insert(struct ovsdb_monitor *dbmon,
 
     node = xmalloc(sizeof *node);
 
-    hash = hash_uint64(from_txn);
+    hash = hash_uint64(version);
+    hash = hash_uint64_basis(from_txn, hash);
+    node->version = version;
     node->from_txn = from_txn;
     node->json = json ? json_clone(json) : NULL;
 
@@ -721,7 +729,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, version, prev_txn);
     if (cache_node) {
         json = cache_node->json ? json_clone(cache_node->json) : NULL;
     } else {
@@ -733,7 +741,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, version, prev_txn, json);
     }
 
     /* Maintain transaction id of 'changes'. */
-- 
2.1.0

_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to