When a slave is activated, it waits for the master device to appear. Once the master is present, it acquires a reference which is released again when the slave is deactivated.
Signed-off-by: Thomas Graf <[email protected]> --- src/nm-device.c | 3 +++ src/nm-manager.c | 18 ++++++++++++++++++ src/nm-manager.h | 4 ++++ src/nm-policy.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 75 insertions(+), 0 deletions(-) diff --git a/src/nm-device.c b/src/nm-device.c index 6142243..89c5000 100644 --- a/src/nm-device.c +++ b/src/nm-device.c @@ -3388,6 +3388,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); } diff --git a/src/nm-manager.c b/src/nm-manager.c index b930f17..83a20dd 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -367,6 +367,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) { diff --git a/src/nm-manager.h b/src/nm-manager.h index 22bfca9..ccf5364 100644 --- a/src/nm-manager.h +++ b/src/nm-manager.h @@ -83,6 +83,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, diff --git a/src/nm-policy.c b/src/nm-policy.c index 02292f7..69ab0ef 100644 --- a/src/nm-policy.c +++ b/src/nm-policy.c @@ -708,6 +708,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 = (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION); + g_assert (s_con); + + master = nm_setting_connection_get_master (s_con); + + /* no master defined, proceed with activation */ + if (!master) + return NM_ACT_STAGE_RETURN_SUCCESS; + + 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 NM_ACT_STAGE_RETURN_POSTPONE; + + nm_device_set_master (device, master_device); + + return NM_ACT_STAGE_RETURN_SUCCESS; +} + static gboolean auto_activate_device (gpointer user_data) { @@ -763,6 +790,28 @@ auto_activate_device (gpointer user_data) best_connection = nm_device_get_best_auto_connection (data->device, connections, &specific_object); if (best_connection) { GError *error = NULL; + NMActStageReturn ret; + + ret = check_master_dependency (data->policy->manager, data->device, best_connection); + switch (ret) { + case NM_ACT_STAGE_RETURN_SUCCESS: + break; + + case NM_ACT_STAGE_RETURN_POSTPONE: + nm_log_info (LOGD_DEVICE, "Connection '%s' auto-activation postponed: master not available", + nm_connection_get_id (best_connection)); + goto postpone; + + case NM_ACT_STAGE_RETURN_STOP: + case NM_ACT_STAGE_RETURN_FAILURE: + /* Avoid further retries and postpone activation */ + set_connection_auto_retries (best_connection, 0); + + nm_log_info (LOGD_DEVICE, "Connection '%s' auto-activation not allowed due to master dependency", + nm_connection_get_id (best_connection)); + + goto postpone; + } nm_log_info (LOGD_DEVICE, "Auto-activating connection '%s'.", nm_connection_get_id (best_connection)); @@ -778,6 +827,7 @@ auto_activate_device (gpointer user_data) } } + postpone: g_slist_free (connections); out: -- 1.7.6 _______________________________________________ networkmanager-list mailing list [email protected] http://mail.gnome.org/mailman/listinfo/networkmanager-list
