Blame SOURCES/0027-rh1269199-assume-external-device-race.patch

ab7d06
From 0551c1cb8106bf3483433fd9da6e391b9c2c2712 Mon Sep 17 00:00:00 2001
ab7d06
From: Thomas Haller <thaller@redhat.com>
ab7d06
Date: Thu, 8 Oct 2015 11:11:42 +0200
ab7d06
Subject: [PATCH 1/1] device: fix race wrongly managing external-down device
ab7d06
 due to late udev signal
ab7d06
ab7d06
Executing:
ab7d06
ab7d06
  # brctl addbr lbr0
ab7d06
  # ip addr add 10.1.1.1/24 dev lbr0
ab7d06
  # ip link set lbr0 up
ab7d06
ab7d06
can result in a race so that NetworkManager would manage the device
ab7d06
(and clear the IP addresses).
ab7d06
ab7d06
It happens, when NetworkManager first receives platform signals that
ab7d06
the device is already up:
ab7d06
ab7d06
    signal: link changed: 11: lbr0 <UP,LOWER_UP;broadcast,multicast,up,running,lowerup> mtu 1500 arp 1 bridge* not-init addrgenmode eui64 addr D2:A1:B4:17:18:F2 driver bridge
ab7d06
ab7d06
Note that the device is still unknown via udev (not-init). The
ab7d06
unmanaged-state NM_UNMANAGED_EXTERNAL_DOWN gets cleared, but the
ab7d06
device still stays unmanaged.
ab7d06
ab7d06
Only afterwards the device is known in udev:
ab7d06
ab7d06
    signal: link changed: 11: lbr0 <UP,LOWER_UP;broadcast,multicast,up,running,lowerup> mtu 1500 arp 1 bridge* init addrgenmode eui64 addr D2:A1:B4:17:18:F2 driver bridge
ab7d06
ab7d06
At this point, we also clear NM_UNMANAGED_PLATFORM_INIT, making
ab7d06
the device managed with reason NM_DEVICE_STATE_REASON_NOW_MANAGED.
ab7d06
That results in managing the external device.
ab7d06
ab7d06
Fix that by only clearing NM_UNMANAGED_EXTERNAL_DOWN after the device
ab7d06
is no longer NM_UNMANAGED_PLATFORM_INIT.
ab7d06
ab7d06
https://bugzilla.redhat.com/show_bug.cgi?id=1269199
ab7d06
ab7d06
(cherry picked from commit e29ab54335c6a5ef1ce6bac525f1f18a8e81b96e)
ab7d06
(cherry picked from commit cde15dda2e513517433e6273ca62e8b8c2c35ccb)
ab7d06
---
ab7d06
 src/devices/nm-device.c | 44 ++++++++++++++++++++++++++------------------
ab7d06
 1 file changed, 26 insertions(+), 18 deletions(-)
ab7d06
ab7d06
diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c
ab7d06
index 83cd6e9..7c49f3f 100644
ab7d06
--- a/src/devices/nm-device.c
ab7d06
+++ b/src/devices/nm-device.c
ab7d06
@@ -1375,6 +1375,8 @@ device_link_changed (NMDevice *self)
ab7d06
 	NMPlatformLink info;
ab7d06
 	const NMPlatformLink *pllink;
ab7d06
 	int ifindex;
ab7d06
+	gboolean emit_link_initialized = FALSE;
ab7d06
+	gboolean was_up;
ab7d06
 
ab7d06
 	priv->device_link_changed_id = 0;
ab7d06
 
ab7d06
@@ -1450,8 +1452,29 @@ device_link_changed (NMDevice *self)
ab7d06
 	if (ip_ifname_changed)
ab7d06
 		update_dynamic_ip_setup (self);
ab7d06
 
ab7d06
-	if (priv->up != NM_FLAGS_HAS (info.flags, IFF_UP)) {
ab7d06
-		priv->up = NM_FLAGS_HAS (info.flags, IFF_UP);
ab7d06
+	if (priv->ifindex > 0 && !priv->platform_link_initialized && info.initialized) {
ab7d06
+		priv->platform_link_initialized = TRUE;
ab7d06
+
ab7d06
+		if (nm_platform_link_get_unmanaged (NM_PLATFORM_GET, priv->ifindex, &platform_unmanaged)) {
ab7d06
+			nm_device_set_unmanaged (self,
ab7d06
+			                         NM_UNMANAGED_DEFAULT,
ab7d06
+			                         platform_unmanaged,
ab7d06
+			                         NM_DEVICE_STATE_REASON_USER_REQUESTED);
ab7d06
+		}
ab7d06
+
ab7d06
+		nm_device_set_unmanaged (self,
ab7d06
+		                         NM_UNMANAGED_PLATFORM_INIT,
ab7d06
+		                         FALSE,
ab7d06
+		                         NM_DEVICE_STATE_REASON_NOW_MANAGED);
ab7d06
+
ab7d06
+		emit_link_initialized = TRUE;
ab7d06
+	}
ab7d06
+
ab7d06
+	was_up = priv->up;
ab7d06
+	priv->up = NM_FLAGS_HAS (info.flags, IFF_UP);
ab7d06
+
ab7d06
+	if (   priv->platform_link_initialized
ab7d06
+	    && (emit_link_initialized || priv->up != was_up)) {
ab7d06
 
ab7d06
 		/* Manage externally-created software interfaces only when they are IFF_UP */
ab7d06
 		g_assert (priv->ifindex > 0);
ab7d06
@@ -1493,23 +1516,8 @@ device_link_changed (NMDevice *self)
ab7d06
 		}
ab7d06
 	}
ab7d06
 
ab7d06
-	if (priv->ifindex > 0 && !priv->platform_link_initialized && info.initialized) {
ab7d06
-		priv->platform_link_initialized = TRUE;
ab7d06
-
ab7d06
-		if (nm_platform_link_get_unmanaged (NM_PLATFORM_GET, priv->ifindex, &platform_unmanaged)) {
ab7d06
-			nm_device_set_unmanaged (self,
ab7d06
-			                         NM_UNMANAGED_DEFAULT,
ab7d06
-			                         platform_unmanaged,
ab7d06
-			                         NM_DEVICE_STATE_REASON_USER_REQUESTED);
ab7d06
-		}
ab7d06
-
ab7d06
-		nm_device_set_unmanaged (self,
ab7d06
-		                         NM_UNMANAGED_PLATFORM_INIT,
ab7d06
-		                         FALSE,
ab7d06
-		                         NM_DEVICE_STATE_REASON_NOW_MANAGED);
ab7d06
-
ab7d06
+	if (emit_link_initialized)
ab7d06
 		g_signal_emit (self, signals[LINK_INITIALIZED], 0);
ab7d06
-	}
ab7d06
 
ab7d06
 	return G_SOURCE_REMOVE;
ab7d06
 }
ab7d06
-- 
ab7d06
2.4.3
ab7d06