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.
This commit is contained in:
Thomas Haller
2017-03-20 12:27:17 +01:00
parent c48c13b8e5
commit c7ccdf5fc8
3 changed files with 41 additions and 20 deletions

View File

@@ -22,6 +22,7 @@
#include "nm-default.h" #include "nm-default.h"
#include <string.h> #include <string.h>
#include <libudev.h>
#include "nm-utils.h" #include "nm-utils.h"
#include "nm-client.h" #include "nm-client.h"
@@ -96,6 +97,7 @@ typedef struct {
NMDnsManager *dns_manager; NMDnsManager *dns_manager;
GDBusObjectManager *object_manager; GDBusObjectManager *object_manager;
GCancellable *new_object_manager_cancellable; GCancellable *new_object_manager_cancellable;
struct udev *udev;
} NMClientPrivate; } NMClientPrivate;
enum { enum {
@@ -2018,8 +2020,9 @@ proxy_type (GDBusObjectManagerClient *manager,
} }
static NMObject * 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 *interfaces;
GList *l; GList *l;
GType type = G_TYPE_INVALID; 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, object,
NM_OBJECT_DBUS_OBJECT_MANAGER, object_manager, NM_OBJECT_DBUS_OBJECT_MANAGER, object_manager,
NULL); 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 (), g_object_set_qdata_full (G_OBJECT (object), _nm_object_obj_nm_quark (),
obj_nm, g_object_unref); obj_nm, g_object_unref);
return obj_nm; return obj_nm;
@@ -2130,9 +2139,10 @@ obj_nm_inited (GObject *object, GAsyncResult *result, gpointer user_data)
static void static void
object_added (GDBusObjectManager *object_manager, GDBusObject *object, gpointer user_data) object_added (GDBusObjectManager *object_manager, GDBusObject *object, gpointer user_data)
{ {
NMClient *client = user_data;
NMObject *obj_nm; 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) { if (obj_nm) {
g_async_initable_init_async (G_ASYNC_INITABLE (obj_nm), g_async_initable_init_async (G_ASYNC_INITABLE (obj_nm),
G_PRIORITY_DEFAULT, NULL, 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. */ /* First just ensure all the NMObjects for known GDBusObjects exist. */
objects = g_dbus_object_manager_get_objects (object_manager); objects = g_dbus_object_manager_get_objects (object_manager);
for (iter = objects; iter; iter = iter->next) 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); g_list_free_full (objects, g_object_unref);
manager = g_dbus_object_manager_get_object (object_manager, NM_DBUS_PATH); 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); G_OBJECT_CLASS (nm_client_parent_class)->dispose (object);
if (priv->udev) {
udev_unref (priv->udev);
priv->udev = NULL;
}
} }
static void static void

View File

@@ -40,7 +40,6 @@
#include "nm-dbus-helpers.h" #include "nm-dbus-helpers.h"
#include "nm-device-tun.h" #include "nm-device-tun.h"
#include "nm-setting-connection.h" #include "nm-setting-connection.h"
#include "nm-utils/nm-udev-utils.h"
#include "introspection/org.freedesktop.NetworkManager.Device.h" #include "introspection/org.freedesktop.NetworkManager.Device.h"
@@ -80,7 +79,7 @@ typedef struct {
NMActiveConnection *active_connection; NMActiveConnection *active_connection;
GPtrArray *available_connections; GPtrArray *available_connections;
NMUdevClient *udev_client; struct udev *udev;
char *product, *short_product; char *product, *short_product;
char *vendor, *short_vendor; char *vendor, *short_vendor;
char *description, *bus_name; char *description, *bus_name;
@@ -295,7 +294,8 @@ dispose (GObject *object)
g_clear_object (&priv->dhcp6_config); g_clear_object (&priv->dhcp6_config);
g_clear_object (&priv->active_connection); 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->available_connections, g_ptr_array_unref);
g_clear_pointer (&priv->lldp_neighbors, 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; return unescaped;
} }
static gboolean void
ensure_udev_client (NMDevice *device) _nm_device_set_udev (NMDevice *device, struct udev *udev)
{ {
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device); NMDevicePrivate *priv;
if (!priv->udev_client) { nm_assert (NM_IS_DEVICE (device));
priv->udev_client = nm_udev_client_new ((const char *[]) { "net", "tty", NULL }, nm_assert (udev);
NULL, NULL);
} priv = NM_DEVICE_GET_PRIVATE (device);
return !!priv->udev_client;
nm_assert (!priv->udev);
priv->udev = udev_ref (udev);
} }
static char * static char *
@@ -1355,16 +1358,16 @@ _get_udev_property (NMDevice *device,
guint32 count = 0; guint32 count = 0;
char *enc_value = NULL, *db_value = NULL; char *enc_value = NULL, *db_value = NULL;
if (!ensure_udev_client (device)) if (!priv->udev)
return NULL; return NULL;
ifname = nm_device_get_iface (device); ifname = nm_device_get_iface (device);
if (!ifname) if (!ifname)
return NULL; 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) { 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) if (!udev_device)
return NULL; return NULL;
} }
@@ -1734,16 +1737,16 @@ get_bus_name (NMDevice *device)
if (priv->bus_name) if (priv->bus_name)
goto out; goto out;
if (!ensure_udev_client (device)) if (!priv->udev)
return NULL; return NULL;
ifname = nm_device_get_iface (device); ifname = nm_device_get_iface (device);
if (!ifname) if (!ifname)
return NULL; 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) { 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) if (!udevice)
return NULL; return NULL;
} }

View File

@@ -56,4 +56,7 @@ void _nm_object_set_property (NMObject *object,
GDBusProxy *_nm_object_get_proxy (NMObject *object, GDBusProxy *_nm_object_get_proxy (NMObject *object,
const char *interface); const char *interface);
struct udev;
void _nm_device_set_udev (NMDevice *device, struct udev *udev);
#endif /* __NM_OBJECT_PRIVATE_H__ */ #endif /* __NM_OBJECT_PRIVATE_H__ */