diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c index 33e3ddf8e2..72ca62a71b 100644 --- a/src/platform/nm-linux-platform.c +++ b/src/platform/nm-linux-platform.c @@ -5937,15 +5937,21 @@ static void nm_linux_platform_init (NMLinuxPlatform *self) { NMLinuxPlatformPrivate *priv = G_TYPE_INSTANCE_GET_PRIVATE (self, NM_TYPE_LINUX_PLATFORM, NMLinuxPlatformPrivate); + gboolean use_udev; + + use_udev = access ("/sys", W_OK) == 0; self->priv = priv; priv->nlh_seq_next = 1; - priv->cache = nmp_cache_new (); + priv->cache = nmp_cache_new (use_udev); priv->delayed_action.list_master_connected = g_ptr_array_new (); priv->delayed_action.list_refresh_link = g_ptr_array_new (); priv->delayed_action.list_wait_for_nl_response = g_array_new (FALSE, TRUE, sizeof (DelayedActionWaitForNlResponseData)); priv->wifi_data = g_hash_table_new_full (NULL, NULL, NULL, (GDestroyNotify) wifi_utils_deinit); + + if (use_udev) + priv->udev_client = g_udev_client_new ((const char *[]) { "net", NULL }); } static void @@ -5953,14 +5959,12 @@ constructed (GObject *_object) { NMPlatform *platform = NM_PLATFORM (_object); NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE (platform); - const char *udev_subsys[] = { "net", NULL }; int channel_flags; gboolean status; int nle; - GUdevEnumerator *enumerator; - GList *devices, *iter; - _LOGD ("create"); + _LOGD ("create (%s udev)", + nmp_cache_use_udev_get (priv->cache) ? "use" : "no"); priv->nlh = nl_socket_alloc (); g_assert (priv->nlh); @@ -5992,16 +5996,12 @@ constructed (GObject *_object) channel_flags = g_io_channel_get_flags (priv->event_channel); status = g_io_channel_set_flags (priv->event_channel, - channel_flags | G_IO_FLAG_NONBLOCK, NULL); + channel_flags | G_IO_FLAG_NONBLOCK, NULL); g_assert (status); priv->event_id = g_io_add_watch (priv->event_channel, (EVENT_CONDITIONS | ERROR_CONDITIONS | DISCONNECT_CONDITIONS), event_handler, platform); - /* Set up udev monitoring */ - priv->udev_client = g_udev_client_new (udev_subsys); - g_signal_connect (priv->udev_client, "uevent", G_CALLBACK (handle_udev_event), platform); - /* complete construction of the GObject instance before populating the cache. */ G_OBJECT_CLASS (nm_linux_platform_parent_class)->constructed (_object); @@ -6016,19 +6016,27 @@ constructed (GObject *_object) delayed_action_handle_all (platform, FALSE); - /* And read initial device list */ - enumerator = g_udev_enumerator_new (priv->udev_client); - g_udev_enumerator_add_match_subsystem (enumerator, "net"); + /* Set up udev monitoring */ + if (priv->udev_client) { + GUdevEnumerator *enumerator; + GList *devices, *iter; - g_udev_enumerator_add_match_is_initialized (enumerator); + g_signal_connect (priv->udev_client, "uevent", G_CALLBACK (handle_udev_event), platform); - devices = g_udev_enumerator_execute (enumerator); - for (iter = devices; iter; iter = g_list_next (iter)) { - udev_device_added (platform, G_UDEV_DEVICE (iter->data)); - g_object_unref (G_UDEV_DEVICE (iter->data)); + /* And read initial device list */ + enumerator = g_udev_enumerator_new (priv->udev_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)) { + udev_device_added (platform, G_UDEV_DEVICE (iter->data)); + g_object_unref (G_UDEV_DEVICE (iter->data)); + } + g_list_free (devices); + g_object_unref (enumerator); } - g_list_free (devices); - g_object_unref (enumerator); } static void @@ -6047,6 +6055,11 @@ dispose (GObject *object) g_clear_pointer (&priv->prune_candidates, g_hash_table_unref); + if (priv->udev_client) { + g_signal_handlers_disconnect_by_func (priv->udev_client, G_CALLBACK (handle_udev_event), platform); + g_clear_object (&priv->udev_client); + } + G_OBJECT_CLASS (nm_linux_platform_parent_class)->dispose (object); } @@ -6066,7 +6079,6 @@ nm_linux_platform_finalize (GObject *object) g_io_channel_unref (priv->event_channel); nl_socket_free (priv->nlh); - g_object_unref (priv->udev_client); g_hash_table_unref (priv->wifi_data); if (priv->sysctl_get_prev_values) { diff --git a/src/platform/nmp-object.c b/src/platform/nmp-object.c index b7b04490c1..adeb3aabe3 100644 --- a/src/platform/nmp-object.c +++ b/src/platform/nmp-object.c @@ -174,10 +174,6 @@ _nmp_object_fixup_link_udev_fields (NMPObject *obj, gboolean use_udev) * nmp_cache_use_udev_get(). It is on purpose not to test * for a writable /sys on every call. A minor reason for that is * performance, but the real reason is reproducibility. - * - * If you want to support changing of whether udev is enabled, - * reset the value via nmp_cache_use_udev_set() carefully -- and - * possibly update the links in the cache accordingly. * */ initialized = TRUE; } @@ -1191,12 +1187,6 @@ _vt_cmd_obj_init_cache_id_ipx_route (const NMPObject *obj, NMPCacheIdType id_typ /******************************************************************/ -gboolean -nmp_cache_use_udev_detect () -{ - return access ("/sys", W_OK) == 0; -} - gboolean nmp_cache_use_udev_get (const NMPCache *cache) { @@ -1205,19 +1195,6 @@ nmp_cache_use_udev_get (const NMPCache *cache) return cache->use_udev; } -gboolean -nmp_cache_use_udev_set (NMPCache *cache, gboolean use_udev) -{ - g_return_val_if_fail (cache, FALSE); - - use_udev = !!use_udev; - if (use_udev == cache->use_udev) - return FALSE; - - cache->use_udev = use_udev; - return TRUE; -} - /******************************************************************/ /** @@ -1858,7 +1835,7 @@ nmp_cache_update_link_master_connected (NMPCache *cache, int ifindex, NMPObject /******************************************************************/ NMPCache * -nmp_cache_new () +nmp_cache_new (gboolean use_udev) { NMPCache *cache = g_new (NMPCache, 1); @@ -1870,7 +1847,7 @@ nmp_cache_new () (NMMultiIndexFuncEqual) nmp_cache_id_equal, (NMMultiIndexFuncClone) nmp_cache_id_clone, (NMMultiIndexFuncDestroy) nmp_cache_id_destroy); - cache->use_udev = nmp_cache_use_udev_detect (); + cache->use_udev = !!use_udev; return cache; } diff --git a/src/platform/nmp-object.h b/src/platform/nmp-object.h index 7758798f33..6d5b9627ce 100644 --- a/src/platform/nmp-object.h +++ b/src/platform/nmp-object.h @@ -399,9 +399,7 @@ GHashTable *nmp_cache_lookup_all_to_hash (const NMPCache *cache, gboolean nmp_cache_link_connected_needs_toggle (const NMPCache *cache, const NMPObject *master, const NMPObject *potential_slave, const NMPObject *ignore_slave); const NMPObject *nmp_cache_link_connected_needs_toggle_by_ifindex (const NMPCache *cache, int master_ifindex, const NMPObject *potential_slave, const NMPObject *ignore_slave); -gboolean nmp_cache_use_udev_detect (void); gboolean nmp_cache_use_udev_get (const NMPCache *cache); -gboolean nmp_cache_use_udev_set (NMPCache *cache, gboolean use_udev); void ASSERT_nmp_cache_is_consistent (const NMPCache *cache); @@ -411,7 +409,7 @@ NMPCacheOpsType nmp_cache_update_netlink (NMPCache *cache, NMPObject *obj, NMPOb NMPCacheOpsType nmp_cache_update_link_udev (NMPCache *cache, int ifindex, GUdevDevice *udev_device, NMPObject **out_obj, gboolean *out_was_visible, NMPCachePreHook pre_hook, gpointer user_data); NMPCacheOpsType nmp_cache_update_link_master_connected (NMPCache *cache, int ifindex, NMPObject **out_obj, gboolean *out_was_visible, NMPCachePreHook pre_hook, gpointer user_data); -NMPCache *nmp_cache_new (void); +NMPCache *nmp_cache_new (gboolean use_udev); void nmp_cache_free (NMPCache *cache); #endif /* __NMP_OBJECT_H__ */ diff --git a/src/platform/tests/test-general.c b/src/platform/tests/test-general.c index eb5adb9541..66f72fa570 100644 --- a/src/platform/tests/test-general.c +++ b/src/platform/tests/test-general.c @@ -22,6 +22,7 @@ #include +#include "nm-platform-utils.h" #include "nm-linux-platform.h" #include "nm-test-utils.h" diff --git a/src/platform/tests/test-nmp-object.c b/src/platform/tests/test-nmp-object.c index 3b44abb8d6..d77170b364 100644 --- a/src/platform/tests/test-nmp-object.c +++ b/src/platform/tests/test-nmp-object.c @@ -223,9 +223,7 @@ test_cache_link (void) GUdevDevice *udev_device_3 = g_list_nth_data (global.udev_devices, 0); NMPCacheOpsType ops_type; - cache = nmp_cache_new (); - - nmp_cache_use_udev_set (cache, g_rand_int_range (nmtst_get_rand (), 0, 2)); + cache = nmp_cache_new (nmtst_get_rand_int () % 2); /* if we have a link, and don't set is_in_netlink, adding it has no effect. */ obj1 = nmp_object_new (NMP_OBJECT_TYPE_LINK, (NMPlatformObject *) &pl_link_2);