From c6fb063e0906469beb9c0bbf214052d0d39a145d Mon Sep 17 00:00:00 2001 From: Daniel Drake Date: Mon, 26 Nov 2012 15:02:03 -0500 Subject: [PATCH] core: don't enumerate uninitialized devices from udev (fdo #56929) When enumerating devices, libgudev's matching by default will return devices which udev has not yet finished initializing. This was frequently causing boot-time races on the OLPC XO, where NetworkManager would bring a device up before udev had renamed it, causing the later rename to fail. To solve this, filter the enumeration matches to only include initialized devices. The devices that are present but uninitialized at this time will arrive a short time later, via a uevent. https://bugs.freedesktop.org/show_bug.cgi?id=56929 (dcbw: update gudev version check in configure.ac) --- configure.ac | 2 +- src/nm-udev-manager.c | 14 ++++++++++++-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/configure.ac b/configure.ac index ab92513e5c..64755d9f11 100644 --- a/configure.ac +++ b/configure.ac @@ -226,7 +226,7 @@ GLIB_CFLAGS="$GLIB_CFLAGS $GLIB_VERSION_DEFINES" AC_SUBST(GLIB_CFLAGS) AC_SUBST(GLIB_LIBS) -PKG_CHECK_MODULES(GUDEV, gudev-1.0 >= 147) +PKG_CHECK_MODULES(GUDEV, gudev-1.0 >= 165) AC_SUBST(GUDEV_CFLAGS) AC_SUBST(GUDEV_LIBS) diff --git a/src/nm-udev-manager.c b/src/nm-udev-manager.c index 792e53bfd1..60f41aab29 100644 --- a/src/nm-udev-manager.c +++ b/src/nm-udev-manager.c @@ -515,25 +515,35 @@ void nm_udev_manager_query_devices (NMUdevManager *self) { NMUdevManagerPrivate *priv = NM_UDEV_MANAGER_GET_PRIVATE (self); + GUdevEnumerator *enumerator; GList *devices, *iter; g_return_if_fail (self != NULL); g_return_if_fail (NM_IS_UDEV_MANAGER (self)); - devices = g_udev_client_query_by_subsystem (priv->client, "net"); + enumerator = g_udev_enumerator_new (priv->client); + g_udev_enumerator_add_match_subsystem (enumerator, "net"); + g_udev_enumerator_add_match_is_initialized (enumerator); + + devices = g_udev_enumerator_execute (enumerator); for (iter = devices; iter; iter = g_list_next (iter)) { net_add (self, G_UDEV_DEVICE (iter->data)); g_object_unref (G_UDEV_DEVICE (iter->data)); } g_list_free (devices); + g_object_unref (enumerator); - devices = g_udev_client_query_by_subsystem (priv->client, "atm"); + enumerator = g_udev_enumerator_new (priv->client); + g_udev_enumerator_add_match_subsystem (enumerator, "atm"); + g_udev_enumerator_add_match_is_initialized (enumerator); + devices = g_udev_enumerator_execute (enumerator); for (iter = devices; iter; iter = g_list_next (iter)) { adsl_add (self, G_UDEV_DEVICE (iter->data)); g_object_unref (G_UDEV_DEVICE (iter->data)); } g_list_free (devices); + g_object_unref (enumerator); } static void