core: add configurable auto connection retries (bgo #628825)

Presently, when automatic connecting fails, the connection is marked
as invalid and is not retried again. This commit adds a configuration
parameter to specify how many times the connection should be re-tried.
This commit is contained in:
Jiří Klimeš 2010-10-19 19:32:01 +02:00
parent 607350294d
commit fe493ec91e
5 changed files with 100 additions and 26 deletions

View file

@ -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

View file

@ -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;

View file

@ -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:

View file

@ -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

View file

@ -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.
*/