From 05e2e701a8638f5a159392f7ed1fd82b02886fd9 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Wed, 18 Jun 2014 11:58:30 +0200 Subject: [PATCH 1/6] core: check file permissions when loading device plugins and order by file modification time Refactor the loading of device plugins by creating the list of module filenames in a separate function. Thereby also check for file permissions (must be only modifiable by root) and sort the files by last file modification time. This has the advantage, that if several plugins provide the same device type, that we (deterministically) prefer the most recent one. Signed-off-by: Thomas Haller --- src/nm-manager.c | 112 +++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 93 insertions(+), 19 deletions(-) diff --git a/src/nm-manager.c b/src/nm-manager.c index b806809d80..13b4a01417 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -1879,42 +1879,116 @@ factory_component_added_cb (NMDeviceFactory *factory, #define PLUGIN_PATH_TAG "NMManager-plugin-path" #define PLUGIN_TYPEFUNC_TAG "typefunc" -static void -load_device_factories (NMManager *self) +struct read_device_factory_paths_data { + char *path; + struct stat st; +}; + +static gint +read_device_factory_paths_sort_fcn (gconstpointer a, gconstpointer b) +{ + const struct read_device_factory_paths_data *da = a; + const struct read_device_factory_paths_data *db = b; + time_t ta, tb; + + ta = MAX (da->st.st_mtime, da->st.st_ctime); + tb = MAX (db->st.st_mtime, db->st.st_ctime); + + if (ta < tb) + return 1; + if (ta > tb) + return -1; + return 0; +} + +static char** +read_device_factory_paths () { - NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); GDir *dir; GError *error = NULL; const char *item; - char *path; - GSList *iter; + GArray *paths; + char **result; + guint i; dir = g_dir_open (NMPLUGINDIR, 0, &error); if (!dir) { - nm_log_warn (LOGD_HW, "Failed to open plugin directory %s: %s", + nm_log_warn (LOGD_HW, "device plugin: failed to open directory %s: %s", NMPLUGINDIR, (error && error->message) ? error->message : "(unknown)"); g_clear_error (&error); - return; + return NULL; } + paths = g_array_new (FALSE, FALSE, sizeof (struct read_device_factory_paths_data)); + while ((item = g_dir_read_name (dir))) { - GModule *plugin; - NMDeviceFactory *factory; - NMDeviceFactoryCreateFunc create_func; - NMDeviceFactoryDeviceTypeFunc type_func; - NMDeviceType dev_type; - const char *found = NULL; + struct read_device_factory_paths_data data; if (!g_str_has_prefix (item, PLUGIN_PREFIX)) continue; if (g_str_has_suffix (item, ".la")) continue; - path = g_module_build_path (NMPLUGINDIR, item); - g_assert (path); - plugin = g_module_open (path, G_MODULE_BIND_LOCAL); - g_free (path); + data.path = g_build_filename (NMPLUGINDIR, item, NULL); + + if (stat (data.path, &data.st) != 0) + goto continue_with_error; + if (!S_ISREG (data.st.st_mode)) + goto continue_silently; + if (data.st.st_uid != 0) + goto continue_with_error; + if (data.st.st_mode & (S_IWGRP | S_IWOTH | S_ISUID)) + goto continue_with_error; + + g_array_append_val (paths, data); + continue; + +continue_with_error: + nm_log_dbg (LOGD_HW, "device plugin: skip invalid file %s", data.path); +continue_silently: + g_free (data.path); + } + g_dir_close (dir); + + /* sort filenames by modification time. */ + g_array_sort (paths, read_device_factory_paths_sort_fcn); + + result = g_new (char *, paths->len + 1); + for (i = 0; i < paths->len; i++) + result[i] = g_array_index (paths, struct read_device_factory_paths_data, i).path; + result[i] = NULL; + + g_array_free (paths, TRUE); + return result; +} + +static void +load_device_factories (NMManager *self) +{ + NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); + char **path; + char **paths; + + paths = read_device_factory_paths (); + if (!paths) + return; + + for (path = paths; *path; path++) { + GError *error = NULL; + GModule *plugin; + NMDeviceFactory *factory; + NMDeviceFactoryCreateFunc create_func; + NMDeviceFactoryDeviceTypeFunc type_func; + NMDeviceType dev_type; + const char *found = NULL; + GSList *iter; + const char *item; + + item = strrchr (*path, '/'); + g_assert (item); + + plugin = g_module_open (*path, G_MODULE_BIND_LOCAL); if (!plugin) { nm_log_warn (LOGD_HW, "(%s): failed to load plugin: %s", item, g_module_error ()); @@ -1939,7 +2013,7 @@ load_device_factories (NMManager *self) } } if (found) { - nm_log_warn (LOGD_HW, "Found multiple device plugins for same type: %s vs %s", + nm_log_warn (LOGD_HW, "Found multiple device plugins for same type: use '%s' instead of '%s'", found, g_module_name (plugin)); g_module_close (plugin); continue; @@ -1978,7 +2052,7 @@ load_device_factories (NMManager *self) nm_log_info (LOGD_HW, "Loaded device plugin: %s", g_module_name (plugin)); }; - g_dir_close (dir); + g_strfreev (paths); priv->factories = g_slist_reverse (priv->factories); } From b855c7b64ad16cbac9f521308720186d0f21d76d Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Wed, 18 Jun 2014 20:46:45 +0200 Subject: [PATCH 2/6] team/trivial: rename NM_TEAM_ERROR* to NM_DEVICE_TEAM_ERROR* Signed-off-by: Thomas Haller --- src/devices/nm-device-team.c | 6 +++--- src/devices/nm-device-team.h | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/devices/nm-device-team.c b/src/devices/nm-device-team.c index 29fb881836..e9dfbf38a2 100644 --- a/src/devices/nm-device-team.c +++ b/src/devices/nm-device-team.c @@ -51,7 +51,7 @@ G_DEFINE_TYPE (NMDeviceTeam, nm_device_team, NM_TYPE_DEVICE) #define NM_DEVICE_TEAM_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE_TEAM, NMDeviceTeamPrivate)) -#define NM_TEAM_ERROR (nm_team_error_quark ()) +#define NM_DEVICE_TEAM_ERROR (nm_device_team_error_quark ()) static gboolean teamd_start (NMDevice *dev, NMSettingTeam *s_team); @@ -75,7 +75,7 @@ enum { /******************************************************************/ static GQuark -nm_team_error_quark (void) +nm_device_team_error_quark (void) { static GQuark quark = 0; if (!quark) @@ -889,5 +889,5 @@ nm_device_team_class_init (NMDeviceTeamClass *klass) G_TYPE_FROM_CLASS (klass), &dbus_glib_nm_device_team_object_info); - dbus_g_error_domain_register (NM_TEAM_ERROR, NULL, NM_TYPE_TEAM_ERROR); + dbus_g_error_domain_register (NM_DEVICE_TEAM_ERROR, NULL, NM_TYPE_TEAM_ERROR); } diff --git a/src/devices/nm-device-team.h b/src/devices/nm-device-team.h index fe1275c6b0..32bc5fd86f 100644 --- a/src/devices/nm-device-team.h +++ b/src/devices/nm-device-team.h @@ -35,9 +35,9 @@ G_BEGIN_DECLS #define NM_DEVICE_TEAM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_TEAM, NMDeviceTeamClass)) typedef enum { - NM_TEAM_ERROR_CONNECTION_NOT_TEAM = 0, /*< nick=ConnectionNotTeam >*/ - NM_TEAM_ERROR_CONNECTION_INVALID, /*< nick=ConnectionInvalid >*/ - NM_TEAM_ERROR_CONNECTION_INCOMPATIBLE, /*< nick=ConnectionIncompatible >*/ + NM_DEVICE_TEAM_ERROR_CONNECTION_NOT_TEAM = 0, /*< nick=ConnectionNotTeam >*/ + NM_DEVICE_TEAM_ERROR_CONNECTION_INVALID, /*< nick=ConnectionInvalid >*/ + NM_DEVICE_TEAM_ERROR_CONNECTION_INCOMPATIBLE, /*< nick=ConnectionIncompatible >*/ } NMTeamError; #define NM_DEVICE_TEAM_SLAVES "slaves" From 4c206d0aaf094b16184e58a0b69f236896bc4eb9 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Wed, 18 Jun 2014 20:17:57 +0200 Subject: [PATCH 3/6] core: refactor update_slave_connection() as virtual function of master device Signed-off-by: Thomas Haller --- src/devices/nm-device-bond.c | 14 +++++ src/devices/nm-device-bridge.c | 33 +++++----- src/devices/nm-device-bridge.h | 2 - src/devices/nm-device-team.c | 85 ++++++++++++++----------- src/devices/nm-device-team.h | 4 +- src/devices/nm-device.c | 110 ++++++++++++++++++--------------- src/devices/nm-device.h | 13 +++- src/nm-manager.c | 22 ++++++- 8 files changed, 176 insertions(+), 107 deletions(-) diff --git a/src/devices/nm-device-bond.c b/src/devices/nm-device-bond.c index 917d457141..cd5e95f908 100644 --- a/src/devices/nm-device-bond.c +++ b/src/devices/nm-device-bond.c @@ -243,6 +243,19 @@ update_connection (NMDevice *device, NMConnection *connection) } } +static gboolean +master_update_slave_connection (NMDevice *self, + NMDevice *slave, + NMConnection *connection, + GError **error) +{ + g_object_set (nm_connection_get_setting_connection (connection), + NM_SETTING_CONNECTION_MASTER, nm_device_get_iface (self), + NM_SETTING_CONNECTION_SLAVE_TYPE, NM_SETTING_BOND_SETTING_NAME, + NULL); + return TRUE; +} + static void set_arp_targets (NMDevice *device, const char *value, @@ -590,6 +603,7 @@ nm_device_bond_class_init (NMDeviceBondClass *klass) parent_class->complete_connection = complete_connection; parent_class->update_connection = update_connection; + parent_class->master_update_slave_connection = master_update_slave_connection; parent_class->act_stage1_prepare = act_stage1_prepare; parent_class->enslave_slave = enslave_slave; diff --git a/src/devices/nm-device-bridge.c b/src/devices/nm-device-bridge.c index cbf6ccf7d8..b00446af0c 100644 --- a/src/devices/nm-device-bridge.c +++ b/src/devices/nm-device-bridge.c @@ -322,27 +322,21 @@ update_connection (NMDevice *device, NMConnection *connection) } } -/** - * nm_bridge_update_slave_connection: - * @slave: the slave #NMDevice, is *not* necessarily a bridge interface - * @connection: the #NMConnection to update with the bridge port settings - * - * Reads bridge port configuration and updates @connection with those - * properties. - * - * Returns: %TRUE if the port configuration was read and @connection updated, - * %FALSE if not. - */ -gboolean -nm_bridge_update_slave_connection (NMDevice *slave, NMConnection *connection) +static gboolean +master_update_slave_connection (NMDevice *self, + NMDevice *slave, + NMConnection *connection, + GError **error) { + NMSettingConnection *s_con; NMSettingBridgePort *s_port; - int ifindex = nm_device_get_ifindex (slave); + int ifindex_slave = nm_device_get_ifindex (slave); + const char *iface = nm_device_get_iface (self); const Option *option; - g_return_val_if_fail (NM_IS_DEVICE (slave), FALSE); - g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE); + g_return_val_if_fail (ifindex_slave > 0, FALSE); + s_con = nm_connection_get_setting_connection (connection); s_port = nm_connection_get_setting_bridge_port (connection); if (!s_port) { s_port = (NMSettingBridgePort *) nm_setting_bridge_port_new (); @@ -350,7 +344,7 @@ nm_bridge_update_slave_connection (NMDevice *slave, NMConnection *connection) } for (option = slave_options; option->name; option++) { - gs_free char *str = nm_platform_slave_get_option (ifindex, option->sysname); + gs_free char *str = nm_platform_slave_get_option (ifindex_slave, option->sysname); int value; if (str) { @@ -367,6 +361,10 @@ nm_bridge_update_slave_connection (NMDevice *slave, NMConnection *connection) } } + g_object_set (s_con, + NM_SETTING_CONNECTION_MASTER, iface, + NM_SETTING_CONNECTION_SLAVE_TYPE, NM_SETTING_BRIDGE_SETTING_NAME, + NULL); return TRUE; } @@ -566,6 +564,7 @@ nm_device_bridge_class_init (NMDeviceBridgeClass *klass) parent_class->complete_connection = complete_connection; parent_class->update_connection = update_connection; + parent_class->master_update_slave_connection = master_update_slave_connection; parent_class->act_stage1_prepare = act_stage1_prepare; parent_class->enslave_slave = enslave_slave; diff --git a/src/devices/nm-device-bridge.h b/src/devices/nm-device-bridge.h index 4194f5a411..5570c73555 100644 --- a/src/devices/nm-device-bridge.h +++ b/src/devices/nm-device-bridge.h @@ -57,8 +57,6 @@ GType nm_device_bridge_get_type (void); NMDevice *nm_device_bridge_new (NMPlatformLink *platform_device); NMDevice *nm_device_bridge_new_for_connection (NMConnection *connection); -gboolean nm_bridge_update_slave_connection (NMDevice *slave, NMConnection *connection); - G_END_DECLS #endif /* NM_DEVICE_BRIDGE_H */ diff --git a/src/devices/nm-device-team.c b/src/devices/nm-device-team.c index e9dfbf38a2..67f3b0d3cf 100644 --- a/src/devices/nm-device-team.c +++ b/src/devices/nm-device-team.c @@ -245,44 +245,63 @@ update_connection (NMDevice *device, NMConnection *connection) /******************************************************************/ -gboolean -nm_team_update_slave_connection (NMDevice *slave, NMConnection *connection) +static gboolean +master_update_slave_connection (NMDevice *self, + NMDevice *slave, + NMConnection *connection, + GError **error) { - NMSettingTeamPort *s_port; - const char *iface = nm_device_get_iface (slave); - char *port_config = NULL; - gboolean with_teamdctl = FALSE; - int err = 0; #if WITH_TEAMDCTL - const char *master_iface; - int master_ifindex; + NMSettingTeamPort *s_port; + char *port_config = NULL; + int err = 0; struct teamdctl *tdc; const char *team_port_config = NULL; #endif + const char *iface = nm_device_get_iface (self); + const char *iface_slave = nm_device_get_iface (slave); - g_return_val_if_fail (NM_IS_DEVICE (slave), FALSE); - g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE); - -#if WITH_TEAMDCTL - master_ifindex = nm_platform_link_get_master (nm_device_get_ifindex (slave)); - g_assert (master_ifindex > 0); - master_iface = nm_platform_link_get_name (master_ifindex); - g_assert (master_iface); - +#if !WITH_TEAMDCTL + g_set_error (error, + NM_DEVICE_TEAM_ERROR, + NM_DEVICE_TEAM_ERROR_NO_SUPPORT, + "update slave connection for slave '%s' failed for team master '%s' because compiled without libteamctl support", + iface_slave, iface); + return FALSE; +#else tdc = teamdctl_alloc (); - g_assert (tdc); - err = teamdctl_connect (tdc, master_iface, NULL, NULL); + if (!tdc) { + g_set_error (error, + NM_DEVICE_TEAM_ERROR, + NM_DEVICE_TEAM_ERROR_TEAMCTL_FAILURE, + "update slave connection for slave '%s' failed to connect to teamd for master %s (out of memory?)", + iface_slave, iface); + g_return_val_if_reached (FALSE); + } + + err = teamdctl_connect (tdc, iface, NULL, NULL); if (err) { - nm_log_err (LOGD_TEAM, "(%s): failed to connect to teamd for master %s (err=%d)", - iface, master_iface, err); teamdctl_free (tdc); + g_set_error (error, + NM_DEVICE_TEAM_ERROR, + NM_DEVICE_TEAM_ERROR_TEAMCTL_FAILURE, + "update slave connection for slave '%s' failed to connect to teamd for master %s (err=%d)", + iface_slave, iface, err); return FALSE; } - err = teamdctl_port_config_get_raw_direct (tdc, iface, (char **)&team_port_config); + + err = teamdctl_port_config_get_raw_direct (tdc, iface_slave, (char **)&team_port_config); port_config = g_strdup (team_port_config); teamdctl_free (tdc); - with_teamdctl = TRUE; -#endif + if (err) { + g_set_error (error, + NM_DEVICE_TEAM_ERROR, + NM_DEVICE_TEAM_ERROR_TEAMCTL_FAILURE, + "update slave connection for slave '%s' failed to get configuration from teamd master %s (err=%d)", + iface_slave, iface, err); + g_free (port_config); + return FALSE; + } s_port = nm_connection_get_setting_team_port (connection); if (!s_port) { @@ -293,17 +312,12 @@ nm_team_update_slave_connection (NMDevice *slave, NMConnection *connection) g_object_set (G_OBJECT (s_port), NM_SETTING_TEAM_PORT_CONFIG, port_config, NULL); g_free (port_config); - if (!with_teamdctl || err != 0) { - if (!with_teamdctl) - nm_log_err (LOGD_TEAM, "(%s): failed to read teamd port configuration " - " (compiled without libteamdctl support)", iface); - else - nm_log_err (LOGD_TEAM, "(%s): failed to read teamd port configuration (err=%d)", - iface, err); - return FALSE; - } - + g_object_set (nm_connection_get_setting_connection (connection), + NM_SETTING_CONNECTION_MASTER, iface, + NM_SETTING_CONNECTION_SLAVE_TYPE, NM_SETTING_TEAM_SETTING_NAME, + NULL); return TRUE; +#endif } /******************************************************************/ @@ -871,6 +885,7 @@ nm_device_team_class_init (NMDeviceTeamClass *klass) parent_class->check_connection_available = check_connection_available; parent_class->complete_connection = complete_connection; parent_class->update_connection = update_connection; + parent_class->master_update_slave_connection = master_update_slave_connection; parent_class->act_stage1_prepare = act_stage1_prepare; parent_class->deactivate = deactivate; diff --git a/src/devices/nm-device-team.h b/src/devices/nm-device-team.h index 32bc5fd86f..9af0bb3c6d 100644 --- a/src/devices/nm-device-team.h +++ b/src/devices/nm-device-team.h @@ -38,6 +38,8 @@ typedef enum { NM_DEVICE_TEAM_ERROR_CONNECTION_NOT_TEAM = 0, /*< nick=ConnectionNotTeam >*/ NM_DEVICE_TEAM_ERROR_CONNECTION_INVALID, /*< nick=ConnectionInvalid >*/ NM_DEVICE_TEAM_ERROR_CONNECTION_INCOMPATIBLE, /*< nick=ConnectionIncompatible >*/ + NM_DEVICE_TEAM_ERROR_TEAMCTL_FAILURE, /*< nick=TeamCtlFailure >*/ + NM_DEVICE_TEAM_ERROR_NO_SUPPORT, /*< nick=NoSupport >*/ } NMTeamError; #define NM_DEVICE_TEAM_SLAVES "slaves" @@ -57,8 +59,6 @@ GType nm_device_team_get_type (void); NMDevice *nm_device_team_new (NMPlatformLink *platform_device); NMDevice *nm_device_team_new_for_connection (NMConnection *connection); -gboolean nm_team_update_slave_connection (NMDevice *slave, NMConnection *connection); - G_END_DECLS #endif /* NM_DEVICE_TEAM_H */ diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index 84c714a102..2ee1c4937b 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -70,10 +70,6 @@ #include "nm-config.h" #include "nm-dns-manager.h" -#include "nm-device-bridge.h" -#include "nm-device-bond.h" -#include "nm-device-team.h" - static void impl_device_disconnect (NMDevice *device, DBusGMethodInvocation *context); #include "nm-device-glue.h" @@ -1627,20 +1623,67 @@ device_has_config (NMDevice *device) return FALSE; } +/** + * nm_device_master_update_slave_connection: + * @self: the master #NMDevice + * @slave: the slave #NMDevice + * @connection: the #NMConnection to update with the slave settings + * @GError: (out): error description + * + * Reads the slave configuration for @slave and updates @connection with those + * properties. This invokes a virtual function on the master device @self. + * + * Returns: %TRUE if the configuration was read and @connection updated, + * %FALSE on failure. + */ +gboolean +nm_device_master_update_slave_connection (NMDevice *self, + NMDevice *slave, + NMConnection *connection, + GError **error) +{ + NMDeviceClass *klass; + gboolean success; + const char *iface; + + g_return_val_if_fail (self, FALSE); + g_return_val_if_fail (NM_IS_DEVICE (self), FALSE); + g_return_val_if_fail (slave, FALSE); + g_return_val_if_fail (connection, FALSE); + g_return_val_if_fail (!error || !*error, FALSE); + g_return_val_if_fail (nm_connection_get_setting_connection (connection), FALSE); + + iface = nm_device_get_iface (self); + g_return_val_if_fail (iface, FALSE); + + klass = NM_DEVICE_GET_CLASS (self); + if (klass->master_update_slave_connection) { + success = klass->master_update_slave_connection (self, slave, connection, error); + + g_return_val_if_fail (!error || (success && !*error) || *error, success); + return success; + } + + g_set_error (error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_UNSUPPORTED_DEVICE_TYPE, + "master device '%s' cannot update a slave connection for slave device '%s' (master type not supported?)", + iface, nm_device_get_iface (slave)); + return FALSE; +} + NMConnection * -nm_device_generate_connection (NMDevice *device) +nm_device_generate_connection (NMDevice *device, NMDevice *master) { NMDeviceClass *klass = NM_DEVICE_GET_CLASS (device); NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device); const char *ifname = nm_device_get_iface (device); - int ifindex = nm_device_get_ifindex (device); NMConnection *connection; NMSetting *s_con; NMSetting *s_ip4; NMSetting *s_ip6; gs_free char *uuid = NULL; gs_free char *name = NULL; - int master_ifindex = 0; const char *ip4_method, *ip6_method; GError *error = NULL; @@ -1654,19 +1697,6 @@ nm_device_generate_connection (NMDevice *device) return NULL; } - if (ifindex) - master_ifindex = nm_platform_link_get_master (ifindex); - if (master_ifindex) { - NMDevice *master; - - master = nm_manager_get_device_by_ifindex (nm_manager_get (), master_ifindex); - if (!master || !nm_device_get_act_request (master)) { - nm_log_dbg (LOGD_DEVICE, "(%s): cannot generate connection for slave before its master (%s)", - ifname, nm_platform_link_get_name (master_ifindex)); - return NULL; - } - } - connection = nm_connection_new (); s_con = nm_setting_connection_new (); uuid = nm_utils_uuid_generate (); @@ -1684,36 +1714,18 @@ nm_device_generate_connection (NMDevice *device) nm_connection_add_setting (connection, s_con); /* If the device is a slave, update various slave settings */ - if (master_ifindex) { - const char *master_iface = nm_platform_link_get_name (master_ifindex); - const char *slave_type = NULL; - gboolean success = FALSE; - - switch (nm_platform_link_get_type (master_ifindex)) { - case NM_LINK_TYPE_BRIDGE: - slave_type = NM_SETTING_BRIDGE_SETTING_NAME; - success = nm_bridge_update_slave_connection (device, connection); - break; - case NM_LINK_TYPE_BOND: - slave_type = NM_SETTING_BOND_SETTING_NAME; - success = TRUE; - break; - case NM_LINK_TYPE_TEAM: - slave_type = NM_SETTING_TEAM_SETTING_NAME; - success = nm_team_update_slave_connection (device, connection); - break; - default: - g_warn_if_reached (); - break; + if (master) { + if (!nm_device_master_update_slave_connection (master, + device, + connection, + &error)) + { + nm_log_err (LOGD_DEVICE, "(%s): master device '%s' failed to update slave connection: %s", + ifname, nm_device_get_iface (master), error ? error->message : "(unknown error)"); + g_error_free (error); + g_object_unref (connection); + return NULL; } - - if (!success) - nm_log_err (LOGD_DEVICE, "(%s): failed to read slave configuration", ifname); - - g_object_set (s_con, - NM_SETTING_CONNECTION_MASTER, master_iface, - NM_SETTING_CONNECTION_SLAVE_TYPE, slave_type, - NULL); } else { /* Only regular and master devices get IP configuration; slaves do not */ s_ip4 = nm_ip4_config_create_setting (priv->ip4_config); diff --git a/src/devices/nm-device.h b/src/devices/nm-device.h index f74486e6fc..d034c946dc 100644 --- a/src/devices/nm-device.h +++ b/src/devices/nm-device.h @@ -94,6 +94,7 @@ typedef enum { NM_DEVICE_ERROR_CONNECTION_ACTIVATING = 0, /*< nick=ConnectionActivating >*/ NM_DEVICE_ERROR_CONNECTION_INVALID, /*< nick=ConnectionInvalid >*/ NM_DEVICE_ERROR_NOT_ACTIVE, /*< nick=NotActive >*/ + NM_DEVICE_ERROR_UNSUPPORTED_DEVICE_TYPE, /*< nick=UnsupportedDeviceType >*/ } NMDeviceError; struct _NMDevice { @@ -192,6 +193,11 @@ typedef struct { /* Update the connection with currently configured L2 settings */ void (* update_connection) (NMDevice *device, NMConnection *connection); + gboolean (*master_update_slave_connection) (NMDevice *self, + NMDevice *slave, + NMConnection *connection, + GError **error); + gboolean (* enslave_slave) (NMDevice *self, NMDevice *slave, NMConnection *connection, @@ -258,7 +264,12 @@ NMConnection * nm_device_get_connection (NMDevice *dev); gboolean nm_device_is_available (NMDevice *dev); gboolean nm_device_has_carrier (NMDevice *dev); -NMConnection * nm_device_generate_connection (NMDevice *device); +NMConnection * nm_device_generate_connection (NMDevice *device, NMDevice *master); + +gboolean nm_device_master_update_slave_connection (NMDevice *master, + NMDevice *slave, + NMConnection *connection, + GError **error); NMConnection * nm_device_get_best_auto_connection (NMDevice *dev, GSList *connections, diff --git a/src/nm-manager.c b/src/nm-manager.c index 13b4a01417..052ccb7834 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -1557,16 +1557,36 @@ get_existing_connection (NMManager *manager, NMDevice *device) NMConnection *connection = NULL, *matched; NMSettingsConnection *added = NULL; GError *error = NULL; + NMDevice *master = NULL; + int ifindex = nm_device_get_ifindex (device); nm_device_capture_initial_config (device); + if (ifindex) { + int master_ifindex = nm_platform_link_get_master (ifindex); + + if (master_ifindex) { + master = nm_manager_get_device_by_ifindex (manager, master_ifindex); + if (!master) { + nm_log_dbg (LOGD_DEVICE, "(%s): cannot generate connection for slave before its master (%s/%d)", + nm_device_get_iface (device), nm_platform_link_get_name (master_ifindex), master_ifindex); + return NULL; + } + if (!nm_device_get_act_request (master)) { + nm_log_dbg (LOGD_DEVICE, "(%s): cannot generate connection for slave before master %s activates", + nm_device_get_iface (device), nm_device_get_iface (master)); + return NULL; + } + } + } + /* The core of the API is nm_device_generate_connection() function and * update_connection() virtual method and the convenient connection_type * class attribute. Subclasses supporting the new API must have * update_connection() implemented, otherwise nm_device_generate_connection() * returns NULL. */ - connection = nm_device_generate_connection (device); + connection = nm_device_generate_connection (device, master); if (!connection) return NULL; From dfe4b45f87a9302c55542848b102f07a6ddf50f3 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Thu, 19 Jun 2014 08:42:35 +0200 Subject: [PATCH 4/6] core: allow creation of virtual devices (software devices) via NMDeviceFactory Signed-off-by: Thomas Haller --- src/devices/nm-device-factory.c | 17 +++++++++++++++++ src/devices/nm-device-factory.h | 22 ++++++++++++++++++++++ src/nm-manager.c | 16 ++++++++++++++++ 3 files changed, 55 insertions(+) diff --git a/src/devices/nm-device-factory.c b/src/devices/nm-device-factory.c index fc4d1c248a..5e84531135 100644 --- a/src/devices/nm-device-factory.c +++ b/src/devices/nm-device-factory.c @@ -104,3 +104,20 @@ nm_device_factory_new_link (NMDeviceFactory *factory, return NULL; } +NMDevice * +nm_device_factory_create_virtual_device_for_connection (NMDeviceFactory *factory, + NMConnection *connection, + GError **error) +{ + NMDeviceFactory *interface; + + g_return_val_if_fail (factory, NULL); + g_return_val_if_fail (connection, NULL); + g_return_val_if_fail (!error || !*error, NULL); + + interface = NM_DEVICE_FACTORY_GET_INTERFACE (factory); + if (interface->create_virtual_device_for_connection) + return interface->create_virtual_device_for_connection (factory, connection, error); + return NULL; +} + diff --git a/src/devices/nm-device-factory.h b/src/devices/nm-device-factory.h index f0e3dc1978..ef412c96d2 100644 --- a/src/devices/nm-device-factory.h +++ b/src/devices/nm-device-factory.h @@ -95,6 +95,24 @@ struct _NMDeviceFactory { NMPlatformLink *plink, GError **error); + /** + * create_virtual_device_for_connection: + * @factory: the #NMDeviceFactory + * @connection: the #NMConnection + * @error: a @GError in case of failure + * + * Virtual device types (such as team, bond, bridge) may need to be created. + * This function tries to create a device based on the given @connection. + * + * Returns: the newly created #NMDevice. If the factory does not support the + * connection type, it should return %NULL and leave @error unset. On error + * it should set @error and return %NULL. + */ + NMDevice * (*create_virtual_device_for_connection) (NMDeviceFactory *factory, + NMConnection *connection, + GError **error); + + /* Signals */ /** @@ -128,6 +146,10 @@ NMDevice * nm_device_factory_new_link (NMDeviceFactory *factory, NMPlatformLink *plink, GError **error); +NMDevice * nm_device_factory_create_virtual_device_for_connection (NMDeviceFactory *factory, + NMConnection *connection, + GError **error); + /* For use by implementations */ gboolean nm_device_factory_emit_component_added (NMDeviceFactory *factory, GObject *component); diff --git a/src/nm-manager.c b/src/nm-manager.c index 052ccb7834..6c6176e6c1 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -1074,6 +1074,7 @@ static NMDevice * system_create_virtual_device (NMManager *self, NMConnection *connection) { NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); + GError *error = NULL; GSList *iter; char *iface = NULL; NMDevice *device = NULL, *parent = NULL; @@ -1110,6 +1111,21 @@ system_create_virtual_device (NMManager *self, NMConnection *connection) device = nm_device_vlan_new_for_connection (connection, parent); } else if (nm_connection_is_type (connection, NM_SETTING_INFINIBAND_SETTING_NAME)) { device = nm_device_infiniband_new_partition (connection, parent); + } else { + for (iter = priv->factories; iter; iter = iter->next) { + device = nm_device_factory_create_virtual_device_for_connection (NM_DEVICE_FACTORY (iter->data), connection, &error); + + if (device || error) { + if (device) + g_assert_no_error (error); + else { + nm_log_err (LOGD_DEVICE, "(%s) failed to create virtual device: %s", + nm_connection_get_id (connection), error ? error->message : "(unknown error)"); + g_clear_error (&error); + } + break; + } + } } if (device) { From 38a83e15a2f741a4a038ce5c55f1ad41b59f69a1 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Wed, 18 Jun 2014 11:10:52 +0200 Subject: [PATCH 5/6] team: make team support a plugin Signed-off-by: Thomas Haller --- configure.ac | 1 + contrib/fedora/rpm/NetworkManager.spec | 29 +++++-- po/POTFILES.in | 2 +- src/Makefile.am | 14 +-- src/devices/team/Makefile.am | 74 ++++++++++++++++ src/devices/team/exports.ver | 7 ++ src/devices/{ => team}/nm-device-team.c | 8 +- src/devices/{ => team}/nm-device-team.h | 3 +- src/devices/team/nm-team-factory.c | 109 ++++++++++++++++++++++++ src/devices/team/nm-team-factory.h | 37 ++++++++ src/nm-manager.c | 6 -- 11 files changed, 262 insertions(+), 28 deletions(-) create mode 100644 src/devices/team/Makefile.am create mode 100644 src/devices/team/exports.ver rename src/devices/{ => team}/nm-device-team.c (98%) rename src/devices/{ => team}/nm-device-team.h (96%) create mode 100644 src/devices/team/nm-team-factory.c create mode 100644 src/devices/team/nm-team-factory.h diff --git a/configure.ac b/configure.ac index 8634203e2d..848a1970b7 100644 --- a/configure.ac +++ b/configure.ac @@ -811,6 +811,7 @@ src/rdisc/tests/Makefile src/devices/adsl/Makefile src/devices/wimax/Makefile src/devices/bluetooth/Makefile +src/devices/team/Makefile src/devices/wifi/Makefile src/devices/wifi/tests/Makefile src/devices/wwan/Makefile diff --git a/contrib/fedora/rpm/NetworkManager.spec b/contrib/fedora/rpm/NetworkManager.spec index 99cb9099fc..f4b22e8c92 100644 --- a/contrib/fedora/rpm/NetworkManager.spec +++ b/contrib/fedora/rpm/NetworkManager.spec @@ -36,6 +36,7 @@ %global with_adsl 1 %global with_bluetooth 1 +%global with_team 1 %global with_wifi 1 %global with_wimax 0 %global with_wwan 1 @@ -59,8 +60,8 @@ %global with_wwan 0 %endif -%if 0%{?rhel} || (0%{?fedora} > 19) -%global with_teamctl 1 +%if (0%{?fedora} && 0%{?fedora} <= 19) +%global with_team 0 %endif @@ -155,9 +156,6 @@ BuildRequires: ModemManager-glib-devel >= 1.0 %if 0%{?with_nmtui} BuildRequires: newt-devel %endif -%if 0%{?with_teamctl} -BuildRequires: teamd-devel -%endif %description @@ -200,6 +198,19 @@ This package contains NetworkManager support for Bluetooth devices. %endif +%if 0%{?with_team} +%package team +Summary: Team device plugin for NetworkManager +Group: System Environment/Base +BuildRequires: teamd-devel +Requires: %{name}%{?_isa} = %{epoch}:%{version}-%{release} +Obsoletes: NetworkManager < %{obsoletes_nmver} + +%description team +This package contains NetworkManager support for team devices. +%endif + + %if 0%{?with_wifi} %package wifi Summary: Wifi plugin for NetworkManager @@ -347,7 +358,7 @@ by nm-connection-editor and nm-applet in a non-graphical environment. %else --with-wext=no \ %endif -%if 0%{?with_teamctl} +%if 0%{?with_team} --enable-teamdctl=yes \ %else --enable-teamdctl=no \ @@ -489,6 +500,12 @@ fi %exclude %{_libdir}/%{name}/libnm-device-plugin-bluetooth.so %endif +%if 0%{?with_team} +%files team +%defattr(-,root,root,0755) +%{_libdir}/%{name}/libnm-device-plugin-team.so +%endif + %if 0%{?with_wifi} %files wifi %defattr(-,root,root,0755) diff --git a/po/POTFILES.in b/po/POTFILES.in index 6368a9f59f..673a9e6244 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -53,8 +53,8 @@ src/devices/nm-device-bond.c src/devices/nm-device-bridge.c src/devices/nm-device-ethernet.c src/devices/nm-device-infiniband.c -src/devices/nm-device-team.c src/devices/nm-device-vlan.c +src/devices/team/nm-device-team.c src/devices/wifi/nm-device-olpc-mesh.c src/devices/wwan/nm-modem-broadband.c src/devices/wwan/nm-modem-old.c diff --git a/src/Makefile.am b/src/Makefile.am index c454127176..e620548738 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -5,7 +5,8 @@ include $(GLIB_MAKEFILE) SUBDIRS = \ . \ devices/adsl \ - devices/wifi \ + devices/team \ + devices/wifi \ dhcp-manager \ ppp-manager \ settings/plugins @@ -84,8 +85,6 @@ nm_sources = \ devices/nm-device-macvlan.c \ devices/nm-device-macvlan.h \ devices/nm-device-private.h \ - devices/nm-device-team.c \ - devices/nm-device-team.h \ devices/nm-device-tun.c \ devices/nm-device-tun.h \ devices/nm-device-veth.c \ @@ -296,7 +295,6 @@ glue_sources = \ nm-device-gre-glue.h \ nm-device-infiniband-glue.h \ nm-device-macvlan-glue.h \ - nm-device-team-glue.h \ nm-device-tun-glue.h \ nm-device-veth-glue.h \ nm-device-vlan-glue.h \ @@ -351,10 +349,6 @@ if SESSION_TRACKING_CK AM_CPPFLAGS += -DCKDB_PATH=\"${CKDB_PATH}\" endif -if WITH_TEAMDCTL -AM_CPPFLAGS += ${LIBTEAMDCTL_CFLAGS} -endif - libNetworkManager_la_SOURCES = \ $(nm_sources) \ $(glue_sources) @@ -375,10 +369,6 @@ if WITH_CONCHECK libNetworkManager_la_LIBADD += $(LIBSOUP_LIBS) endif -if WITH_TEAMDCTL -libNetworkManager_la_LIBADD += $(LIBTEAMDCTL_LIBS) -endif - NetworkManager_LDFLAGS = -rdynamic dbusservicedir = $(DBUS_SYS_DIR) diff --git a/src/devices/team/Makefile.am b/src/devices/team/Makefile.am new file mode 100644 index 0000000000..e2bfd0a04a --- /dev/null +++ b/src/devices/team/Makefile.am @@ -0,0 +1,74 @@ +include $(GLIB_MAKEFILE) + +@GNOME_CODE_COVERAGE_RULES@ + +AM_CPPFLAGS = \ + -I${top_srcdir}/src \ + -I${top_builddir}/src \ + -I${top_srcdir}/src/logging \ + -I${top_srcdir}/src/devices \ + -I${top_srcdir}/src/settings \ + -I${top_srcdir}/src/platform \ + -I${top_srcdir}/src/posix-signals \ + -I${top_builddir}/include \ + -I${top_srcdir}/include \ + -I${top_builddir}/libnm-util \ + -I${top_srcdir}/libnm-util \ + -DG_LOG_DOMAIN=\""NetworkManager-team"\" \ + -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ + $(DBUS_CFLAGS) \ + $(POLKIT_CFLAGS) \ + $(LIBNL_CFLAGS) \ + $(GUDEV_CFLAGS) + +if WITH_TEAMDCTL +AM_CPPFLAGS += ${LIBTEAMDCTL_CFLAGS} +endif + +GLIB_GENERATED = nm-team-enum-types.h nm-team-enum-types.c +GLIB_MKENUMS_H_FLAGS = --identifier-prefix NM +GLIB_MKENUMS_C_FLAGS = --identifier-prefix NM +nm_team_enum_types_sources = $(srcdir)/nm-device-team.h + +glue_sources = \ + nm-device-team-glue.h + +%-glue.h: $(top_srcdir)/introspection/%.xml + $(AM_V_GEN) dbus-binding-tool --prefix=$(subst -,_,$(subst -glue.h,,$@)) --mode=glib-server --output=$@ $< + +BUILT_SOURCES = $(GLIB_GENERATED) $(glue_sources) + +pkglib_LTLIBRARIES = libnm-device-plugin-team.la + +SYMBOL_VIS_FILE=$(srcdir)/exports.ver + +libnm_device_plugin_team_la_SOURCES = \ + nm-device-team.c \ + nm-device-team.h \ + nm-team-factory.c \ + nm-team-factory.h \ + \ + $(BUILT_SOURCES) + +libnm_device_plugin_team_la_LDFLAGS = \ + -module -avoid-version \ + -Wl,--version-script=$(SYMBOL_VIS_FILE) + +libnm_device_plugin_team_la_LIBADD = \ + $(DBUS_LIBS) \ + $(GUDEV_LIBS) + +if WITH_TEAMDCTL +libnm_device_plugin_team_la_LIBADD += $(LIBTEAMDCTL_LIBS) +endif + +CLEANFILES = $(BUILT_SOURCES) +EXTRA_DIST = $(SYMBOL_VIS_FILE) + +if ENABLE_TESTS + +check-local: + $(top_srcdir)/tools/check-exports.sh $(builddir)/.libs/libnm-device-plugin-team.so $(SYMBOL_VIS_FILE) + +endif + diff --git a/src/devices/team/exports.ver b/src/devices/team/exports.ver new file mode 100644 index 0000000000..d2c451244b --- /dev/null +++ b/src/devices/team/exports.ver @@ -0,0 +1,7 @@ +{ +global: + nm_device_factory_create; + nm_device_factory_get_device_type; +local: + *; +}; diff --git a/src/devices/nm-device-team.c b/src/devices/team/nm-device-team.c similarity index 98% rename from src/devices/nm-device-team.c rename to src/devices/team/nm-device-team.c index 67f3b0d3cf..8b27cc1561 100644 --- a/src/devices/nm-device-team.c +++ b/src/devices/team/nm-device-team.c @@ -42,6 +42,7 @@ #include "nm-dbus-glib-types.h" #include "nm-dbus-manager.h" #include "nm-enum-types.h" +#include "nm-team-enum-types.h" #include "nm-posix-signals.h" #include "nm-device-team-glue.h" @@ -780,7 +781,7 @@ nm_device_team_new (NMPlatformLink *platform_device) } NMDevice * -nm_device_team_new_for_connection (NMConnection *connection) +nm_device_team_new_for_connection (NMConnection *connection, GError **error) { const char *iface; @@ -791,7 +792,10 @@ nm_device_team_new_for_connection (NMConnection *connection) if ( !nm_platform_team_add (iface) && nm_platform_get_error () != NM_PLATFORM_ERROR_EXISTS) { - nm_log_warn (LOGD_DEVICE | LOGD_TEAM, "(%s): failed to create team master interface for '%s': %s", + g_set_error (error, + NM_DEVICE_TEAM_ERROR, + NM_DEVICE_TEAM_ERROR_PLATFORM_FAILURE, + "failed to create team master interface '%s' for connection '%s': %s", iface, nm_connection_get_id (connection), nm_platform_get_error_msg ()); return NULL; diff --git a/src/devices/nm-device-team.h b/src/devices/team/nm-device-team.h similarity index 96% rename from src/devices/nm-device-team.h rename to src/devices/team/nm-device-team.h index 9af0bb3c6d..fb2a184115 100644 --- a/src/devices/nm-device-team.h +++ b/src/devices/team/nm-device-team.h @@ -40,6 +40,7 @@ typedef enum { NM_DEVICE_TEAM_ERROR_CONNECTION_INCOMPATIBLE, /*< nick=ConnectionIncompatible >*/ NM_DEVICE_TEAM_ERROR_TEAMCTL_FAILURE, /*< nick=TeamCtlFailure >*/ NM_DEVICE_TEAM_ERROR_NO_SUPPORT, /*< nick=NoSupport >*/ + NM_DEVICE_TEAM_ERROR_PLATFORM_FAILURE, /*< nick=PlatformFailure >*/ } NMTeamError; #define NM_DEVICE_TEAM_SLAVES "slaves" @@ -57,7 +58,7 @@ typedef struct { GType nm_device_team_get_type (void); NMDevice *nm_device_team_new (NMPlatformLink *platform_device); -NMDevice *nm_device_team_new_for_connection (NMConnection *connection); +NMDevice *nm_device_team_new_for_connection (NMConnection *connection, GError **error); G_END_DECLS diff --git a/src/devices/team/nm-team-factory.c b/src/devices/team/nm-team-factory.c new file mode 100644 index 0000000000..ab97de320b --- /dev/null +++ b/src/devices/team/nm-team-factory.c @@ -0,0 +1,109 @@ +/* -*- 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) 2014 Red Hat, Inc. + */ + +#include +#include + +#include "config.h" +#include "nm-device-factory.h" +#include "nm-team-factory.h" +#include "nm-device-team.h" +#include "nm-logging.h" + +static GType nm_team_factory_get_type (void); + +static void device_factory_interface_init (NMDeviceFactory *factory_iface); + +G_DEFINE_TYPE_EXTENDED (NMTeamFactory, nm_team_factory, G_TYPE_OBJECT, 0, + G_IMPLEMENT_INTERFACE (NM_TYPE_DEVICE_FACTORY, device_factory_interface_init)) + +#define NM_TEAM_FACTORY_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_TEAM_FACTORY, NMTeamFactoryPrivate)) + +typedef struct { + char dummy; +} NMTeamFactoryPrivate; + + +/************************************************************************/ + +static NMDevice * +new_link (NMDeviceFactory *factory, NMPlatformLink *plink, GError **error) +{ + if (plink->type == NM_LINK_TYPE_TEAM) + return nm_device_team_new (plink); + return NULL; +} + +static NMDevice * +create_virtual_device_for_connection (NMDeviceFactory *factory, + NMConnection *connection, + GError **error) +{ + if (nm_connection_is_type (connection, NM_SETTING_TEAM_SETTING_NAME)) + return nm_device_team_new_for_connection (connection, error); + return NULL; +} + +/************************************************************************/ + +#define PLUGIN_TYPE NM_DEVICE_TYPE_TEAM + +G_MODULE_EXPORT NMDeviceFactory * +nm_device_factory_create (GError **error) +{ + return (NMDeviceFactory *) g_object_new (NM_TYPE_TEAM_FACTORY, NULL); +} + +G_MODULE_EXPORT NMDeviceType +nm_device_factory_get_device_type (void) +{ + return PLUGIN_TYPE; +} + +/************************************************************************/ + +static void +nm_team_factory_init (NMTeamFactory *self) +{ +} + +static void +device_factory_interface_init (NMDeviceFactory *factory_iface) +{ + factory_iface->new_link = new_link; + factory_iface->create_virtual_device_for_connection = create_virtual_device_for_connection; +} + +static void +dispose (GObject *object) +{ + /* Chain up to the parent class */ + G_OBJECT_CLASS (nm_team_factory_parent_class)->dispose (object); +} + +static void +nm_team_factory_class_init (NMTeamFactoryClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + g_type_class_add_private (object_class, sizeof (NMTeamFactoryPrivate)); + + object_class->dispose = dispose; +} diff --git a/src/devices/team/nm-team-factory.h b/src/devices/team/nm-team-factory.h new file mode 100644 index 0000000000..f637371d77 --- /dev/null +++ b/src/devices/team/nm-team-factory.h @@ -0,0 +1,37 @@ +/* -*- 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) 2014 Red Hat, Inc. + */ + +#ifndef NM_TEAM_FACTORY_H +#define NM_TEAM_FACTORY_H + +#include + +#define NM_TYPE_TEAM_FACTORY (nm_team_factory_get_type ()) +#define NM_TEAM_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_TEAM_FACTORY, NMTeamFactory)) + +typedef struct { + GObject parent; +} NMTeamFactory; + +typedef struct { + GObjectClass parent; +} NMTeamFactoryClass; + +#endif /* NM_TEAM_FACTORY_H */ diff --git a/src/nm-manager.c b/src/nm-manager.c index 6c6176e6c1..ac8fb6c489 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -43,7 +43,6 @@ #include "nm-device-ethernet.h" #include "nm-device-infiniband.h" #include "nm-device-bond.h" -#include "nm-device-team.h" #include "nm-device-bridge.h" #include "nm-device-vlan.h" #include "nm-device-generic.h" @@ -1103,8 +1102,6 @@ system_create_virtual_device (NMManager *self, NMConnection *connection) if (nm_connection_is_type (connection, NM_SETTING_BOND_SETTING_NAME)) { device = nm_device_bond_new_for_connection (connection); - } else if (nm_connection_is_type (connection, NM_SETTING_TEAM_SETTING_NAME)) { - device = nm_device_team_new_for_connection (connection); } else if (nm_connection_is_type (connection, NM_SETTING_BRIDGE_SETTING_NAME)) { device = nm_device_bridge_new_for_connection (connection); } else if (nm_connection_is_type (connection, NM_SETTING_VLAN_SETTING_NAME)) { @@ -2146,9 +2143,6 @@ platform_link_added (NMManager *self, case NM_LINK_TYPE_BOND: device = nm_device_bond_new (plink); break; - case NM_LINK_TYPE_TEAM: - device = nm_device_team_new (plink); - break; case NM_LINK_TYPE_BRIDGE: device = nm_device_bridge_new (plink); break; From 71cc0b2345405bea7a0aa5e7c23cd30e405b675c Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Thu, 19 Jun 2014 12:23:10 +0200 Subject: [PATCH 6/6] team: remove conditional compilation WITH_TEAMDCTL teamdctl related parts are now in the device plugin src/devices/team/*. Remove the conditional compilation. Signed-off-by: Thomas Haller --- src/Makefile.am | 5 ++++- src/devices/team/nm-device-team.c | 32 ------------------------------- 2 files changed, 4 insertions(+), 33 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index e620548738..244574af44 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -5,7 +5,6 @@ include $(GLIB_MAKEFILE) SUBDIRS = \ . \ devices/adsl \ - devices/team \ devices/wifi \ dhcp-manager \ ppp-manager \ @@ -21,6 +20,10 @@ if WITH_WIMAX SUBDIRS += devices/wimax endif +if WITH_TEAMDCTL +SUBDIRS += devices/team +endif + if ENABLE_TESTS SUBDIRS += \ config/tests \ diff --git a/src/devices/team/nm-device-team.c b/src/devices/team/nm-device-team.c index 8b27cc1561..fa7be78843 100644 --- a/src/devices/team/nm-device-team.c +++ b/src/devices/team/nm-device-team.c @@ -28,9 +28,7 @@ #include #include #include -#if WITH_TEAMDCTL #include -#endif #include #include "nm-device-team.h" @@ -57,9 +55,7 @@ G_DEFINE_TYPE (NMDeviceTeam, nm_device_team, NM_TYPE_DEVICE) static gboolean teamd_start (NMDevice *dev, NMSettingTeam *s_team); typedef struct { -#if WITH_TEAMDCTL struct teamdctl *tdc; -#endif GPid teamd_pid; guint teamd_process_watch; guint teamd_timeout; @@ -191,7 +187,6 @@ complete_connection (NMDevice *device, return TRUE; } -#if WITH_TEAMDCTL static gboolean ensure_teamd_connection (NMDevice *self) { @@ -213,7 +208,6 @@ ensure_teamd_connection (NMDevice *self) return !!priv->tdc; } -#endif static void update_connection (NMDevice *device, NMConnection *connection) @@ -228,7 +222,6 @@ update_connection (NMDevice *device, NMConnection *connection) } g_object_set (G_OBJECT (s_team), NM_SETTING_TEAM_CONFIG, NULL, NULL); -#if WITH_TEAMDCTL teamd_start (device, s_team); if (NM_DEVICE_TEAM_GET_PRIVATE (device)->teamd_pid > 0 && ensure_teamd_connection (device)) { const char *config = NULL; @@ -241,7 +234,6 @@ update_connection (NMDevice *device, NMConnection *connection) else nm_log_err (LOGD_TEAM, "(%s): failed to read teamd config (err=%d)", iface, err); } -#endif } /******************************************************************/ @@ -252,24 +244,14 @@ master_update_slave_connection (NMDevice *self, NMConnection *connection, GError **error) { -#if WITH_TEAMDCTL NMSettingTeamPort *s_port; char *port_config = NULL; int err = 0; struct teamdctl *tdc; const char *team_port_config = NULL; -#endif const char *iface = nm_device_get_iface (self); const char *iface_slave = nm_device_get_iface (slave); -#if !WITH_TEAMDCTL - g_set_error (error, - NM_DEVICE_TEAM_ERROR, - NM_DEVICE_TEAM_ERROR_NO_SUPPORT, - "update slave connection for slave '%s' failed for team master '%s' because compiled without libteamctl support", - iface_slave, iface); - return FALSE; -#else tdc = teamdctl_alloc (); if (!tdc) { g_set_error (error, @@ -318,7 +300,6 @@ master_update_slave_connection (NMDevice *self, NM_SETTING_CONNECTION_SLAVE_TYPE, NM_SETTING_TEAM_SETTING_NAME, NULL); return TRUE; -#endif } /******************************************************************/ @@ -385,13 +366,11 @@ teamd_cleanup (NMDevice *dev, gboolean device_state_failed) priv->teamd_pid = 0; } -#if WITH_TEAMDCTL if (priv->tdc) { teamdctl_disconnect (priv->tdc); teamdctl_free (priv->tdc); priv->tdc = NULL; } -#endif teamd_timeout_remove (dev); @@ -429,12 +408,10 @@ teamd_dbus_appeared (GDBusConnection *connection, nm_log_info (LOGD_TEAM, "(%s): teamd appeared on D-Bus", nm_device_get_iface (dev)); teamd_timeout_remove (dev); -#if WITH_TEAMDCTL if (!ensure_teamd_connection (dev)) { nm_device_state_changed (dev, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_TEAMD_CONTROL_FAILED); return; } -#endif nm_device_activate_schedule_stage2_device_config (dev); } @@ -516,9 +493,7 @@ teamd_start (NMDevice *dev, NMSettingTeam *s_team) if (priv->teamd_dbus_watch || priv->teamd_process_watch || priv->teamd_pid > 0 || -#if WITH_TEAMDCTL priv->tdc || -#endif priv->teamd_timeout) { /* Just return if teamd_start() was already called */ @@ -664,9 +639,7 @@ enslave_slave (NMDevice *device, NMConnection *connection, gboolean configure) { -#if WITH_TEAMDCTL NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (device); -#endif gboolean success = TRUE, no_firmware = FALSE; const char *iface = nm_device_get_ip_iface (device); const char *slave_iface = nm_device_get_ip_iface (slave); @@ -682,7 +655,6 @@ enslave_slave (NMDevice *device, const char *config = nm_setting_team_port_get_config (s_team_port); if (config) { -#if WITH_TEAMDCTL if (!priv->tdc) { nm_log_warn (LOGD_TEAM, "(%s): enslaved team port %s config not changed, not connected to teamd", iface, slave_iface); @@ -699,10 +671,6 @@ enslave_slave (NMDevice *device, return FALSE; } } -#else - nm_log_warn (LOGD_TEAM, "(%s): enslaved team port %s config not changed due to lack of Teamd control support", - iface, slave_iface); -#endif } } success = nm_platform_link_enslave (nm_device_get_ip_ifindex (device),