summaryrefslogtreecommitdiff
path: root/ovsdb
diff options
context:
space:
mode:
authorHan Zhou <zhouhan@gmail.com>2015-12-17 22:23:22 -0800
committerAndy Zhou <azhou@ovn.org>2015-12-18 14:40:03 -0800
commita32b4433573ebea26cf3be75446addd029155382 (patch)
tree666cb9ccb7600b0485fdc445336397ea575a7e85 /ovsdb
parent8ab1170b06ddf33dfb06b0346d21f2e4380d8eea (diff)
downloadopenvswitch-a32b4433573ebea26cf3be75446addd029155382.tar.gz
ovsdb: separate json cache for different monitor versions
Cached json objects were reused when sending notifications to clients. This created a problem when there were different versions of monitors coexisting. 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 <zhouhan@gmail.com> Acked-by: Andy Zhou <azhou@ovn.org> Signed-off-by: Andy Zhou <azhou@ovn.org>
Diffstat (limited to 'ovsdb')
-rw-r--r--ovsdb/monitor.c26
1 files changed, 20 insertions, 6 deletions
diff --git a/ovsdb/monitor.c b/ovsdb/monitor.c
index f08607aa3..0dde54e2a 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 */
};
@@ -134,15 +135,27 @@ static void ovsdb_monitor_changes_destroy(
static void ovsdb_monitor_table_track_changes(struct ovsdb_monitor_table *mt,
uint64_t unflushed);
+static uint32_t
+json_cache_hash(enum ovsdb_monitor_version version, uint64_t from_txn)
+{
+ uint32_t hash;
+
+ hash = hash_uint64(version);
+ hash = hash_uint64_basis(from_txn, hash);
+
+ return hash;
+}
+
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 = json_cache_hash(version, from_txn);
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,14 +165,15 @@ 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;
- uint32_t hash;
+ uint32_t hash = json_cache_hash(version, from_txn);
node = xmalloc(sizeof *node);
- hash = hash_uint64(from_txn);
+ node->version = version;
node->from_txn = from_txn;
node->json = json ? json_clone(json) : NULL;
@@ -721,7 +735,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 +747,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'. */