diff --git a/libnm-util/Makefile.am b/libnm-util/Makefile.am index f43fb60242..9cf2a06bac 100644 --- a/libnm-util/Makefile.am +++ b/libnm-util/Makefile.am @@ -59,7 +59,7 @@ libnm_util_la_SOURCES= \ libnm_util_la_LIBADD = $(GLIB_LIBS) $(DBUS_LIBS) $(UUID_LIBS) libnm_util_la_LDFLAGS = -Wl,--version-script=$(srcdir)/libnm-util.ver \ - -version-info "7:0:6" + -version-info "8:0:7" if WITH_GNUTLS libnm_util_la_SOURCES += crypto_gnutls.c diff --git a/libnm-util/libnm-util.ver b/libnm-util/libnm-util.ver index 6c2b9fc71e..0cf3f12b1e 100644 --- a/libnm-util/libnm-util.ver +++ b/libnm-util/libnm-util.ver @@ -113,6 +113,7 @@ global: nm_setting_connection_get_uuid; nm_setting_connection_get_connection_type; nm_setting_connection_get_autoconnect; + nm_setting_connection_get_autoconnect_retries; nm_setting_connection_get_timestamp; nm_setting_connection_get_read_only; nm_setting_duplicate; diff --git a/libnm-util/nm-setting-connection.c b/libnm-util/nm-setting-connection.c index 65f613eba9..10f4b09a9d 100644 --- a/libnm-util/nm-setting-connection.c +++ b/libnm-util/nm-setting-connection.c @@ -19,7 +19,7 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2007 - 2008 Red Hat, Inc. + * (C) Copyright 2007 - 2010 Red Hat, Inc. * (C) Copyright 2007 - 2008 Novell, Inc. */ @@ -86,6 +86,7 @@ typedef struct { char *uuid; char *type; gboolean autoconnect; + gint autoconnect_retries; guint64 timestamp; gboolean read_only; } NMSettingConnectionPrivate; @@ -96,6 +97,7 @@ enum { PROP_UUID, PROP_TYPE, PROP_AUTOCONNECT, + PROP_AUTOCONNECT_RETRIES, PROP_TIMESTAMP, PROP_READ_ONLY, @@ -178,6 +180,22 @@ nm_setting_connection_get_autoconnect (NMSettingConnection *setting) return NM_SETTING_CONNECTION_GET_PRIVATE (setting)->autoconnect; } +/** + * nm_setting_connection_get_autoconnect_retries: + * @setting: the #NMSettingConnection + * + * Returns the #NMSettingConnection:autoconnect-retries property of the connection. + * + * Returns: the connection's number of autoconnect retries + **/ +gint +nm_setting_connection_get_autoconnect_retries (NMSettingConnection *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_CONNECTION (setting), 0); + + return NM_SETTING_CONNECTION_GET_PRIVATE (setting)->autoconnect_retries; +} + /** * nm_setting_connection_get_timestamp: * @setting: the #NMSettingConnection @@ -334,6 +352,9 @@ set_property (GObject *object, guint prop_id, case PROP_AUTOCONNECT: priv->autoconnect = g_value_get_boolean (value); break; + case PROP_AUTOCONNECT_RETRIES: + priv->autoconnect_retries = g_value_get_int (value); + break; case PROP_TIMESTAMP: priv->timestamp = g_value_get_uint64 (value); break; @@ -365,6 +386,9 @@ get_property (GObject *object, guint prop_id, case PROP_AUTOCONNECT: g_value_set_boolean (value, nm_setting_connection_get_autoconnect (setting)); break; + case PROP_AUTOCONNECT_RETRIES: + g_value_set_int (value, nm_setting_connection_get_autoconnect_retries (setting)); + break; case PROP_TIMESTAMP: g_value_set_uint64 (value, nm_setting_connection_get_timestamp (setting)); break; @@ -469,19 +493,39 @@ nm_setting_connection_class_init (NMSettingConnectionClass *setting_class) * * Whether or not the connection should be automatically connected by * NetworkManager when the resources for the connection are available. - * %TRUE to automatically activate the connection, %FALSE to require manual - * intervention to activate the connection. Defaults to %TRUE. + * %TRUE to automatically activate the connection. It makes autoconnect-retries + * attempts at most in addition to the initial try. %FALSE to require + * manual intervention to activate the connection. Defaults to %TRUE. **/ g_object_class_install_property (object_class, PROP_AUTOCONNECT, g_param_spec_boolean (NM_SETTING_CONNECTION_AUTOCONNECT, "Autoconnect", "If TRUE, NetworkManager will activate this connection " - "when its network resources are available. If FALSE, " - "the connection must be manually activated by the user " - "or some other mechanism.", + "when its network resources are available. It makes " + "autoconnect-retries attempts at most when the initial " + "activation was not successful. If FALSE, the connection " + "must be manually activated by the user or some other " + "mechanism.", TRUE, G_PARAM_READWRITE | G_PARAM_CONSTRUCT | NM_SETTING_PARAM_SERIALIZE | NM_SETTING_PARAM_FUZZY_IGNORE)); + /** + * NMSettingConnection:autoconnect-retries: + * + * How many retries should be made by NetworkManager to automatically + * connect, when the initial attempt was not successful. + * Special value is: -1: infinite. Defaults to 0. + **/ + g_object_class_install_property + (object_class, PROP_AUTOCONNECT_RETRIES, + g_param_spec_int (NM_SETTING_CONNECTION_AUTOCONNECT_RETRIES, + "Autoconnect-Retries", + "How many retries should be made by NetworkManager to " + "automatically connect, when the initial attempt was not " + "successful. Special value is -1 meaning infinite. " + "Defaults to 0.", + -1, G_MAXINT, 0, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT | NM_SETTING_PARAM_SERIALIZE | NM_SETTING_PARAM_FUZZY_IGNORE)); /** * NMSettingConnection:timestamp: diff --git a/libnm-util/nm-setting-connection.h b/libnm-util/nm-setting-connection.h index 6dedca220b..ad962a952b 100644 --- a/libnm-util/nm-setting-connection.h +++ b/libnm-util/nm-setting-connection.h @@ -19,7 +19,7 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2007 - 2008 Red Hat, Inc. + * (C) Copyright 2007 - 2010 Red Hat, Inc. * (C) Copyright 2007 - 2008 Novell, Inc. */ @@ -68,12 +68,13 @@ GType nm_setting_connection_error_get_type (void); #define NM_SETTING_CONNECTION_ERROR nm_setting_connection_error_quark () GQuark nm_setting_connection_error_quark (void); -#define NM_SETTING_CONNECTION_ID "id" -#define NM_SETTING_CONNECTION_UUID "uuid" -#define NM_SETTING_CONNECTION_TYPE "type" -#define NM_SETTING_CONNECTION_AUTOCONNECT "autoconnect" -#define NM_SETTING_CONNECTION_TIMESTAMP "timestamp" -#define NM_SETTING_CONNECTION_READ_ONLY "read-only" +#define NM_SETTING_CONNECTION_ID "id" +#define NM_SETTING_CONNECTION_UUID "uuid" +#define NM_SETTING_CONNECTION_TYPE "type" +#define NM_SETTING_CONNECTION_AUTOCONNECT "autoconnect" +#define NM_SETTING_CONNECTION_AUTOCONNECT_RETRIES "autoconnect-retries" +#define NM_SETTING_CONNECTION_TIMESTAMP "timestamp" +#define NM_SETTING_CONNECTION_READ_ONLY "read-only" /** * NMSettingConnection: @@ -97,13 +98,14 @@ typedef struct { GType nm_setting_connection_get_type (void); -NMSetting * nm_setting_connection_new (void); -const char *nm_setting_connection_get_id (NMSettingConnection *setting); -const char *nm_setting_connection_get_uuid (NMSettingConnection *setting); -const char *nm_setting_connection_get_connection_type (NMSettingConnection *setting); -gboolean nm_setting_connection_get_autoconnect (NMSettingConnection *setting); -guint64 nm_setting_connection_get_timestamp (NMSettingConnection *setting); -gboolean nm_setting_connection_get_read_only (NMSettingConnection *setting); +NMSetting * nm_setting_connection_new (void); +const char *nm_setting_connection_get_id (NMSettingConnection *setting); +const char *nm_setting_connection_get_uuid (NMSettingConnection *setting); +const char *nm_setting_connection_get_connection_type (NMSettingConnection *setting); +gboolean nm_setting_connection_get_autoconnect (NMSettingConnection *setting); +gint nm_setting_connection_get_autoconnect_retries (NMSettingConnection *setting); +guint64 nm_setting_connection_get_timestamp (NMSettingConnection *setting); +gboolean nm_setting_connection_get_read_only (NMSettingConnection *setting); G_END_DECLS diff --git a/src/nm-policy.c b/src/nm-policy.c index e8a18d0262..d9be65c8a5 100644 --- a/src/nm-policy.c +++ b/src/nm-policy.c @@ -66,6 +66,7 @@ struct NMPolicy { }; #define INVALID_TAG "invalid" +#define RETRIES_TAG "autoconnect-retries" static const char * get_connection_id (NMConnection *connection) @@ -714,6 +715,19 @@ update_routing_and_dns (NMPolicy *policy, gboolean force_update) update_system_hostname (policy, policy->default_device4, policy->default_device6); } +static void +reset_auto_connection_retries (NMConnection *connection) +{ + NMSettingConnection *s_con; + int retries; + + s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); + g_assert (s_con); + + retries = nm_setting_connection_get_autoconnect_retries (s_con); + g_object_set_data (G_OBJECT (connection), RETRIES_TAG, GINT_TO_POINTER (retries)); +} + typedef struct { NMPolicy *policy; NMDevice *device; @@ -744,17 +758,26 @@ auto_activate_device (gpointer user_data) if (nm_manager_auto_user_connections_allowed (policy->manager)) connections = g_slist_concat (connections, nm_manager_get_connections (policy->manager, NM_CONNECTION_SCOPE_USER)); - /* Remove connections that are in the invalid list. */ + /* Remove connections that have INVALID_TAG and shouldn't be retried any more. */ iter = connections; while (iter) { NMConnection *iter_connection = NM_CONNECTION (iter->data); GSList *next = g_slist_next (iter); if (g_object_get_data (G_OBJECT (iter_connection), INVALID_TAG)) { - connections = g_slist_remove_link (connections, iter); - g_object_unref (iter_connection); - g_slist_free (iter); + int retries = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (iter_connection), RETRIES_TAG)); + if (retries == 0) { + connections = g_slist_remove_link (connections, iter); + g_object_unref (iter_connection); + g_slist_free (iter); + } else if (retries > 0) { + g_object_set_data (G_OBJECT (iter_connection), RETRIES_TAG, GINT_TO_POINTER (retries-1)); + } + } else { + /* Set the initial # of retries for auto-connection */ + reset_auto_connection_retries (iter_connection); } + iter = next; } @@ -902,7 +925,8 @@ device_state_changed (NMDevice *device, */ if (connection && IS_ACTIVATING_STATE (old_state)) { g_object_set_data (G_OBJECT (connection), INVALID_TAG, GUINT_TO_POINTER (TRUE)); - nm_log_info (LOGD_DEVICE, "Marking connection '%s' invalid.", get_connection_id (connection)); + if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (connection), RETRIES_TAG)) == 0) + nm_log_info (LOGD_DEVICE, "Marking connection '%s' invalid.", get_connection_id (connection)); nm_connection_clear_secrets (connection); } schedule_activate_check (policy, device, 3); @@ -912,6 +936,9 @@ device_state_changed (NMDevice *device, /* Clear the invalid tag on the connection */ g_object_set_data (G_OBJECT (connection), INVALID_TAG, NULL); + /* Reset RETRIES_TAG to number from the setting */ + reset_auto_connection_retries (connection); + /* And clear secrets so they will always be requested from the * settings service when the next connection is made. */