From ce5da1933d66be2ff94759ef640417021b74dae7 Mon Sep 17 00:00:00 2001 From: Dan Winship Date: Fri, 24 May 2013 17:30:31 -0300 Subject: [PATCH] core: split NMAtmManager out of NMUdevManager Split the "atm"-subsystem-monitoring parts of NMUdevManager into a separate class. Now NMUdevManager only handles "net"-subsystem device enumeration. --- src/Makefile.am | 2 + src/nm-atm-manager.c | 211 ++++++++++++++++++++++++++++++++++++++++++ src/nm-atm-manager.h | 63 +++++++++++++ src/nm-manager.c | 99 +++++++++++++++----- src/nm-udev-manager.c | 67 +++----------- 5 files changed, 366 insertions(+), 76 deletions(-) create mode 100644 src/nm-atm-manager.c create mode 100644 src/nm-atm-manager.h diff --git a/src/Makefile.am b/src/Makefile.am index ba0408f7d9..c97c1a2256 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -209,6 +209,8 @@ nm_sources = \ nm-activation-request.h \ nm-active-connection.c \ nm-active-connection.h \ + nm-atm-manager.c \ + nm-atm-manager.h \ nm-call-store.c \ nm-call-store.h \ nm-connection-provider.c \ diff --git a/src/nm-atm-manager.c b/src/nm-atm-manager.c new file mode 100644 index 0000000000..c4df9dc2a2 --- /dev/null +++ b/src/nm-atm-manager.c @@ -0,0 +1,211 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager -- Network link manager + * + * 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 of the License, 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) 2009 - 2013 Red Hat, Inc. + */ + +#include + +#include +#include + +#include "nm-atm-manager.h" +#include "nm-logging.h" + +typedef struct { + GUdevClient *client; + +} NMAtmManagerPrivate; + +#define NM_ATM_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_ATM_MANAGER, NMAtmManagerPrivate)) + +G_DEFINE_TYPE (NMAtmManager, nm_atm_manager, G_TYPE_OBJECT) + +enum { + DEVICE_ADDED, + DEVICE_REMOVED, + + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = { 0 }; + +NMAtmManager * +nm_atm_manager_new (void) +{ + return NM_ATM_MANAGER (g_object_new (NM_TYPE_ATM_MANAGER, NULL)); +} + +static gboolean +dev_get_attrs (GUdevDevice *udev_device, + const char **out_ifname, + const char **out_path, + char **out_driver) +{ + GUdevDevice *parent = NULL; + const char *ifname, *driver, *path; + + g_return_val_if_fail (udev_device != NULL, FALSE); + g_return_val_if_fail (out_ifname != NULL, FALSE); + g_return_val_if_fail (out_path != NULL, FALSE); + g_return_val_if_fail (out_driver != NULL, FALSE); + + ifname = g_udev_device_get_name (udev_device); + if (!ifname) { + nm_log_dbg (LOGD_HW, "failed to get device's interface"); + return FALSE; + } + + path = g_udev_device_get_sysfs_path (udev_device); + if (!path) { + nm_log_warn (LOGD_HW, "couldn't determine device path; ignoring..."); + return FALSE; + } + + driver = g_udev_device_get_driver (udev_device); + if (!driver) { + /* Try the parent */ + parent = g_udev_device_get_parent (udev_device); + if (parent) { + driver = g_udev_device_get_driver (parent); + g_object_unref (parent); + } + } + + *out_ifname = ifname; + *out_path = path; + *out_driver = g_strdup (driver); + + return TRUE; +} + +static void +adsl_add (NMAtmManager *self, GUdevDevice *udev_device) +{ + const char *ifname = NULL, *path = NULL; + char *driver = NULL; + + g_return_if_fail (udev_device != NULL); + + nm_log_dbg (LOGD_HW, "adsl_add: ATM Device detected from udev. Adding .."); + + if (dev_get_attrs (udev_device, &ifname, &path, &driver)) + g_signal_emit (self, signals[DEVICE_ADDED], 0, ifname, path, driver); + g_free (driver); +} + +static void +adsl_remove (NMAtmManager *self, GUdevDevice *device) +{ + nm_log_dbg (LOGD_HW, "adsl_remove: Removing ATM Device"); + + g_signal_emit (self, signals[DEVICE_REMOVED], 0, g_udev_device_get_name (device)); +} + +void +nm_atm_manager_query_devices (NMAtmManager *self) +{ + NMAtmManagerPrivate *priv = NM_ATM_MANAGER_GET_PRIVATE (self); + GUdevEnumerator *enumerator; + GList *devices, *iter; + + g_return_if_fail (NM_IS_ATM_MANAGER (self)); + + 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)); + } + g_list_free (devices); + g_object_unref (enumerator); +} + +static void +handle_uevent (GUdevClient *client, + const char *action, + GUdevDevice *device, + gpointer user_data) +{ + NMAtmManager *self = NM_ATM_MANAGER (user_data); + const char *subsys; + + g_return_if_fail (action != NULL); + + /* A bit paranoid */ + subsys = g_udev_device_get_subsystem (device); + g_return_if_fail (!g_strcmp0 (subsys, "atm")); + + nm_log_dbg (LOGD_HW, "UDEV event: action '%s' subsys '%s' device '%s'", + action, subsys, g_udev_device_get_name (device)); + + if (!strcmp (action, "add")) + adsl_add (self, device); + else if (!strcmp (action, "remove")) + adsl_remove (self, device); +} + +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); +} + +static void +dispose (GObject *object) +{ + NMAtmManager *self = NM_ATM_MANAGER (object); + NMAtmManagerPrivate *priv = NM_ATM_MANAGER_GET_PRIVATE (self); + + g_clear_object (&priv->client); + + G_OBJECT_CLASS (nm_atm_manager_parent_class)->dispose (object); +} + +static void +nm_atm_manager_class_init (NMAtmManagerClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + g_type_class_add_private (klass, sizeof (NMAtmManagerPrivate)); + + /* virtual methods */ + object_class->dispose = dispose; + + /* Signals */ + signals[DEVICE_ADDED] = + g_signal_new ("device-added", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMAtmManagerClass, device_added), + NULL, NULL, NULL, + G_TYPE_NONE, 3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING); + + signals[DEVICE_REMOVED] = + g_signal_new ("device-removed", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMAtmManagerClass, device_removed), + NULL, NULL, NULL, + G_TYPE_NONE, 1, G_TYPE_STRING); +} diff --git a/src/nm-atm-manager.h b/src/nm-atm-manager.h new file mode 100644 index 0000000000..773f33ffc7 --- /dev/null +++ b/src/nm-atm-manager.h @@ -0,0 +1,63 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager -- Network link manager + * + * 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 of the License, 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) 2007 - 2008 Novell, Inc. + * Copyright (C) 2007 - 2012 Red Hat, Inc. + */ + +#ifndef NM_ATM_MANAGER_H +#define NM_ATM_MANAGER_H + +#include +#include + +#include + +G_BEGIN_DECLS + +#define NM_TYPE_ATM_MANAGER (nm_atm_manager_get_type ()) +#define NM_ATM_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_ATM_MANAGER, NMAtmManager)) +#define NM_ATM_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_ATM_MANAGER, NMAtmManagerClass)) +#define NM_IS_ATM_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_ATM_MANAGER)) +#define NM_IS_ATM_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_ATM_MANAGER)) +#define NM_ATM_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_ATM_MANAGER, NMAtmManagerClass)) + +typedef struct { + GObject parent; +} NMAtmManager; + +typedef struct { + GObjectClass parent; + + /* signals */ + void (*device_added) (NMAtmManager *manager, + const char *iface, + const char *sysfs_path, + const char *driver); + + void (*device_removed) (NMAtmManager *manager, + const char *iface); +} NMAtmManagerClass; + +GType nm_atm_manager_get_type (void); + +NMAtmManager *nm_atm_manager_new (void); + +void nm_atm_manager_query_devices (NMAtmManager *manager); + +#endif /* NM_ATM_MANAGER_H */ + diff --git a/src/nm-manager.c b/src/nm-manager.c index b98b66e7e8..daf2f80565 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -64,6 +64,7 @@ #include "nm-dbus-glib-types.h" #include "nm-platform.h" #include "nm-udev-manager.h" +#include "nm-atm-manager.h" #include "nm-rfkill-manager.h" #include "nm-hostname-provider.h" #include "nm-bluez-manager.h" @@ -224,6 +225,7 @@ typedef struct { NMDBusManager *dbus_mgr; guint dbus_connection_changed_id; NMUdevManager *udev_mgr; + NMAtmManager *atm_mgr; NMRfkillManager *rfkill_mgr; NMBluezManager *bluez_mgr; @@ -2029,6 +2031,21 @@ find_device_by_ip_iface (NMManager *self, const gchar *iface) return NULL; } +static NMDevice * +find_device_by_iface (NMManager *self, const gchar *iface) +{ + NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); + GSList *iter; + + for (iter = priv->devices; iter; iter = g_slist_next (iter)) { + NMDevice *candidate = iter->data; + + if (g_strcmp0 (nm_device_get_iface (candidate), iface) == 0) + return candidate; + } + return NULL; +} + static NMDevice * find_device_by_ifindex (NMManager *self, guint32 ifindex) { @@ -2181,12 +2198,6 @@ is_olpc_mesh (GUdevDevice *device) return (prop != NULL); } -static gboolean -is_adsl (GUdevDevice *device) -{ - return (g_strcmp0 (g_udev_device_get_subsystem (device), "atm") == 0); -} - static void udev_device_added_cb (NMUdevManager *udev_mgr, GUdevDevice *udev_device, @@ -2205,21 +2216,13 @@ udev_device_added_cb (NMUdevManager *udev_mgr, g_return_if_fail (udev_device != NULL); g_return_if_fail (iface != NULL); g_return_if_fail (sysfs_path != NULL); + g_return_if_fail (ifindex > 0); - /* Most devices will have an ifindex here */ - if (ifindex > 0) { - device = find_device_by_ifindex (self, ifindex); - if (device) { - /* If it's a virtual device we may need to update its UDI */ - g_object_set (G_OBJECT (device), NM_DEVICE_UDI, sysfs_path, NULL); - return; - } - } else { - /* But ATM/ADSL devices don't */ - g_return_if_fail (is_adsl (udev_device)); - device = find_device_by_ip_iface (self, iface); - if (device) - return; + device = find_device_by_ifindex (self, ifindex); + if (device) { + /* If it's a virtual device we may need to update its UDI */ + g_object_set (G_OBJECT (device), NM_DEVICE_UDI, sysfs_path, NULL); + return; } /* Try registered device factories */ @@ -2258,8 +2261,6 @@ udev_device_added_cb (NMUdevManager *udev_mgr, device = nm_device_olpc_mesh_new (sysfs_path, iface, driver); else if (is_wireless (udev_device)) device = nm_device_wifi_new (sysfs_path, iface, driver); - else if (is_adsl (udev_device)) - device = nm_device_adsl_new (sysfs_path, iface, driver); else device = nm_device_ethernet_new (sysfs_path, iface, driver); break; @@ -2361,6 +2362,49 @@ udev_device_removed_cb (NMUdevManager *manager, priv->devices = remove_one_device (self, priv->devices, device, FALSE); } +static void +atm_device_added_cb (NMAtmManager *atm_mgr, + const char *iface, + const char *sysfs_path, + const char *driver, + gpointer user_data) +{ + NMManager *self = NM_MANAGER (user_data); + NMDevice *device; + + g_return_if_fail (iface != NULL); + g_return_if_fail (sysfs_path != NULL); + + device = find_device_by_iface (self, iface); + if (device) + return; + + device = nm_device_adsl_new (sysfs_path, iface, driver); + if (device) + add_device (self, device); +} + +static void +atm_device_removed_cb (NMAtmManager *manager, + const char *iface, + gpointer user_data) +{ + NMManager *self = NM_MANAGER (user_data); + NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); + NMDevice *device = NULL; + GSList *iter; + + for (iter = priv->devices; iter; iter = g_slist_next (iter)) { + if (g_strcmp0 (nm_device_get_iface (NM_DEVICE (iter->data)), iface) == 0) { + device = iter->data; + break; + } + } + + if (device) + priv->devices = remove_one_device (self, priv->devices, device, FALSE); +} + static void rfkill_manager_rfkill_changed_cb (NMRfkillManager *rfkill_mgr, RfKillType rtype, @@ -3743,6 +3787,7 @@ nm_manager_start (NMManager *self) read_nm_created_bridges (self); nm_udev_manager_query_devices (priv->udev_mgr); + nm_atm_manager_query_devices (priv->atm_mgr); nm_bluez_manager_query_devices (priv->bluez_mgr); /* Query devices again to ensure that we catch all virtual interfaces (like @@ -4073,6 +4118,16 @@ nm_manager_new (NMSettings *settings, G_CALLBACK (udev_device_removed_cb), singleton); + priv->atm_mgr = nm_atm_manager_new (); + g_signal_connect (priv->atm_mgr, + "device-added", + G_CALLBACK (atm_device_added_cb), + singleton); + g_signal_connect (priv->atm_mgr, + "device-removed", + G_CALLBACK (atm_device_removed_cb), + singleton); + priv->rfkill_mgr = nm_rfkill_manager_new (); g_signal_connect (priv->rfkill_mgr, "rfkill-changed", diff --git a/src/nm-udev-manager.c b/src/nm-udev-manager.c index 93739e8dba..bc2d14b06c 100644 --- a/src/nm-udev-manager.c +++ b/src/nm-udev-manager.c @@ -80,6 +80,13 @@ dev_get_attrs (GUdevDevice *udev_device, return FALSE; } + if (g_udev_device_get_sysfs_attr (udev_device, "ifindex")) + ifindex = g_udev_device_get_sysfs_attr_as_int (udev_device, "ifindex"); + else { + nm_log_warn (LOGD_HW, "failed to get device's ifindex"); + return FALSE; + } + driver = g_udev_device_get_driver (udev_device); if (!driver) { /* Try the parent */ @@ -102,9 +109,6 @@ dev_get_attrs (GUdevDevice *udev_device, } } - if (g_udev_device_get_sysfs_attr (udev_device, "ifindex")) - ifindex = g_udev_device_get_sysfs_attr_as_int (udev_device, "ifindex"); - if (!driver) { switch (nm_platform_link_get_type (ifindex)) { case NM_LINK_TYPE_BOND: @@ -178,30 +182,6 @@ net_remove (NMUdevManager *self, GUdevDevice *device) g_signal_emit (self, signals[DEVICE_REMOVED], 0, device); } -static void -adsl_add (NMUdevManager *self, GUdevDevice *udev_device) -{ - gint ifindex = -1; - const char *ifname = NULL, *path = NULL; - char *driver = NULL; - - g_return_if_fail (udev_device != NULL); - - nm_log_dbg (LOGD_HW, "adsl_add: ATM Device detected from udev. Adding .."); - - if (dev_get_attrs (udev_device, &ifname, &path, &driver, &ifindex)) - g_signal_emit (self, signals[DEVICE_ADDED], 0, udev_device, ifname, path, driver, ifindex); - g_free (driver); -} - -static void -adsl_remove (NMUdevManager *self, GUdevDevice *device) -{ - nm_log_dbg (LOGD_HW, "adsl_remove: Removing ATM Device"); - - g_signal_emit (self, signals[DEVICE_REMOVED], 0, device); -} - void nm_udev_manager_query_devices (NMUdevManager *self) { @@ -222,18 +202,6 @@ nm_udev_manager_query_devices (NMUdevManager *self) } g_list_free (devices); g_object_unref (enumerator); - - - 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)); - } - g_list_free (devices); - g_object_unref (enumerator); } static void @@ -249,31 +217,22 @@ handle_uevent (GUdevClient *client, /* A bit paranoid */ subsys = g_udev_device_get_subsystem (device); - g_return_if_fail (subsys != NULL); + g_return_if_fail (!g_strcmp0 (subsys, "net")); nm_log_dbg (LOGD_HW, "UDEV event: action '%s' subsys '%s' device '%s'", action, subsys, g_udev_device_get_name (device)); - g_return_if_fail (!strcmp (subsys, "net") || !strcmp (subsys, "atm")); - - if (!strcmp (action, "add")) { - if (!strcmp (subsys, "net")) - net_add (self, device); - else if (!strcmp (subsys, "atm")) - adsl_add (self, device); - } else if (!strcmp (action, "remove")) { - if (!strcmp (subsys, "net")) - net_remove (self, device); - else if (!strcmp (subsys, "atm")) - adsl_remove (self, device); - } + if (!strcmp (action, "add")) + net_add (self, device); + else if (!strcmp (action, "remove")) + net_remove (self, device); } static void nm_udev_manager_init (NMUdevManager *self) { NMUdevManagerPrivate *priv = NM_UDEV_MANAGER_GET_PRIVATE (self); - const char *subsys[] = { "net", "atm", NULL }; + const char *subsys[] = { "net", NULL }; priv->client = g_udev_client_new (subsys); g_signal_connect (priv->client, "uevent", G_CALLBACK (handle_uevent), self);