Commit c7ccdf5f authored by Thomas Haller's avatar Thomas Haller

libnm/udev: cache and reuse udev instance for NMDevice

No need to create a separate NMUdevClient instance for all devices.
Instead, have one "struct udev" instance in NMClient and pass
it down during object construction.
parent c48c13b8
......@@ -22,6 +22,7 @@
#include "nm-default.h"
#include <string.h>
#include <libudev.h>
#include "nm-utils.h"
#include "nm-client.h"
......@@ -96,6 +97,7 @@ typedef struct {
NMDnsManager *dns_manager;
GDBusObjectManager *object_manager;
GCancellable *new_object_manager_cancellable;
struct udev *udev;
} NMClientPrivate;
enum {
......@@ -2018,8 +2020,9 @@ proxy_type (GDBusObjectManagerClient *manager,
}
static NMObject *
obj_nm_for_gdbus_object (GDBusObject *object, GDBusObjectManager *object_manager)
obj_nm_for_gdbus_object (NMClient *self, GDBusObject *object, GDBusObjectManager *object_manager)
{
NMClientPrivate *priv;
GList *interfaces;
GList *l;
GType type = G_TYPE_INVALID;
......@@ -2111,6 +2114,12 @@ obj_nm_for_gdbus_object (GDBusObject *object, GDBusObjectManager *object_manager
NM_OBJECT_DBUS_OBJECT, object,
NM_OBJECT_DBUS_OBJECT_MANAGER, object_manager,
NULL);
if (NM_IS_DEVICE (object)) {
priv = NM_CLIENT_GET_PRIVATE (self);
if (!priv->udev)
priv->udev = udev_new ();
_nm_device_set_udev (NM_DEVICE (obj_nm), priv->udev);
}
g_object_set_qdata_full (G_OBJECT (object), _nm_object_obj_nm_quark (),
obj_nm, g_object_unref);
return obj_nm;
......@@ -2130,9 +2139,10 @@ obj_nm_inited (GObject *object, GAsyncResult *result, gpointer user_data)
static void
object_added (GDBusObjectManager *object_manager, GDBusObject *object, gpointer user_data)
{
NMClient *client = user_data;
NMObject *obj_nm;
obj_nm = obj_nm_for_gdbus_object (object, object_manager);
obj_nm = obj_nm_for_gdbus_object (client, object, object_manager);
if (obj_nm) {
g_async_initable_init_async (G_ASYNC_INITABLE (obj_nm),
G_PRIORITY_DEFAULT, NULL,
......@@ -2159,7 +2169,7 @@ objects_created (NMClient *client, GDBusObjectManager *object_manager, GError **
/* First just ensure all the NMObjects for known GDBusObjects exist. */
objects = g_dbus_object_manager_get_objects (object_manager);
for (iter = objects; iter; iter = iter->next)
obj_nm_for_gdbus_object (iter->data, object_manager);
obj_nm_for_gdbus_object (client, iter->data, object_manager);
g_list_free_full (objects, g_object_unref);
manager = g_dbus_object_manager_get_object (object_manager, NM_DBUS_PATH);
......@@ -2559,6 +2569,11 @@ dispose (GObject *object)
}
G_OBJECT_CLASS (nm_client_parent_class)->dispose (object);
if (priv->udev) {
udev_unref (priv->udev);
priv->udev = NULL;
}
}
static void
......
......@@ -40,7 +40,6 @@
#include "nm-dbus-helpers.h"
#include "nm-device-tun.h"
#include "nm-setting-connection.h"
#include "nm-utils/nm-udev-utils.h"
#include "introspection/org.freedesktop.NetworkManager.Device.h"
......@@ -80,7 +79,7 @@ typedef struct {
NMActiveConnection *active_connection;
GPtrArray *available_connections;
NMUdevClient *udev_client;
struct udev *udev;
char *product, *short_product;
char *vendor, *short_vendor;
char *description, *bus_name;
......@@ -295,7 +294,8 @@ dispose (GObject *object)
g_clear_object (&priv->dhcp6_config);
g_clear_object (&priv->active_connection);
priv->udev_client = nm_udev_client_unref (priv->udev_client);
udev_unref (priv->udev);
priv->udev = NULL;
g_clear_pointer (&priv->available_connections, g_ptr_array_unref);
g_clear_pointer (&priv->lldp_neighbors, g_ptr_array_unref);
......@@ -1332,16 +1332,19 @@ get_decoded_property (struct udev_device *device, const char *property)
return unescaped;
}
static gboolean
ensure_udev_client (NMDevice *device)
void
_nm_device_set_udev (NMDevice *device, struct udev *udev)
{
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device);
NMDevicePrivate *priv;
if (!priv->udev_client) {
priv->udev_client = nm_udev_client_new ((const char *[]) { "net", "tty", NULL },
NULL, NULL);
}
return !!priv->udev_client;
nm_assert (NM_IS_DEVICE (device));
nm_assert (udev);
priv = NM_DEVICE_GET_PRIVATE (device);
nm_assert (!priv->udev);
priv->udev = udev_ref (udev);
}
static char *
......@@ -1355,16 +1358,16 @@ _get_udev_property (NMDevice *device,
guint32 count = 0;
char *enc_value = NULL, *db_value = NULL;
if (!ensure_udev_client (device))
if (!priv->udev)
return NULL;
ifname = nm_device_get_iface (device);
if (!ifname)
return NULL;
udev_device = udev_device_new_from_subsystem_sysname (nm_udev_client_get_udev (priv->udev_client), "net", ifname);
udev_device = udev_device_new_from_subsystem_sysname (priv->udev, "net", ifname);
if (!udev_device) {
udev_device = udev_device_new_from_subsystem_sysname (nm_udev_client_get_udev (priv->udev_client), "tty", ifname);
udev_device = udev_device_new_from_subsystem_sysname (priv->udev, "tty", ifname);
if (!udev_device)
return NULL;
}
......@@ -1734,16 +1737,16 @@ get_bus_name (NMDevice *device)
if (priv->bus_name)
goto out;
if (!ensure_udev_client (device))
if (!priv->udev)
return NULL;
ifname = nm_device_get_iface (device);
if (!ifname)
return NULL;
udevice = udev_device_new_from_subsystem_sysname (nm_udev_client_get_udev (priv->udev_client), "net", ifname);
udevice = udev_device_new_from_subsystem_sysname (priv->udev, "net", ifname);
if (!udevice) {
udevice = udev_device_new_from_subsystem_sysname (nm_udev_client_get_udev (priv->udev_client), "tty", ifname);
udevice = udev_device_new_from_subsystem_sysname (priv->udev, "tty", ifname);
if (!udevice)
return NULL;
}
......
......@@ -56,4 +56,7 @@ void _nm_object_set_property (NMObject *object,
GDBusProxy *_nm_object_get_proxy (NMObject *object,
const char *interface);
struct udev;
void _nm_device_set_udev (NMDevice *device, struct udev *udev);
#endif /* __NM_OBJECT_PRIVATE_H__ */
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