summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2022-02-08 11:56:17 +0100
committerThomas Haller <thaller@redhat.com>2022-02-09 19:13:05 +0100
commit9e90bb081786c4e525b2cc25bdef63f634778b31 (patch)
treeaf6f5abe0626b3ad48f97d0a50d2527103f20260
parent5489aa596b23890480bc64657c96e2997a762f06 (diff)
downloadNetworkManager-9e90bb081786c4e525b2cc25bdef63f634778b31.tar.gz
platform: improve way to prune dirty route-manager entries
The general idea is that when we have entries tracked by the route-manager, that we can mark them all as dirty. Then, calling the "track" function will reset the dirty flag. Finally, there is a method to delete all dirty entries. As we can lookup an entry with O(1) (using dictionaries), we can sync the list of tracked objects with O(n). We just need to track all the ones we care about, and then delete those that were not touched (that is, are still dirty). Previously, we had to explicitly mark all entries as dirty. We can do better. Just let nmp_route_manager_untrack_all() mark the survivors as dirty right away. This way, we can save iterating the list once. It also makes sense because the only purpose of the dirty flag is to aid this prune mechanism with track/untrack-all. So, untrack-all can just help out, and leave the remaining entries dirty, so that the next track does the right thing.
-rw-r--r--src/core/devices/nm-device.c7
-rw-r--r--src/libnm-platform/nmp-route-manager.c6
-rw-r--r--src/libnm-platform/nmp-route-manager.h3
3 files changed, 9 insertions, 7 deletions
diff --git a/src/core/devices/nm-device.c b/src/core/devices/nm-device.c
index 30e0fe8fef..5cb3d27065 100644
--- a/src/core/devices/nm-device.c
+++ b/src/core/devices/nm-device.c
@@ -9301,9 +9301,6 @@ _routing_rules_sync(NMDevice *self, NMTernary set_mode)
int is_ipv4;
untrack_only_dirty = TRUE;
- nmp_route_manager_set_dirty(route_manager, user_tag_1);
- if (klass->get_extra_rules)
- nmp_route_manager_set_dirty(route_manager, user_tag_2);
applied_connection = nm_device_get_applied_connection(self);
@@ -9350,9 +9347,9 @@ _routing_rules_sync(NMDevice *self, NMTernary set_mode)
}
}
- nmp_route_manager_untrack_all(route_manager, user_tag_1, !untrack_only_dirty);
+ nmp_route_manager_untrack_all(route_manager, user_tag_1, !untrack_only_dirty, TRUE);
if (klass->get_extra_rules)
- nmp_route_manager_untrack_all(route_manager, user_tag_2, !untrack_only_dirty);
+ nmp_route_manager_untrack_all(route_manager, user_tag_2, !untrack_only_dirty, TRUE);
keep_deleted_rules = FALSE;
if (set_mode == NM_TERNARY_DEFAULT) {
diff --git a/src/libnm-platform/nmp-route-manager.c b/src/libnm-platform/nmp-route-manager.c
index c5ca02600c..c31c9806a5 100644
--- a/src/libnm-platform/nmp-route-manager.c
+++ b/src/libnm-platform/nmp-route-manager.c
@@ -514,7 +514,8 @@ nmp_route_manager_set_dirty(NMPRouteManager *self, gconstpointer user_tag)
gboolean
nmp_route_manager_untrack_all(NMPRouteManager *self,
gconstpointer user_tag,
- gboolean all /* or only dirty */)
+ gboolean all /* or only dirty */,
+ gboolean make_survivors_dirty)
{
TrackData *track_data;
TrackData *track_data_safe;
@@ -535,7 +536,10 @@ nmp_route_manager_untrack_all(NMPRouteManager *self,
if (all || track_data->dirty) {
_track_data_untrack(self, track_data, FALSE, FALSE);
changed = TRUE;
+ continue;
}
+ if (make_survivors_dirty)
+ track_data->dirty = TRUE;
}
if (c_list_is_empty(&user_tag_data->user_tag_lst_head))
g_hash_table_remove(self->by_user_tag, user_tag_data);
diff --git a/src/libnm-platform/nmp-route-manager.h b/src/libnm-platform/nmp-route-manager.h
index a61a68ca98..97ec3840df 100644
--- a/src/libnm-platform/nmp-route-manager.h
+++ b/src/libnm-platform/nmp-route-manager.h
@@ -69,7 +69,8 @@ void nmp_route_manager_set_dirty(NMPRouteManager *self, gconstpointer user_tag);
gboolean nmp_route_manager_untrack_all(NMPRouteManager *self,
gconstpointer user_tag,
- gboolean all /* or only dirty */);
+ gboolean all /* or only dirty */,
+ gboolean make_survivors_dirty);
void nmp_route_manager_sync(NMPRouteManager *self, NMPObjectType obj_type, gboolean keep_deleted);