udev: drop libgudev in favor of libudev

libgudev is just a wrapper around libudev. We can
use libudev directly and drop the dependency for
libgudev.
This commit is contained in:
Thomas Haller 2017-03-12 15:54:02 +01:00
parent edaa7d064e
commit e32839838e
22 changed files with 724 additions and 374 deletions

View File

@ -3,7 +3,7 @@ before_install:
- sudo apt-get update
- sudo apt-get install autoconf libtool pkg-config intltool libdbus-glib-1-dev libdbus-1-dev libiw-dev libglib2.0-dev
libnl-3-dev libnl-route-3-dev libnl-genl-3-dev ppp-dev libpolkit-gobject-1-dev libgnutls28-dev libgcrypt11-dev
uuid-dev libudev-dev libgudev-1.0-dev libgirepository1.0-dev gobject-introspection libsoup2.4-dev gtk-doc-tools
uuid-dev libudev-dev libgirepository1.0-dev gobject-introspection libsoup2.4-dev gtk-doc-tools
libglib2.0-doc libreadline-dev libnewt-dev libnss3-dev iptables make python-software-properties python-gi
python-dbus dbus dbus-x11 libjansson4 libjansson-dev
- sudo dbus-uuidgen --ensure

View File

@ -414,6 +414,7 @@ libnm_core_lib_h_pub_mkenums = \
libnm-core/nm-core-enum-types.h
libnm_core_lib_h_priv = \
shared/nm-utils/nm-shared-utils.h \
shared/nm-utils/nm-udev-utils.h \
shared/nm-setting-metadata.h \
libnm-core/crypto.h \
libnm-core/nm-connection-private.h \
@ -426,6 +427,7 @@ libnm_core_lib_h_priv = \
libnm-core/nm-utils-private.h
libnm_core_lib_c_real = \
shared/nm-utils/nm-shared-utils.c \
shared/nm-utils/nm-udev-utils.c \
shared/nm-setting-metadata.c \
libnm-core/crypto.c \
libnm-core/nm-connection.c \
@ -491,7 +493,8 @@ dflt_cppflags_libnm_core = \
-I$(srcdir)/libnm-core \
-I$(builddir)/libnm-core \
$(CODE_COVERAGE_CFLAGS) \
$(GLIB_CFLAGS)
$(GLIB_CFLAGS) \
$(LIBUDEV_CFLAGS)
if WITH_JANSSON
dflt_cppflags_libnm_core += $(JANSSON_CFLAGS)
@ -556,7 +559,8 @@ nodist_libnm_core_libnm_core_la_SOURCES = \
libnm_core_libnm_core_la_LIBADD = \
$(GLIB_LIBS) \
$(UUID_LIBS)
$(UUID_LIBS) \
$(LIBUDEV_LIBS)
if WITH_JANSSON
libnm_core_libnm_core_la_LIBADD += $(JANSSON_LIBS)
@ -810,7 +814,7 @@ libnm_libnm_la_CPPFLAGS = \
$(dflt_cppflags_libnm_core) \
-I$(srcdir)/libnm \
-I$(builddir)/libnm \
$(GUDEV_CFLAGS) \
$(LIBUDEV_CFLAGS) \
-DG_LOG_DOMAIN=\""libnm"\" \
-DNETWORKMANAGER_COMPILATION=NM_NETWORKMANAGER_COMPILATION_LIB \
-DNMRUNDIR=\"$(nmrundir)\"
@ -834,7 +838,7 @@ libnm_libnm_la_LIBADD = \
$(DL_LIBS) \
$(GLIB_LIBS) \
$(UUID_LIBS) \
$(GUDEV_LIBS)
$(LIBUDEV_LIBS)
libnm_libnm_la_LDFLAGS = \
-Wl,--version-script="$(srcdir)/libnm/libnm.ver" \
@ -859,7 +863,7 @@ EXTRA_DIST += \
if HAVE_INTROSPECTION
libnm/NM-1.0.gir: libnm/libnm.la
libnm_NM_1_0_gir_INCLUDES = Gio-2.0
libnm_NM_1_0_gir_PACKAGES = gio-2.0 gudev-1.0
libnm_NM_1_0_gir_PACKAGES = gio-2.0
libnm_NM_1_0_gir_EXPORT_PACKAGES = libnm
libnm_NM_1_0_gir_CFLAGS = $(libnm_libnm_la_CPPFLAGS)
libnm_NM_1_0_gir_LIBS = libnm/libnm.la
@ -1031,7 +1035,7 @@ src_cppflags = \
-DDHCLIENT_PATH=\"$(DHCLIENT_PATH)\" \
-DDHCPCD_PATH=\"$(DHCPCD_PATH)\" \
\
$(GUDEV_CFLAGS) \
$(LIBUDEV_CFLAGS) \
$(LIBNL_CFLAGS) \
$(LIBNDP_CFLAGS) \
$(LIBPSL_CFLAGS) \
@ -1288,6 +1292,7 @@ src_libNetworkManagerBase_la_LIBADD = \
introspection/libnmdbus.la \
$(GLIB_LIBS) \
$(SYSTEMD_JOURNAL_LIBS) \
$(LIBUDEV_LIBS) \
$(NULL)
###############################################################################
@ -1463,7 +1468,7 @@ src_libNetworkManager_la_LIBADD = \
src/libNetworkManagerBase.la \
src/libsystemd-nm.la \
$(GLIB_LIBS) \
$(GUDEV_LIBS) \
$(LIBUDEV_LIBS) \
$(LIBNL_LIBS) \
$(SYSTEMD_LOGIN_LIBS) \
$(LIBNDP_LIBS) \
@ -1502,7 +1507,7 @@ src_libNetworkManagerTest_la_LIBADD = \
src/libNetworkManager.la \
$(CODE_COVERAGE_LDFLAGS) \
$(GLIB_LIBS) \
$(GUDEV_LIBS) \
$(LIBUDEV_LIBS) \
$(LIBNL_LIBS)
###############################################################################
@ -1538,7 +1543,7 @@ src_nm_iface_helper_LDADD = \
src/libNetworkManagerBase.la \
src/libsystemd-nm.la \
$(GLIB_LIBS) \
$(GUDEV_LIBS) \
$(LIBUDEV_LIBS) \
$(LIBNL_LIBS) \
$(LIBNDP_LIBS) \
$(DL_LIBS) \
@ -2131,7 +2136,7 @@ src_settings_plugins_ifupdown_cppflags = \
-DG_LOG_DOMAIN=\""NetworkManager"\" \
-DNETWORKMANAGER_COMPILATION=NM_NETWORKMANAGER_COMPILATION_INSIDE_DAEMON \
$(GLIB_CFLAGS) \
$(GUDEV_CFLAGS) \
$(LIBUDEV_CFLAGS) \
-DSYSCONFDIR=\"$(sysconfdir)\"
@ -2143,6 +2148,8 @@ src_settings_plugins_ifupdown_libnms_ifupdown_core_la_SOURCES = \
src_settings_plugins_ifupdown_libnms_ifupdown_core_la_CPPFLAGS = $(src_settings_plugins_ifupdown_cppflags)
src_settings_plugins_ifupdown_libnms_ifupdown_core_la_LIBADD = \
$(LIBUDEV_LIBS)
src_settings_plugins_ifupdown_libnm_settings_plugin_ifupdown_la_SOURCES = \
src/settings/plugins/ifupdown/nms-ifupdown-connection.c \
@ -2157,7 +2164,8 @@ src_settings_plugins_ifupdown_libnm_settings_plugin_ifupdown_la_LDFLAGS = \
-Wl,--version-script="$(srcdir)/linker-script-settings.ver"
src_settings_plugins_ifupdown_libnm_settings_plugin_ifupdown_la_LIBADD = \
src/settings/plugins/ifupdown/libnms-ifupdown-core.la
src/settings/plugins/ifupdown/libnms-ifupdown-core.la \
$(LIBUDEV_LIBS)
check-local-symbols-settings-ifupdown: src/settings/plugins/ifupdown/libnm-settings-plugin-ifupdown.la
$(call check_so_symbols,$(builddir)/src/settings/plugins/ifupdown/.libs/libnm-settings-plugin-ifupdown.so)
@ -2325,7 +2333,7 @@ src_devices_adsl_libnm_device_plugin_adsl_la_CPPFLAGS = \
-DG_LOG_DOMAIN=\""NetworkManager"\" \
-DNETWORKMANAGER_COMPILATION=NM_NETWORKMANAGER_COMPILATION_INSIDE_DAEMON \
$(GLIB_CFLAGS) \
$(GUDEV_CFLAGS)
$(LIBUDEV_CFLAGS)
src_devices_adsl_libnm_device_plugin_adsl_la_LDFLAGS = \
-module -avoid-version \
@ -2333,7 +2341,7 @@ src_devices_adsl_libnm_device_plugin_adsl_la_LDFLAGS = \
src_devices_adsl_libnm_device_plugin_adsl_la_LIBADD = \
introspection/libnmdbus.la \
$(GUDEV_LIBS)
$(LIBUDEV_LIBS)
check-local-devices-adsl: src/devices/adsl/libnm-device-plugin-adsl.la
$(srcdir)/tools/check-exports.sh $(builddir)/src/devices/adsl/.libs/libnm-device-plugin-adsl.so "$(srcdir)/linker-script-devices.ver"
@ -2464,8 +2472,7 @@ src_devices_bluetooth_libnm_device_plugin_bluetooth_la_LDFLAGS = \
src_devices_bluetooth_libnm_device_plugin_bluetooth_la_LIBADD = \
introspection/libnmdbus.la \
src/devices/wwan/libnm-wwan.la \
$(GLIB_LIBS) \
$(GUDEV_LIBS)
$(GLIB_LIBS)
if WITH_BLUEZ5_DUN
src_devices_bluetooth_libnm_device_plugin_bluetooth_la_CPPFLAGS += $(BLUEZ5_CFLAGS)
@ -2521,8 +2528,7 @@ src_devices_wifi_libnm_device_plugin_wifi_la_LDFLAGS = \
src_devices_wifi_libnm_device_plugin_wifi_la_LIBADD = \
introspection/libnmdbus.la \
$(GLIB_LIBS) \
$(GUDEV_LIBS)
$(GLIB_LIBS)
check-local-devices-wifi: src/devices/wifi/libnm-device-plugin-wifi.la
$(srcdir)/tools/check-exports.sh $(builddir)/src/devices/wifi/.libs/libnm-device-plugin-wifi.so "$(srcdir)/linker-script-devices.ver"
@ -2588,8 +2594,7 @@ src_devices_team_libnm_device_plugin_team_la_LIBADD = \
introspection/libnmdbus.la \
$(LIBTEAMDCTL_LIBS) \
$(JANSSON_LIBS) \
$(GLIB_LIBS) \
$(GUDEV_LIBS)
$(GLIB_LIBS)
check-local-devices-team: src/devices/team/libnm-device-plugin-team.la
$(srcdir)/tools/check-exports.sh $(builddir)/src/devices/team/.libs/libnm-device-plugin-team.so "$(srcdir)/linker-script-devices.ver"
@ -2622,7 +2627,7 @@ src_platform_tests_ldflags = \
src_platform_tests_libadd = \
src/libNetworkManagerTest.la \
$(GLIB_LIBS) \
$(GUDEV_LIBS) \
$(LIBUDEV_LIBS) \
$(LIBNL_LIBS)
check_programs_norun += \
@ -2843,7 +2848,7 @@ src_tests_test_route_manager_ldflags = \
src_tests_test_route_manager_ldadd = \
src/libNetworkManagerTest.la \
$(GLIB_LIBS) \
$(GUDEV_LIBS) \
$(LIBUDEV_LIBS) \
$(LIBNL_LIBS)
src_tests_test_route_manager_fake_SOURCES = src/tests/test-route-manager.c
@ -3283,7 +3288,6 @@ clients_tui_nmtui_CPPFLAGS = \
-I$(srcdir)/clients/common \
$(GLIB_CFLAGS) \
$(NEWT_CFLAGS) \
$(GUDEV_CFLAGS) \
-DG_LOG_DOMAIN=\""nmtui"\" \
-DLOCALEDIR=\""$(localedir)"\" \
$(NULL)
@ -3294,9 +3298,8 @@ clients_tui_nmtui_LDFLAGS = \
clients_tui_nmtui_LDADD = \
libnm/libnm.la \
clients/tui/newt/libnmt-newt.a \
$(GUDEV_LIBS) \
$(NEWT_LIBS) \
$(GLIB_LIBS) \
$(NEWT_LIBS) \
$(NULL)
nmtui_links = nmtui-edit nmtui-connect nmtui-hostname
@ -3743,6 +3746,7 @@ libnm_glib_lib_h_pub_real = \
libnm_glib_lib_h_pub_mkenums = \
libnm-glib/nm-glib-enum-types.h
libnm_glib_lib_h_priv = \
shared/nm-utils/nm-udev-utils.h \
libnm-glib/nm-object-private.h \
libnm-glib/nm-device-private.h \
libnm-glib/nm-types-private.h \
@ -3769,6 +3773,7 @@ nodist_libnm_glib_libnmvpn_HEADERS = \
$(libnm_glib_vpn_h_mkenums)
libnm_glib_lib_c_real = \
shared/nm-utils/nm-udev-utils.c \
libnm-glib/nm-object.c \
libnm-glib/nm-dbus-helpers.c \
libnm-glib/nm-client.c \
@ -3813,7 +3818,7 @@ nodist_libnm_glib_libnm_glib_la_SOURCES = \
libnm_glib_libnm_glib_la_CPPFLAGS = \
$(libnm_glib_cppflags) \
$(GUDEV_CFLAGS) \
$(LIBUDEV_CFLAGS) \
-DNMRUNDIR=\"$(nmrundir)\"
libnm_glib_libnm_glib_la_LDFLAGS = \
@ -3825,7 +3830,7 @@ libnm_glib_libnm_glib_la_LIBADD = \
libnm-glib/libdeprecated-nm-glib.la \
$(GLIB_LIBS) \
$(DBUS_LIBS) \
$(GUDEV_LIBS)
$(LIBUDEV_LIBS)
GLIB_GENERATED += \
@ -3905,7 +3910,7 @@ EXTRA_DIST += \
if HAVE_INTROSPECTION
libnm-glib/NMClient-1.0.gir: libnm-glib/libnm-glib.la $(builddir)/libnm-util/NetworkManager-1.0.gir
libnm_glib_NMClient_1_0_gir_INCLUDES = Gio-2.0 DBusGLib-1.0
libnm_glib_NMClient_1_0_gir_PACKAGES = gio-2.0 dbus-glib-1 gudev-1.0
libnm_glib_NMClient_1_0_gir_PACKAGES = gio-2.0 dbus-glib-1
libnm_glib_NMClient_1_0_gir_EXPORT_PACKAGES = libnm-glib libnm-glib-vpn
libnm_glib_NMClient_1_0_gir_CFLAGS = $(libnm_glib_cppflags)
libnm_glib_NMClient_1_0_gir_LIBS = \

View File

@ -310,7 +310,7 @@ Configure with --without-libnm-glib if you do not need the legacy libraries])])
fi
AM_CONDITIONAL(WITH_LEGACY_LIBRARIES, test "$with_libnm_glib" != "no")
PKG_CHECK_MODULES(GUDEV, gudev-1.0 >= 165)
PKG_CHECK_MODULES([LIBUDEV], [libudev >= 175])
GOBJECT_INTROSPECTION_CHECK([0.9.6])

View File

@ -21,7 +21,6 @@ yum install \
gettext-devel \
dbus-devel \
dbus-glib-devel \
libgudev1-devel \
libuuid-devel \
nss-devel \
ppp-devel \

View File

@ -33,7 +33,7 @@ ARCH=i386
ROOT="${ROOT:-"fedora-20-$ARCH"}"
TREE="/var/lib/mock/$ROOT/root"
PACKAGES="kernel passwd git autoconf automake libtool intltool gtk-doc libnl3-devel
dbus-glib-devel libgudev1-devel libuuid-devel nss-devel ppp-devel newt-devel libndp-devel
dbus-glib-devel libuuid-devel nss-devel ppp-devel newt-devel libndp-devel
readline-devel
gobject-introspection-devel
pygobject3

View File

@ -129,7 +129,6 @@ BuildRequires: gtk-doc
%endif
BuildRequires: libudev-devel
BuildRequires: libuuid-devel
BuildRequires: libgudev1-devel >= 143
BuildRequires: vala-tools
BuildRequires: iptables
BuildRequires: libxslt

View File

@ -22,9 +22,11 @@
#include "nm-default.h"
#include <string.h>
#include <gudev/gudev.h>
#include <libudev.h>
#include "NetworkManager.h"
#include "nm-utils/nm-udev-utils.h"
#include "nm-device-ethernet.h"
#include "nm-device-adsl.h"
#include "nm-device-wifi.h"
@ -92,7 +94,7 @@ typedef struct {
NMActiveConnection *active_connection;
GPtrArray *available_connections;
GUdevClient *client;
NMUdevClient *udev_client;
char *product, *short_product;
char *vendor, *short_vendor;
char *description, *bus_name;
@ -374,9 +376,10 @@ dispose (GObject *object)
g_clear_object (&priv->dhcp4_config);
g_clear_object (&priv->ip6_config);
g_clear_object (&priv->dhcp6_config);
g_clear_object (&priv->client);
g_clear_object (&priv->active_connection);
priv->udev_client = nm_udev_client_unref (priv->udev_client);
if (priv->available_connections) {
int i;
@ -1501,13 +1504,13 @@ nm_device_get_available_connections (NMDevice *device)
}
static char *
get_decoded_property (GUdevDevice *device, const char *property)
get_decoded_property (struct udev_device *device, const char *property)
{
const char *orig, *p;
char *unescaped, *n;
guint len;
p = orig = g_udev_device_get_property (device, property);
p = orig = udev_device_get_property_value (device, property);
if (!orig)
return NULL;
@ -1530,13 +1533,13 @@ get_decoded_property (GUdevDevice *device, const char *property)
static gboolean
ensure_udev_client (NMDevice *device)
{
static const char *const subsys[3] = { "net", "tty", NULL };
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device);
if (!priv->client)
priv->client = g_udev_client_new (subsys);
return priv->client != NULL;
if (!priv->udev_client) {
priv->udev_client = nm_udev_client_new ((const char *[]) { "net", "tty", NULL },
NULL, NULL);
}
return !!priv->udev_client;
}
static char *
@ -1545,7 +1548,7 @@ _get_udev_property (NMDevice *device,
const char *db_prop) /* ID_XXX_FROM_DATABASE */
{
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device);
GUdevDevice *udev_device = NULL, *tmpdev, *olddev;
struct udev_device *udev_device, *tmpdev;
const char *ifname;
guint32 count = 0;
char *enc_value = NULL, *db_value = NULL;
@ -1557,39 +1560,25 @@ _get_udev_property (NMDevice *device,
if (!ifname)
return NULL;
udev_device = g_udev_client_query_by_subsystem_and_name (priv->client, "net", ifname);
if (!udev_device)
udev_device = g_udev_client_query_by_subsystem_and_name (priv->client, "tty", ifname);
if (!udev_device)
return NULL;
udev_device = udev_device_new_from_subsystem_sysname (nm_udev_client_get_udev (priv->udev_client), "net", ifname);
if (!udev_device) {
udev_device = udev_device_new_from_subsystem_sysname (nm_udev_client_get_udev (priv->udev_client), "tty", ifname);
if (!udev_device)
return NULL;
}
/* Walk up the chain of the device and its parents a few steps to grab
* vendor and device ID information off it.
*/
/* Ref the device again because we have to unref it each iteration,
* as g_udev_device_get_parent() returns a ref-ed object.
*/
tmpdev = g_object_ref (udev_device);
tmpdev = udev_device;
while ((count++ < 3) && tmpdev && !enc_value) {
if (!enc_value)
enc_value = get_decoded_property (tmpdev, enc_prop);
if (!db_value)
db_value = g_strdup (g_udev_device_get_property (tmpdev, db_prop));
db_value = g_strdup (udev_device_get_property_value (tmpdev, db_prop));
olddev = tmpdev;
tmpdev = g_udev_device_get_parent (tmpdev);
g_object_unref (olddev);
tmpdev = udev_device_get_parent (tmpdev);
}
/* Unref the last device if we found what we needed before running out
* of parents.
*/
if (tmpdev)
g_object_unref (tmpdev);
/* Balance the initial g_udev_client_query_by_subsystem_and_name() */
g_object_unref (udev_device);
udev_device_unref (udev_device);
/* Prefer the encoded value which comes directly from the device
* over the hwdata database value.
@ -1930,7 +1919,7 @@ static const char *
get_bus_name (NMDevice *device)
{
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device);
GUdevDevice *udevice;
struct udev_device *udevice;
const char *ifname, *bus;
if (priv->bus_name)
@ -1943,13 +1932,13 @@ get_bus_name (NMDevice *device)
if (!ifname)
return NULL;
udevice = g_udev_client_query_by_subsystem_and_name (priv->client, "net", ifname);
udevice = udev_device_new_from_subsystem_sysname (nm_udev_client_get_udev (priv->udev_client), "net", ifname);
if (!udevice)
udevice = g_udev_client_query_by_subsystem_and_name (priv->client, "tty", ifname);
udevice = udev_device_new_from_subsystem_sysname (nm_udev_client_get_udev (priv->udev_client), "tty", ifname);
if (!udevice)
return NULL;
bus = g_udev_device_get_property (udevice, "ID_BUS");
bus = udev_device_get_property_value (udevice, "ID_BUS");
if (!g_strcmp0 (bus, "pci"))
priv->bus_name = g_strdup (_("PCI"));
else if (!g_strcmp0 (bus, "usb"))
@ -1960,7 +1949,7 @@ get_bus_name (NMDevice *device)
*/
priv->bus_name = g_strdup ("");
}
g_object_unref (udevice);
udev_device_unref (udevice);
out:
if (*priv->bus_name)

View File

@ -24,7 +24,7 @@
#include "nm-device.h"
#include <string.h>
#include <gudev/gudev.h>
#include <libudev.h>
#include "nm-dbus-interface.h"
#include "nm-active-connection.h"
@ -40,6 +40,7 @@
#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"
@ -79,7 +80,7 @@ typedef struct {
NMActiveConnection *active_connection;
GPtrArray *available_connections;
GUdevClient *client;
NMUdevClient *udev_client;
char *product, *short_product;
char *vendor, *short_vendor;
char *description, *bus_name;
@ -292,9 +293,10 @@ dispose (GObject *object)
g_clear_object (&priv->dhcp4_config);
g_clear_object (&priv->ip6_config);
g_clear_object (&priv->dhcp6_config);
g_clear_object (&priv->client);
g_clear_object (&priv->active_connection);
priv->udev_client = nm_udev_client_unref (priv->udev_client);
g_clear_pointer (&priv->available_connections, g_ptr_array_unref);
g_clear_pointer (&priv->lldp_neighbors, g_ptr_array_unref);
@ -1304,13 +1306,13 @@ hex2byte (const char *hex)
}
static char *
get_decoded_property (GUdevDevice *device, const char *property)
get_decoded_property (struct udev_device *device, const char *property)
{
const char *orig, *p;
char *unescaped, *n;
guint len;
p = orig = g_udev_device_get_property (device, property);
p = orig = udev_device_get_property_value (device, property);
if (!orig)
return NULL;
@ -1333,13 +1335,13 @@ get_decoded_property (GUdevDevice *device, const char *property)
static gboolean
ensure_udev_client (NMDevice *device)
{
static const char *const subsys[3] = { "net", "tty", NULL };
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device);
if (!priv->client)
priv->client = g_udev_client_new (subsys);
return priv->client != NULL;
if (!priv->udev_client) {
priv->udev_client = nm_udev_client_new ((const char *[]) { "net", "tty", NULL },
NULL, NULL);
}
return !!priv->udev_client;
}
static char *
@ -1348,7 +1350,7 @@ _get_udev_property (NMDevice *device,
const char *db_prop) /* ID_XXX_FROM_DATABASE */
{
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device);
GUdevDevice *udev_device = NULL, *tmpdev, *olddev;
struct udev_device *udev_device, *tmpdev;
const char *ifname;
guint32 count = 0;
char *enc_value = NULL, *db_value = NULL;
@ -1360,39 +1362,25 @@ _get_udev_property (NMDevice *device,
if (!ifname)
return NULL;
udev_device = g_udev_client_query_by_subsystem_and_name (priv->client, "net", ifname);
if (!udev_device)
udev_device = g_udev_client_query_by_subsystem_and_name (priv->client, "tty", ifname);
if (!udev_device)
return NULL;
udev_device = udev_device_new_from_subsystem_sysname (nm_udev_client_get_udev (priv->udev_client), "net", ifname);
if (!udev_device) {
udev_device = udev_device_new_from_subsystem_sysname (nm_udev_client_get_udev (priv->udev_client), "tty", ifname);
if (!udev_device)
return NULL;
}
/* Walk up the chain of the device and its parents a few steps to grab
* vendor and device ID information off it.
*/
/* Ref the device again because we have to unref it each iteration,
* as g_udev_device_get_parent() returns a ref-ed object.
*/
tmpdev = g_object_ref (udev_device);
tmpdev = udev_device;
while ((count++ < 3) && tmpdev && !enc_value) {
if (!enc_value)
enc_value = get_decoded_property (tmpdev, enc_prop);
if (!db_value)
db_value = g_strdup (g_udev_device_get_property (tmpdev, db_prop));
db_value = g_strdup (udev_device_get_property_value (tmpdev, db_prop));
olddev = tmpdev;
tmpdev = g_udev_device_get_parent (tmpdev);
g_object_unref (olddev);
tmpdev = udev_device_get_parent (tmpdev);
}
/* Unref the last device if we found what we needed before running out
* of parents.
*/
if (tmpdev)
g_object_unref (tmpdev);
/* Balance the initial g_udev_client_query_by_subsystem_and_name() */
g_object_unref (udev_device);
udev_device_unref (udev_device);
/* Prefer the encoded value which comes directly from the device
* over the hwdata database value.
@ -1740,7 +1728,7 @@ static const char *
get_bus_name (NMDevice *device)
{
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device);
GUdevDevice *udevice;
struct udev_device *udevice;
const char *ifname, *bus;
if (priv->bus_name)
@ -1753,13 +1741,13 @@ get_bus_name (NMDevice *device)
if (!ifname)
return NULL;
udevice = g_udev_client_query_by_subsystem_and_name (priv->client, "net", ifname);
if (!udevice)
udevice = g_udev_client_query_by_subsystem_and_name (priv->client, "tty", ifname);
if (!udevice)
return NULL;
bus = g_udev_device_get_property (udevice, "ID_BUS");
udevice = udev_device_new_from_subsystem_sysname (nm_udev_client_get_udev (priv->udev_client), "net", ifname);
if (!udevice) {
udevice = udev_device_new_from_subsystem_sysname (nm_udev_client_get_udev (priv->udev_client), "tty", ifname);
if (!udevice)
return NULL;
}
bus = udev_device_get_property_value (udevice, "ID_BUS");
if (!g_strcmp0 (bus, "pci"))
priv->bus_name = g_strdup (_("PCI"));
else if (!g_strcmp0 (bus, "usb"))
@ -1770,7 +1758,7 @@ get_bus_name (NMDevice *device)
*/
priv->bus_name = g_strdup ("");
}
g_object_unref (udevice);
udev_device_unref (udevice);
out:
if (*priv->bus_name)

View File

@ -0,0 +1,240 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/* nm-udev-utils.c - udev utils functions
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Copyright (C) 2017 Red Hat, Inc.
*/
#include "nm-default.h"
#include "nm-udev-utils.h"
#include <libudev.h>
struct _NMPUdevClient {
char **subsystems;
GSource *watch_source;
struct udev *udev;
struct udev_monitor *monitor;
NMUdevClientEvent event_handler;
gpointer event_user_data;
};
/*****************************************************************************/
gboolean
nm_udev_utils_property_as_boolean (const char *uproperty)
{
/* taken from g_udev_device_get_property_as_boolean() */
if (uproperty) {
if ( strcmp (uproperty, "1") == 0
|| g_ascii_strcasecmp (uproperty, "true") == 0)
return TRUE;
}
return FALSE;
}
/*****************************************************************************/
static void
_subsystem_split (const char *subsystem_full,
const char **out_subsystem,
const char **out_devtype,
char **to_free)
{
char *tmp, *s;
nm_assert (subsystem_full);
nm_assert (out_subsystem);
nm_assert (out_devtype);
nm_assert (to_free);
s = strstr (subsystem_full, "/");
if (s) {
tmp = g_strdup (subsystem_full);
s = &tmp[s - subsystem_full];
*s = '\0';
*out_subsystem = tmp;
*out_devtype = &s[1];
*to_free = tmp;
} else {
*out_subsystem = subsystem_full;
*out_devtype = NULL;
*to_free = NULL;
}
}
static struct udev_enumerate *
nm_udev_utils_enumerate (struct udev *uclient,
const char *const*subsystems)
{
struct udev_enumerate *enumerate;
guint n;
enumerate = udev_enumerate_new (uclient);
if (subsystems) {
for (n = 0; subsystems[n]; n++) {
const char *subsystem;
const char *devtype;
gs_free char *to_free;
_subsystem_split (subsystems[n], &subsystem, &devtype, &to_free);
udev_enumerate_add_match_subsystem (enumerate, subsystem);
if (devtype != NULL)
udev_enumerate_add_match_property (enumerate, "DEVTYPE", devtype);
}
}
return enumerate;
}
struct udev *
nm_udev_client_get_udev (NMUdevClient *self)
{
g_return_val_if_fail (self, NULL);
return self->udev;
}
struct udev_enumerate *
nm_udev_client_enumerate_new (NMUdevClient *self)
{
g_return_val_if_fail (self, NULL);
return nm_udev_utils_enumerate (self->udev, (const char *const*) self->subsystems);
}
/*****************************************************************************/
static gboolean
monitor_event (GIOChannel *source,
GIOCondition condition,
gpointer user_data)
{
NMUdevClient *self = user_data;
struct udev_device *udevice;
if (!self->monitor)
goto out;
if (!self->event_handler)
goto out;
udevice = udev_monitor_receive_device (self->monitor);
if (udevice == NULL)
goto out;
self->event_handler (self,
udevice,
self->event_user_data);
udev_device_unref (udevice);
out:
return TRUE;
}
/**
* nm_udev_client_new:
* @subsystems: the subsystems
* @event_handler: callback for events
* @event_user_data: user-data for @event_handler
*
* Basically, it is g_udev_client_new(), and most notably
* g_udev_client_constructed().
*
* Returns: a new NMUdevClient instance.
*/
NMUdevClient *
nm_udev_client_new (const char *const*subsystems,
NMUdevClientEvent event_handler,
gpointer event_user_data)
{
NMUdevClient *self;
GIOChannel *channel;
guint n;
self = g_slice_new0 (NMUdevClient);
self->event_handler = event_handler;
self->event_user_data = event_user_data;
self->subsystems = subsystems && subsystems[0] ? g_strdupv ((char **) subsystems) : NULL;
self->udev = udev_new ();
if (!self->udev)
goto fail;
/* connect to event source */
self->monitor = udev_monitor_new_from_netlink (self->udev, "udev");
if (!self->monitor)
goto fail;
if (self->subsystems) {
/* install subsystem filters to only wake up for certain events */
for (n = 0; self->subsystems[n]; n++) {
if (self->monitor) {
gs_free char *to_free;
const char *subsystem;
const char *devtype;
_subsystem_split (self->subsystems[n], &subsystem, &devtype, &to_free);
udev_monitor_filter_add_match_subsystem_devtype (self->monitor, subsystem, devtype);
}
}
/* listen to events, and buffer them */
if (self->monitor) {
udev_monitor_enable_receiving (self->monitor);
channel = g_io_channel_unix_new (udev_monitor_get_fd (self->monitor));
self->watch_source = g_io_create_watch (channel, G_IO_IN);
g_io_channel_unref (channel);
g_source_set_callback (self->watch_source, (GSourceFunc) monitor_event, self, NULL);
g_source_attach (self->watch_source, g_main_context_get_thread_default ());
g_source_unref (self->watch_source);
}
}
return self;
fail:
return nm_udev_client_unref (self);
}
NMUdevClient *
nm_udev_client_unref (NMUdevClient *self)
{
if (!self)
return NULL;
if (self->watch_source) {
g_source_destroy (self->watch_source);
self->watch_source = NULL;
}
udev_monitor_unref (self->monitor);
self->monitor = NULL;
udev_unref (self->udev);
self->udev = NULL;
g_strfreev (self->subsystems);
g_slice_free (NMUdevClient, self);
return NULL;
}

View File

@ -0,0 +1,46 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/* nm-udev-utils.h - udev utils functions
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Copyright (C) 2017 Red Hat, Inc.
*/
#ifndef __NM_UDEV_UTILS_H__
#define __NM_UDEV_UTILS_H__
struct udev;
struct udev_device;
struct udev_enumerate;
gboolean nm_udev_utils_property_as_boolean (const char *uproperty);
typedef struct _NMPUdevClient NMUdevClient;
typedef void (*NMUdevClientEvent) (NMUdevClient *udev_client,
struct udev_device *udevice,
gpointer event_user_data);
NMUdevClient *nm_udev_client_new (const char *const*subsystems,
NMUdevClientEvent event_handler,
gpointer event_user_data);
NMUdevClient *nm_udev_client_unref (NMUdevClient *self);
struct udev *nm_udev_client_get_udev (NMUdevClient *self);
struct udev_enumerate *nm_udev_client_enumerate_new (NMUdevClient *self);
#endif /* __NM_UDEV_UTILS_H__ */

View File

@ -21,13 +21,14 @@
#include "nm-default.h"
#include <string.h>
#include <gudev/gudev.h>
#include <gmodule.h>
#include <libudev.h>
#include "nm-setting-adsl.h"
#include "nm-device-adsl.h"
#include "devices/nm-device-factory.h"
#include "platform/nm-platform.h"
#include "nm-utils/nm-udev-utils.h"
/*****************************************************************************/
@ -39,7 +40,7 @@
#define NM_ATM_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_ATM_MANAGER, NMAtmManagerClass))
typedef struct {
GUdevClient *client;
NMUdevClient *udev_client;
GSList *devices;
} NMAtmManagerPrivate;
@ -73,35 +74,34 @@ nm_device_factory_create (GError **error)
/*****************************************************************************/
static gboolean
dev_get_attrs (GUdevDevice *udev_device,
dev_get_attrs (struct udev_device *udev_device,
const char **out_path,
char **out_driver)
{
GUdevDevice *parent = NULL;
struct udev_device *parent = NULL;
const char *driver, *path;
g_return_val_if_fail (udev_device != NULL, FALSE);
g_return_val_if_fail (out_path != NULL, FALSE);
g_return_val_if_fail (out_driver != NULL, FALSE);
path = g_udev_device_get_sysfs_path (udev_device);
path = udev_device_get_syspath (udev_device);
if (!path) {
nm_log_warn (LOGD_PLATFORM, "couldn't determine device path; ignoring...");
return FALSE;
}
driver = g_udev_device_get_driver (udev_device);
driver = udev_device_get_driver (udev_device);
if (!driver) {
/* Try the parent */
parent = g_udev_device_get_parent (udev_device);
parent = udev_device_get_parent (udev_device);
if (parent)
driver = g_udev_device_get_driver (parent);
driver = udev_device_get_driver (parent);
}
*out_path = path;
*out_driver = g_strdup (driver);
g_clear_object (&parent);
return TRUE;
}
@ -115,7 +115,7 @@ device_destroyed (gpointer user_data, GObject *dead)
}
static void
adsl_add (NMAtmManager *self, GUdevDevice *udev_device)
adsl_add (NMAtmManager *self, struct udev_device *udev_device)
{
NMAtmManagerPrivate *priv = NM_ATM_MANAGER_GET_PRIVATE (self);
const char *ifname, *sysfs_path = NULL;
@ -126,7 +126,7 @@ adsl_add (NMAtmManager *self, GUdevDevice *udev_device)
g_return_if_fail (udev_device != NULL);
ifname = g_udev_device_get_name (udev_device);
ifname = udev_device_get_sysname (udev_device);
if (!ifname) {
nm_log_warn (LOGD_PLATFORM, "failed to get device's interface name");
return;
@ -165,10 +165,10 @@ adsl_add (NMAtmManager *self, GUdevDevice *udev_device)
}
static void
adsl_remove (NMAtmManager *self, GUdevDevice *udev_device)
adsl_remove (NMAtmManager *self, struct udev_device *udev_device)
{
NMAtmManagerPrivate *priv = NM_ATM_MANAGER_GET_PRIVATE (self);
const char *iface = g_udev_device_get_name (udev_device);
const char *iface = udev_device_get_sysname (udev_device);
GSList *iter;
nm_log_dbg (LOGD_PLATFORM, "(%s): removing ATM device", iface);
@ -194,42 +194,49 @@ start (NMDeviceFactory *factory)
{
NMAtmManager *self = NM_ATM_MANAGER (factory);
NMAtmManagerPrivate *priv = NM_ATM_MANAGER_GET_PRIVATE (self);
GUdevEnumerator *enumerator;
GList *devices, *iter;
struct udev_enumerate *enumerate;
struct udev_list_entry *devices;
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));
enumerate = nm_udev_client_enumerate_new (priv->udev_client);
udev_enumerate_add_match_is_initialized (enumerate);
udev_enumerate_scan_devices (enumerate);
devices = udev_enumerate_get_list_entry (enumerate);
for (; devices; devices = udev_list_entry_get_next (devices)) {
struct udev_device *udevice;
udevice = udev_device_new_from_syspath (udev_enumerate_get_udev (enumerate),
udev_list_entry_get_name (devices));
if (udevice) {
adsl_add (self, udevice);
udev_device_unref (udevice);
}
}
g_list_free (devices);
g_object_unref (enumerator);
udev_enumerate_unref (enumerate);
}
static void
handle_uevent (GUdevClient *client,
const char *action,
GUdevDevice *device,
handle_uevent (NMUdevClient *client,
struct udev_device *device,
gpointer user_data)
{
NMAtmManager *self = NM_ATM_MANAGER (user_data);
const char *subsys;
const char *ifindex;
guint64 seqnum;
const char *action;
action = udev_device_get_action (device);
g_return_if_fail (action != NULL);
/* A bit paranoid */
subsys = g_udev_device_get_subsystem (device);
subsys = udev_device_get_subsystem (device);
g_return_if_fail (!g_strcmp0 (subsys, "atm"));
ifindex = g_udev_device_get_property (device, "IFINDEX");
seqnum = g_udev_device_get_seqnum (device);
ifindex = udev_device_get_property_value (device, "IFINDEX");
seqnum = udev_device_get_seqnum (device);
nm_log_dbg (LOGD_PLATFORM, "UDEV event: action '%s' subsys '%s' device '%s' (%s); seqnum=%" G_GUINT64_FORMAT,
action, subsys, g_udev_device_get_name (device), ifindex ? ifindex : "unknown", seqnum);
action, subsys, udev_device_get_sysname (device), ifindex ? ifindex : "unknown", seqnum);
if (!strcmp (action, "add"))
adsl_add (self, device);
@ -243,10 +250,9 @@ static void
nm_atm_manager_init (NMAtmManager *self)
{
NMAtmManagerPrivate *priv = NM_ATM_MANAGER_GET_PRIVATE (self);
const char *subsys[] = { "atm", NULL };
priv->client = g_udev_client_new (subsys);
g_signal_connect (priv->client, "uevent", G_CALLBACK (handle_uevent), self);
priv->udev_client = nm_udev_client_new ((const char *[]) {"atm", NULL },
handle_uevent, self);
}
static void
@ -256,15 +262,12 @@ dispose (GObject *object)
NMAtmManagerPrivate *priv = NM_ATM_MANAGER_GET_PRIVATE (self);
GSList *iter;
if (priv->client) {
g_signal_handlers_disconnect_by_func (priv->client, handle_uevent, self);
g_clear_object (&priv->client);
}
for (iter = priv->devices; iter; iter = iter->next)
g_object_weak_unref (G_OBJECT (iter->data), device_destroyed, self);
g_clear_pointer (&priv->devices, g_slist_free);
priv->udev_client = nm_udev_client_unref (priv->udev_client);
G_OBJECT_CLASS (nm_atm_manager_parent_class)->dispose (object);
}

View File

@ -29,7 +29,7 @@
#include <unistd.h>
#include <errno.h>
#include <gudev/gudev.h>
#include <libudev.h>
#include "nm-device-private.h"
#include "nm-act-request.h"
@ -155,8 +155,8 @@ static void
_update_s390_subchannels (NMDeviceEthernet *self)
{
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self);
gs_unref_object GUdevDevice *dev = NULL;
gs_unref_object GUdevDevice *parent = NULL;
struct udev_device *dev = NULL;
struct udev_device *parent = NULL;
const char *parent_path, *item;
int ifindex;
GDir *dir;
@ -172,21 +172,20 @@ _update_s390_subchannels (NMDeviceEthernet *self)
}
ifindex = nm_device_get_ifindex ((NMDevice *) self);
dev = (GUdevDevice *) nm_g_object_ref (nm_platform_link_get_udev_device (NM_PLATFORM_GET, ifindex));
dev = nm_platform_link_get_udev_device (NM_PLATFORM_GET, ifindex);
if (!dev)
return;
/* Try for the "ccwgroup" parent */
parent = g_udev_device_get_parent_with_subsystem (dev, "ccwgroup", NULL);
parent = udev_device_get_parent_with_subsystem_devtype (dev, "ccwgroup", NULL);
if (!parent) {
/* FIXME: whatever 'lcs' devices' subsystem is here... */
if (!parent) {
/* Not an s390 device */
return;
}
/* Not an s390 device */
return;
}
parent_path = g_udev_device_get_sysfs_path (parent);
parent_path = udev_device_get_syspath (parent);
dir = g_dir_open (parent_path, 0, &error);
if (!dir) {
_LOGW (LOGD_DEVICE | LOGD_PLATFORM, "update-s390: failed to open directory '%s': %s",

View File

@ -23,7 +23,9 @@
#include "nm-rfkill-manager.h"
#include <string.h>
#include <gudev/gudev.h>
#include <libudev.h>
#include "nm-utils/nm-udev-utils.h"
/*****************************************************************************/
@ -35,7 +37,7 @@ enum {
static guint signals[LAST_SIGNAL] = { 0 };
typedef struct {
GUdevClient *client;
NMUdevClient *udev_client;
/* Authoritative rfkill state (RFKILL_* enum) */
RfKillState rfkill_states[RFKILL_TYPE_MAX];
@ -101,32 +103,32 @@ rfkill_state_to_desc (RfKillState rstate)
}
static Killswitch *
killswitch_new (GUdevDevice *device, RfKillType rtype)
killswitch_new (struct udev_device *device, RfKillType rtype)
{
Killswitch *ks;
GUdevDevice *parent = NULL, *grandparent = NULL;
struct udev_device *parent = NULL, *grandparent = NULL;
const char *driver, *subsys, *parent_subsys = NULL;
ks = g_malloc0 (sizeof (Killswitch));
ks->name = g_strdup (g_udev_device_get_name (device));
ks->seqnum = g_udev_device_get_seqnum (device);
ks->path = g_strdup (g_udev_device_get_sysfs_path (device));
ks->name = g_strdup (udev_device_get_sysname (device));
ks->seqnum = udev_device_get_seqnum (device);
ks->path = g_strdup (udev_device_get_syspath (device));
ks->rtype = rtype;
driver = g_udev_device_get_property (device, "DRIVER");
subsys = g_udev_device_get_subsystem (device);
driver = udev_device_get_property_value (device, "DRIVER");
subsys = udev_device_get_subsystem (device);
/* Check parent for various attributes */
parent = g_udev_device_get_parent (device);
parent = udev_device_get_parent (device);
if (parent) {
parent_subsys = g_udev_device_get_subsystem (parent);
parent_subsys = udev_device_get_subsystem (parent);
if (!driver)
driver = g_udev_device_get_property (parent, "DRIVER");
driver = udev_device_get_property_value (parent, "DRIVER");
if (!driver) {
/* Sigh; try the grandparent */
grandparent = g_udev_device_get_parent (parent);
grandparent = udev_device_get_parent (parent);
if (grandparent)
driver = g_udev_device_get_property (grandparent, "DRIVER");
driver = udev_device_get_property_value (grandparent, "DRIVER");
}
}
@ -140,10 +142,6 @@ killswitch_new (GUdevDevice *device, RfKillType rtype)
|| g_strcmp0 (parent_subsys, "acpi") == 0)
ks->platform = TRUE;
if (grandparent)
g_object_unref (grandparent);
if (parent)
g_object_unref (parent);
return ks;
}
@ -196,32 +194,34 @@ recheck_killswitches (NMRfkillManager *self)
/* Poll the states of all killswitches */
for (iter = priv->killswitches; iter; iter = g_slist_next (iter)) {
Killswitch *ks = iter->data;
GUdevDevice *device;
struct udev_device *device;
RfKillState dev_state;
int sysfs_state;
device = g_udev_client_query_by_subsystem_and_name (priv->client, "rfkill", ks->name);
if (device) {
sysfs_state = g_udev_device_get_property_as_int (device, "RFKILL_STATE");
dev_state = sysfs_state_to_nm_state (sysfs_state);
device = udev_device_new_from_subsystem_sysname (nm_udev_client_get_udev (priv->udev_client),
"rfkill", ks->name);
if (!device)
continue;
sysfs_state = _nm_utils_ascii_str_to_int64 (udev_device_get_property_value (device, "RFKILL_STATE"),
10, G_MININT, G_MAXINT, -1);
dev_state = sysfs_state_to_nm_state (sysfs_state);
nm_log_dbg (LOGD_RFKILL, "%s rfkill%s switch %s state now %d/%u",
rfkill_type_to_desc (ks->rtype),
ks->platform ? " platform" : "",
ks->name,
sysfs_state,
dev_state);
nm_log_dbg (LOGD_RFKILL, "%s rfkill%s switch %s state now %d/%u",
rfkill_type_to_desc (ks->rtype),
ks->platform ? " platform" : "",
ks->name,
sysfs_state,
dev_state);
if (ks->platform == FALSE) {
if (dev_state > poll_states[ks->rtype])
poll_states[ks->rtype] = dev_state;
} else {
platform_checked[ks->rtype] = TRUE;
if (dev_state > platform_states[ks->rtype])
platform_states[ks->rtype] = dev_state;
}
g_object_unref (device);
if (ks->platform == FALSE) {
if (dev_state > poll_states[ks->rtype])
poll_states[ks->rtype] = dev_state;
} else {
platform_checked[ks->rtype] = TRUE;
if (dev_state > platform_states[ks->rtype])
platform_states[ks->rtype] = dev_state;
}
udev_device_unref (device);
}
/* Log and emit change signal for final rfkill states */
@ -276,14 +276,14 @@ rfkill_type_to_enum (const char *str)
}
static void
add_one_killswitch (NMRfkillManager *self, GUdevDevice *device)
add_one_killswitch (NMRfkillManager *self, struct udev_device *device)
{
NMRfkillManagerPrivate *priv = NM_RFKILL_MANAGER_GET_PRIVATE (self);
const char *str_type;
RfKillType rtype;
Killswitch *ks;
str_type = g_udev_device_get_property (device, "RFKILL_TYPE");
str_type = udev_device_get_property_value (device, "RFKILL_TYPE");
rtype = rfkill_type_to_enum (str_type);
if (rtype == RFKILL_TYPE_UNKNOWN)
return;
@ -300,12 +300,12 @@ add_one_killswitch (NMRfkillManager *self, GUdevDevice *device)
}
static void
rfkill_add (NMRfkillManager *self, GUdevDevice *device)
rfkill_add (NMRfkillManager *self, struct udev_device *device)
{
const char *name;
g_return_if_fail (device != NULL);
name = g_udev_device_get_name (device);
name = udev_device_get_sysname (device);
g_return_if_fail (name != NULL);
if (!killswitch_find_by_name (self, name))
@ -314,14 +314,14 @@ rfkill_add (NMRfkillManager *self, GUdevDevice *device)
static void
rfkill_remove (NMRfkillManager *self,
GUdevDevice *device)
struct udev_device *device)
{
NMRfkillManagerPrivate *priv = NM_RFKILL_MANAGER_GET_PRIVATE (self);
GSList *iter;
const char *name;
g_return_if_fail (device != NULL);
name = g_udev_device_get_name (device);
name = udev_device_get_sysname (device);
g_return_if_fail (name != NULL);
for (iter = priv->killswitches; iter; iter = g_slist_next (iter)) {
@ -337,22 +337,24 @@ rfkill_remove (NMRfkillManager *self,
}
static void
handle_uevent (GUdevClient *client,
const char *action,
GUdevDevice *device,
handle_uevent (NMUdevClient *client,
struct udev_device *device,
gpointer user_data)
{
NMRfkillManager *self = NM_RFKILL_MANAGER (user_data);
const char *subsys;
const char *action;
action = udev_device_get_action (device);
g_return_if_fail (action != NULL);
/* A bit paranoid */
subsys = g_udev_device_get_subsystem (device);
subsys = udev_device_get_subsystem (device);
g_return_if_fail (!g_strcmp0 (subsys, "rfkill"));
nm_log_dbg (LOGD_PLATFORM, "udev rfkill event: action '%s' device '%s'",
action, g_udev_device_get_name (device));
action, udev_device_get_sysname (device));
if (!strcmp (action, "add"))
rfkill_add (self, device);
@ -368,22 +370,31 @@ static void
nm_rfkill_manager_init (NMRfkillManager *self)
{
NMRfkillManagerPrivate *priv = NM_RFKILL_MANAGER_GET_PRIVATE (self);
const char *subsys[] = { "rfkill", NULL };
GList *switches, *iter;
guint32 i;
struct udev_enumerate *enumerate;
struct udev_list_entry *iter;
guint i;
for (i = 0; i < RFKILL_TYPE_MAX; i++)
priv->rfkill_states[i] = RFKILL_UNBLOCKED;
priv->client = g_udev_client_new (subsys);
g_signal_connect (priv->client, "uevent", G_CALLBACK (handle_uevent), self);
priv->udev_client = nm_udev_client_new ((const char *[]) { "rfkill", NULL },
handle_uevent, self);
switches = g_udev_client_query_by_subsystem (priv->client, "rfkill");
for (iter = switches; iter; iter = g_list_next (iter)) {
add_one_killswitch (self, G_UDEV_DEVICE (iter->data));
g_object_unref (G_UDEV_DEVICE (iter->data));
enumerate = nm_udev_client_enumerate_new (priv->udev_client);
udev_enumerate_scan_devices (enumerate);
iter = udev_enumerate_get_list_entry (enumerate);
for (; iter; iter = udev_list_entry_get_next (iter)) {
struct udev_device *udevice;
udevice = udev_device_new_from_syspath (udev_enumerate_get_udev (enumerate),
udev_list_entry_get_name (iter));
if (!udevice)
continue;
add_one_killswitch (self, udevice);
udev_device_unref (udevice);
}
g_list_free (switches);
udev_enumerate_unref (enumerate);
recheck_killswitches (self);
}
@ -400,13 +411,13 @@ dispose (GObject *object)
NMRfkillManager *self = NM_RFKILL_MANAGER (object);
NMRfkillManagerPrivate *priv = NM_RFKILL_MANAGER_GET_PRIVATE (self);
g_clear_object (&priv->client);
if (priv->killswitches) {
g_slist_free_full (priv->killswitches, (GDestroyNotify) killswitch_destroy);
priv->killswitches = NULL;
}
priv->udev_client = nm_udev_client_unref (priv->udev_client);
G_OBJECT_CLASS (nm_rfkill_manager_parent_class)->dispose (object);
}

View File

@ -38,7 +38,7 @@
#include <linux/if_tunnel.h>
#include <netlink/netlink.h>
#include <netlink/msg.h>
#include <gudev/gudev.h>
#include <libudev.h>
#include "nm-utils.h"
#include "nm-core-internal.h"
@ -51,6 +51,7 @@
#include "wifi/wifi-utils.h"
#include "wifi/wifi-utils-wext.h"
#include "nm-utils/unaligned.h"
#include "nm-utils/nm-udev-utils.h"
#define VLAN_FLAG_MVRP 0x8
@ -2547,7 +2548,7 @@ typedef struct {
gboolean sysctl_get_warned;
GHashTable *sysctl_get_prev_values;
GUdevClient *udev_client;
NMUdevClient *udev_client;
struct {
/* which delayed actions are scheduled, as marked in @flags.
@ -4399,18 +4400,20 @@ link_get_unmanaged (NMPlatform *platform, int ifindex, gboolean *unmanaged)
{
NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE (platform);
const NMPObject *link;
GUdevDevice *udev_device = NULL;
struct udev_device *udevice = NULL;
const char *uproperty;
link = nmp_cache_lookup_link (priv->cache, ifindex);
if (link)
udev_device = link->_link.udev.device;
if (!link)
return FALSE;
if (udev_device && g_udev_device_get_property (udev_device, "NM_UNMANAGED")) {
*unmanaged = g_udev_device_get_property_as_boolean (udev_device, "NM_UNMANAGED");
return TRUE;
}
udevice = link->_link.udev.device;
if (!udevice)
return FALSE;
return FALSE;
uproperty = udev_device_get_property_value (udevice, "NM_UNMANAGED");
return nm_udev_utils_property_as_boolean (uproperty);
}
static gboolean
@ -4510,10 +4513,10 @@ link_get_udi (NMPlatform *platform, int ifindex)
|| !obj->_link.netlink.is_in_netlink
|| !obj->_link.udev.device)
return NULL;
return g_udev_device_get_sysfs_path (obj->_link.udev.device);
return udev_device_get_syspath (obj->_link.udev.device);
}
static GObject *
static struct udev_device *
link_get_udev_device (NMPlatform *platform, int ifindex)
{
const NMPObject *obj_cache;
@ -4524,7 +4527,7 @@ link_get_udev_device (NMPlatform *platform, int ifindex)
* appears invisible via other platform functions. */
obj_cache = nmp_cache_lookup_link (NM_LINUX_PLATFORM_GET_PRIVATE (platform)->cache, ifindex);
return obj_cache ? (GObject *) obj_cache->_link.udev.device : NULL;
return obj_cache ? obj_cache->_link.udev.device : NULL;
}
static NMPlatformError
@ -6503,14 +6506,16 @@ after_read:
/*****************************************************************************/
static void
cache_update_link_udev (NMPlatform *platform, int ifindex, GUdevDevice *udev_device)
cache_update_link_udev (NMPlatform *platform,
int ifindex,
struct udev_device *udevice)
{
NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE (platform);
nm_auto_nmpobj NMPObject *obj_cache = NULL;
gboolean was_visible;
NMPCacheOpsType cache_op;
cache_op = nmp_cache_update_link_udev (priv->cache, ifindex, udev_device, &obj_cache, &was_visible, cache_pre_hook, platform);
cache_op = nmp_cache_update_link_udev (priv->cache, ifindex, udevice, &obj_cache, &was_visible, cache_pre_hook, platform);
if (cache_op != NMP_CACHE_OPS_UNCHANGED) {
nm_auto_pop_netns NMPNetns *netns = NULL;
@ -6523,55 +6528,58 @@ cache_update_link_udev (NMPlatform *platform, int ifindex, GUdevDevice *udev_dev
static void
udev_device_added (NMPlatform *platform,
GUdevDevice *udev_device)
struct udev_device *udevice)
{
const char *ifname;
const char *ifindex_s;
int ifindex;
ifname = g_udev_device_get_name (udev_device);
ifname = udev_device_get_sysname (udevice);
if (!ifname) {
_LOGD ("udev-add: failed to get device's interface");
return;
}
if (!g_udev_device_get_property (udev_device, "IFINDEX")) {
ifindex_s = udev_device_get_property_value (udevice, "IFINDEX");
if (!ifindex_s) {
_LOGW ("udev-add[%s]failed to get device's ifindex", ifname);
return;
}
ifindex = g_udev_device_get_property_as_int (udev_device, "IFINDEX");
ifindex = _nm_utils_ascii_str_to_int64 (ifindex_s, 10, 1, G_MAXINT, 0);
if (ifindex <= 0) {
_LOGW ("udev-add[%s]: retrieved invalid IFINDEX=%d", ifname, ifindex);
return;
}
if (!g_udev_device_get_sysfs_path (udev_device)) {
if (!udev_device_get_syspath (udevice)) {
_LOGD ("udev-add[%s,%d]: couldn't determine device path; ignoring...", ifname, ifindex);
return;
}
_LOGT ("udev-add[%s,%d]: device added", ifname, ifindex);
cache_update_link_udev (platform, ifindex, udev_device);
cache_update_link_udev (platform, ifindex, udevice);
}
static gboolean
_udev_device_removed_match_link (const NMPObject *obj, gpointer udev_device)
_udev_device_removed_match_link (const NMPObject *obj, gpointer udevice)
{
return obj->_link.udev.device == udev_device;
return obj->_link.udev.device == udevice;
}
static void
udev_device_removed (NMPlatform *platform,
GUdevDevice *udev_device)
struct udev_device *udevice)
{
const char *ifindex_s;
int ifindex = 0;
if (g_udev_device_get_property (udev_device, "IFINDEX"))
ifindex = g_udev_device_get_property_as_int (udev_device, "IFINDEX");
else {
ifindex_s = udev_device_get_property_value (udevice, "IFINDEX");
ifindex = _nm_utils_ascii_str_to_int64 (ifindex_s, 10, 1, G_MAXINT, 0);
if (ifindex <= 0) {
const NMPObject *obj;
obj = nmp_cache_lookup_link_full (NM_LINUX_PLATFORM_GET_PRIVATE (platform)->cache,
0, NULL, FALSE, NM_LINK_TYPE_NONE, _udev_device_removed_match_link, udev_device);
0, NULL, FALSE, NM_LINK_TYPE_NONE, _udev_device_removed_match_link, udevice);
if (obj)
ifindex = obj->link.ifindex;
}
@ -6584,9 +6592,8 @@ udev_device_removed (NMPlatform *platform,
}
static void
handle_udev_event (GUdevClient *client,
const char *action,
GUdevDevice *udev_device,
handle_udev_event (NMUdevClient *udev_client,
struct udev_device *udevice,
gpointer user_data)
{
nm_auto_pop_netns NMPNetns *netns = NULL;
@ -6594,26 +6601,27 @@ handle_udev_event (GUdevClient *client,
const char *subsys;
const char *ifindex;
guint64 seqnum;
const char *action;
g_return_if_fail (action != NULL);
action = udev_device_get_action (udevice);
g_return_if_fail (action);
subsys = udev_device_get_subsystem (udevice);
g_return_if_fail (nm_streq0 (subsys, "net"));
if (!nm_platform_netns_push (platform, &netns))
return;
/* A bit paranoid */
subsys = g_udev_device_get_subsystem (udev_device);
g_return_if_fail (!g_strcmp0 (subsys, "net"));
ifindex = g_udev_device_get_property (udev_device, "IFINDEX");
seqnum = g_udev_device_get_seqnum (udev_device);
ifindex = udev_device_get_property_value (udevice, "IFINDEX");
seqnum = udev_device_get_seqnum (udevice);
_LOGD ("UDEV event: action '%s' subsys '%s' device '%s' (%s); seqnum=%" G_GUINT64_FORMAT,
action, subsys, g_udev_device_get_name (udev_device),
action, subsys, udev_device_get_sysname (udevice),
ifindex ? ifindex : "unknown", seqnum);
if (!strcmp (action, "add") || !strcmp (action, "move"))
udev_device_added (platform, udev_device);
if (!strcmp (action, "remove"))
udev_device_removed (platform, udev_device);
if (NM_IN_STRSET (action, "add", "move"))
udev_device_added (platform, udevice);
else if (NM_IN_STRSET (action, "remove"))
udev_device_removed (platform, udevice);
}
/*****************************************************************************/
@ -6634,8 +6642,10 @@ nm_linux_platform_init (NMLinuxPlatform *self)
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 });
if (use_udev) {
priv->udev_client = nm_udev_client_new ((const char *[]) { "net", NULL },
handle_udev_event, self);
}
}
static void
@ -6718,24 +6728,30 @@ constructed (GObject *_object)
/* 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);
struct udev_enumerate *enumerator;
struct udev_list_entry *devices, *l;
/* And read initial device list */
enumerator = g_udev_enumerator_new (priv->udev_client);
g_udev_enumerator_add_match_subsystem (enumerator, "net");
enumerator = nm_udev_client_enumerate_new (priv->udev_client);
g_udev_enumerator_add_match_is_initialized (enumerator);
udev_enumerate_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));
udev_enumerate_scan_devices (enumerator);
devices = udev_enumerate_get_list_entry (enumerator);
for (l = devices; l; l = udev_list_entry_get_next (l)) {
struct udev_device *udevice;
udevice = udev_device_new_from_syspath (udev_enumerate_get_udev (enumerator),
udev_list_entry_get_name (l));
if (!udevice)
continue;
udev_device_added (platform, udevice);
udev_device_unref (udevice);
}
g_list_free (devices);
g_object_unref (enumerator);
udev_enumerate_unref (enumerator);
}
}
@ -6755,11 +6771,6 @@ 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);
}
@ -6785,6 +6796,8 @@ finalize (GObject *object)
g_hash_table_destroy (priv->sysctl_get_prev_values);
}
priv->udev_client = nm_udev_client_unref (priv->udev_client);
G_OBJECT_CLASS (nm_linux_platform_parent_class)->finalize (object);
}

View File

@ -32,6 +32,7 @@
#include <linux/version.h>
#include <linux/rtnetlink.h>
#include <fcntl.h>
#include <libudev.h>
#include "nm-utils.h"
#include "nm-setting-wired.h"
@ -520,35 +521,33 @@ nmp_utils_mii_supports_carrier_detect (int ifindex)
******************************************************************/
const char *
nmp_utils_udev_get_driver (GUdevDevice *device)
nmp_utils_udev_get_driver (struct udev_device *udevice)
{
GUdevDevice *parent = NULL, *grandparent = NULL;
struct udev_device *parent = NULL, *grandparent = NULL;
const char *driver, *subsys;
driver = g_udev_device_get_driver (device);
driver = udev_device_get_driver (udevice);
if (driver)
goto out;
/* Try the parent */
parent = g_udev_device_get_parent (device);
parent = udev_device_get_parent (udevice);
if (parent) {
driver = g_udev_device_get_driver (parent);
driver = udev_device_get_driver (parent);
if (!driver) {
/* Try the grandparent if it's an ibmebus device or if the
* subsys is NULL which usually indicates some sort of
* platform device like a 'gadget' net interface.
*/
subsys = g_udev_device_get_subsystem (parent);
subsys = udev_device_get_subsystem (parent);
if ( (g_strcmp0 (subsys, "ibmebus") == 0)
|| (subsys == NULL)) {
grandparent = g_udev_device_get_parent (parent);
grandparent = udev_device_get_parent (parent);
if (grandparent)
driver = g_udev_device_get_driver (grandparent);
driver = udev_device_get_driver (grandparent);
}
}
}
g_clear_object (&parent);
g_clear_object (&grandparent);
out:
/* Intern the string so we don't have to worry about memory

View File

@ -21,8 +21,6 @@
#ifndef __NM_PLATFORM_UTILS_H__
#define __NM_PLATFORM_UTILS_H__
#include <gudev/gudev.h>
#include "nm-platform.h"
#include "nm-setting-wired.h"
@ -66,7 +64,9 @@ gboolean nmp_utils_ethtool_get_permanent_address (int ifindex,
gboolean nmp_utils_mii_supports_carrier_detect (int ifindex);
const char *nmp_utils_udev_get_driver (GUdevDevice *device);
struct udev_device;
const char *nmp_utils_udev_get_driver (struct udev_device *udevice);
NMIPConfigSource nmp_utils_ip_config_source_from_rtprot (guint8 rtprot) _nm_const;
guint8 nmp_utils_ip_config_source_coerce_to_rtprot (NMIPConfigSource source) _nm_const;

View File

@ -1000,7 +1000,7 @@ nm_platform_link_get_udi (NMPlatform *self, int ifindex)
return NULL;
}
GObject *
struct udev_device *
nm_platform_link_get_udev_device (NMPlatform *self, int ifindex)
{
_CHECK_SELF (self, klass, FALSE);

View File

@ -49,6 +49,8 @@
/*****************************************************************************/
struct udev_device;
/* workaround for older libnl version, that does not define these flags. */
#ifndef IFA_F_MANAGETEMPADDR
#define IFA_F_MANAGETEMPADDR 0x100
@ -562,7 +564,7 @@ typedef struct {
gboolean (*link_set_noarp) (NMPlatform *, int ifindex);
const char *(*link_get_udi) (NMPlatform *self, int ifindex);
GObject *(*link_get_udev_device) (NMPlatform *self, int ifindex);
struct udev_device *(*link_get_udev_device) (NMPlatform *self, int ifindex);
NMPlatformError (*link_set_user_ipv6ll_enabled) (NMPlatform *, int ifindex, gboolean enabled);
gboolean (*link_set_token) (NMPlatform *, int ifindex, NMUtilsIPv6IfaceId iid);
@ -814,7 +816,7 @@ gboolean nm_platform_link_set_noarp (NMPlatform *self, int ifindex);
const char *nm_platform_link_get_udi (NMPlatform *self, int ifindex);
GObject *nm_platform_link_get_udev_device (NMPlatform *self, int ifindex);
struct udev_device *nm_platform_link_get_udev_device (NMPlatform *self, int ifindex);
NMPlatformError nm_platform_link_set_user_ipv6ll_enabled (NMPlatform *self, int ifindex, gboolean enabled);
gboolean nm_platform_link_set_ipv6_token (NMPlatform *self, int ifindex, NMUtilsIPv6IfaceId iid);

View File

@ -24,6 +24,7 @@
#include <unistd.h>
#include <linux/rtnetlink.h>
#include <libudev.h>
#include "nm-utils.h"
@ -125,14 +126,14 @@ _vlan_xgress_qos_mappings_cpy (guint *dst_n_map,
/*****************************************************************************/
static const char *
_link_get_driver (GUdevDevice *udev_device, const char *kind, int ifindex)
_link_get_driver (struct udev_device *udevice, const char *kind, int ifindex)
{
const char *driver = NULL;
nm_assert (kind == g_intern_string (kind));
if (udev_device) {
driver = nmp_utils_udev_get_driver (udev_device);
if (udevice) {
driver = nmp_utils_udev_get_driver (udevice);
if (driver)
return driver;
}
@ -242,7 +243,10 @@ nmp_object_unref (NMPObject *obj)
static void
_vt_cmd_obj_dispose_link (NMPObject *obj)
{
g_clear_object (&obj->_link.udev.device);
if (obj->_link.udev.device) {
udev_device_unref (obj->_link.udev.device);
obj->_link.udev.device = NULL;
}
nmp_object_unref (obj->_link.netlink.lnk);
}
@ -619,8 +623,7 @@ _vt_cmd_obj_cmp_link (const NMPObject *obj1, const NMPObject *obj2)
return 1;
/* Only compare based on pointer values. That is ugly because it's not a
* stable sort order, but probably udev gives us always the same GUdevDevice
* instance.
* stable sort order.
*
* Have this check as very last. */
return (obj1->_link.udev.device < obj2->_link.udev.device) ? -1 : 1;
@ -687,15 +690,17 @@ _vt_cmd_obj_copy_link (NMPObject *dst, const NMPObject *src)
{
if (dst->_link.udev.device != src->_link.udev.device) {
if (src->_link.udev.device)
g_object_ref (src->_link.udev.device);
udev_device_ref (src->_link.udev.device);
if (dst->_link.udev.device)
g_object_unref (dst->_link.udev.device);
udev_device_unref (dst->_link.udev.device);
dst->_link.udev.device = src->_link.udev.device;
}
if (dst->_link.netlink.lnk != src->_link.netlink.lnk) {
if (src->_link.netlink.lnk)
nmp_object_ref (src->_link.netlink.lnk);
if (dst->_link.netlink.lnk)
nmp_object_unref (dst->_link.netlink.lnk);
dst->_link.netlink.lnk = src->_link.netlink.lnk;
}
dst->_link = src->_link;
}
@ -1870,8 +1875,8 @@ nmp_cache_update_netlink (NMPCache *cache, NMPObject *obj, NMPObject **out_obj,
_nmp_object_fixup_link_master_connected (obj, cache);
/* Merge the netlink parts with what we have from udev. */
g_clear_object (&obj->_link.udev.device);
obj->_link.udev.device = old->_link.udev.device ? g_object_ref (old->_link.udev.device) : NULL;
udev_device_unref (obj->_link.udev.device);
obj->_link.udev.device = old->_link.udev.device ? udev_device_ref (old->_link.udev.device) : NULL;
_nmp_object_fixup_link_udev_fields (obj, cache->use_udev);
}
} else
@ -1896,7 +1901,7 @@ nmp_cache_update_netlink (NMPCache *cache, NMPObject *obj, NMPObject **out_obj,
}
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)
nmp_cache_update_link_udev (NMPCache *cache, int ifindex, struct udev_device *udevice, NMPObject **out_obj, gboolean *out_was_visible, NMPCachePreHook pre_hook, gpointer user_data)
{
NMPObject *old;
nm_auto_nmpobj NMPObject *obj = NULL;
@ -1909,12 +1914,12 @@ nmp_cache_update_link_udev (NMPCache *cache, int ifindex, GUdevDevice *udev_devi
*out_was_visible = FALSE;
if (!old) {
if (!udev_device)
if (!udevice)
return NMP_CACHE_OPS_UNCHANGED;
obj = nmp_object_new (NMP_OBJECT_TYPE_LINK, NULL);
obj->link.ifindex = ifindex;
obj->_link.udev.device = g_object_ref (udev_device);
obj->_link.udev.device = udev_device_ref (udevice);
_nmp_object_fixup_link_udev_fields (obj, cache->use_udev);
@ -1935,10 +1940,10 @@ nmp_cache_update_link_udev (NMPCache *cache, int ifindex, GUdevDevice *udev_devi
if (out_was_visible)
*out_was_visible = nmp_object_is_visible (old);
if (old->_link.udev.device == udev_device)
if (old->_link.udev.device == udevice)
return NMP_CACHE_OPS_UNCHANGED;
if (!udev_device && !old->_link.netlink.is_in_netlink) {
if (!udevice && !old->_link.netlink.is_in_netlink) {
/* the update would make @old invalid. Remove it. */
if (pre_hook)
pre_hook (cache, old, NULL, NMP_CACHE_OPS_REMOVED, user_data);
@ -1948,8 +1953,8 @@ nmp_cache_update_link_udev (NMPCache *cache, int ifindex, GUdevDevice *udev_devi
obj = nmp_object_clone (old, FALSE);
g_clear_object (&obj->_link.udev.device);
obj->_link.udev.device = udev_device ? g_object_ref (udev_device) : NULL;
udev_device_unref (obj->_link.udev.device);
obj->_link.udev.device = udevice ? udev_device_ref (udevice) : NULL;
_nmp_object_fixup_link_udev_fields (obj, cache->use_udev);

View File

@ -21,11 +21,11 @@
#ifndef __NMP_OBJECT_H__
#define __NMP_OBJECT_H__
#include <gudev/gudev.h>
#include "nm-platform.h"
#include "nm-multi-index.h"
struct udev_device;
typedef enum { /*< skip >*/
NMP_OBJECT_TO_STRING_ID,
NMP_OBJECT_TO_STRING_PUBLIC,
@ -186,7 +186,23 @@ typedef struct {
} netlink;
struct {
GUdevDevice *device;
/* note that "struct udev_device" references the library context
* "struct udev", but doesn't own it.
*
* Hence, the udev.device shall not be used after the library
* context is is destroyed.
*
* In case of NMPObjectLink instances that you obtained from the
* platform cache, that means that you shall no keep references
* to those instances that outlife the NMPlatform instance.
*
* In practice, the requirement is less strict and you'll be even
* fine if the platform instance (and the "struct udev" instance)
* are already destroyed while you still hold onto a reference to
* the NMPObjectLink instance. Just don't make use of udev functions
* that cause access to the udev library context.
*/
struct udev_device *device;
} udev;
} NMPObjectLink;
@ -442,7 +458,7 @@ void ASSERT_nmp_cache_is_consistent (const NMPCache *cache);
NMPCacheOpsType nmp_cache_remove (NMPCache *cache, const NMPObject *obj, gboolean equals_by_ptr, NMPObject **out_obj, gboolean *out_was_visible, NMPCachePreHook pre_hook, gpointer user_data);
NMPCacheOpsType nmp_cache_remove_netlink (NMPCache *cache, const NMPObject *obj, NMPObject **out_obj, gboolean *out_was_visible, NMPCachePreHook pre_hook, gpointer user_data);
NMPCacheOpsType nmp_cache_update_netlink (NMPCache *cache, NMPObject *obj, NMPObject **out_obj, gboolean *out_was_visible, NMPCachePreHook pre_hook, gpointer user_data);
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_udev (NMPCache *cache, int ifindex, struct udev_device *udevice, 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 (gboolean use_udev);

View File

@ -20,7 +20,10 @@
#include "nm-default.h"
#include <libudev.h>
#include "platform/nmp-object.h"
#include "nm-utils/nm-udev-utils.h"
#include "nm-test-utils-core.h"
@ -159,7 +162,7 @@ _nmp_cache_update_netlink (NMPCache *cache, NMPObject *obj, NMPObject **out_obj,
obj_old = nmp_cache_lookup_link (cache, obj->object.ifindex);
if (obj_old && obj_old->_link.udev.device)
obj_clone->_link.udev.device = g_object_ref (obj_old->_link.udev.device);
obj_clone->_link.udev.device = udev_device_ref (obj_old->_link.udev.device);
_nmp_object_fixup_link_udev_fields (obj_clone, nmp_cache_use_udev_get (cache));
g_assert (cache);
@ -219,8 +222,8 @@ test_cache_link (void)
NMPObject objs1;
gboolean was_visible;
NMPCacheId cache_id_storage;
GUdevDevice *udev_device_2 = g_list_nth_data (global.udev_devices, 0);
GUdevDevice *udev_device_3 = g_list_nth_data (global.udev_devices, 0);
struct udev_device *udev_device_2 = g_list_nth_data (global.udev_devices, 0);
struct udev_device *udev_device_3 = g_list_nth_data (global.udev_devices, 0);
NMPCacheOpsType ops_type;
cache = nmp_cache_new (nmtst_get_rand_int () % 2);
@ -390,23 +393,40 @@ int
main (int argc, char **argv)
{
int result;
gs_unref_object GUdevClient *udev_client = NULL;
NMUdevClient *udev_client;
nmtst_init_assert_logging (&argc, &argv, "INFO", "DEFAULT");
udev_client = g_udev_client_new ((const char *[]) { "net", NULL });
udev_client = nm_udev_client_new ((const char *[]) { "net", NULL },
NULL, NULL);
{
gs_unref_object GUdevEnumerator *udev_enumerator = g_udev_enumerator_new (udev_client);
struct udev_enumerate *enumerator;
struct udev_list_entry *devices, *l;
g_udev_enumerator_add_match_subsystem (udev_enumerator, "net");
enumerator = nm_udev_client_enumerate_new (udev_client);
/* Demand that the device is initialized (udev rules ran,
* device has a stable name now) in case udev is running
* (not in a container). */
if (access ("/sys", W_OK) == 0)
g_udev_enumerator_add_match_is_initialized (udev_enumerator);
udev_enumerate_add_match_is_initialized (enumerator);
global.udev_devices = g_udev_enumerator_execute (udev_enumerator);
udev_enumerate_scan_devices (enumerator);
devices = udev_enumerate_get_list_entry (enumerator);
for (l = devices; l != NULL; l = udev_list_entry_get_next (l)) {
struct udev_device *udevice;
udevice = udev_device_new_from_syspath (udev_enumerate_get_udev (enumerator),
udev_list_entry_get_name (l));
if (udevice == NULL)
continue;
global.udev_devices = g_list_prepend (global.udev_devices, udevice);
}
global.udev_devices = g_list_reverse (global.udev_devices);
udev_enumerate_unref (enumerator);
}
g_test_add_func ("/nmp-object/cache_link", test_cache_link);
@ -414,10 +434,12 @@ main (int argc, char **argv)
result = g_test_run ();
while (global.udev_devices) {
g_object_unref (global.udev_devices->data);
udev_device_unref (global.udev_devices->data);
global.udev_devices = g_list_remove (global.udev_devices, global.udev_devices->data);
}
nm_udev_client_unref (udev_client);
return result;
}

View File

@ -28,8 +28,8 @@
#include <string.h>
#include <arpa/inet.h>
#include <gudev/gudev.h>
#include <gmodule.h>
#include <libudev.h>
#include "nm-setting-connection.h"
#include "nm-dbus-interface.h"
@ -42,6 +42,7 @@
#include "nm-core-internal.h"
#include "NetworkManagerUtils.h"
#include "nm-config.h"
#include "nm-utils/nm-udev-utils.h"
#include "nms-ifupdown-interface-parser.h"
#include "nms-ifupdown-connection.h"
@ -62,7 +63,7 @@
/*****************************************************************************/
typedef struct {
GUdevClient *client;
NMUdevClient *udev_client;
GHashTable *connections; /* /e/n/i block name :: NMIfupdownConnection */
@ -103,21 +104,21 @@ NM_DEFINE_SINGLETON_GETTER (SettingsPluginIfupdown, settings_plugin_ifupdown_get
static void
bind_device_to_connection (SettingsPluginIfupdown *self,
GUdevDevice *device,
struct udev_device *device,
NMIfupdownConnection *exported)
{
NMSettingWired *s_wired;
NMSettingWireless *s_wifi;
const char *iface, *address;
iface = g_udev_device_get_name (device);
iface = udev_device_get_sysname (device);
if (!iface) {
nm_log_warn (LOGD_SETTINGS, "failed to get ifname for device.");
return;
}
address = g_udev_device_get_sysfs_attr (device, "address");
if (!address || !strlen (address)) {
address = udev_device_get_sysattr_value (device, "address");
if (!address || !address[0]) {
nm_log_warn (LOGD_SETTINGS, "failed to get MAC address for %s", iface);
return;
}
@ -142,14 +143,14 @@ bind_device_to_connection (SettingsPluginIfupdown *self,
}
static void
udev_device_added (SettingsPluginIfupdown *self, GUdevDevice *device)
udev_device_added (SettingsPluginIfupdown *self, struct udev_device *device)
{
SettingsPluginIfupdownPrivate *priv = SETTINGS_PLUGIN_IFUPDOWN_GET_PRIVATE (self);
const char *iface, *path;
NMIfupdownConnection *exported;
iface = g_udev_device_get_name (device);
path = g_udev_device_get_sysfs_path (device);
iface = udev_device_get_sysname (device);
path = udev_device_get_syspath (device);
if (!iface || !path)
return;
@ -165,7 +166,7 @@ udev_device_added (SettingsPluginIfupdown *self, GUdevDevice *device)
return;
}
g_hash_table_insert (priv->kernel_ifaces, g_strdup (iface), g_object_ref (device));
g_hash_table_insert (priv->kernel_ifaces, g_strdup (iface), udev_device_ref (device));
if (exported)
bind_device_to_connection (self, device, exported);
@ -175,13 +176,13 @@ udev_device_added (SettingsPluginIfupdown *self, GUdevDevice *device)
}
static void
udev_device_removed (SettingsPluginIfupdown *self, GUdevDevice *device)
udev_device_removed (SettingsPluginIfupdown *self, struct udev_device *device)
{
SettingsPluginIfupdownPrivate *priv = SETTINGS_PLUGIN_IFUPDOWN_GET_PRIVATE (self);
const char *iface, *path;
iface = g_udev_device_get_name (device);
path = g_udev_device_get_sysfs_path (device);
iface = udev_device_get_sysname (device);
path = udev_device_get_syspath (device);
if (!iface || !path)
return;
@ -195,13 +196,13 @@ udev_device_removed (SettingsPluginIfupdown *self, GUdevDevice *device)
}
static void
udev_device_changed (SettingsPluginIfupdown *self, GUdevDevice *device)
udev_device_changed (SettingsPluginIfupdown *self, struct udev_device *device)
{
SettingsPluginIfupdownPrivate *priv = SETTINGS_PLUGIN_IFUPDOWN_GET_PRIVATE (self);
const char *iface, *path;
iface = g_udev_device_get_name (device);
path = g_udev_device_get_sysfs_path (device);
iface = udev_device_get_sysname (device);
path = udev_device_get_syspath (device);
if (!iface || !path)
return;
@ -215,20 +216,21 @@ udev_device_changed (SettingsPluginIfupdown *self, GUdevDevice *device)
}
static void
handle_uevent (GUdevClient *client,
const char *action,
GUdevDevice *device,
handle_uevent (NMUdevClient *client,
struct udev_device *device,
gpointer user_data)
{
SettingsPluginIfupdown *self = SETTINGS_PLUGIN_IFUPDOWN (user_data);
const char *subsys;
const char *action;
action = udev_device_get_action (device);
g_return_if_fail (action != NULL);
/* A bit paranoid */
subsys = g_udev_device_get_subsystem (device);
g_return_if_fail (subsys != NULL);
g_return_if_fail (strcmp (subsys, "net") == 0);
subsys = udev_device_get_subsystem (device);
g_return_if_fail (nm_streq0 (subsys, "net"));
if (!strcmp (action, "add"))
udev_device_added (self, device);
@ -271,7 +273,7 @@ get_unmanaged_specs (NMSettingsPlugin *config)
SettingsPluginIfupdownPrivate *priv = SETTINGS_PLUGIN_IFUPDOWN_GET_PRIVATE ((SettingsPluginIfupdown *) config);
GSList *specs = NULL;
GHashTableIter iter;
GUdevDevice *device;
struct udev_device *device;
const char *iface;
if (!ALWAYS_UNMANAGE && !priv->unmanage_well_known)
@ -284,7 +286,7 @@ get_unmanaged_specs (NMSettingsPlugin *config)
while (g_hash_table_iter_next (&iter, (gpointer) &iface, (gpointer) &device)) {
const char *address;
address = g_udev_device_get_sysfs_attr (device, "address");
address = udev_device_get_sysattr_value (device, "address");
if (address)
specs = g_slist_append (specs, g_strdup_printf ("mac:%s", address));
else
@ -317,6 +319,12 @@ get_property (GObject *object, guint prop_id,
/*****************************************************************************/
static void
_udev_device_unref (gpointer ptr)
{
udev_device_unref (ptr);
}
static void
init (NMSettingsPlugin *config)
{
@ -324,11 +332,11 @@ init (NMSettingsPlugin *config)
SettingsPluginIfupdownPrivate *priv = SETTINGS_PLUGIN_IFUPDOWN_GET_PRIVATE (self);
GHashTable *auto_ifaces;
if_block *block = NULL;
GList *keys, *iter;
struct udev_enumerate *enumerate;
struct udev_list_entry *keys;
GHashTableIter con_iter;
const char *block_name;
NMIfupdownConnection *connection;
const char *subsys[2] = { "net", NULL };
auto_ifaces = g_hash_table_new (g_str_hash, g_str_equal);
@ -336,18 +344,15 @@ init (NMSettingsPlugin *config)
priv->connections = g_hash_table_new (g_str_hash, g_str_equal);
if(!priv->kernel_ifaces)
priv->kernel_ifaces = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
priv->kernel_ifaces = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, _udev_device_unref);
if(!priv->eni_ifaces)
priv->eni_ifaces = g_hash_table_new (g_str_hash, g_str_equal);
nm_log_info (LOGD_SETTINGS, "init!");
priv->client = g_udev_client_new (subsys);
if (!priv->client) {
nm_log_warn (LOGD_SETTINGS, " error initializing libgudev");
} else
g_signal_connect (priv->client, "uevent", G_CALLBACK (handle_uevent), self);
priv->udev_client = nm_udev_client_new ((const char *[]) { "net", NULL },
handle_uevent, self);
/* Read in all the interfaces */
ifparser_init (ENI_INTERFACES_FILE, 0);
@ -445,12 +450,20 @@ init (NMSettingsPlugin *config)
nm_log_info (LOGD_SETTINGS, "management mode: %s", priv->unmanage_well_known ? "unmanaged" : "managed");
/* Add well-known interfaces */
keys = g_udev_client_query_by_subsystem (priv->client, "net");
for (iter = keys; iter; iter = g_list_next (iter)) {
udev_device_added (self, G_UDEV_DEVICE (iter->data));
g_object_unref (G_UDEV_DEVICE (iter->data));
enumerate = nm_udev_client_enumerate_new (priv->udev_client);
udev_enumerate_scan_devices (enumerate);
keys = udev_enumerate_get_list_entry (enumerate);
for (; keys; keys = udev_list_entry_get_next (keys)) {
struct udev_device *udevice;
udevice = udev_device_new_from_syspath (udev_enumerate_get_udev (enumerate),
udev_list_entry_get_name (keys));
if (udevice) {
udev_device_added (self, udevice);
udev_device_unref (udevice);
}
}
g_list_free (keys);
udev_enumerate_unref (enumerate);
/* Now if we're running in managed mode, let NM know there are new connections */
if (!priv->unmanage_well_known) {
@ -483,7 +496,8 @@ dispose (GObject *object)
g_clear_pointer (&priv->kernel_ifaces, g_hash_table_destroy);
g_clear_pointer (&priv->eni_ifaces, g_hash_table_destroy);
g_clear_object (&priv->client);
priv->udev_client = nm_udev_client_unref (priv->udev_client);
G_OBJECT_CLASS (settings_plugin_ifupdown_parent_class)->dispose (object);
}