summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2018-02-08 16:34:29 +0100
committerThomas Haller <thaller@redhat.com>2018-02-09 17:40:01 +0100
commit1de10532f2b0bbd1fbe3a07d0315ccc90ae5c7a8 (patch)
tree6692a1b7c68602dc985727c9780c98af95c26aa3
parentff61cf1e981b9d9908c3d0dd236483b2e35e6cb7 (diff)
downloadNetworkManager-1de10532f2b0bbd1fbe3a07d0315ccc90ae5c7a8.tar.gz
platform: fix object order in platform cache during dump
Originally, the platform cache did not preserve any stable order. We added that during the large cache rework. However, we still would only care about a particular ordering for route's BY_WEAK_ID index. For all other indexes, it was sufficient to have the object in some arbitrary order, not necessarily the one as indicated by kernel. However, for addresses we actually care about the order (at least, regarding the the OBJECT_BY_IFINDEX index, which is considered by platform's address sync). During a dump we get all objects in the right order. That means, as we (re) insert the objects into the cache, we must forcefully move them to the end of their list. If the object didn't actually change, previously we would not have updated their position in the cache. Fix that now.
-rw-r--r--src/platform/nmp-object.c39
1 files changed, 37 insertions, 2 deletions
diff --git a/src/platform/nmp-object.c b/src/platform/nmp-object.c
index 6605424e9d..4df64e608c 100644
--- a/src/platform/nmp-object.c
+++ b/src/platform/nmp-object.c
@@ -1787,6 +1787,36 @@ _obj_get_add_mode (const NMPObject *obj)
}
static void
+_idxcache_update_order_for_dump (NMPCache *cache,
+ const NMDedupMultiEntry *entry)
+{
+ const NMPClass *klass;
+ const guint8 *i_idx_type;
+ const NMDedupMultiEntry *entry2;
+
+ nm_dedup_multi_entry_reorder (entry, NULL, TRUE);
+
+ klass = NMP_OBJECT_GET_CLASS (entry->obj);
+ for (i_idx_type = klass->supported_cache_ids; *i_idx_type; i_idx_type++) {
+ NMPCacheIdType id_type = *i_idx_type;
+
+ if (id_type == NMP_CACHE_ID_TYPE_OBJECT_TYPE)
+ continue;
+
+ entry2 = nm_dedup_multi_index_lookup_obj (cache->multi_idx,
+ _idx_type_get (cache, id_type),
+ entry->obj);
+ if (!entry2)
+ continue;
+
+ nm_assert (entry2 != entry);
+ nm_assert (entry2->obj == entry->obj);
+
+ nm_dedup_multi_entry_reorder (entry2, NULL, TRUE);
+ }
+}
+
+static void
_idxcache_update_other_cache_ids (NMPCache *cache,
NMPCacheIdType cache_id_type,
const NMPObject *obj_old,
@@ -2180,6 +2210,8 @@ nmp_cache_update_netlink (NMPCache *cache,
}
if (nmp_object_equal (obj_old, obj_hand_over)) {
+ if (is_dump)
+ _idxcache_update_order_for_dump (cache, entry_old);
nm_dedup_multi_entry_set_dirty (entry_old, FALSE);
NM_SET_OUT (out_obj_new, nmp_object_ref (obj_old));
return NMP_CACHE_OPS_UNCHANGED;
@@ -2253,6 +2285,8 @@ nmp_cache_update_netlink_route (NMPCache *cache,
}
if (nmp_object_equal (entry_old->obj, obj_hand_over)) {
+ if (is_dump)
+ _idxcache_update_order_for_dump (cache, entry_old);
nm_dedup_multi_entry_set_dirty (entry_old, FALSE);
goto update_done;
}
@@ -2276,9 +2310,8 @@ update_done:
* properly find @obj_replaced. */
resync_required = FALSE;
entry_replace = NULL;
- if (is_dump) {
+ if (is_dump)
goto out;
- }
if (!entry_new) {
if ( NM_FLAGS_HAS (nlmsgflags, NLM_F_REPLACE)
@@ -2293,6 +2326,8 @@ update_done:
goto out;
}
+ /* FIXME: for routes, we only maintain the order correctly for the BY_WEAK_ID
+ * index. For all other indexes their order becomes messed up. */
entry_cur = _lookup_entry_with_idx_type (cache,
NMP_CACHE_ID_TYPE_ROUTES_BY_WEAK_ID,
entry_new->obj);