Commit 1a1c5fb7 authored by Thomas Haller's avatar Thomas Haller

platform: don't create udev client if udev isn't used

Inside container, where we don't use udev we don't receive
any events from udev client. Thus the client only returns
devices when iterating it initially, but no events for newly
added devices that appear later.

Thus, inside containers we don't want to create a udev client
at all.
parent 6165df78
......@@ -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_signal_connect (priv->udev_client, "uevent", G_CALLBACK (handle_udev_event), platform);
/* 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);
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));
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) {
......
......@@ -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;
}
......
......@@ -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__ */
......@@ -22,6 +22,7 @@
#include <linux/rtnetlink.h>
#include "nm-platform-utils.h"
#include "nm-linux-platform.h"
#include "nm-test-utils.h"
......
......@@ -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);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment