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