summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2015-09-14 15:27:36 +0200
committerThomas Haller <thaller@redhat.com>2015-09-14 16:41:01 +0200
commit234e48f7ef3b49467408ae87bf3ef6e10176cb5d (patch)
treeee8ab87e5d682438901f07cf84974a2d227c9a1a
parent61a05376ad886380be8e4211289341f7d13288f5 (diff)
downloadNetworkManager-th/platform-refresh-link-bgo754996.tar.gz
platform: cancel delayed action REFRESH_LINK when receiving an updateth/platform-refresh-link-bgo754996
When we receive an update for a link, cancel the scheduled REFRESH_LINK delayed-action. At the point when we scheduled refrehing the link, we only cared about receiving a notification that was newer then the current state, i.e. to resync with the actual netlink state. We don't necessarily require to sent a new link-request. This extra work can be saved if we already receive a new update for the link.
-rw-r--r--src/platform/nm-linux-platform.c43
1 files changed, 37 insertions, 6 deletions
diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c
index a7e0bbd938..5f3fc6aacc 100644
--- a/src/platform/nm-linux-platform.c
+++ b/src/platform/nm-linux-platform.c
@@ -1653,6 +1653,33 @@ delayed_action_handle_idle (gpointer user_data)
}
static void
+delayed_action_clear_REFRESH_LINK (NMPlatform *platform, int ifindex)
+{
+ NMLinuxPlatformPrivate *priv;
+ gssize idx;
+ gpointer user_data;
+
+ if (ifindex <= 0)
+ return;
+
+ priv = NM_LINUX_PLATFORM_GET_PRIVATE (platform);
+ if (!NM_FLAGS_HAS (priv->delayed_action.flags, DELAYED_ACTION_TYPE_REFRESH_LINK))
+ return;
+
+ user_data = GINT_TO_POINTER (ifindex);
+
+ idx = _nm_utils_ptrarray_find_first (priv->delayed_action.list_refresh_link->pdata, priv->delayed_action.list_refresh_link->len, user_data);
+ if (idx < 0)
+ return;
+
+ _LOGT_delayed_action (DELAYED_ACTION_TYPE_REFRESH_LINK, user_data, "clear");
+
+ g_ptr_array_remove_index_fast (priv->delayed_action.list_refresh_link, idx);
+ if (priv->delayed_action.list_refresh_link->len == 0)
+ priv->delayed_action.flags &= ~DELAYED_ACTION_TYPE_REFRESH_LINK;
+}
+
+static void
delayed_action_schedule (NMPlatform *platform, DelayedActionType action_type, gpointer user_data)
{
NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE (platform);
@@ -2068,9 +2095,11 @@ do_request_all (NMPlatform *platform, DelayedActionType action_type, gboolean ha
/* clear any delayed action that request a refresh of this object type. */
priv->delayed_action.flags &= ~iflags;
+ _LOGT_delayed_action (iflags, NULL, "handle (do-request-all)");
if (obj_type == NMP_OBJECT_TYPE_LINK) {
priv->delayed_action.flags &= ~DELAYED_ACTION_TYPE_REFRESH_LINK;
g_ptr_array_set_size (priv->delayed_action.list_refresh_link, 0);
+ _LOGT_delayed_action (DELAYED_ACTION_TYPE_REFRESH_LINK, NULL, "clear (do-request-all)");
}
event_handler_read_netlink_all (platform, FALSE);
@@ -2381,12 +2410,14 @@ event_notification (struct nl_msg *msg, gpointer user_data)
switch (msghdr->nlmsg_type) {
case RTM_NEWLINK:
- if ( NMP_OBJECT_GET_TYPE (obj) == NMP_OBJECT_TYPE_LINK
- && g_hash_table_lookup (priv->delayed_deletion, obj) != NULL) {
- /* the object is scheduled for delayed deletion. Replace that object
- * by clearing the value from priv->delayed_deletion. */
- _LOGT ("delayed-deletion: clear delayed deletion of protected object %s", nmp_object_to_string (obj, NMP_OBJECT_TO_STRING_ID, NULL, 0));
- g_hash_table_insert (priv->delayed_deletion, nmp_object_ref (obj), NULL);
+ if (NMP_OBJECT_GET_TYPE (obj) == NMP_OBJECT_TYPE_LINK) {
+ if (g_hash_table_lookup (priv->delayed_deletion, obj) != NULL) {
+ /* the object is scheduled for delayed deletion. Replace that object
+ * by clearing the value from priv->delayed_deletion. */
+ _LOGT ("delayed-deletion: clear delayed deletion of protected object %s", nmp_object_to_string (obj, NMP_OBJECT_TO_STRING_ID, NULL, 0));
+ g_hash_table_insert (priv->delayed_deletion, nmp_object_ref (obj), NULL);
+ }
+ delayed_action_clear_REFRESH_LINK (platform, obj->link.ifindex);
}
/* fall-through */
case RTM_NEWADDR: