mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager
synced 2024-10-16 13:04:25 +00:00
bonding: postpone auto-activation of a slave until master is present
For a slave to be activatetable the master connection must be present. Activation of the slave is postponed until this condition is met. Once the slave is being activated, a reference to the master connection is acquired and held for the lifetime of the bond. Changes v2: - Made check_master_dependency() return TRUE/FALSE Signed-off-by: Thomas Graf <tgraf@redhat.com>
This commit is contained in:
parent
6349151de1
commit
a65028a025
|
@ -163,6 +163,9 @@ typedef struct {
|
|||
|
||||
/* inhibit autoconnect feature */
|
||||
gboolean autoconnect_inhibit;
|
||||
|
||||
/* master interface for bridge, bond, vlan, etc */
|
||||
NMDevice * master;
|
||||
} NMDevicePrivate;
|
||||
|
||||
static gboolean check_connection_compatible (NMDeviceInterface *device,
|
||||
|
@ -502,6 +505,24 @@ nm_device_get_type_desc (NMDevice *self)
|
|||
return NM_DEVICE_GET_PRIVATE (self)->type_desc;
|
||||
}
|
||||
|
||||
NMDevice *
|
||||
nm_device_get_master (NMDevice *self)
|
||||
{
|
||||
g_return_val_if_fail (self != NULL, NULL);
|
||||
|
||||
return NM_DEVICE_GET_PRIVATE (self)->master;
|
||||
}
|
||||
|
||||
void
|
||||
nm_device_set_master (NMDevice *self, NMDevice *master)
|
||||
{
|
||||
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self);
|
||||
|
||||
if (priv->master)
|
||||
g_object_unref (priv->master);
|
||||
priv->master = master ? g_object_ref (master) : NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* nm_device_get_act_request
|
||||
*
|
||||
|
@ -3324,6 +3345,9 @@ finalize (GObject *object)
|
|||
if (priv->dhcp_anycast_address)
|
||||
g_byte_array_free (priv->dhcp_anycast_address, TRUE);
|
||||
|
||||
/* release master reference it still exists */
|
||||
nm_device_set_master (self, NULL);
|
||||
|
||||
G_OBJECT_CLASS (nm_device_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
|
|
|
@ -151,6 +151,9 @@ NMDHCP6Config * nm_device_get_dhcp6_config (NMDevice *dev);
|
|||
NMIP4Config * nm_device_get_ip4_config (NMDevice *dev);
|
||||
NMIP6Config * nm_device_get_ip6_config (NMDevice *dev);
|
||||
|
||||
NMDevice * nm_device_get_master (NMDevice *self);
|
||||
void nm_device_set_master (NMDevice *self, NMDevice *master);
|
||||
|
||||
NMActRequest * nm_device_get_act_request (NMDevice *dev);
|
||||
|
||||
gboolean nm_device_is_available (NMDevice *dev);
|
||||
|
|
|
@ -366,6 +366,24 @@ nm_manager_get_device_by_path (NMManager *manager, const char *path)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
NMDevice *
|
||||
nm_manager_get_device_by_master (NMManager *manager, const char *master, const char *driver)
|
||||
{
|
||||
GSList *iter;
|
||||
|
||||
g_return_val_if_fail (master != NULL, NULL);
|
||||
|
||||
for (iter = NM_MANAGER_GET_PRIVATE (manager)->devices; iter; iter = iter->next) {
|
||||
NMDevice *device = NM_DEVICE (iter->data);
|
||||
|
||||
if (!strcmp (nm_device_get_iface (device), master) &&
|
||||
(!driver || !strcmp (nm_device_get_driver (device), driver)))
|
||||
return device;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
manager_sleeping (NMManager *self)
|
||||
{
|
||||
|
|
|
@ -84,6 +84,10 @@ void nm_manager_start (NMManager *manager);
|
|||
|
||||
GSList *nm_manager_get_devices (NMManager *manager);
|
||||
|
||||
NMDevice *nm_manager_get_device_by_master (NMManager *manager,
|
||||
const char *master,
|
||||
const char *driver);
|
||||
|
||||
const char * nm_manager_activate_connection (NMManager *manager,
|
||||
NMConnection *connection,
|
||||
const char *specific_object,
|
||||
|
|
|
@ -730,6 +730,33 @@ activate_data_free (ActivateData *data)
|
|||
g_free (data);
|
||||
}
|
||||
|
||||
static NMActStageReturn
|
||||
check_master_dependency (NMManager *manager, NMDevice *device, NMConnection *connection)
|
||||
{
|
||||
NMSettingConnection *s_con;
|
||||
NMDevice *master_device;
|
||||
const char *master;
|
||||
|
||||
s_con = nm_connection_get_setting_connection (connection);
|
||||
g_assert (s_con);
|
||||
|
||||
master = nm_setting_connection_get_master (s_con);
|
||||
|
||||
/* no master defined, proceed with activation */
|
||||
if (!master)
|
||||
return TRUE;
|
||||
|
||||
master_device = nm_manager_get_device_by_master (manager, master, NULL);
|
||||
|
||||
/* If master device is not yet present, postpone activation until later */
|
||||
if (!master_device)
|
||||
return FALSE;
|
||||
|
||||
nm_device_set_master (device, master_device);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
auto_activate_device (gpointer user_data)
|
||||
{
|
||||
|
@ -786,6 +813,12 @@ auto_activate_device (gpointer user_data)
|
|||
if (best_connection) {
|
||||
GError *error = NULL;
|
||||
|
||||
if (!check_master_dependency (data->policy->manager, data->device, best_connection)) {
|
||||
nm_log_info (LOGD_DEVICE, "Connection '%s' auto-activation postponed: master not available",
|
||||
nm_connection_get_id (best_connection));
|
||||
goto postpone;
|
||||
}
|
||||
|
||||
nm_log_info (LOGD_DEVICE, "Auto-activating connection '%s'.",
|
||||
nm_connection_get_id (best_connection));
|
||||
if (!nm_manager_activate_connection (policy->manager,
|
||||
|
@ -800,6 +833,7 @@ auto_activate_device (gpointer user_data)
|
|||
}
|
||||
}
|
||||
|
||||
postpone:
|
||||
g_slist_free (connections);
|
||||
|
||||
out:
|
||||
|
|
Loading…
Reference in a new issue