bonding: kernel bonding device creation
Creates virtual kernel devices as needed. Since the manager is initialized after the connections have been loaded no CONNECTIONS_ADDED notification is received for connections parsed at startup. Therefore walks the loaded connections looking for bonding connections. Connections added on the fly are handled via the notifications. Connection renaming and deleting is not supported yet. Signed-off-by: Thomas Graf <tgraf@redhat.com>
This commit is contained in:

committed by
Dan Williams

parent
a2a0d78818
commit
095aff0c21
@@ -924,12 +924,80 @@ get_active_connections (NMManager *manager, NMConnection *filter)
|
||||
/* Settings stuff via NMSettings */
|
||||
/*******************************************************************/
|
||||
|
||||
static gboolean
|
||||
connection_needs_virtual_device (NMConnection *connection)
|
||||
{
|
||||
if (nm_connection_is_type (connection, NM_SETTING_BOND_SETTING_NAME))
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
system_update_virtual_device (NMConnection *connection)
|
||||
{
|
||||
if (nm_connection_is_type (connection, NM_SETTING_BOND_SETTING_NAME)) {
|
||||
NMSettingBond *s_bond;
|
||||
|
||||
s_bond = nm_connection_get_setting_bond (connection);
|
||||
g_assert (s_bond);
|
||||
|
||||
return nm_system_add_bonding_master (s_bond);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
connections_changed (NMSettings *settings,
|
||||
system_create_virtual_devices (NMSettings *settings)
|
||||
{
|
||||
GSList *iter, *connections;
|
||||
|
||||
nm_log_info (LOGD_CORE, "Creating virtual devices");
|
||||
|
||||
connections = nm_settings_get_connections (settings);
|
||||
for (iter = connections; iter; iter = g_slist_next (iter)) {
|
||||
NMConnection *connection = NM_CONNECTION (iter->data);
|
||||
|
||||
if (connection_needs_virtual_device (connection))
|
||||
system_update_virtual_device (connection);
|
||||
}
|
||||
|
||||
g_slist_free (connections);
|
||||
}
|
||||
|
||||
static void
|
||||
connection_added (NMSettings *settings,
|
||||
NMSettingsConnection *connection,
|
||||
NMManager *manager)
|
||||
{
|
||||
bluez_manager_resync_devices (manager);
|
||||
|
||||
if (connection_needs_virtual_device (NM_CONNECTION (connection)))
|
||||
system_update_virtual_device (NM_CONNECTION (connection));
|
||||
}
|
||||
|
||||
static void
|
||||
connection_changed (NMSettings *settings,
|
||||
NMSettingsConnection *connection,
|
||||
NMManager *manager)
|
||||
{
|
||||
bluez_manager_resync_devices (manager);
|
||||
|
||||
/* FIXME: Some virtual devices may need to be updated in the future. */
|
||||
}
|
||||
|
||||
static void
|
||||
connection_removed (NMSettings *settings,
|
||||
NMSettingsConnection *connection,
|
||||
NMManager *manager)
|
||||
{
|
||||
bluez_manager_resync_devices (manager);
|
||||
|
||||
/*
|
||||
* Do not delete existing virtual devices to keep connectivity up.
|
||||
* Virtual devices are reused when NetworkManager is restarted.
|
||||
*/
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -2823,6 +2891,12 @@ nm_manager_start (NMManager *self)
|
||||
|
||||
nm_udev_manager_query_devices (priv->udev_mgr);
|
||||
bluez_manager_resync_devices (self);
|
||||
|
||||
/*
|
||||
* Connections added before the manager is started do not emit
|
||||
* connection-added signals thus devices have to be created manually.
|
||||
*/
|
||||
system_create_virtual_devices (priv->settings);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -3099,13 +3173,13 @@ nm_manager_new (NMSettings *settings,
|
||||
g_signal_connect (priv->settings, "notify::" NM_SETTINGS_HOSTNAME,
|
||||
G_CALLBACK (system_hostname_changed_cb), singleton);
|
||||
g_signal_connect (priv->settings, NM_SETTINGS_SIGNAL_CONNECTION_ADDED,
|
||||
G_CALLBACK (connections_changed), singleton);
|
||||
G_CALLBACK (connection_added), singleton);
|
||||
g_signal_connect (priv->settings, NM_SETTINGS_SIGNAL_CONNECTION_UPDATED,
|
||||
G_CALLBACK (connections_changed), singleton);
|
||||
G_CALLBACK (connection_changed), singleton);
|
||||
g_signal_connect (priv->settings, NM_SETTINGS_SIGNAL_CONNECTION_REMOVED,
|
||||
G_CALLBACK (connections_changed), singleton);
|
||||
G_CALLBACK (connection_removed), singleton);
|
||||
g_signal_connect (priv->settings, NM_SETTINGS_SIGNAL_CONNECTION_VISIBILITY_CHANGED,
|
||||
G_CALLBACK (connections_changed), singleton);
|
||||
G_CALLBACK (connection_changed), singleton);
|
||||
|
||||
dbus_g_connection_register_g_object (bus, NM_DBUS_PATH, G_OBJECT (singleton));
|
||||
|
||||
|
@@ -68,7 +68,14 @@ __rtnl_link_alloc_cache (struct nl_sock *h, struct nl_cache **cache)
|
||||
|
||||
/* functions with similar prototypes */
|
||||
#define nlmsg_datalen nlmsg_len
|
||||
#endif
|
||||
|
||||
static inline int
|
||||
rtnl_link_bond_add (struct nl_sock *h, const char *name, void *data)
|
||||
{
|
||||
/* Bonding only in libnl3 */
|
||||
return -NLE_OPNOTSUPP;
|
||||
}
|
||||
#endif /* HAVE_LIBNL2 */
|
||||
|
||||
|
||||
/* libnl-1.0 compat functions */
|
||||
@@ -214,6 +221,14 @@ static inline int __genl_ctrl_alloc_cache(struct nl_sock *h, struct nl_cache **c
|
||||
#define NLE_NOACCESS 27
|
||||
#define NLE_PERM 28
|
||||
#define NLE_PKTLOC_FILE 29
|
||||
#endif
|
||||
|
||||
static inline int
|
||||
rtnl_link_bond_add (struct nl_sock *h, const char *name, void *data)
|
||||
{
|
||||
/* Bonding only in libnl3 */
|
||||
return -NLE_OPNOTSUPP;
|
||||
}
|
||||
|
||||
#endif /* HAVE_LIBNL1 */
|
||||
|
||||
#endif /* NM_NETLINK_COMPAT_H */
|
||||
|
@@ -1202,3 +1202,34 @@ nm_system_device_set_priority (int ifindex,
|
||||
rtnl_route_put (found);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_system_add_bonding_master:
|
||||
* @setting: bonding setting
|
||||
*
|
||||
* Adds a virtual bonding device if it does not exist yet.
|
||||
*
|
||||
* Returns: %TRUE on success, %FALSE on failure
|
||||
*/
|
||||
gboolean
|
||||
nm_system_add_bonding_master(NMSettingBond *setting)
|
||||
{
|
||||
struct nl_sock *sock;
|
||||
const char *name;
|
||||
int err;
|
||||
|
||||
sock = nm_netlink_get_default_handle ();
|
||||
name = nm_setting_bond_get_interface_name (setting);
|
||||
g_assert (name);
|
||||
|
||||
/* Existing bonding devices with matching name will be reused */
|
||||
err = rtnl_link_bond_add (sock, name, NULL);
|
||||
if (err < 0) {
|
||||
nm_log_err (LOGD_DEVICE, "(%s): error %d returned from "
|
||||
"rtnl_link_bond_add(): %s",
|
||||
name, err, nl_geterror (err));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
@@ -30,6 +30,7 @@
|
||||
#include <glib.h>
|
||||
#include "nm-device.h"
|
||||
#include "nm-ip4-config.h"
|
||||
#include "nm-setting-bond.h"
|
||||
|
||||
/* Prototypes for system/distribution dependent functions,
|
||||
* implemented in the backend files in backends/ directory
|
||||
@@ -89,4 +90,6 @@ gboolean nm_system_iface_set_mtu (int ifindex, guint32 mtu);
|
||||
|
||||
gboolean nm_system_iface_set_mac (int ifindex, const struct ether_addr *mac);
|
||||
|
||||
gboolean nm_system_add_bonding_master (NMSettingBond *setting);
|
||||
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user