Blame SOURCES/0020-rh1264361-platform-link-cache.patch

ab7d06
From 891e3b8f1bd14d4f7eea689ec3f0d7c1845d0ccd Mon Sep 17 00:00:00 2001
ab7d06
From: Thomas Haller <thaller@redhat.com>
ab7d06
Date: Mon, 14 Sep 2015 16:40:51 +0200
ab7d06
Subject: [PATCH 1/3] platform: fix handling refresh-link delayed actions
ab7d06
ab7d06
Due to a bug, we would only handle one REFRESH_LINK delayed action
ab7d06
and ignore the ones queued afterwards.
ab7d06
ab7d06
Fixes: 051cf8bbde9b73cdb3718be94e78237758b451ff
ab7d06
(cherry picked from commit eee240ffe82d1cf4e3e84688a37fbdc215c119d0)
ab7d06
(cherry picked from commit bdbc3bbb7b919307b0a353b5de6bb1369127df5d)
ab7d06
---
ab7d06
 src/platform/nm-linux-platform.c | 2 +-
ab7d06
 1 file changed, 1 insertion(+), 1 deletion(-)
ab7d06
ab7d06
diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c
ab7d06
index cd0a4e0..cc24707 100644
ab7d06
--- a/src/platform/nm-linux-platform.c
ab7d06
+++ b/src/platform/nm-linux-platform.c
ab7d06
@@ -1617,7 +1617,7 @@ delayed_action_handle_one (NMPlatform *platform)
ab7d06
 
ab7d06
 	user_data = priv->delayed_action.list_refresh_link->pdata[0];
ab7d06
 	g_ptr_array_remove_index_fast (priv->delayed_action.list_refresh_link, 0);
ab7d06
-	if (priv->delayed_action.list_master_connected->len == 0)
ab7d06
+	if (priv->delayed_action.list_refresh_link->len == 0)
ab7d06
 		priv->delayed_action.flags &= ~DELAYED_ACTION_TYPE_REFRESH_LINK;
ab7d06
 	nm_assert (_nm_utils_ptrarray_find_first (priv->delayed_action.list_refresh_link->pdata, priv->delayed_action.list_refresh_link->len, user_data) < 0);
ab7d06
 
ab7d06
-- 
ab7d06
2.4.3
ab7d06
ab7d06
ab7d06
From 211a064f15cbcc63374f14d39d939f0ab6c1070f Mon Sep 17 00:00:00 2001
ab7d06
From: Thomas Haller <thaller@redhat.com>
ab7d06
Date: Mon, 14 Sep 2015 15:05:00 +0200
ab7d06
Subject: [PATCH 2/3] platform: refresh links when parent gets removed
ab7d06
ab7d06
When moving a link to another netns, it gets removed from
ab7d06
NMPlatform's view.
ab7d06
ab7d06
Currently kernel does not sent a notification to inform about
ab7d06
that change (see related bug rh#1262908).
ab7d06
ab7d06
Ensure that we reload all linked interfaces which now might
ab7d06
have an invisible parent.
ab7d06
ab7d06
(cherry picked from commit 2cd6aaa918333813879c97f7a1cb228e706a0586)
ab7d06
(cherry picked from commit e79caf9b4ad888e9d78c4256f402b9eb8a524641)
ab7d06
---
ab7d06
 src/platform/nm-linux-platform.c | 31 +++++++++++++++++++++++++++++++
ab7d06
 1 file changed, 31 insertions(+)
ab7d06
ab7d06
diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c
ab7d06
index cc24707..6b65135 100644
ab7d06
--- a/src/platform/nm-linux-platform.c
ab7d06
+++ b/src/platform/nm-linux-platform.c
ab7d06
@@ -1869,6 +1869,37 @@ cache_pre_hook (NMPCache *cache, const NMPObject *old, const NMPObject *new, NMP
ab7d06
 			}
ab7d06
 		}
ab7d06
 		{
ab7d06
+			int ifindex = -1;
ab7d06
+
ab7d06
+			/* removal of a link could be caused by moving the link to another netns.
ab7d06
+			 * In this case, we potentially have to update other links that have this link as parent.
ab7d06
+			 * Currently, kernel misses to sent us a notification in this case (rh #1262908). */
ab7d06
+
ab7d06
+			if (   ops_type == NMP_CACHE_OPS_REMOVED
ab7d06
+			    && old /* <-- nonsensical, make coverity happy */
ab7d06
+			    && old->_link.netlink.is_in_netlink)
ab7d06
+				ifindex = old->link.ifindex;
ab7d06
+			else if (   ops_type == NMP_CACHE_OPS_UPDATED
ab7d06
+			         && old && new /* <-- nonsensical, make coverity happy */
ab7d06
+			         && old->_link.netlink.is_in_netlink
ab7d06
+			         && !new->_link.netlink.is_in_netlink)
ab7d06
+				ifindex = new->link.ifindex;
ab7d06
+
ab7d06
+			if (ifindex > 0) {
ab7d06
+				const NMPlatformLink *const *links;
ab7d06
+
ab7d06
+				links = cache_lookup_all_objects (NMPlatformLink, platform, NMP_OBJECT_TYPE_LINK, FALSE);
ab7d06
+				if (links) {
ab7d06
+					for (; *links; links++) {
ab7d06
+						const NMPlatformLink *l = (*links);
ab7d06
+
ab7d06
+						if (l->parent == ifindex)
ab7d06
+							delayed_action_schedule (platform, DELAYED_ACTION_TYPE_REFRESH_LINK, GINT_TO_POINTER (l->ifindex));
ab7d06
+					}
ab7d06
+				}
ab7d06
+			}
ab7d06
+		}
ab7d06
+		{
ab7d06
 			/* if a link goes down, we must refresh routes */
ab7d06
 			if (   ops_type == NMP_CACHE_OPS_UPDATED
ab7d06
 			    && old && new /* <-- nonsensical, make coverity happy */
ab7d06
-- 
ab7d06
2.4.3
ab7d06
ab7d06
ab7d06
From 729222d9e2997f262e070c1820b742e6aea07fa7 Mon Sep 17 00:00:00 2001
ab7d06
From: Thomas Haller <thaller@redhat.com>
ab7d06
Date: Mon, 14 Sep 2015 15:27:36 +0200
ab7d06
Subject: [PATCH 3/3] platform: cancel delayed action REFRESH_LINK when
ab7d06
 receiving an update
ab7d06
ab7d06
When we receive an update for a link, cancel a scheduled
ab7d06
REFRESH_LINK delayed-action for that ifindex. At the point when we
ab7d06
scheduled refrehing the link, we only cared about receiving a
ab7d06
notification that was newer then the current state.
ab7d06
ab7d06
We scheduled requesting this new notification to resync the cache.
ab7d06
It is not necessary to actually request a new update, any update we
ab7d06
receive *after* requesting a new update will suffice.
ab7d06
ab7d06
This potentially saves extra round-trips re-requesting the link.
ab7d06
ab7d06
(cherry picked from commit f4f4e1cf092ce5236aa9394ad5c485ad1c5885c2)
ab7d06
(cherry picked from commit 91c00072f2fd23e90a840a7c466c3ed95217eb68)
ab7d06
---
ab7d06
 src/platform/nm-linux-platform.c | 43 ++++++++++++++++++++++++++++++++++------
ab7d06
 1 file changed, 37 insertions(+), 6 deletions(-)
ab7d06
ab7d06
diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c
ab7d06
index 6b65135..ac6bb05 100644
ab7d06
--- a/src/platform/nm-linux-platform.c
ab7d06
+++ b/src/platform/nm-linux-platform.c
ab7d06
@@ -1653,6 +1653,33 @@ delayed_action_handle_idle (gpointer user_data)
ab7d06
 }
ab7d06
 
ab7d06
 static void
ab7d06
+delayed_action_clear_REFRESH_LINK (NMPlatform *platform, int ifindex)
ab7d06
+{
ab7d06
+	NMLinuxPlatformPrivate *priv;
ab7d06
+	gssize idx;
ab7d06
+	gpointer user_data;
ab7d06
+
ab7d06
+	if (ifindex <= 0)
ab7d06
+		return;
ab7d06
+
ab7d06
+	priv = NM_LINUX_PLATFORM_GET_PRIVATE (platform);
ab7d06
+	if (!NM_FLAGS_HAS (priv->delayed_action.flags, DELAYED_ACTION_TYPE_REFRESH_LINK))
ab7d06
+		return;
ab7d06
+
ab7d06
+	user_data = GINT_TO_POINTER (ifindex);
ab7d06
+
ab7d06
+	idx = _nm_utils_ptrarray_find_first (priv->delayed_action.list_refresh_link->pdata, priv->delayed_action.list_refresh_link->len, user_data);
ab7d06
+	if (idx < 0)
ab7d06
+		return;
ab7d06
+
ab7d06
+	_LOGT_delayed_action (DELAYED_ACTION_TYPE_REFRESH_LINK, user_data, "clear");
ab7d06
+
ab7d06
+	g_ptr_array_remove_index_fast (priv->delayed_action.list_refresh_link, idx);
ab7d06
+	if (priv->delayed_action.list_refresh_link->len == 0)
ab7d06
+		priv->delayed_action.flags &= ~DELAYED_ACTION_TYPE_REFRESH_LINK;
ab7d06
+}
ab7d06
+
ab7d06
+static void
ab7d06
 delayed_action_schedule (NMPlatform *platform, DelayedActionType action_type, gpointer user_data)
ab7d06
 {
ab7d06
 	NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE (platform);
ab7d06
@@ -2069,9 +2096,11 @@ do_request_all (NMPlatform *platform, DelayedActionType action_type, gboolean ha
ab7d06
 
ab7d06
 			/* clear any delayed action that request a refresh of this object type. */
ab7d06
 			priv->delayed_action.flags &= ~iflags;
ab7d06
+			_LOGT_delayed_action (iflags, NULL, "handle (do-request-all)");
ab7d06
 			if (obj_type == NMP_OBJECT_TYPE_LINK) {
ab7d06
 				priv->delayed_action.flags &= ~DELAYED_ACTION_TYPE_REFRESH_LINK;
ab7d06
 				g_ptr_array_set_size (priv->delayed_action.list_refresh_link, 0);
ab7d06
+				_LOGT_delayed_action (DELAYED_ACTION_TYPE_REFRESH_LINK, NULL, "clear (do-request-all)");
ab7d06
 			}
ab7d06
 
ab7d06
 			event_handler_read_netlink_all (platform, FALSE);
ab7d06
@@ -2382,12 +2411,14 @@ event_notification (struct nl_msg *msg, gpointer user_data)
ab7d06
 		switch (msghdr->nlmsg_type) {
ab7d06
 
ab7d06
 		case RTM_NEWLINK:
ab7d06
-			if (   NMP_OBJECT_GET_TYPE (obj) == NMP_OBJECT_TYPE_LINK
ab7d06
-			    && g_hash_table_lookup (priv->delayed_deletion, obj) != NULL) {
ab7d06
-				/* the object is scheduled for delayed deletion. Replace that object
ab7d06
-				 * by clearing the value from priv->delayed_deletion. */
ab7d06
-				_LOGT ("delayed-deletion: clear delayed deletion of protected object %s", nmp_object_to_string (obj, NMP_OBJECT_TO_STRING_ID, NULL, 0));
ab7d06
-				g_hash_table_insert (priv->delayed_deletion, nmp_object_ref (obj), NULL);
ab7d06
+			if (NMP_OBJECT_GET_TYPE (obj) == NMP_OBJECT_TYPE_LINK) {
ab7d06
+				if (g_hash_table_lookup (priv->delayed_deletion, obj) != NULL) {
ab7d06
+					/* the object is scheduled for delayed deletion. Replace that object
ab7d06
+					 * by clearing the value from priv->delayed_deletion. */
ab7d06
+					_LOGT ("delayed-deletion: clear delayed deletion of protected object %s", nmp_object_to_string (obj, NMP_OBJECT_TO_STRING_ID, NULL, 0));
ab7d06
+					g_hash_table_insert (priv->delayed_deletion, nmp_object_ref (obj), NULL);
ab7d06
+				}
ab7d06
+				delayed_action_clear_REFRESH_LINK (platform, obj->link.ifindex);
ab7d06
 			}
ab7d06
 			/* fall-through */
ab7d06
 		case RTM_NEWADDR:
ab7d06
-- 
ab7d06
2.4.3
ab7d06