NetworkManager/0063-rh1095378-endless-loop...

2873 lines
109 KiB
Diff

From e299d7b30f7accbd83270fb1eb973fd903714d77 Mon Sep 17 00:00:00 2001
COMMENT: Rebased the following upstream master commits dealing with auto-connecting
COMMENT: and re-trying (and edited to apply):
COMMENT: e299d7b30f7accbd83270fb1eb973fd903714d77
COMMENT: f8da87af32a6d5fb5a75d0b04866e3ca88b3b8b4
COMMENT: 0234bd4acc3be1948b24a2779212170441651a4a
COMMENT:
COMMENT: 0f382131294cae8dd8ff9b143ddbd110517759ee
COMMENT: 123bf9eea44b2a570cf862f98564ca3a3e2ce8de
COMMENT: ff6315cbabd0b7f65561410264910ae655d9435c
COMMENT: 22cbc77bae4145de955905448b32ec42d044eebc
COMMENT: 85f3da83510fa2f5a961f63d95636168a4743f56
COMMENT: 0cdd4ada5be88f6481846594e83e5847fc4bb548
COMMENT: f027c4ad0e20e17725ed05e26a90f80a1c24311b
COMMENT:
COMMENT: 3d30ff01ef1d78cee8169f5bb464b988c8ac817b
COMMENT: 828c316080ce58c43a521eca856efa95d008fd87
COMMENT: 4e74670b472e34bfa6c40534714cd86f5dfa7b4a
COMMENT: eceb613f4c62eb9bb2d29d1e8ae720db8311606d
COMMENT: 971167e2a8693c75e84854a030ba491932b7d105
COMMENT: 979b8920b465867ea248dee23a8a290da28f75e5
COMMENT: 12ee696d8375279d14733cb98dec4ce2405bc0b4
COMMENT:
COMMENT: 40562b0aa54a1de7571d8ef8eb3c0c4d3ff3a265
COMMENT: a217a742f1207e4451f401280048f64e10cfd5be
COMMENT: 4f0c70e94534abafde6a0459af74b68a7da724d9 - schedule_activate_check() modified with ff7e47a
COMMENT: 58500b3b8bf8f06b04f1d349daa1cae4e46915b8
From: Thomas Haller <thaller@redhat.com>
Date: Wed, 11 Dec 2013 16:32:11 +0100
Subject: [PATCH] core: workaround indefinite retries of activating connection
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Workaround a serious issue, that a connection that failed to activate
might retry to autoconnect indefinitly.
In NMPolicy, device_state_changed() decrements the retry count for
autoconnect. But immediatly it calls nm_connection_clear_secrets(),
which in turn triggers an NM_SETTINGS_SIGNAL_CONNECTION_UPDATED signal.
The problem is, that connection_updated() resets the try count again to
the default, and thus, the counter was effictivly not decremented.
For now, do not reset the retry count in connection_updated(). This
works arount the issue, but means, that when a user changes the
connection, it is not immediatly retried to autoconnect (as the intent
originally was). This will be fixed later.
https://bugzilla.redhat.com/show_bug.cgi?id=1040528
Signed-off-by: Thomas Haller <thaller@redhat.com>
Signed-off-by: Jiří Klimeš <jklimes@redhat.com>
---
src/nm-policy.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/src/nm-policy.c b/src/nm-policy.c
index 3c09a04..739ac81 100644
--- a/src/nm-policy.c
+++ b/src/nm-policy.c
@@ -1961,8 +1961,11 @@ connection_updated (NMSettings *settings,
firewall_update_zone (policy, connection);
- /* Reset auto retries back to default since connection was updated */
- set_connection_auto_retries (connection, RETRIES_DEFAULT);
+ /* FIXME: previously, we set_connection_auto_retries() again to
+ * RETRIES_DEFAULT, in order to re-enable a connection when it is changed
+ * by the user. This caused a serious problem, so remove it for now
+ * (rh #1040528).
+ **/
schedule_activate_all (policy);
}
--
1.7.11.7
From f8da87af32a6d5fb5a75d0b04866e3ca88b3b8b4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ji=C5=99=C3=AD=20Klime=C5=A1?= <jklimes@redhat.com>
Date: Tue, 3 Dec 2013 16:19:10 +0100
Subject: [PATCH] policy: remove schedule_activate_check() from FAILED handler
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The call is redundant, because the device will transition to DISCONNECTED
and schedule_activate_check() will be called of this state.
Signed-off-by: Jiří Klimeš <jklimes@redhat.com>
---
src/nm-policy.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/src/nm-policy.c b/src/nm-policy.c
index 739ac81..f9dd047 100644
--- a/src/nm-policy.c
+++ b/src/nm-policy.c
@@ -1454,7 +1454,6 @@ device_state_changed (NMDevice *device,
}
nm_connection_clear_secrets (connection);
}
- schedule_activate_check (policy, device, 3);
break;
case NM_DEVICE_STATE_ACTIVATED:
if (connection) {
--
1.7.11.7
From 0234bd4acc3be1948b24a2779212170441651a4a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ji=C5=99=C3=AD=20Klime=C5=A1?= <jklimes@redhat.com>
Date: Thu, 12 Dec 2013 10:26:32 +0100
Subject: [PATCH] policy: invoke NMPolicy::device_state_changed() after other
handlers (rh #1033187)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This fixes automatic activation after changes in
commit ff7e47a41858881e102ce7c3686962f43d08cce4.
When a connection is deactivated impl_manager_deactivate_connection() is called
and the device goes to NM_DEVICE_STATE_DISCONNECTED. nm_device_state_changed()
then issues "state-changed" signal. The signal is connected to by various
listeners. The most interesting ones for this case are NMPolicy and
NMActiveConnection.
The problem is that NMPolicy's device_state_changed() is processed first and
thus in schedule_activate_check() we still have the old active connection
present (in ACTIVATED state).
This commit fixes the issue by connecting to "state-changed" signal using
g_signal_connect_after() in NMPolicy. This ensures NMPolicy's state-changed
handler is called after active connections are processed.
https://bugzilla.redhat.com/show_bug.cgi?id=1033187
Signed-off-by: Jiří Klimeš <jklimes@redhat.com>
---
src/nm-policy.c | 30 +++++++++++++++++++-----------
1 file changed, 19 insertions(+), 11 deletions(-)
diff --git a/src/nm-policy.c b/src/nm-policy.c
index f9dd047..37b8234 100644
--- a/src/nm-policy.c
+++ b/src/nm-policy.c
@@ -1627,14 +1627,21 @@ typedef struct {
} DeviceSignalId;
static void
-_connect_device_signal (NMPolicy *policy, NMDevice *device, const char *name, gpointer callback)
+_connect_device_signal (NMPolicy *policy,
+ NMDevice *device,
+ const char *name,
+ gpointer callback,
+ gboolean after)
{
NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (policy);
DeviceSignalId *data;
data = g_slice_new0 (DeviceSignalId);
g_assert (data);
- data->id = g_signal_connect (device, name, callback, policy);
+ if (after)
+ data->id = g_signal_connect_after (device, name, callback, policy);
+ else
+ data->id = g_signal_connect (device, name, callback, policy);
data->device = device;
priv->dev_ids = g_slist_prepend (priv->dev_ids, data);
}
@@ -1644,22 +1651,23 @@ device_added (NMManager *manager, NMDevice *device, gpointer user_data)
{
NMPolicy *policy = (NMPolicy *) user_data;
- _connect_device_signal (policy, device, "state-changed", device_state_changed);
- _connect_device_signal (policy, device, NM_DEVICE_IP4_CONFIG_CHANGED, device_ip4_config_changed);
- _connect_device_signal (policy, device, NM_DEVICE_IP6_CONFIG_CHANGED, device_ip6_config_changed);
- _connect_device_signal (policy, device, "notify::" NM_DEVICE_AUTOCONNECT, device_autoconnect_changed);
+ /* Connect state-changed with _after, so that the handler is invoked after other handlers. */
+ _connect_device_signal (policy, device, "state-changed", device_state_changed, TRUE);
+ _connect_device_signal (policy, device, NM_DEVICE_IP4_CONFIG_CHANGED, device_ip4_config_changed, FALSE);
+ _connect_device_signal (policy, device, NM_DEVICE_IP6_CONFIG_CHANGED, device_ip6_config_changed, FALSE);
+ _connect_device_signal (policy, device, "notify::" NM_DEVICE_AUTOCONNECT, device_autoconnect_changed, FALSE);
switch (nm_device_get_device_type (device)) {
case NM_DEVICE_TYPE_WIFI:
- _connect_device_signal (policy, device, "access-point-added", wireless_networks_changed);
- _connect_device_signal (policy, device, "access-point-removed", wireless_networks_changed);
+ _connect_device_signal (policy, device, "access-point-added", wireless_networks_changed, FALSE);
+ _connect_device_signal (policy, device, "access-point-removed", wireless_networks_changed, FALSE);
break;
case NM_DEVICE_TYPE_WIMAX:
- _connect_device_signal (policy, device, "nsp-added", nsps_changed);
- _connect_device_signal (policy, device, "nsp-removed", nsps_changed);
+ _connect_device_signal (policy, device, "nsp-added", nsps_changed, FALSE);
+ _connect_device_signal (policy, device, "nsp-removed", nsps_changed, FALSE);
break;
case NM_DEVICE_TYPE_MODEM:
- _connect_device_signal (policy, device, "enable-changed", modem_enabled_changed);
+ _connect_device_signal (policy, device, "enable-changed", modem_enabled_changed, FALSE);
break;
default:
break;
--
1.7.11.7
From 0f382131294cae8dd8ff9b143ddbd110517759ee Mon Sep 17 00:00:00 2001
From: Thomas Haller <thaller@redhat.com>
Date: Wed, 11 Dec 2013 14:33:49 +0100
Subject: [PATCH 1/6] libnm-util: raise CHANGED signal in
nm_connection_clear_secrets only on change
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Often, nm_connection_clear_secrets does have no consequences, because
there is nothing to be cleared. Only raise a signal, if something
actually changed.
Signed-off-by: Thomas Haller <thaller@redhat.com>
Signed-off-by: Jiří Klimeš <jklimes@redhat.com>
---
libnm-util/nm-connection.c | 22 +++++++++++----
libnm-util/nm-setting-private.h | 6 ++++
libnm-util/nm-setting-vpn.c | 6 ++--
libnm-util/nm-setting.c | 62 +++++++++++++++++++++++++++++++----------
libnm-util/nm-setting.h | 2 +-
5 files changed, 74 insertions(+), 24 deletions(-)
diff --git a/libnm-util/nm-connection.c b/libnm-util/nm-connection.c
index 7a4e219..f62a2e9 100644
--- a/libnm-util/nm-connection.c
+++ b/libnm-util/nm-connection.c
@@ -841,15 +841,20 @@ nm_connection_clear_secrets (NMConnection *connection)
{
GHashTableIter iter;
NMSetting *setting;
+ gboolean changed = FALSE;
g_return_if_fail (NM_IS_CONNECTION (connection));
g_hash_table_iter_init (&iter, NM_CONNECTION_GET_PRIVATE (connection)->settings);
- while (g_hash_table_iter_next (&iter, NULL, (gpointer) &setting))
- nm_setting_clear_secrets (setting);
+ while (g_hash_table_iter_next (&iter, NULL, (gpointer) &setting)) {
+ g_signal_handlers_block_by_func (setting, (GCallback) setting_changed_cb, connection);
+ changed |= _nm_setting_clear_secrets (setting);
+ g_signal_handlers_unblock_by_func (setting, (GCallback) setting_changed_cb, connection);
+ }
g_signal_emit (connection, signals[SECRETS_CLEARED], 0);
- g_signal_emit (connection, signals[CHANGED], 0);
+ if (changed)
+ g_signal_emit (connection, signals[CHANGED], 0);
}
/**
@@ -868,15 +873,20 @@ nm_connection_clear_secrets_with_flags (NMConnection *connection,
{
GHashTableIter iter;
NMSetting *setting;
+ gboolean changed = FALSE;
g_return_if_fail (NM_IS_CONNECTION (connection));
g_hash_table_iter_init (&iter, NM_CONNECTION_GET_PRIVATE (connection)->settings);
- while (g_hash_table_iter_next (&iter, NULL, (gpointer) &setting))
- nm_setting_clear_secrets_with_flags (setting, func, user_data);
+ while (g_hash_table_iter_next (&iter, NULL, (gpointer) &setting)) {
+ g_signal_handlers_block_by_func (setting, (GCallback) setting_changed_cb, connection);
+ changed |= _nm_setting_clear_secrets_with_flags (setting, func, user_data);
+ g_signal_handlers_unblock_by_func (setting, (GCallback) setting_changed_cb, connection);
+ }
g_signal_emit (connection, signals[SECRETS_CLEARED], 0);
- g_signal_emit (connection, signals[CHANGED], 0);
+ if (changed)
+ g_signal_emit (connection, signals[CHANGED], 0);
}
/**
diff --git a/libnm-util/nm-setting-private.h b/libnm-util/nm-setting-private.h
index 30b43dd..058e7bd 100644
--- a/libnm-util/nm-setting-private.h
+++ b/libnm-util/nm-setting-private.h
@@ -42,6 +42,12 @@ GType _nm_setting_lookup_setting_type (const char *name);
GType _nm_setting_lookup_setting_type_by_quark (GQuark error_quark);
gint _nm_setting_compare_priority (gconstpointer a, gconstpointer b);
+gboolean _nm_setting_clear_secrets (NMSetting *setting);
+gboolean _nm_setting_clear_secrets_with_flags (NMSetting *setting,
+ NMSettingClearSecretsWithFlagsFn func,
+ gpointer user_data);
+
+
/* NM_SETTING_COMPARE_FLAG_CANDIDATE: check a whether a device-generated connection
* can be meaningfully replaced by a configured connection. With this flag
* the matching function is asymetric and only takes into account properties
diff --git a/libnm-util/nm-setting-vpn.c b/libnm-util/nm-setting-vpn.c
index 9ded0dd..3de47a0 100644
--- a/libnm-util/nm-setting-vpn.c
+++ b/libnm-util/nm-setting-vpn.c
@@ -649,7 +649,7 @@ compare_property (NMSetting *setting,
return same;
}
-static void
+static gboolean
clear_secrets_with_flags (NMSetting *setting,
GParamSpec *pspec,
NMSettingClearSecretsWithFlagsFn func,
@@ -661,7 +661,7 @@ clear_secrets_with_flags (NMSetting *setting,
gboolean changed = TRUE;
if (priv->secrets == NULL)
- return;
+ return FALSE;
/* Iterate through secrets hash and check each entry */
g_hash_table_iter_init (&iter, priv->secrets);
@@ -677,6 +677,8 @@ clear_secrets_with_flags (NMSetting *setting,
if (changed)
g_object_notify (G_OBJECT (setting), NM_SETTING_VPN_SECRETS);
+
+ return changed;
}
static void
diff --git a/libnm-util/nm-setting.c b/libnm-util/nm-setting.c
index a3484e8..d0c992f 100644
--- a/libnm-util/nm-setting.c
+++ b/libnm-util/nm-setting.c
@@ -815,46 +815,68 @@ nm_setting_enumerate_values (NMSetting *setting,
void
nm_setting_clear_secrets (NMSetting *setting)
{
+ _nm_setting_clear_secrets (setting);
+}
+
+gboolean
+_nm_setting_clear_secrets (NMSetting *setting)
+{
GParamSpec **property_specs;
guint n_property_specs;
guint i;
+ gboolean changed = FALSE;
- g_return_if_fail (NM_IS_SETTING (setting));
+ g_return_val_if_fail (NM_IS_SETTING (setting), FALSE);
property_specs = g_object_class_list_properties (G_OBJECT_GET_CLASS (setting), &n_property_specs);
for (i = 0; i < n_property_specs; i++) {
GParamSpec *prop_spec = property_specs[i];
- GValue value = G_VALUE_INIT;
if (prop_spec->flags & NM_SETTING_PARAM_SECRET) {
+ GValue value = G_VALUE_INIT;
+
g_value_init (&value, prop_spec->value_type);
- g_param_value_set_default (prop_spec, &value);
- g_object_set_property (G_OBJECT (setting), prop_spec->name, &value);
+ g_object_get_property (G_OBJECT (setting), prop_spec->name, &value);
+ if (!g_param_value_defaults (prop_spec, &value)) {
+ g_param_value_set_default (prop_spec, &value);
+ g_object_set_property (G_OBJECT (setting), prop_spec->name, &value);
+ changed = TRUE;
+ }
g_value_unset (&value);
}
}
g_free (property_specs);
+
+ return changed;
}
-static void
+static gboolean
clear_secrets_with_flags (NMSetting *setting,
GParamSpec *pspec,
NMSettingClearSecretsWithFlagsFn func,
gpointer user_data)
{
- GValue value = G_VALUE_INIT;
NMSettingSecretFlags flags = NM_SETTING_SECRET_FLAG_NONE;
+ gboolean changed = FALSE;
/* Clear the secret if the user function says to do so */
nm_setting_get_secret_flags (setting, pspec->name, &flags, NULL);
if (func (setting, pspec->name, flags, user_data) == TRUE) {
+ GValue value = G_VALUE_INIT;
+
g_value_init (&value, pspec->value_type);
- g_param_value_set_default (pspec, &value);
- g_object_set_property (G_OBJECT (setting), pspec->name, &value);
+ g_object_get_property (G_OBJECT (setting), pspec->name, &value);
+ if (!g_param_value_defaults (pspec, &value)) {
+ g_param_value_set_default (pspec, &value);
+ g_object_set_property (G_OBJECT (setting), pspec->name, &value);
+ changed = TRUE;
+ }
g_value_unset (&value);
}
+
+ return changed;
}
/**
@@ -871,25 +893,35 @@ nm_setting_clear_secrets_with_flags (NMSetting *setting,
NMSettingClearSecretsWithFlagsFn func,
gpointer user_data)
{
+ _nm_setting_clear_secrets_with_flags (setting, func, user_data);
+}
+
+gboolean
+_nm_setting_clear_secrets_with_flags (NMSetting *setting,
+ NMSettingClearSecretsWithFlagsFn func,
+ gpointer user_data)
+{
GParamSpec **property_specs;
guint n_property_specs;
guint i;
+ gboolean changed = FALSE;
- g_return_if_fail (setting);
- g_return_if_fail (NM_IS_SETTING (setting));
- g_return_if_fail (func != NULL);
+ g_return_val_if_fail (setting, FALSE);
+ g_return_val_if_fail (NM_IS_SETTING (setting), FALSE);
+ g_return_val_if_fail (func != NULL, FALSE);
property_specs = g_object_class_list_properties (G_OBJECT_GET_CLASS (setting), &n_property_specs);
for (i = 0; i < n_property_specs; i++) {
if (property_specs[i]->flags & NM_SETTING_PARAM_SECRET) {
- NM_SETTING_GET_CLASS (setting)->clear_secrets_with_flags (setting,
- property_specs[i],
- func,
- user_data);
+ changed |= NM_SETTING_GET_CLASS (setting)->clear_secrets_with_flags (setting,
+ property_specs[i],
+ func,
+ user_data);
}
}
g_free (property_specs);
+ return changed;
}
/**
diff --git a/libnm-util/nm-setting.h b/libnm-util/nm-setting.h
index e054288..b7f7d62 100644
--- a/libnm-util/nm-setting.h
+++ b/libnm-util/nm-setting.h
@@ -200,7 +200,7 @@ typedef struct {
const GParamSpec *prop_spec,
NMSettingCompareFlags flags);
- void (*clear_secrets_with_flags) (NMSetting *setting,
+ gboolean (*clear_secrets_with_flags) (NMSetting *setting,
GParamSpec *pspec,
NMSettingClearSecretsWithFlagsFn func,
gpointer user_data);
--
1.7.11.7
From 123bf9eea44b2a570cf862f98564ca3a3e2ce8de Mon Sep 17 00:00:00 2001
From: Thomas Haller <thaller@redhat.com>
Date: Wed, 11 Dec 2013 14:33:49 +0100
Subject: [PATCH 2/6] libnm-util: raise CHANGED signal in
nm_connection_update_secrets only on change
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This changes behaviour of nm_connection_update_secrets() in that it will
now return %TRUE, if there are no secrets to be cleared. Seems more
correct, to return success if there is nothing to do.
Signed-off-by: Thomas Haller <thaller@redhat.com>
Signed-off-by: Jiří Klimeš <jklimes@redhat.com>
---
libnm-util/nm-connection.c | 43 ++++++++++++++++++---------
libnm-util/nm-setting-private.h | 9 ++++++
libnm-util/nm-setting-vpn.c | 38 ++++++++++++++----------
libnm-util/nm-setting.c | 65 ++++++++++++++++++++++++++++-------------
libnm-util/nm-setting.h | 2 +-
5 files changed, 108 insertions(+), 49 deletions(-)
diff --git a/libnm-util/nm-connection.c b/libnm-util/nm-connection.c
index f62a2e9..807a893 100644
--- a/libnm-util/nm-connection.c
+++ b/libnm-util/nm-connection.c
@@ -676,11 +676,12 @@ nm_connection_update_secrets (NMConnection *connection,
GError **error)
{
NMSetting *setting;
- gboolean success = FALSE, updated = FALSE;
+ gboolean success = TRUE, updated = FALSE;
GHashTable *setting_hash = NULL;
GHashTableIter iter;
const char *key;
gboolean hashed_connection = FALSE;
+ int success_detail;
g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE);
g_return_val_if_fail (secrets != NULL, FALSE);
@@ -721,15 +722,20 @@ nm_connection_update_secrets (NMConnection *connection,
/* The hashed connection that didn't contain any secrets for
* @setting_name; just return success.
*/
- success = TRUE;
+ return TRUE;
}
}
- if (!success) {
- updated = success = nm_setting_update_secrets (setting,
- setting_hash ? setting_hash : secrets,
- error);
- }
+ g_signal_handlers_block_by_func (setting, (GCallback) setting_changed_cb, connection);
+ success_detail = _nm_setting_update_secrets (setting,
+ setting_hash ? setting_hash : secrets,
+ error);
+ g_signal_handlers_unblock_by_func (setting, (GCallback) setting_changed_cb, connection);
+
+ if (success_detail == NM_SETTING_UPDATE_SECRET_ERROR)
+ return FALSE;
+ if (success_detail == NM_SETTING_UPDATE_SECRET_SUCCESS_MODIFIED)
+ updated = TRUE;
} else {
if (!hashed_connection) {
g_set_error_literal (error,
@@ -739,9 +745,9 @@ nm_connection_update_secrets (NMConnection *connection,
return FALSE;
}
- /* Update each setting with any secrets from the hashed connection */
+ /* check first, whether all the settings exist... */
g_hash_table_iter_init (&iter, secrets);
- while (g_hash_table_iter_next (&iter, (gpointer) &key, (gpointer) &setting_hash)) {
+ while (g_hash_table_iter_next (&iter, (gpointer) &key, NULL)) {
setting = nm_connection_get_setting_by_name (connection, key);
if (!setting) {
g_set_error_literal (error,
@@ -750,13 +756,24 @@ nm_connection_update_secrets (NMConnection *connection,
key);
return FALSE;
}
+ }
+ /* Update each setting with any secrets from the hashed connection */
+ g_hash_table_iter_init (&iter, secrets);
+ while (g_hash_table_iter_next (&iter, (gpointer) &key, (gpointer) &setting_hash)) {
/* Update the secrets for this setting */
- success = nm_setting_update_secrets (setting, setting_hash, error);
- if (success)
- updated = TRUE;
- else
+ setting = nm_connection_get_setting_by_name (connection, key);
+
+ g_signal_handlers_block_by_func (setting, (GCallback) setting_changed_cb, connection);
+ success_detail = _nm_setting_update_secrets (setting, setting_hash, error);
+ g_signal_handlers_unblock_by_func (setting, (GCallback) setting_changed_cb, connection);
+
+ if (success_detail == NM_SETTING_UPDATE_SECRET_ERROR) {
+ success = FALSE;
break;
+ }
+ if (success_detail == NM_SETTING_UPDATE_SECRET_SUCCESS_MODIFIED)
+ updated = TRUE;
}
}
diff --git a/libnm-util/nm-setting-private.h b/libnm-util/nm-setting-private.h
index 058e7bd..fd5f009 100644
--- a/libnm-util/nm-setting-private.h
+++ b/libnm-util/nm-setting-private.h
@@ -42,6 +42,15 @@ GType _nm_setting_lookup_setting_type (const char *name);
GType _nm_setting_lookup_setting_type_by_quark (GQuark error_quark);
gint _nm_setting_compare_priority (gconstpointer a, gconstpointer b);
+typedef enum NMSettingUpdateSecretResult {
+ NM_SETTING_UPDATE_SECRET_ERROR = FALSE,
+ NM_SETTING_UPDATE_SECRET_SUCCESS_MODIFIED = TRUE,
+ NM_SETTING_UPDATE_SECRET_SUCCESS_UNCHANGED = 2,
+} NMSettingUpdateSecretResult;
+
+NMSettingUpdateSecretResult _nm_setting_update_secrets (NMSetting *setting,
+ GHashTable *secrets,
+ GError **error);
gboolean _nm_setting_clear_secrets (NMSetting *setting);
gboolean _nm_setting_clear_secrets_with_flags (NMSetting *setting,
NMSettingClearSecretsWithFlagsFn func,
diff --git a/libnm-util/nm-setting-vpn.c b/libnm-util/nm-setting-vpn.c
index 3de47a0..b5cffc1 100644
--- a/libnm-util/nm-setting-vpn.c
+++ b/libnm-util/nm-setting-vpn.c
@@ -429,7 +429,7 @@ verify (NMSetting *setting, GSList *all_settings, GError **error)
return TRUE;
}
-static gboolean
+static NMSettingUpdateSecretResult
update_secret_string (NMSetting *setting,
const char *key,
const char *value,
@@ -437,21 +437,24 @@ update_secret_string (NMSetting *setting,
{
NMSettingVPNPrivate *priv = NM_SETTING_VPN_GET_PRIVATE (setting);
- g_return_val_if_fail (key != NULL, FALSE);
- g_return_val_if_fail (value != NULL, FALSE);
+ g_return_val_if_fail (key != NULL, NM_SETTING_UPDATE_SECRET_ERROR);
+ g_return_val_if_fail (value != NULL, NM_SETTING_UPDATE_SECRET_ERROR);
if (!value || !strlen (value)) {
g_set_error (error, NM_SETTING_ERROR,
NM_SETTING_ERROR_PROPERTY_TYPE_MISMATCH,
"Secret %s was empty", key);
- return FALSE;
+ return NM_SETTING_UPDATE_SECRET_ERROR;
}
+ if (g_strcmp0 (g_hash_table_lookup (priv->secrets, key), value) == 0)
+ return NM_SETTING_UPDATE_SECRET_SUCCESS_UNCHANGED;
+
g_hash_table_insert (priv->secrets, g_strdup (key), g_strdup (value));
- return TRUE;
+ return NM_SETTING_UPDATE_SECRET_SUCCESS_MODIFIED;
}
-static gboolean
+static NMSettingUpdateSecretResult
update_secret_hash (NMSetting *setting,
GHashTable *secrets,
GError **error)
@@ -459,8 +462,9 @@ update_secret_hash (NMSetting *setting,
NMSettingVPNPrivate *priv = NM_SETTING_VPN_GET_PRIVATE (setting);
GHashTableIter iter;
const char *name, *value;
+ NMSettingUpdateSecretResult result = NM_SETTING_UPDATE_SECRET_SUCCESS_UNCHANGED;
- g_return_val_if_fail (secrets != NULL, FALSE);
+ g_return_val_if_fail (secrets != NULL, NM_SETTING_UPDATE_SECRET_ERROR);
/* Make sure the items are valid */
g_hash_table_iter_init (&iter, secrets);
@@ -469,14 +473,14 @@ update_secret_hash (NMSetting *setting,
g_set_error_literal (error, NM_SETTING_ERROR,
NM_SETTING_ERROR_PROPERTY_TYPE_MISMATCH,
"Secret name was empty");
- return FALSE;
+ return NM_SETTING_UPDATE_SECRET_ERROR;
}
if (!value || !strlen (value)) {
g_set_error (error, NM_SETTING_ERROR,
NM_SETTING_ERROR_PROPERTY_TYPE_MISMATCH,
"Secret %s value was empty", name);
- return FALSE;
+ return NM_SETTING_UPDATE_SECRET_ERROR;
}
}
@@ -492,19 +496,23 @@ update_secret_hash (NMSetting *setting,
continue;
}
+ if (g_strcmp0 (g_hash_table_lookup (priv->secrets, name), value) == 0)
+ continue;
+
g_hash_table_insert (priv->secrets, g_strdup (name), g_strdup (value));
+ result = NM_SETTING_UPDATE_SECRET_SUCCESS_MODIFIED;
}
- return TRUE;
+ return result;
}
-static gboolean
+static int
update_one_secret (NMSetting *setting, const char *key, GValue *value, GError **error)
{
- gboolean success = FALSE;
+ NMSettingUpdateSecretResult success = NM_SETTING_UPDATE_SECRET_ERROR;
- g_return_val_if_fail (key != NULL, FALSE);
- g_return_val_if_fail (value != NULL, FALSE);
+ g_return_val_if_fail (key != NULL, NM_SETTING_UPDATE_SECRET_ERROR);
+ g_return_val_if_fail (value != NULL, NM_SETTING_UPDATE_SECRET_ERROR);
if (G_VALUE_HOLDS_STRING (value)) {
/* Passing the string properties individually isn't correct, and won't
@@ -522,7 +530,7 @@ update_one_secret (NMSetting *setting, const char *key, GValue *value, GError **
} else
g_set_error_literal (error, NM_SETTING_ERROR, NM_SETTING_ERROR_PROPERTY_TYPE_MISMATCH, key);
- if (success)
+ if (success == NM_SETTING_UPDATE_SECRET_SUCCESS_MODIFIED)
g_object_notify (G_OBJECT (setting), NM_SETTING_VPN_SECRETS);
return success;
diff --git a/libnm-util/nm-setting.c b/libnm-util/nm-setting.c
index d0c992f..8b2ee5d 100644
--- a/libnm-util/nm-setting.c
+++ b/libnm-util/nm-setting.c
@@ -951,12 +951,11 @@ nm_setting_need_secrets (NMSetting *setting)
return secrets;
}
-static gboolean
+static int
update_one_secret (NMSetting *setting, const char *key, GValue *value, GError **error)
{
GParamSpec *prop_spec;
GValue transformed_value = G_VALUE_INIT;
- gboolean success = FALSE;
prop_spec = g_object_class_find_property (G_OBJECT_GET_CLASS (setting), key);
if (!prop_spec) {
@@ -964,27 +963,40 @@ update_one_secret (NMSetting *setting, const char *key, GValue *value, GError **
NM_SETTING_ERROR,
NM_SETTING_ERROR_PROPERTY_NOT_FOUND,
"%s", key);
- return FALSE;
+ return NM_SETTING_UPDATE_SECRET_ERROR;
}
/* Silently ignore non-secrets */
if (!(prop_spec->flags & NM_SETTING_PARAM_SECRET))
- return TRUE;
+ return NM_SETTING_UPDATE_SECRET_SUCCESS_UNCHANGED;
if (g_value_type_compatible (G_VALUE_TYPE (value), G_PARAM_SPEC_VALUE_TYPE (prop_spec))) {
+ if (G_VALUE_HOLDS_STRING (value) && G_IS_PARAM_SPEC_STRING (prop_spec)) {
+ /* String is expected to be a common case. Handle it specially and check whether
+ * the value is already set. Otherwise, we just reset the property and
+ * assume the value got modified. */
+ char *v;
+
+ g_object_get (G_OBJECT (setting), prop_spec->name, &v, NULL);
+ if (g_strcmp0 (v, g_value_get_string (value)) == 0) {
+ g_free (v);
+ return NM_SETTING_UPDATE_SECRET_SUCCESS_UNCHANGED;
+ }
+ g_free (v);
+ }
g_object_set_property (G_OBJECT (setting), prop_spec->name, value);
- success = TRUE;
- } else if (g_value_transform (value, &transformed_value)) {
+ return NM_SETTING_UPDATE_SECRET_SUCCESS_MODIFIED;
+ }
+ if (g_value_transform (value, &transformed_value)) {
g_object_set_property (G_OBJECT (setting), prop_spec->name, &transformed_value);
g_value_unset (&transformed_value);
- success = TRUE;
- } else {
- g_set_error (error,
- NM_SETTING_ERROR,
- NM_SETTING_ERROR_PROPERTY_TYPE_MISMATCH,
- "%s", key);
+ return NM_SETTING_UPDATE_SECRET_SUCCESS_MODIFIED;
}
- return success;
+ g_set_error (error,
+ NM_SETTING_ERROR,
+ NM_SETTING_ERROR_PROPERTY_TYPE_MISMATCH,
+ "%s", key);
+ return NM_SETTING_UPDATE_SECRET_ERROR;
}
/**
@@ -1003,28 +1015,41 @@ update_one_secret (NMSetting *setting, const char *key, GValue *value, GError **
gboolean
nm_setting_update_secrets (NMSetting *setting, GHashTable *secrets, GError **error)
{
+ return _nm_setting_update_secrets (setting, secrets, error) != NM_SETTING_UPDATE_SECRET_ERROR;
+}
+
+NMSettingUpdateSecretResult
+_nm_setting_update_secrets (NMSetting *setting, GHashTable *secrets, GError **error)
+{
GHashTableIter iter;
gpointer key, data;
GError *tmp_error = NULL;
+ NMSettingUpdateSecretResult result = NM_SETTING_UPDATE_SECRET_SUCCESS_UNCHANGED;
- g_return_val_if_fail (NM_IS_SETTING (setting), FALSE);
- g_return_val_if_fail (secrets != NULL, FALSE);
+ g_return_val_if_fail (NM_IS_SETTING (setting), NM_SETTING_UPDATE_SECRET_ERROR);
+ g_return_val_if_fail (secrets != NULL, NM_SETTING_UPDATE_SECRET_ERROR);
if (error)
- g_return_val_if_fail (*error == NULL, FALSE);
+ g_return_val_if_fail (*error == NULL, NM_SETTING_UPDATE_SECRET_ERROR);
g_hash_table_iter_init (&iter, secrets);
while (g_hash_table_iter_next (&iter, &key, &data)) {
+ int success;
const char *secret_key = (const char *) key;
GValue *secret_value = (GValue *) data;
- NM_SETTING_GET_CLASS (setting)->update_one_secret (setting, secret_key, secret_value, &tmp_error);
- if (tmp_error) {
+ success = NM_SETTING_GET_CLASS (setting)->update_one_secret (setting, secret_key, secret_value, &tmp_error);
+ g_assert (!((success == NM_SETTING_UPDATE_SECRET_ERROR) ^ (!!tmp_error)));
+
+ if (success == NM_SETTING_UPDATE_SECRET_ERROR) {
g_propagate_error (error, tmp_error);
- return FALSE;
+ return NM_SETTING_UPDATE_SECRET_ERROR;
}
+
+ if (success == NM_SETTING_UPDATE_SECRET_SUCCESS_MODIFIED)
+ result = NM_SETTING_UPDATE_SECRET_SUCCESS_MODIFIED;
}
- return TRUE;
+ return result;
}
static gboolean
diff --git a/libnm-util/nm-setting.h b/libnm-util/nm-setting.h
index b7f7d62..07e0747 100644
--- a/libnm-util/nm-setting.h
+++ b/libnm-util/nm-setting.h
@@ -177,7 +177,7 @@ typedef struct {
GPtrArray *(*need_secrets) (NMSetting *setting);
- gboolean (*update_one_secret) (NMSetting *setting,
+ int (*update_one_secret) (NMSetting *setting,
const char *key,
GValue *value,
GError **error);
--
1.7.11.7
From ff6315cbabd0b7f65561410264910ae655d9435c Mon Sep 17 00:00:00 2001
From: Thomas Haller <thaller@redhat.com>
Date: Wed, 11 Dec 2013 17:53:25 +0100
Subject: [PATCH 3/6] libnm-util: only emit one CHANGED signal when adding
several settings
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Thomas Haller <thaller@redhat.com>
Signed-off-by: Jiří Klimeš <jklimes@redhat.com>
---
libnm-util/nm-connection.c | 68 ++++++++++++++++++++++++++++++----------------
1 file changed, 45 insertions(+), 23 deletions(-)
diff --git a/libnm-util/nm-connection.c b/libnm-util/nm-connection.c
index 807a893..f7d6431 100644
--- a/libnm-util/nm-connection.c
+++ b/libnm-util/nm-connection.c
@@ -183,6 +183,16 @@ setting_changed_cb (NMSetting *setting,
g_signal_emit (self, signals[CHANGED], 0);
}
+static void
+_nm_connection_add_setting (NMConnection *connection, NMSetting *setting)
+{
+ g_hash_table_insert (NM_CONNECTION_GET_PRIVATE (connection)->settings,
+ (gpointer) G_OBJECT_TYPE_NAME (setting),
+ setting);
+ /* Listen for property changes so we can emit the 'changed' signal */
+ g_signal_connect (setting, "notify", (GCallback) setting_changed_cb, connection);
+}
+
/**
* nm_connection_add_setting:
* @connection: a #NMConnection
@@ -199,12 +209,7 @@ nm_connection_add_setting (NMConnection *connection, NMSetting *setting)
g_return_if_fail (NM_IS_CONNECTION (connection));
g_return_if_fail (NM_IS_SETTING (setting));
- g_hash_table_insert (NM_CONNECTION_GET_PRIVATE (connection)->settings,
- (gpointer) G_OBJECT_TYPE_NAME (setting),
- setting);
- /* Listen for property changes so we can emit the 'changed' signal */
- g_signal_connect (setting, "notify", (GCallback) setting_changed_cb, connection);
-
+ _nm_connection_add_setting (connection, setting);
g_signal_emit (connection, signals[CHANGED], 0);
}
@@ -336,19 +341,30 @@ hash_to_connection (NMConnection *connection, GHashTable *new, GError **error)
GHashTableIter iter;
const char *setting_name;
GHashTable *setting_hash;
- NMSetting *setting = NULL;
- GType type;
+ gboolean changed, valid;
+ NMConnectionPrivate *priv = NM_CONNECTION_GET_PRIVATE (connection);
+
+ if ((changed = g_hash_table_size (priv->settings) > 0))
+ g_hash_table_remove_all (priv->settings);
- g_hash_table_remove_all (NM_CONNECTION_GET_PRIVATE (connection)->settings);
g_hash_table_iter_init (&iter, new);
while (g_hash_table_iter_next (&iter, (gpointer) &setting_name, (gpointer) &setting_hash)) {
- type = nm_connection_lookup_setting_type (setting_name);
- if (type)
- setting = nm_setting_new_from_hash (type, setting_hash);
- if (setting)
- nm_connection_add_setting (connection, setting);
+ GType type = nm_connection_lookup_setting_type (setting_name);
+
+ if (type) {
+ NMSetting *setting = nm_setting_new_from_hash (type, setting_hash);
+
+ if (setting) {
+ _nm_connection_add_setting (connection, setting);
+ changed = TRUE;
+ }
+ }
}
- return nm_connection_verify (connection, error);
+
+ valid = nm_connection_verify (connection, error);
+ if (changed)
+ g_signal_emit (connection, signals[CHANGED], 0);
+ return valid;
}
/**
@@ -372,10 +388,8 @@ nm_connection_replace_settings (NMConnection *connection,
if (error)
g_return_val_if_fail (*error == NULL, FALSE);
- if (validate_permissions_type (new_settings, error)) {
+ if (validate_permissions_type (new_settings, error))
valid = hash_to_connection (connection, new_settings, error);
- g_signal_emit (connection, signals[CHANGED], 0);
- }
return valid;
}
@@ -398,8 +412,10 @@ nm_connection_replace_settings_from_connection (NMConnection *connection,
NMConnection *new_connection,
GError **error)
{
+ NMConnectionPrivate *priv;
GHashTableIter iter;
NMSetting *setting;
+ gboolean changed, valid;
g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE);
g_return_val_if_fail (NM_IS_CONNECTION (new_connection), FALSE);
@@ -414,16 +430,22 @@ nm_connection_replace_settings_from_connection (NMConnection *connection,
/* No need to validate permissions like nm_connection_replace_settings()
* since we're dealing with an NMConnection which has already done that.
*/
- g_hash_table_remove_all (NM_CONNECTION_GET_PRIVATE (connection)->settings);
+
+ priv = NM_CONNECTION_GET_PRIVATE (connection);
+ if ((changed = g_hash_table_size (priv->settings) > 0))
+ g_hash_table_remove_all (priv->settings);
if (g_hash_table_size (NM_CONNECTION_GET_PRIVATE (new_connection)->settings)) {
g_hash_table_iter_init (&iter, NM_CONNECTION_GET_PRIVATE (new_connection)->settings);
while (g_hash_table_iter_next (&iter, NULL, (gpointer) &setting))
- nm_connection_add_setting (connection, nm_setting_duplicate (setting));
- } else
- g_signal_emit (connection, signals[CHANGED], 0);
+ _nm_connection_add_setting (connection, nm_setting_duplicate (setting));
+ changed = TRUE;
+ }
- return nm_connection_verify (connection, error);
+ valid = nm_connection_verify (connection, error);
+ if (changed)
+ g_signal_emit (connection, signals[CHANGED], 0);
+ return valid;
}
/**
--
1.7.11.7
From 22cbc77bae4145de955905448b32ec42d044eebc Mon Sep 17 00:00:00 2001
From: Thomas Haller <thaller@redhat.com>
Date: Wed, 11 Dec 2013 21:30:36 +0100
Subject: [PATCH 4/6] core: trivial rename NMSettings signal dbus-updated to
updated-by-user
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
https://bugzilla.redhat.com/show_bug.cgi?id=1040528
Signed-off-by: Thomas Haller <thaller@redhat.com>
Signed-off-by: Jiří Klimeš <jklimes@redhat.com>
---
src/settings/nm-settings-connection.c | 8 ++++----
src/settings/nm-settings-connection.h | 4 ++--
src/settings/nm-settings.c | 8 ++++----
3 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/src/settings/nm-settings-connection.c b/src/settings/nm-settings-connection.c
index 7e0d518..6864810 100644
--- a/src/settings/nm-settings-connection.c
+++ b/src/settings/nm-settings-connection.c
@@ -83,6 +83,7 @@ enum {
enum {
UPDATED,
REMOVED,
+ UPDATED_BY_USER,
LAST_SIGNAL
};
static guint signals[LAST_SIGNAL] = { 0 };
@@ -1233,6 +1233,8 @@ con_update_cb (NMSettingsConnection *self,
GUINT_TO_POINTER (NM_SETTING_SECRET_FLAG_AGENT_OWNED));
nm_agent_manager_save_secrets (info->agent_mgr, for_agent, TRUE, info->sender_uid);
g_object_unref (for_agent);
+
+ g_signal_emit (self, signals[UPDATED_BY_USER], 0);
}
update_complete (self, info, error);
@@ -2040,6 +2040,15 @@ nm_settings_connection_class_init (NMSettingsConnectionClass *class)
NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
+
+ /* Emitted when connection is changed from D-Bus */
+ signals[UPDATED_BY_USER] =
+ g_signal_new (NM_SETTINGS_CONNECTION_UPDATED_BY_USER,
+ G_TYPE_FROM_CLASS (class),
+ G_SIGNAL_RUN_FIRST,
+ 0, NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
signals[REMOVED] =
g_signal_new (NM_SETTINGS_CONNECTION_REMOVED,
diff --git a/src/settings/nm-settings-connection.h b/src/settings/nm-settings-connection.h
index ab29ae8..a16acc9 100644
--- a/src/settings/nm-settings-connection.h
+++ b/src/settings/nm-settings-connection.h
@@ -42,6 +42,9 @@ G_BEGIN_DECLS
#define NM_SETTINGS_CONNECTION_REMOVED "removed"
#define NM_SETTINGS_CONNECTION_GET_SECRETS "get-secrets"
#define NM_SETTINGS_CONNECTION_CANCEL_SECRETS "cancel-secrets"
+
+/* Emitted when connection is changed by a user action */
+#define NM_SETTINGS_CONNECTION_UPDATED_BY_USER "updated-by-user"
/* Properties */
#define NM_SETTINGS_CONNECTION_VISIBLE "visible"
From 85f3da83510fa2f5a961f63d95636168a4743f56 Mon Sep 17 00:00:00 2001
From: Thomas Haller <thaller@redhat.com>
Date: Thu, 12 Dec 2013 10:43:50 +0100
Subject: [PATCH 5/6] core: emit UPDATED_BY_USER signal when reloading
connection from file
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Now UPDATED_BY_USER signal gets emitted immediately after the connection
is updated, rather then only after it is successfully saved.
This means, that the signal will be emitted earlier then before (right
after changing the connection, but before it gets commited).
Furthermore, the signal will also be emitted for connections that
get changed but are not to be saved.
Currently, the only subscriber to this signal is NMSettings
(default_wired_connection_updated_by_user_cb), which should be fine with
this change of semantics (even better).
https://bugzilla.redhat.com/show_bug.cgi?id=1040528
Signed-off-by: Thomas Haller <thaller@redhat.com>
Signed-off-by: Jiří Klimeš <jklimes@redhat.com>
---
src/settings/nm-settings-connection.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/settings/nm-settings-connection.c b/src/settings/nm-settings-connection.c
index 6864810..55cc157 100644
--- a/src/settings/nm-settings-connection.c
+++ b/src/settings/nm-settings-connection.c
@@ -474,6 +474,8 @@ nm_settings_connection_replace_settings (NMSettingsConnection *self,
* only update Unsaved if the caller wanted us to.
*/
changed_cb (self, GUINT_TO_POINTER (update_unsaved));
+
+ g_signal_emit (self, signals[UPDATED_BY_USER], 0);
}
g_signal_handlers_unblock_by_func (self, G_CALLBACK (changed_cb), GUINT_TO_POINTER (TRUE));
--
1.7.11.7
From 0cdd4ada5be88f6481846594e83e5847fc4bb548 Mon Sep 17 00:00:00 2001
From: Thomas Haller <thaller@redhat.com>
Date: Thu, 12 Dec 2013 21:37:06 +0100
Subject: [PATCH 6/6] core: add signal CONNECTION_UPDATED_BY_USER to
NMSettings
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This forwards the signal UPDATED_BY_USER received from one of their
NMConnection.
Signed-off-by: Thomas Haller <thaller@redhat.com>
Signed-off-by: Jiří Klimeš <jklimes@redhat.com>
---
src/settings/nm-settings.c | 23 +++++++++++++++++++++++
src/settings/nm-settings.h | 1 +
2 files changed, 24 insertions(+)
diff --git a/src/settings/nm-settings.c b/src/settings/nm-settings.c
index 5cc4938..a114f52 100644
--- a/src/settings/nm-settings.c
+++ b/src/settings/nm-settings.c
@@ -149,6 +149,7 @@ enum {
PROPERTIES_CHANGED,
CONNECTION_ADDED,
CONNECTION_UPDATED,
+ CONNECTION_UPDATED_BY_USER,
CONNECTION_REMOVED,
CONNECTION_VISIBILITY_CHANGED,
CONNECTIONS_LOADED,
@@ -693,6 +694,16 @@ connection_updated (NMSettingsConnection *connection, gpointer user_data)
}
static void
+connection_updated_by_user (NMSettingsConnection *connection, gpointer user_data)
+{
+ /* Re-emit for listeners like NMPolicy */
+ g_signal_emit (NM_SETTINGS (user_data),
+ signals[CONNECTION_UPDATED_BY_USER],
+ 0,
+ connection);
+}
+
+static void
connection_visibility_changed (NMSettingsConnection *connection,
GParamSpec *pspec,
gpointer user_data)
@@ -718,6 +729,7 @@ connection_removed (NMSettingsConnection *connection, gpointer user_data)
g_signal_handlers_disconnect_by_func (connection, G_CALLBACK (connection_removed), self);
g_signal_handlers_disconnect_by_func (connection, G_CALLBACK (connection_updated), self);
+ g_signal_handlers_disconnect_by_func (connection, G_CALLBACK (connection_updated_by_user), self);
g_signal_handlers_disconnect_by_func (connection, G_CALLBACK (connection_visibility_changed), self);
/* Forget about the connection internally */
@@ -831,6 +843,8 @@ claim_connection (NMSettings *self,
G_CALLBACK (connection_removed), self);
g_signal_connect (connection, NM_SETTINGS_CONNECTION_UPDATED,
G_CALLBACK (connection_updated), self);
+ g_signal_connect (connection, NM_SETTINGS_CONNECTION_UPDATED_BY_USER,
+ G_CALLBACK (connection_updated_by_user), self);
g_signal_connect (connection, "notify::" NM_SETTINGS_CONNECTION_VISIBLE,
G_CALLBACK (connection_visibility_changed),
self);
@@ -1955,6 +1969,15 @@ nm_settings_class_init (NMSettingsClass *class)
g_cclosure_marshal_VOID__OBJECT,
G_TYPE_NONE, 1, G_TYPE_OBJECT);
+ signals[CONNECTION_UPDATED_BY_USER] =
+ g_signal_new (NM_SETTINGS_SIGNAL_CONNECTION_UPDATED_BY_USER,
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_FIRST,
+ 0,
+ NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 1, G_TYPE_OBJECT);
+
signals[CONNECTION_REMOVED] =
g_signal_new (NM_SETTINGS_SIGNAL_CONNECTION_REMOVED,
G_OBJECT_CLASS_TYPE (object_class),
diff --git a/src/settings/nm-settings.h b/src/settings/nm-settings.h
index 7e699c2..d9a5211 100644
--- a/src/settings/nm-settings.h
+++ b/src/settings/nm-settings.h
@@ -46,6 +46,7 @@
#define NM_SETTINGS_SIGNAL_CONNECTION_ADDED "connection-added"
#define NM_SETTINGS_SIGNAL_CONNECTION_UPDATED "connection-updated"
+#define NM_SETTINGS_SIGNAL_CONNECTION_UPDATED_BY_USER "connection-updated-by-user"
#define NM_SETTINGS_SIGNAL_CONNECTION_REMOVED "connection-removed"
#define NM_SETTINGS_SIGNAL_CONNECTION_VISIBILITY_CHANGED "connection-visibility-changed"
#define NM_SETTINGS_SIGNAL_CONNECTIONS_LOADED "connections-loaded"
--
1.7.11.7
From f027c4ad0e20e17725ed05e26a90f80a1c24311b Mon Sep 17 00:00:00 2001
From: Thomas Haller <thaller@redhat.com>
Date: Thu, 12 Dec 2013 20:00:38 +0100
Subject: [PATCH] core: reset auto-retry counter when a connection gets
updated
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This restores the behaviour, that was removed in commit
e299d7b30f7accbd83270fb1eb973fd903714d77.
https://bugzilla.redhat.com/show_bug.cgi?id=1040528
Signed-off-by: Thomas Haller <thaller@redhat.com>
Signed-off-by: Jiří Klimeš <jklimes@redhat.com>
---
src/nm-policy.c | 16 ++++++++++------
1 file changed, 10 insertions(+), 6 deletions(-)
diff --git a/src/nm-policy.c b/src/nm-policy.c
index e6a0498..251bd79 100644
--- a/src/nm-policy.c
+++ b/src/nm-policy.c
@@ -1963,16 +1963,19 @@ connection_updated (NMSettings *settings,
firewall_update_zone (policy, connection);
- /* FIXME: previously, we set_connection_auto_retries() again to
- * RETRIES_DEFAULT, in order to re-enable a connection when it is changed
- * by the user. This caused a serious problem, so remove it for now
- * (rh #1040528).
- **/
-
schedule_activate_all (policy);
}
static void
+connection_updated_by_user (NMSettings *settings,
+ NMConnection *connection,
+ gpointer user_data)
+{
+ /* Reset auto retries back to default since connection was updated */
+ set_connection_auto_retries (connection, RETRIES_DEFAULT);
+}
+
+static void
_deactivate_if_active (NMManager *manager, NMConnection *connection)
{
const GSList *active, *iter;
@@ -2110,6 +2113,7 @@ nm_policy_new (NMManager *manager, NMSettings *settings)
_connect_settings_signal (policy, NM_SETTINGS_SIGNAL_CONNECTIONS_LOADED, connections_loaded);
_connect_settings_signal (policy, NM_SETTINGS_SIGNAL_CONNECTION_ADDED, connection_added);
_connect_settings_signal (policy, NM_SETTINGS_SIGNAL_CONNECTION_UPDATED, connection_updated);
+ _connect_settings_signal (policy, NM_SETTINGS_SIGNAL_CONNECTION_UPDATED_BY_USER, connection_updated_by_user);
_connect_settings_signal (policy, NM_SETTINGS_SIGNAL_CONNECTION_REMOVED, connection_removed);
_connect_settings_signal (policy, NM_SETTINGS_SIGNAL_CONNECTION_VISIBILITY_CHANGED,
connection_visibility_changed);
--
1.7.11.7
From 3d30ff01ef1d78cee8169f5bb464b988c8ac817b Mon Sep 17 00:00:00 2001
From: Dan Winship <danw@gnome.org>
Date: Thu, 5 Dec 2013 08:50:10 -0500
Subject: [PATCH] core: remove useless NMSettings::connections-loaded signal
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
NMSettings (and NMConnectionProvider) had a signal to indicate when it
had loaded the connections, but in reality this always happened before
nm_settings_new() returned (as a side effect of calling
unmanaged_specs_changed()) and so no one else would ever actually see
the signal. So just kill it.
Signed-off-by: Jiří Klimeš <jklimes@redhat.com>
---
src/bluez-manager/nm-bluez-device.c | 22 +++++-----------
src/devices/nm-device.c | 20 ---------------
src/nm-connection-provider.c | 17 -------------
src/nm-connection-provider.h | 17 -------------
src/nm-policy.c | 14 ----------
src/settings/nm-settings.c | 51 ++++---------------------------------
src/settings/nm-settings.h | 3 ---
7 files changed, 11 insertions(+), 133 deletions(-)
diff --git a/src/bluez-manager/nm-bluez-device.c b/src/bluez-manager/nm-bluez-device.c
index 88e0ad7..8e8f39d 100644
--- a/src/bluez-manager/nm-bluez-device.c
+++ b/src/bluez-manager/nm-bluez-device.c
@@ -180,11 +180,6 @@ pan_connection_check_create (NMBluezDevice *self)
return;
}
- if (!nm_connection_provider_has_connections_loaded (priv->provider)) {
- /* do not try to create any connections until the connection provider is ready. */
- return;
- }
-
/* Only try once to create a connection. If it does not succeed, we do not try again. Also,
* if the connection gets deleted later, do not create another one for this device. */
priv->pan_connection_no_autocreate = TRUE;
@@ -387,13 +382,14 @@ cp_connection_updated (NMConnectionProvider *provider,
}
static void
-cp_connections_loaded (NMConnectionProvider *provider, NMBluezDevice *self)
+load_connections (NMBluezDevice *self)
{
+ NMBluezDevicePrivate *priv = NM_BLUEZ_DEVICE_GET_PRIVATE (self);
const GSList *connections, *iter;
- connections = nm_connection_provider_get_connections (provider);
+ connections = nm_connection_provider_get_connections (priv->provider);
for (iter = connections; iter; iter = g_slist_next (iter))
- cp_connection_added (provider, NM_CONNECTION (iter->data), self);
+ cp_connection_added (priv->provider, NM_CONNECTION (iter->data), self);
}
/***********************************************************/
@@ -848,7 +848,7 @@ query_properties (NMBluezDevice *self)
}
/* Check if any connections match this device */
- cp_connections_loaded (priv->provider, self);
+ load_connections (self);
}
#else
static void
@@ -832,7 +828,7 @@ get_properties_cb_4 (GObject *source_object, GAsyncResult *res, gpointer user_da
g_hash_table_unref (properties);
/* Check if any connections match this device */
- cp_connections_loaded (priv->provider, self);
+ load_connections (self);
priv->initialized = TRUE;
g_signal_emit (self, signals[INITIALIZED], 0, TRUE);
@@ -970,11 +966,6 @@ nm_bluez_device_new (const char *path, NMConnectionProvider *provider, int bluez
G_CALLBACK (cp_connection_updated),
self);
- g_signal_connect (priv->provider,
- NM_CP_SIGNAL_CONNECTIONS_LOADED,
- G_CALLBACK (cp_connections_loaded),
- self);
-
g_bus_get (G_BUS_TYPE_SYSTEM,
NULL,
(GAsyncReadyCallback) on_bus_acquired,
@@ -1027,7 +1018,6 @@ dispose (GObject *object)
g_signal_handlers_disconnect_by_func (priv->provider, cp_connection_added, self);
g_signal_handlers_disconnect_by_func (priv->provider, cp_connection_removed, self);
g_signal_handlers_disconnect_by_func (priv->provider, cp_connection_updated, self);
- g_signal_handlers_disconnect_by_func (priv->provider, cp_connections_loaded, self);
#if ! WITH_BLUEZ4
g_clear_object (&priv->adapter);
diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c
index b3b324b..4157598 100644
--- a/src/devices/nm-device.c
+++ b/src/devices/nm-device.c
@@ -351,7 +351,6 @@ static const char *reason_to_string (NMDeviceStateReason reason);
static void ip_check_gw_ping_cleanup (NMDevice *self);
static void cp_connection_added (NMConnectionProvider *cp, NMConnection *connection, gpointer user_data);
-static void cp_connections_loaded (NMConnectionProvider *cp, NMConnection *connection, gpointer user_data);
static void cp_connection_removed (NMConnectionProvider *cp, NMConnection *connection, gpointer user_data);
static void cp_connection_updated (NMConnectionProvider *cp, NMConnection *connection, gpointer user_data);
@@ -907,11 +906,6 @@ nm_device_set_connection_provider (NMDevice *device,
G_CALLBACK (cp_connection_added),
device);
- priv->cp_loaded_id = g_signal_connect (priv->con_provider,
- NM_CP_SIGNAL_CONNECTIONS_LOADED,
- G_CALLBACK (cp_connections_loaded),
- device);
-
priv->cp_removed_id = g_signal_connect (priv->con_provider,
NM_CP_SIGNAL_CONNECTION_REMOVED,
G_CALLBACK (cp_connection_removed),
@@ -7043,20 +7037,6 @@ cp_connection_added (NMConnectionProvider *cp, NMConnection *connection, gpointe
}
static void
-cp_connections_loaded (NMConnectionProvider *cp, NMConnection *connection, gpointer user_data)
-{
- const GSList *connections, *iter;
- gboolean added = FALSE;
-
- connections = nm_connection_provider_get_connections (cp);
- for (iter = connections; iter; iter = g_slist_next (iter))
- added |= _try_add_available_connection (NM_DEVICE (user_data), NM_CONNECTION (iter->data));
-
- if (added)
- _signal_available_connections_changed (NM_DEVICE (user_data));
-}
-
-static void
cp_connection_removed (NMConnectionProvider *cp, NMConnection *connection, gpointer user_data)
{
if (_del_available_connection (NM_DEVICE (user_data), connection))
diff --git a/src/nm-connection-provider.c b/src/nm-connection-provider.c
index 39ede1d..f6ee745 100644
--- a/src/nm-connection-provider.c
+++ b/src/nm-connection-provider.c
@@ -41,15 +41,6 @@ nm_connection_provider_get_connections (NMConnectionProvider *self)
return NULL;
}
-gboolean
-nm_connection_provider_has_connections_loaded (NMConnectionProvider *self)
-{
- g_return_val_if_fail (NM_IS_CONNECTION_PROVIDER (self), FALSE);
-
- g_assert (NM_CONNECTION_PROVIDER_GET_INTERFACE (self)->has_connections_loaded);
- return NM_CONNECTION_PROVIDER_GET_INTERFACE (self)->has_connections_loaded (self);
-}
-
NMConnection *
nm_connection_provider_add_connection (NMConnectionProvider *self,
NMConnection *connection,
@@ -131,14 +122,6 @@ nm_connection_provider_init (gpointer g_iface)
NULL, NULL,
g_cclosure_marshal_VOID__OBJECT,
G_TYPE_NONE, 1, G_TYPE_OBJECT);
-
- g_signal_new (NM_CP_SIGNAL_CONNECTIONS_LOADED,
- iface_type,
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (NMConnectionProvider, connections_loaded),
- NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
}
GType
diff --git a/src/nm-connection-provider.h b/src/nm-connection-provider.h
index 05c49a7..96db76a 100644
--- a/src/nm-connection-provider.h
+++ b/src/nm-connection-provider.h
@@ -29,7 +29,6 @@ typedef struct _NMConnectionProvider NMConnectionProvider;
#define NM_CP_SIGNAL_CONNECTION_ADDED "cp-connection-added"
#define NM_CP_SIGNAL_CONNECTION_UPDATED "cp-connection-updated"
#define NM_CP_SIGNAL_CONNECTION_REMOVED "cp-connection-removed"
-#define NM_CP_SIGNAL_CONNECTIONS_LOADED "cp-connections-loaded"
/**
@@ -58,8 +57,6 @@ struct _NMConnectionProvider {
const GSList * (*get_connections) (NMConnectionProvider *self);
- gboolean (*has_connections_loaded) (NMConnectionProvider *self);
-
NMConnection * (*add_connection) (NMConnectionProvider *self,
NMConnection *connection,
gboolean save_to_disk,
@@ -75,7 +72,6 @@ struct _NMConnectionProvider {
void (*connection_removed) (NMConnectionProvider *self, NMConnection *connection);
- void (*connections_loaded) (NMConnectionProvider *self);
};
GType nm_connection_provider_get_type (void);
@@ -114,19 +110,6 @@ GSList *nm_connection_provider_get_best_connections (NMConnectionProvider *self,
const GSList *nm_connection_provider_get_connections (NMConnectionProvider *self);
/**
- * nm_connection_provider_has_connections_loaded:
- * @self: the #NMConnectionProvider
- *
- * Returns: TRUE or FALSE indicating whether the connections of the provider are already
- * loaded. If they are not yet loaded, the provider will not emit the signals
- * NM_CP_SIGNAL_CONNECTION_ADDED, NM_CP_SIGNAL_CONNECTION_UPDATED and
- * NM_CP_SIGNAL_CONNECTION_REMOVED until NM_CP_SIGNAL_CONNECTIONS_LOADED gets
- * emited.
- */
-gboolean nm_connection_provider_has_connections_loaded (NMConnectionProvider *self);
-
-
-/**
* nm_connection_provider_add_connection:
* @self: the #NMConnectionProvider
* @connection: the connection to be added
diff --git a/src/nm-policy.c b/src/nm-policy.c
index 0a0fe3f..d8f6447 100644
--- a/src/nm-policy.c
+++ b/src/nm-policy.c
@@ -1835,19 +1835,6 @@ connection_added (NMSettings *settings,
}
static void
-connections_loaded (NMSettings *settings, gpointer user_data)
-{
- // FIXME: "connections-loaded" signal is emmitted *before* we connect to it
- // in nm_policy_new(). So this function is never called. Currently we work around
- // that by calling reset_retries_all() in nm_policy_new()
-
- /* Initialize connections' auto-retries */
- reset_retries_all (settings, NULL);
-
- schedule_activate_all ((NMPolicy *) user_data);
-}
-
-static void
add_or_change_zone_cb (GError *error, gpointer user_data)
{
NMDevice *device = NM_DEVICE (user_data);
@@ -2099,7 +2086,6 @@ nm_policy_new (NMManager *manager, NMSettings *settings)
_connect_manager_signal (policy, NM_MANAGER_ACTIVE_CONNECTION_ADDED, active_connection_added);
_connect_manager_signal (policy, NM_MANAGER_ACTIVE_CONNECTION_REMOVED, active_connection_removed);
- _connect_settings_signal (policy, NM_SETTINGS_SIGNAL_CONNECTIONS_LOADED, connections_loaded);
_connect_settings_signal (policy, NM_SETTINGS_SIGNAL_CONNECTION_ADDED, connection_added);
_connect_settings_signal (policy, NM_SETTINGS_SIGNAL_CONNECTION_UPDATED, connection_updated);
_connect_settings_signal (policy, NM_SETTINGS_SIGNAL_CONNECTION_UPDATED_BY_USER, connection_updated_by_user);
diff --git a/src/settings/nm-settings.c b/src/settings/nm-settings.c
index a114f52..42c8b95 100644
--- a/src/settings/nm-settings.c
+++ b/src/settings/nm-settings.c
@@ -152,7 +152,6 @@ enum {
CONNECTION_UPDATED_BY_USER,
CONNECTION_REMOVED,
CONNECTION_VISIBILITY_CHANGED,
- CONNECTIONS_LOADED,
AGENT_REGISTERED,
NEW_CONNECTION, /* exported, not used internally */
@@ -183,9 +182,6 @@ load_connections (NMSettings *self)
NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
GSList *iter;
- if (priv->connections_loaded)
- return;
-
for (iter = priv->plugins; iter; iter = g_slist_next (iter)) {
NMSystemConfigInterface *plugin = NM_SYSTEM_CONFIG_INTERFACE (iter->data);
GSList *plugin_connections;
@@ -214,9 +210,6 @@ load_connections (NMSettings *self)
priv->connections_loaded = TRUE;
unmanaged_specs_changed (NULL, self);
-
- g_signal_emit (self, signals[CONNECTIONS_LOADED], 0);
- g_signal_emit_by_name (self, NM_CP_SIGNAL_CONNECTIONS_LOADED);
}
void
@@ -233,8 +226,6 @@ nm_settings_for_each_connection (NMSettings *self,
priv = NM_SETTINGS_GET_PRIVATE (self);
- load_connections (self);
-
g_hash_table_iter_init (&iter, priv->connections);
while (g_hash_table_iter_next (&iter, NULL, &data))
for_each_func (self, NM_SETTINGS_CONNECTION (data), user_data);
@@ -249,8 +240,6 @@ impl_settings_list_connections (NMSettings *self,
GHashTableIter iter;
gpointer key;
- load_connections (self);
-
*connections = g_ptr_array_sized_new (g_hash_table_size (priv->connections) + 1);
g_hash_table_iter_init (&iter, priv->connections);
while (g_hash_table_iter_next (&iter, &key, NULL))
@@ -270,8 +259,6 @@ nm_settings_get_connection_by_uuid (NMSettings *self, const char *uuid)
priv = NM_SETTINGS_GET_PRIVATE (self);
- load_connections (self);
-
g_hash_table_iter_init (&iter, priv->connections);
while (g_hash_table_iter_next (&iter, NULL, (gpointer) &candidate)) {
if (g_strcmp0 (uuid, nm_connection_get_uuid (NM_CONNECTION (candidate))) == 0)
@@ -361,8 +348,6 @@ nm_settings_get_connection_by_path (NMSettings *self, const char *path)
priv = NM_SETTINGS_GET_PRIVATE (self);
- load_connections (self);
-
return (NMSettingsConnection *) g_hash_table_lookup (priv->connections, path);
}
@@ -416,7 +401,6 @@ nm_settings_get_unmanaged_specs (NMSettings *self)
{
NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
- load_connections (self);
return priv->unmanaged_specs;
}
@@ -861,9 +845,7 @@ claim_connection (NMSettings *self,
g_object_ref (connection));
/* Only emit the individual connection-added signal after connections
- * have been initially loaded. While getting the first list of connections
- * we suppress it, then send the connections-loaded signal after we're all
- * done to minimize processing.
+ * have been initially loaded.
*/
if (priv->connections_loaded) {
/* Internal added signal */
@@ -1314,14 +1296,10 @@ impl_settings_reload_connections (NMSettings *self,
if (!ensure_root (priv->dbus_mgr, context))
return;
- if (!priv->connections_loaded) {
- load_connections (self);
- } else {
- for (iter = priv->plugins; iter; iter = g_slist_next (iter)) {
- NMSystemConfigInterface *plugin = NM_SYSTEM_CONFIG_INTERFACE (iter->data);
+ for (iter = priv->plugins; iter; iter = g_slist_next (iter)) {
+ NMSystemConfigInterface *plugin = NM_SYSTEM_CONFIG_INTERFACE (iter->data);
- nm_system_config_interface_reload_connections (plugin);
- }
+ nm_system_config_interface_reload_connections (plugin);
}
dbus_g_method_return (context, TRUE);
@@ -1770,14 +1748,6 @@ get_connections (NMConnectionProvider *provider)
return g_slist_reverse (list);
}
-static gboolean
-has_connections_loaded (NMConnectionProvider *provider)
-{
- NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (provider);
-
- return priv->connections_loaded;
-}
-
/***************************************************************/
NMSettings *
@@ -1805,7 +1775,7 @@ nm_settings_new (GError **error)
return NULL;
}
- unmanaged_specs_changed (NULL, self);
+ load_connections (self);
nm_dbus_manager_register_object (priv->dbus_mgr, NM_DBUS_PATH_SETTINGS, self);
return self;
@@ -1817,7 +1786,6 @@ connection_provider_init (NMConnectionProvider *cp_class)
{
cp_class->get_best_connections = get_best_connections;
cp_class->get_connections = get_connections;
- cp_class->has_connections_loaded = has_connections_loaded;
cp_class->add_connection = _nm_connection_provider_add_connection;
}
@@ -1996,15 +1964,6 @@ nm_settings_class_init (NMSettingsClass *class)
g_cclosure_marshal_VOID__OBJECT,
G_TYPE_NONE, 1, G_TYPE_OBJECT);
- signals[CONNECTIONS_LOADED] =
- g_signal_new (NM_SETTINGS_SIGNAL_CONNECTIONS_LOADED,
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (NMSettingsClass, connections_loaded),
- NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
-
signals[AGENT_REGISTERED] =
g_signal_new (NM_SETTINGS_SIGNAL_AGENT_REGISTERED,
G_OBJECT_CLASS_TYPE (object_class),
diff --git a/src/settings/nm-settings.h b/src/settings/nm-settings.h
index d9a5211..5b316a4 100644
--- a/src/settings/nm-settings.h
+++ b/src/settings/nm-settings.h
@@ -49,7 +49,6 @@
#define NM_SETTINGS_SIGNAL_CONNECTION_UPDATED_BY_USER "connection-updated-by-user"
#define NM_SETTINGS_SIGNAL_CONNECTION_REMOVED "connection-removed"
#define NM_SETTINGS_SIGNAL_CONNECTION_VISIBILITY_CHANGED "connection-visibility-changed"
-#define NM_SETTINGS_SIGNAL_CONNECTIONS_LOADED "connections-loaded"
#define NM_SETTINGS_SIGNAL_AGENT_REGISTERED "agent-registered"
typedef struct {
@@ -70,8 +69,6 @@ typedef struct {
void (*connection_visibility_changed) (NMSettings *self, NMSettingsConnection *connection);
- void (*connections_loaded) (NMSettings *self);
-
void (*agent_registered) (NMSettings *self, NMSecretAgent *agent);
} NMSettingsClass;
--
1.7.11.7
From 828c316080ce58c43a521eca856efa95d008fd87 Mon Sep 17 00:00:00 2001
From: Dan Winship <danw@gnome.org>
Date: Thu, 5 Dec 2013 04:57:01 -0500
Subject: [PATCH] core: simplify autoconnect retry handling
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Move some of the can-autoconnect tracking into NMSettingsConnection
rather than having NMPolicy track it using object data.
Signed-off-by: Jiří Klimeš <jklimes@redhat.com>
---
src/nm-policy.c | 164 ++++++++++++++--------------------
src/settings/nm-settings-connection.c | 75 ++++++++++++++++
src/settings/nm-settings-connection.h | 13 +++
3 files changed, 155 insertions(+), 97 deletions(-)
diff --git a/src/nm-policy.c b/src/nm-policy.c
index d8f6447..55effd5 100644
--- a/src/nm-policy.c
+++ b/src/nm-policy.c
@@ -89,12 +89,6 @@ enum {
PROP_ACTIVATING_IP6_DEVICE
};
-#define RETRIES_TAG "autoconnect-retries"
-#define RETRIES_DEFAULT 4
-#define RESET_RETRIES_TIMESTAMP_TAG "reset-retries-timestamp-tag"
-#define RESET_RETRIES_TIMER 300
-#define FAILURE_REASON_TAG "failure-reason"
-
static void schedule_activate_all (NMPolicy *policy);
@@ -927,20 +921,6 @@ check_activating_devices (NMPolicy *policy)
g_object_thaw_notify (object);
}
-static void
-set_connection_auto_retries (NMConnection *connection, guint retries)
-{
- /* add +1 so that the tag still exists if the # retries is 0 */
- g_object_set_data (G_OBJECT (connection), RETRIES_TAG, GUINT_TO_POINTER (retries + 1));
-}
-
-static guint32
-get_connection_auto_retries (NMConnection *connection)
-{
- /* subtract 1 to handle the +1 from set_connection_auto_retries() */
- return GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (connection), RETRIES_TAG)) - 1;
-}
-
typedef struct {
NMPolicy *policy;
NMDevice *device;
@@ -989,28 +969,11 @@ auto_activate_device (gpointer user_data)
/* Remove connections that shouldn't be auto-activated */
while (iter) {
NMSettingsConnection *candidate = NM_SETTINGS_CONNECTION (iter->data);
- gboolean remove_it = FALSE;
- const char *permission;
/* Grab next item before we possibly delete the current item */
iter = g_slist_next (iter);
- /* Ignore connections that were tried too many times or are not visible
- * to any logged-in users. Also ignore shared wifi connections for
- * which no user has the shared wifi permission.
- */
- if ( get_connection_auto_retries (NM_CONNECTION (candidate)) == 0
- || nm_settings_connection_is_visible (candidate) == FALSE)
- remove_it = TRUE;
- else {
- permission = nm_utils_get_shared_wifi_permission (NM_CONNECTION (candidate));
- if (permission) {
- if (nm_settings_connection_check_permission (candidate, permission) == FALSE)
- remove_it = TRUE;
- }
- }
-
- if (remove_it)
+ if (!nm_settings_connection_can_autoconnect (candidate))
connections = g_slist_remove (connections, candidate);
}
@@ -1164,32 +1127,34 @@ hostname_changed (NMManager *manager, GParamSpec *pspec, gpointer user_data)
}
static void
-reset_retries_all (NMSettings *settings, NMDevice *device)
+reset_autoconnect_all (NMPolicy *policy, NMDevice *device)
{
+ NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (policy);
GSList *connections, *iter;
- GError *error = NULL;
- connections = nm_settings_get_connections (settings);
+ connections = nm_settings_get_connections (priv->settings);
for (iter = connections; iter; iter = g_slist_next (iter)) {
- if (!device || nm_device_check_connection_compatible (device, iter->data, &error))
- set_connection_auto_retries (NM_CONNECTION (iter->data), RETRIES_DEFAULT);
- g_clear_error (&error);
+ if (!device || nm_device_check_connection_compatible (device, iter->data, NULL)) {
+ nm_settings_connection_reset_autoconnect_retries (iter->data);
+ nm_settings_connection_set_autoconnect_blocked_reason (iter->data, NM_DEVICE_STATE_REASON_NONE);
+ }
}
g_slist_free (connections);
}
static void
-reset_retries_for_failed_secrets (NMSettings *settings)
+reset_autoconnect_for_failed_secrets (NMPolicy *policy)
{
+ NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (policy);
GSList *connections, *iter;
- connections = nm_settings_get_connections (settings);
+ connections = nm_settings_get_connections (priv->settings);
for (iter = connections; iter; iter = g_slist_next (iter)) {
- NMDeviceStateReason reason = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (iter->data), FAILURE_REASON_TAG));
+ NMSettingsConnection *connection = NM_SETTINGS_CONNECTION (iter->data);
- if (reason == NM_DEVICE_STATE_REASON_NO_SECRETS) {
- set_connection_auto_retries (NM_CONNECTION (iter->data), RETRIES_DEFAULT);
- g_object_set_data (G_OBJECT (iter->data), FAILURE_REASON_TAG, GUINT_TO_POINTER (0));
+ if (nm_settings_connection_get_autoconnect_blocked_reason (connection) == NM_DEVICE_STATE_REASON_NO_SECRETS) {
+ nm_settings_connection_reset_autoconnect_retries (connection);
+ nm_settings_connection_set_autoconnect_blocked_reason (connection, NM_DEVICE_STATE_REASON_NONE);
}
}
g_slist_free (connections);
@@ -1199,7 +1164,6 @@ static void
sleeping_changed (NMManager *manager, GParamSpec *pspec, gpointer user_data)
{
NMPolicy *policy = user_data;
- NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (policy);
gboolean sleeping = FALSE, enabled = FALSE;
g_object_get (G_OBJECT (manager), NM_MANAGER_SLEEPING, &sleeping, NULL);
@@ -1207,7 +1171,7 @@ sleeping_changed (NMManager *manager, GParamSpec *pspec, gpointer user_data)
/* Reset retries on all connections so they'll checked on wakeup */
if (sleeping || !enabled)
- reset_retries_all (priv->settings, NULL);
+ reset_autoconnect_all (policy, NULL);
}
static void
@@ -1253,26 +1217,28 @@ reset_connections_retries (gpointer user_data)
priv->reset_retries_id = 0;
- min_stamp = now = time (NULL);
+ min_stamp = 0;
+ now = time (NULL);
connections = nm_settings_get_connections (priv->settings);
for (iter = connections; iter; iter = g_slist_next (iter)) {
- con_stamp = GPOINTER_TO_SIZE (g_object_get_data (G_OBJECT (iter->data), RESET_RETRIES_TIMESTAMP_TAG));
+ NMSettingsConnection *connection = NM_SETTINGS_CONNECTION (iter->data);
+
+ con_stamp = nm_settings_connection_get_autoconnect_retry_time (connection);
if (con_stamp == 0)
continue;
- if (con_stamp + RESET_RETRIES_TIMER <= now) {
- set_connection_auto_retries (NM_CONNECTION (iter->data), RETRIES_DEFAULT);
- g_object_set_data (G_OBJECT (iter->data), RESET_RETRIES_TIMESTAMP_TAG, GSIZE_TO_POINTER (0));
+
+ if (con_stamp < now) {
+ nm_settings_connection_reset_autoconnect_retries (connection);
+ nm_settings_connection_set_autoconnect_blocked_reason (connection, NM_DEVICE_STATE_REASON_NONE);
changed = TRUE;
- continue;
- }
- if (con_stamp < min_stamp)
+ } else if (min_stamp == 0 || min_stamp > con_stamp)
min_stamp = con_stamp;
}
g_slist_free (connections);
/* Schedule the handler again if there are some stamps left */
- if (min_stamp != now)
- priv->reset_retries_id = g_timeout_add_seconds (RESET_RETRIES_TIMER - (now - min_stamp), reset_connections_retries, policy);
+ if (min_stamp != 0)
+ priv->reset_retries_id = g_timeout_add_seconds (min_stamp - now, reset_connections_retries, policy);
/* If anything changed, try to activate the newly re-enabled connections */
if (changed)
@@ -1306,7 +1271,7 @@ activate_slave_connections (NMPolicy *policy, NMConnection *connection,
g_assert (s_slave_con);
if (!g_strcmp0 (nm_setting_connection_get_master (s_slave_con), master_device))
- set_connection_auto_retries (slave, RETRIES_DEFAULT);
+ nm_settings_connection_reset_autoconnect_retries (NM_SETTINGS_CONNECTION (slave));
}
g_slist_free (connections);
@@ -1393,14 +1358,14 @@ device_state_changed (NMDevice *device,
{
NMPolicy *policy = (NMPolicy *) user_data;
NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (policy);
- NMConnection *connection = nm_device_get_connection (device);
+ NMSettingsConnection *connection = NM_SETTINGS_CONNECTION (nm_device_get_connection (device));
const char *ip_iface = nm_device_get_ip_iface (device);
NMIP4Config *ip4_config;
NMIP6Config *ip6_config;
NMSettingConnection *s_con = NULL;
if (connection)
- g_object_set_data (G_OBJECT (connection), FAILURE_REASON_TAG, GUINT_TO_POINTER (0));
+ nm_settings_connection_set_autoconnect_blocked_reason (connection, NM_DEVICE_STATE_REASON_NONE);
switch (new_state) {
case NM_DEVICE_STATE_FAILED:
@@ -1410,46 +1375,50 @@ device_state_changed (NMDevice *device,
if ( connection
&& old_state >= NM_DEVICE_STATE_PREPARE
&& old_state <= NM_DEVICE_STATE_ACTIVATED) {
- guint32 tries = get_connection_auto_retries (connection);
+ guint32 tries = nm_settings_connection_get_autoconnect_retries (connection);
if (reason == NM_DEVICE_STATE_REASON_NO_SECRETS) {
/* If the connection couldn't get the secrets it needed (ex because
* the user canceled, or no secrets exist), there's no point in
* automatically retrying because it's just going to fail anyway.
*/
- set_connection_auto_retries (connection, 0);
+ nm_settings_connection_set_autoconnect_retries (connection, 0);
- /* Mark the connection as failed due to missing secrets so that we can reset
- * RETRIES_TAG and automatically re-try when an secret agent registers.
+ /* Mark the connection as failed due to missing secrets so that we can
+ * automatically re-try when an secret agent registers.
*/
- g_object_set_data (G_OBJECT (connection), FAILURE_REASON_TAG, GUINT_TO_POINTER (NM_DEVICE_STATE_REASON_NO_SECRETS));
+ nm_settings_connection_set_autoconnect_blocked_reason (connection, NM_DEVICE_STATE_REASON_NO_SECRETS);
} else if (tries > 0) {
/* Otherwise if it's a random failure, just decrease the number
* of automatic retries so that the connection gets tried again
* if it still has a retry count.
*/
- set_connection_auto_retries (connection, tries - 1);
+ nm_settings_connection_set_autoconnect_retries (connection, tries - 1);
}
- if (get_connection_auto_retries (connection) == 0) {
- nm_log_info (LOGD_DEVICE, "Marking connection '%s' invalid.", nm_connection_get_id (connection));
+ if (nm_settings_connection_get_autoconnect_retries (connection) == 0) {
+ nm_log_info (LOGD_DEVICE, "Marking connection '%s' invalid.",
+ nm_connection_get_id (NM_CONNECTION (connection)));
/* Schedule a handler to reset retries count */
- g_object_set_data (G_OBJECT (connection), RESET_RETRIES_TIMESTAMP_TAG, GSIZE_TO_POINTER ((gsize) time (NULL)));
- if (!priv->reset_retries_id)
- priv->reset_retries_id = g_timeout_add_seconds (RESET_RETRIES_TIMER, reset_connections_retries, policy);
+ if (!priv->reset_retries_id) {
+ time_t retry_time = nm_settings_connection_get_autoconnect_retry_time (connection);
+
+ g_warn_if_fail (retry_time != 0);
+ priv->reset_retries_id = g_timeout_add_seconds (MAX (0, retry_time - time (NULL)), reset_connections_retries, policy);
+ }
}
- nm_connection_clear_secrets (connection);
+ nm_connection_clear_secrets (NM_CONNECTION (connection));
}
break;
case NM_DEVICE_STATE_ACTIVATED:
if (connection) {
/* Reset auto retries back to default since connection was successful */
- set_connection_auto_retries (connection, RETRIES_DEFAULT);
+ nm_settings_connection_reset_autoconnect_retries (connection);
/* And clear secrets so they will always be requested from the
* settings service when the next connection is made.
*/
- nm_connection_clear_secrets (connection);
+ nm_connection_clear_secrets (NM_CONNECTION (connection));
}
/* Add device's new IPv4 and IPv6 configs to DNS */
@@ -1473,10 +1442,11 @@ device_state_changed (NMDevice *device,
update_routing_and_dns (policy, FALSE);
break;
case NM_DEVICE_STATE_DISCONNECTED:
- /* Reset RETRIES_TAG when carrier on. If cable was unplugged
- * and plugged again, we should try to reconnect */
+ /* Reset retry counts for a device's connections when carrier on; if cable
+ * was unplugged and plugged in again, we should try to reconnect.
+ */
if (reason == NM_DEVICE_STATE_REASON_CARRIER && old_state == NM_DEVICE_STATE_UNAVAILABLE)
- reset_retries_all (priv->settings, device);
+ reset_autoconnect_all (policy, device);
if (old_state > NM_DEVICE_STATE_DISCONNECTED)
update_routing_and_dns (policy, FALSE);
@@ -1488,13 +1458,13 @@ device_state_changed (NMDevice *device,
break;
case NM_DEVICE_STATE_SECONDARIES:
if (connection)
- s_con = nm_connection_get_setting_connection (connection);
+ s_con = nm_connection_get_setting_connection (NM_CONNECTION (connection));
if (s_con && nm_setting_connection_get_num_secondaries (s_con) > 0) {
/* Make routes and DNS up-to-date before activating dependent connections */
update_routing_and_dns (policy, FALSE);
/* Activate secondary (VPN) connections */
- if (!activate_secondary_connections (policy, connection, device))
+ if (!activate_secondary_connections (policy, NM_CONNECTION (connection), device))
nm_device_queue_state (device, NM_DEVICE_STATE_FAILED,
NM_DEVICE_STATE_REASON_SECONDARY_CONNECTION_FAILED);
} else
@@ -1827,11 +1797,12 @@ schedule_activate_all (NMPolicy *policy)
static void
connection_added (NMSettings *settings,
- NMConnection *connection,
+ NMSettingsConnection *connection,
gpointer user_data)
{
- set_connection_auto_retries (connection, RETRIES_DEFAULT);
- schedule_activate_all ((NMPolicy *) user_data);
+ NMPolicy *policy = NM_POLICY (user_data);
+
+ schedule_activate_all (policy);
}
static void
@@ -1944,11 +1915,11 @@ connection_updated (NMSettings *settings,
static void
connection_updated_by_user (NMSettings *settings,
- NMConnection *connection,
+ NMSettingsConnection *connection,
gpointer user_data)
{
/* Reset auto retries back to default since connection was updated */
- set_connection_auto_retries (connection, RETRIES_DEFAULT);
+ nm_settings_connection_reset_autoconnect_retries (connection);
}
static void
@@ -2008,12 +1979,14 @@ secret_agent_registered (NMSettings *settings,
NMSecretAgent *agent,
gpointer user_data)
{
+ NMPolicy *policy = NM_POLICY (user_data);
+
/* The registered secret agent may provide some missing secrets. Thus we
* reset retries count here and schedule activation, so that the
* connections failed due to missing secrets may re-try auto-connection.
*/
- reset_retries_for_failed_secrets (settings);
- schedule_activate_all ((NMPolicy *) user_data);
+ reset_autoconnect_for_failed_secrets (policy);
+ schedule_activate_all (policy);
}
static void
@@ -2094,9 +2067,6 @@ nm_policy_new (NMManager *manager, NMSettings *settings)
connection_visibility_changed);
_connect_settings_signal (policy, NM_SETTINGS_SIGNAL_AGENT_REGISTERED, secret_agent_registered);
- /* Initialize connections' auto-retries */
- reset_retries_all (priv->settings, NULL);
-
initialized = TRUE;
return policy;
}
diff --git a/src/settings/nm-settings-connection.c b/src/settings/nm-settings-connection.c
index 55cc157..63bc8aa 100644
--- a/src/settings/nm-settings-connection.c
+++ b/src/settings/nm-settings-connection.c
@@ -124,6 +124,11 @@ typedef struct {
guint64 timestamp; /* Up-to-date timestamp of connection use */
gboolean timestamp_set;
GHashTable *seen_bssids; /* Up-to-date BSSIDs that's been seen for the connection */
+
+ int autoconnect_retries;
+ time_t autoconnect_retry_time;
+ NMDeviceStateReason autoconnect_blocked_reason;
+
} NMSettingsConnectionPrivate;
/**************************************************************/
@@ -1899,6 +1904,73 @@ nm_settings_connection_read_and_fill_seen_bssids (NMSettingsConnection *connecti
}
}
+#define AUTOCONNECT_RETRIES_DEFAULT 4
+#define AUTOCONNECT_RESET_RETRIES_TIMER 300
+
+int
+nm_settings_connection_get_autoconnect_retries (NMSettingsConnection *connection)
+{
+ return NM_SETTINGS_CONNECTION_GET_PRIVATE (connection)->autoconnect_retries;
+}
+
+void
+nm_settings_connection_set_autoconnect_retries (NMSettingsConnection *connection,
+ int retries)
+{
+ NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (connection);
+
+ priv->autoconnect_retries = retries;
+ if (retries)
+ priv->autoconnect_retry_time = 0;
+ else
+ priv->autoconnect_retry_time = time (NULL) + AUTOCONNECT_RESET_RETRIES_TIMER;
+}
+
+void
+nm_settings_connection_reset_autoconnect_retries (NMSettingsConnection *connection)
+{
+ nm_settings_connection_set_autoconnect_retries (connection, AUTOCONNECT_RETRIES_DEFAULT);
+}
+
+time_t
+nm_settings_connection_get_autoconnect_retry_time (NMSettingsConnection *connection)
+{
+ return NM_SETTINGS_CONNECTION_GET_PRIVATE (connection)->autoconnect_retry_time;
+}
+
+NMDeviceStateReason
+nm_settings_connection_get_autoconnect_blocked_reason (NMSettingsConnection *connection)
+{
+ return NM_SETTINGS_CONNECTION_GET_PRIVATE (connection)->autoconnect_blocked_reason;
+}
+
+void
+nm_settings_connection_set_autoconnect_blocked_reason (NMSettingsConnection *connection,
+ NMDeviceStateReason reason)
+{
+ NM_SETTINGS_CONNECTION_GET_PRIVATE (connection)->autoconnect_blocked_reason = reason;
+}
+
+gboolean
+nm_settings_connection_can_autoconnect (NMSettingsConnection *connection)
+{
+ NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (connection);
+ const char *permission;
+
+ if ( !priv->visible
+ || priv->autoconnect_retries == 0
+ || priv->autoconnect_blocked_reason != NM_DEVICE_STATE_REASON_NONE)
+ return FALSE;
+
+ permission = nm_utils_get_shared_wifi_permission (NM_CONNECTION (connection));
+ if (permission) {
+ if (nm_settings_connection_check_permission (connection, permission) == FALSE)
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
/**************************************************************/
static void
@@ -1918,6 +1990,9 @@ nm_settings_connection_init (NMSettingsConnection *self)
priv->seen_bssids = g_hash_table_new_full (mac_hash, mac_equal, g_free, g_free);
+ priv->autoconnect_retries = AUTOCONNECT_RETRIES_DEFAULT;
+ priv->autoconnect_blocked_reason = NM_DEVICE_STATE_REASON_NONE;
+
g_signal_connect (self, NM_CONNECTION_SECRETS_CLEARED, G_CALLBACK (secrets_cleared_cb), NULL);
g_signal_connect (self, NM_CONNECTION_CHANGED, G_CALLBACK (changed_cb), GUINT_TO_POINTER (TRUE));
}
diff --git a/src/settings/nm-settings-connection.h b/src/settings/nm-settings-connection.h
index a16acc9..d79c62d 100644
--- a/src/settings/nm-settings-connection.h
+++ b/src/settings/nm-settings-connection.h
@@ -149,6 +149,19 @@ void nm_settings_connection_add_seen_bssid (NMSettingsConnection *connection,
void nm_settings_connection_read_and_fill_seen_bssids (NMSettingsConnection *connection);
+int nm_settings_connection_get_autoconnect_retries (NMSettingsConnection *connection);
+void nm_settings_connection_set_autoconnect_retries (NMSettingsConnection *connection,
+ int retries);
+void nm_settings_connection_reset_autoconnect_retries (NMSettingsConnection *connection);
+
+time_t nm_settings_connection_get_autoconnect_retry_time (NMSettingsConnection *connection);
+
+NMDeviceStateReason nm_settings_connection_get_autoconnect_blocked_reason (NMSettingsConnection *connection);
+void nm_settings_connection_set_autoconnect_blocked_reason (NMSettingsConnection *connection,
+ NMDeviceStateReason reason);
+
+gboolean nm_settings_connection_can_autoconnect (NMSettingsConnection *connection);
+
G_END_DECLS
#endif /* NM_SETTINGS_CONNECTION_H */
--
1.7.11.7
From 4e74670b472e34bfa6c40534714cd86f5dfa7b4a Mon Sep 17 00:00:00 2001
From: Dan Winship <danw@gnome.org>
Date: Thu, 23 Jan 2014 10:30:50 -0500
Subject: [PATCH] core: clarify clearing of autoconnect-blocked state
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
NMPolicy was clearing the autoconnect-blocked state on a connection
any time a device with that connection changed state. This happened to
basically do the right thing, but it would be clearer if we only reset
the state after successfully getting past the NEED_AUTH stage.
Signed-off-by: Jiří Klimeš <jklimes@redhat.com>
---
src/nm-policy.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/src/nm-policy.c b/src/nm-policy.c
index 55effd5..b47343c 100644
--- a/src/nm-policy.c
+++ b/src/nm-policy.c
@@ -1364,9 +1364,6 @@ device_state_changed (NMDevice *device,
NMIP6Config *ip6_config;
NMSettingConnection *s_con = NULL;
- if (connection)
- nm_settings_connection_set_autoconnect_blocked_reason (connection, NM_DEVICE_STATE_REASON_NONE);
-
switch (new_state) {
case NM_DEVICE_STATE_FAILED:
/* Mark the connection invalid if it failed during activation so that
@@ -1460,6 +1457,10 @@ device_state_changed (NMDevice *device,
* activation. */
activate_slave_connections (policy, device);
break;
+ case NM_DEVICE_STATE_IP_CONFIG:
+ /* We must have secrets if we got here. */
+ nm_settings_connection_set_autoconnect_blocked_reason (connection, NM_DEVICE_STATE_REASON_NONE);
+ break;
case NM_DEVICE_STATE_SECONDARIES:
if (connection)
s_con = nm_connection_get_setting_connection (NM_CONNECTION (connection));
if (s_con && nm_setting_connection_get_num_secondaries (s_con) > 0) {
--
1.7.11.7
From eceb613f4c62eb9bb2d29d1e8ae720db8311606d Mon Sep 17 00:00:00 2001
From: Dan Winship <danw@gnome.org>
Date: Wed, 15 Jan 2014 12:47:13 -0500
Subject: [PATCH] core: don't retry connection with no secrets after timeout
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
NMPolicy was resetting the "don't autoconnect because we don't have
secrets" state on a connection when the autoconnect-retries timer
timed out, but this doesn't make sense, since the timeout doesn't
change the fact that there are no secrets.
https://bugzilla.gnome.org/show_bug.cgi?id=670631
Signed-off-by: Jiří Klimeš <jklimes@redhat.com>
---
src/nm-policy.c | 7 -------
1 file changed, 7 deletions(-)
diff --git a/src/nm-policy.c b/src/nm-policy.c
index b47343c..bcf36ce 100644
--- a/src/nm-policy.c
+++ b/src/nm-policy.c
@@ -1229,7 +1229,6 @@ reset_connections_retries (gpointer user_data)
if (con_stamp < now) {
nm_settings_connection_reset_autoconnect_retries (connection);
- nm_settings_connection_set_autoconnect_blocked_reason (connection, NM_DEVICE_STATE_REASON_NONE);
changed = TRUE;
} else if (min_stamp == 0 || min_stamp > con_stamp)
min_stamp = con_stamp;
@@ -1375,12 +1374,6 @@ device_state_changed (NMDevice *device,
guint32 tries = nm_settings_connection_get_autoconnect_retries (connection);
if (reason == NM_DEVICE_STATE_REASON_NO_SECRETS) {
- /* If the connection couldn't get the secrets it needed (ex because
- * the user canceled, or no secrets exist), there's no point in
- * automatically retrying because it's just going to fail anyway.
- */
- nm_settings_connection_set_autoconnect_retries (connection, 0);
-
/* Mark the connection as failed due to missing secrets so that we can
* automatically re-try when an secret agent registers.
*/
--
1.7.11.7
From 971167e2a8693c75e84854a030ba491932b7d105 Mon Sep 17 00:00:00 2001
From: Dan Winship <danw@gnome.org>
Date: Fri, 3 Jan 2014 14:04:54 -0500
Subject: [PATCH] core: disable auto-re-connect of intentionally-disconnected
connection
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
If a connection is disconnected by the user, don't allow it to
autoconnect again immediately after.
Signed-off-by: Jiří Klimeš <jklimes@redhat.com>
---
src/nm-policy.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/src/nm-policy.c b/src/nm-policy.c
index bcf36ce..01ddc15 100644
--- a/src/nm-policy.c
+++ b/src/nm-policy.c
@@ -1431,6 +1431,10 @@ device_state_changed (NMDevice *device,
if (old_state > NM_DEVICE_STATE_DISCONNECTED)
update_routing_and_dns (policy, FALSE);
break;
+ case NM_DEVICE_STATE_DEACTIVATING:
+ if (reason == NM_DEVICE_STATE_REASON_USER_REQUESTED)
+ nm_settings_connection_set_autoconnect_blocked_reason (connection, NM_DEVICE_STATE_REASON_USER_REQUESTED);
+ break;
case NM_DEVICE_STATE_DISCONNECTED:
/* Reset retry counts for a device's connections when carrier on; if cable
* was unplugged and plugged in again, we should try to reconnect.
--
1.7.11.7
From 979b8920b465867ea248dee23a8a290da28f75e5 Mon Sep 17 00:00:00 2001
From: Dan Winship <danw@gnome.org>
Date: Tue, 17 Dec 2013 10:09:47 -0500
Subject: [PATCH] core: move virtual device autoconnect tracking bits out of
NMManager
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Virtual devices may be created and destroyed, but we need to keep
their autoconnect state across that. Previously this was handled by
NMManager, but it really belongs with the other autoconnect tracking
in NMPolicy and NMSettingsConnection.
This also fixes a bug where NMPolicy would sometimes decide to
autoactivate a virtual device connection which NMManager would then
have to cancel.
Signed-off-by: Jiří Klimeš <jklimes@redhat.com>
---
src/devices/nm-device.c | 7 ----
src/nm-manager.c | 76 ++---------------------------------
src/nm-manager.h | 6 ---
src/nm-policy.c | 33 ++++++++++++++-
src/settings/nm-settings-connection.c | 5 +++
5 files changed, 40 insertions(+), 87 deletions(-)
diff --git a/src/nm-policy.c b/src/nm-policy.c
index 01ddc15..dee85d6 100644
--- a/src/nm-policy.c
+++ b/src/nm-policy.c
@@ -1161,6 +1161,28 @@ reset_autoconnect_for_failed_secrets (NMPolicy *policy)
}
static void
+block_autoconnect_for_device (NMPolicy *policy, NMDevice *device)
+{
+ NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (policy);
+ GSList *connections, *iter;
+
+ /* NMDevice keeps its own autoconnect-able-ness state; we only need to
+ * explicitly block connections for software devices, where the NMDevice
+ * might be destroyed and recreated later.
+ */
+ if (!nm_device_is_software (device))
+ return;
+
+ connections = nm_settings_get_connections (priv->settings);
+ for (iter = connections; iter; iter = g_slist_next (iter)) {
+ if (nm_device_check_connection_compatible (device, iter->data, NULL)) {
+ nm_settings_connection_set_autoconnect_blocked_reason (NM_SETTINGS_CONNECTION (iter->data),
+ NM_DEVICE_STATE_REASON_USER_REQUESTED);
+ }
+ }
+}
+
+static void
sleeping_changed (NMManager *manager, GParamSpec *pspec, gpointer user_data)
{
NMPolicy *policy = user_data;
@@ -1432,8 +1454,15 @@ device_state_changed (NMDevice *device,
update_routing_and_dns (policy, FALSE);
break;
case NM_DEVICE_STATE_DEACTIVATING:
- if (reason == NM_DEVICE_STATE_REASON_USER_REQUESTED)
- nm_settings_connection_set_autoconnect_blocked_reason (connection, NM_DEVICE_STATE_REASON_USER_REQUESTED);
+ if (reason == NM_DEVICE_STATE_REASON_USER_REQUESTED) {
+ if (!nm_device_get_autoconnect (device)) {
+ /* The device was disconnected; block all connections on it */
+ block_autoconnect_for_device (policy, device);
+ } else {
+ /* The connection was deactivated, so block just this connection */
+ nm_settings_connection_set_autoconnect_blocked_reason (connection, NM_DEVICE_STATE_REASON_USER_REQUESTED);
+ }
+ }
break;
case NM_DEVICE_STATE_DISCONNECTED:
/* Reset retry counts for a device's connections when carrier on; if cable
diff --git a/src/settings/nm-settings-connection.c b/src/settings/nm-settings-connection.c
index 63bc8aa..2a23396 100644
--- a/src/settings/nm-settings-connection.c
+++ b/src/settings/nm-settings-connection.c
@@ -1955,6 +1955,7 @@ gboolean
nm_settings_connection_can_autoconnect (NMSettingsConnection *connection)
{
NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (connection);
+ NMSettingConnection *s_con;
const char *permission;
if ( !priv->visible
@@ -1962,6 +1963,10 @@ nm_settings_connection_can_autoconnect (NMSettingsConnection *connection)
|| priv->autoconnect_blocked_reason != NM_DEVICE_STATE_REASON_NONE)
return FALSE;
+ s_con = nm_connection_get_setting_connection (NM_CONNECTION (connection));
+ if (!nm_setting_connection_get_autoconnect (s_con))
+ return FALSE;
+
permission = nm_utils_get_shared_wifi_permission (NM_CONNECTION (connection));
if (permission) {
if (nm_settings_connection_check_permission (connection, permission) == FALSE)
--
1.7.11.7
From 12ee696d8375279d14733cb98dec4ce2405bc0b4 Mon Sep 17 00:00:00 2001
From: Dan Winship <danw@gnome.org>
Date: Tue, 17 Dec 2013 10:30:04 -0500
Subject: [PATCH] core: add some autoconnect debugging messages
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Jiří Klimeš <jklimes@redhat.com>
---
src/nm-policy.c | 27 +++++++++++++++++++--------
1 file changed, 19 insertions(+), 8 deletions(-)
diff --git a/src/nm-policy.c b/src/nm-policy.c
index dee85d6..92ec1ab 100644
--- a/src/nm-policy.c
+++ b/src/nm-policy.c
@@ -1132,6 +1132,12 @@ reset_autoconnect_all (NMPolicy *policy, NMDevice *device)
NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (policy);
GSList *connections, *iter;
+ if (device) {
+ nm_log_dbg (LOGD_DEVICE, "Re-enabling autoconnect for all connections on %s",
+ nm_device_get_iface (device));
+ } else
+ nm_log_dbg (LOGD_DEVICE, "Re-enabling autoconnect for all connections");
+
connections = nm_settings_get_connections (priv->settings);
for (iter = connections; iter; iter = g_slist_next (iter)) {
if (!device || nm_device_check_connection_compatible (device, iter->data, NULL)) {
@@ -1148,6 +1154,8 @@ reset_autoconnect_for_failed_secrets (NMPolicy *policy)
NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (policy);
GSList *connections, *iter;
+ nm_log_dbg (LOGD_DEVICE, "Re-enabling autoconnect for all connections with failed secrets");
+
connections = nm_settings_get_connections (priv->settings);
for (iter = connections; iter; iter = g_slist_next (iter)) {
NMSettingsConnection *connection = NM_SETTINGS_CONNECTION (iter->data);
@@ -1166,6 +1174,9 @@ block_autoconnect_for_device (NMPolicy *policy, NMDevice *device)
NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (policy);
GSList *connections, *iter;
+ nm_log_dbg (LOGD_DEVICE, "Blocking autoconnect for all connections on %s",
+ nm_device_get_iface (device));
+
/* NMDevice keeps its own autoconnect-able-ness state; we only need to
* explicitly block connections for software devices, where the NMDevice
* might be destroyed and recreated later.
@@ -1396,20 +1407,18 @@ device_state_changed (NMDevice *device,
guint32 tries = nm_settings_connection_get_autoconnect_retries (connection);
if (reason == NM_DEVICE_STATE_REASON_NO_SECRETS) {
- /* Mark the connection as failed due to missing secrets so that we can
- * automatically re-try when an secret agent registers.
- */
+ nm_log_dbg (LOGD_DEVICE, "Connection '%s' now blocked from autoconnect due to no secrets",
+ nm_connection_get_id (NM_CONNECTION (connection)));
+
nm_settings_connection_set_autoconnect_blocked_reason (connection, NM_DEVICE_STATE_REASON_NO_SECRETS);
} else if (tries > 0) {
- /* Otherwise if it's a random failure, just decrease the number
- * of automatic retries so that the connection gets tried again
- * if it still has a retry count.
- */
+ nm_log_dbg (LOGD_DEVICE, "Connection '%s' failed to autoconnect; %d tries left",
+ nm_connection_get_id (NM_CONNECTION (connection)), tries);
nm_settings_connection_set_autoconnect_retries (connection, tries - 1);
}
if (nm_settings_connection_get_autoconnect_retries (connection) == 0) {
- nm_log_info (LOGD_DEVICE, "Marking connection '%s' invalid.",
+ nm_log_info (LOGD_DEVICE, "Disabling autoconnect for connection '%s'.",
nm_connection_get_id (NM_CONNECTION (connection)));
/* Schedule a handler to reset retries count */
if (!priv->reset_retries_id) {
@@ -1460,6 +1469,8 @@ device_state_changed (NMDevice *device,
block_autoconnect_for_device (policy, device);
} else {
/* The connection was deactivated, so block just this connection */
+ nm_log_dbg (LOGD_DEVICE, "Blocking autoconnect of connection '%s' by user request",
+ nm_connection_get_id (NM_CONNECTION (connection)));
nm_settings_connection_set_autoconnect_blocked_reason (connection, NM_DEVICE_STATE_REASON_USER_REQUESTED);
}
}
--
1.7.11.7
From 40562b0aa54a1de7571d8ef8eb3c0c4d3ff3a265 Mon Sep 17 00:00:00 2001
From: Thomas Haller <thaller@redhat.com>
Date: Mon, 20 Jan 2014 21:51:04 +0100
Subject: [PATCH] trivial: rename field to give it a unique name
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Thomas Haller <thaller@redhat.com>
Signed-off-by: Jiří Klimeš <jklimes@redhat.com>
---
src/nm-policy.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/src/nm-policy.c b/src/nm-policy.c
index 34f194f..620efda 100644
--- a/src/nm-policy.c
+++ b/src/nm-policy.c
@@ -944,7 +944,7 @@ get_connection_auto_retries (NMConnection *connection)
typedef struct {
NMPolicy *policy;
NMDevice *device;
- guint id;
+ guint autoactivate_id;
} ActivateData;
static void
@@ -952,8 +952,8 @@ activate_data_free (ActivateData *data)
{
nm_device_remove_pending_action (data->device, "autoactivate");
- if (data->id)
- g_source_remove (data->id);
+ if (data->autoactivate_id)
+ g_source_remove (data->autoactivate_id);
g_object_unref (data->device);
memset (data, 0, sizeof (*data));
g_free (data);
@@ -973,7 +973,7 @@ auto_activate_device (gpointer user_data)
policy = data->policy;
priv = NM_POLICY_GET_PRIVATE (policy);
- data->id = 0;
+ data->autoactivate_id = 0;
priv->pending_activation_checks = g_slist_remove (priv->pending_activation_checks, data);
// FIXME: if a device is already activating (or activated) with a connection
@@ -1052,9 +1052,9 @@ activate_data_new (NMPolicy *policy, NMDevice *device, guint delay_seconds)
data->policy = policy;
data->device = g_object_ref (device);
if (delay_seconds > 0)
- data->id = g_timeout_add_seconds (delay_seconds, auto_activate_device, data);
+ data->autoactivate_id = g_timeout_add_seconds (delay_seconds, auto_activate_device, data);
else
- data->id = g_idle_add (auto_activate_device, data);
+ data->autoactivate_id = g_idle_add (auto_activate_device, data);
nm_device_add_pending_action (device, "autoactivate");
--
1.7.11.7
From a217a742f1207e4451f401280048f64e10cfd5be Mon Sep 17 00:00:00 2001
From: Dan Winship <danw@gnome.org>
Date: Thu, 13 Feb 2014 14:22:26 -0500
Subject: [PATCH] core: remove some unused code
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
We never pass any delay_seconds value to schedule_activate_check()
except "0", so just remove that argument.
Signed-off-by: Jiří Klimeš <jklimes@redhat.com>
---
src/nm-policy.c | 23 ++++++++++-------------
1 file changed, 10 insertions(+), 13 deletions(-)
diff --git a/src/nm-policy.c b/src/nm-policy.c
index 34216c8..71f53e6 100644
--- a/src/nm-policy.c
+++ b/src/nm-policy.c
@@ -1015,17 +1015,14 @@ auto_activate_device (gpointer user_data)
}
static ActivateData *
-activate_data_new (NMPolicy *policy, NMDevice *device, guint delay_seconds)
+activate_data_new (NMPolicy *policy, NMDevice *device)
{
ActivateData *data;
data = g_malloc0 (sizeof (ActivateData));
data->policy = policy;
data->device = g_object_ref (device);
- if (delay_seconds > 0)
- data->autoactivate_id = g_timeout_add_seconds (delay_seconds, auto_activate_device, data);
- else
- data->autoactivate_id = g_idle_add (auto_activate_device, data);
+ data->autoactivate_id = g_idle_add (auto_activate_device, data);
nm_device_add_pending_action (device, "autoactivate");
@@ -1215,7 +1212,7 @@ sleeping_changed (NMManager *manager, GParamSpec *pspec, gpointer user_data)
}
static void
-schedule_activate_check (NMPolicy *policy, NMDevice *device, guint delay_seconds)
+schedule_activate_check (NMPolicy *policy, NMDevice *device)
{
NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (policy);
ActivateData *data;
@@ -1241,7 +1238,7 @@ schedule_activate_check (NMPolicy *policy, NMDevice *device, guint delay_seconds
/* Schedule an auto-activation if there isn't one already for this device */
if (find_pending_activation (priv->pending_activation_checks, device) == NULL) {
- data = activate_data_new (policy, device, delay_seconds);
+ data = activate_data_new (policy, device);
priv->pending_activation_checks = g_slist_append (priv->pending_activation_checks, data);
}
}
@@ -1493,7 +1490,7 @@ device_state_changed (NMDevice *device,
update_routing_and_dns (policy, FALSE);
/* Device is now available for auto-activation */
- schedule_activate_check (policy, device, 0);
+ schedule_activate_check (policy, device);
break;
case NM_DEVICE_STATE_PREPARE:
@@ -1601,25 +1598,25 @@ device_autoconnect_changed (NMDevice *device,
gpointer user_data)
{
if (nm_device_get_autoconnect (device))
- schedule_activate_check ((NMPolicy *) user_data, device, 0);
+ schedule_activate_check ((NMPolicy *) user_data, device);
}
static void
wireless_networks_changed (NMDevice *device, GObject *ap, gpointer user_data)
{
- schedule_activate_check ((NMPolicy *) user_data, device, 0);
+ schedule_activate_check ((NMPolicy *) user_data, device);
}
static void
nsps_changed (NMDevice *device, GObject *nsp, gpointer user_data)
{
- schedule_activate_check ((NMPolicy *) user_data, device, 0);
+ schedule_activate_check ((NMPolicy *) user_data, device);
}
static void
modem_enabled_changed (NMDevice *device, gpointer user_data)
{
- schedule_activate_check ((NMPolicy *) (user_data), device, 0);
+ schedule_activate_check ((NMPolicy *) (user_data), device);
}
typedef struct {
@@ -1837,7 +1834,7 @@ schedule_activate_all (NMPolicy *policy)
devices = nm_manager_get_devices (priv->manager);
for (iter = devices; iter; iter = g_slist_next (iter))
- schedule_activate_check (policy, NM_DEVICE (iter->data), 0);
+ schedule_activate_check (policy, NM_DEVICE (iter->data));
}
static void
--
1.7.11.7
From 4f0c70e94534abafde6a0459af74b68a7da724d9 Mon Sep 17 00:00:00 2001
From: Dan Winship <danw@gnome.org>
Date: Thu, 13 Feb 2014 14:45:25 -0500
Subject: [PATCH] core: don't recursively schedule an autoactivate check on a
device
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
NMPolicy's auto_activate_device() was immediately removing the device
from priv->pending_activation_checks, which meant that if
nm_manager_activate_connection() had some side effect that would cause
schedule_activation_check() to be called again, another
auto-activation check could be queued while the first was still in
progress (causing a warning). Fix this by not removing the device from
the list until the activation attempt is complete.
This requires some additional minor changes to correctly handle the
possibility of remove_device() being triggered as a side effect of
nm_manager_activate_connection().
Also merge activate_data_new() into schedule_activation_check() so
that all the "start an auto-activation" code is in one place.
Signed-off-by: Jiří Klimeš <jklimes@redhat.com>
---
src/nm-policy.c | 56 +++++++++++++++++++++++++-------------------------------
1 file changed, 25 insertions(+), 31 deletions(-)
diff --git a/src/nm-policy.c b/src/nm-policy.c
index 142cf65..90fbc36 100644
--- a/src/nm-policy.c
+++ b/src/nm-policy.c
@@ -937,12 +937,14 @@ typedef struct {
static void
activate_data_free (ActivateData *data)
{
+ NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (data->policy);
+
nm_device_remove_pending_action (data->device, "autoactivate");
+ priv->pending_activation_checks = g_slist_remove (priv->pending_activation_checks, data);
if (data->autoactivate_id)
g_source_remove (data->autoactivate_id);
g_object_unref (data->device);
- memset (data, 0, sizeof (*data));
g_free (data);
}
@@ -961,7 +963,6 @@ auto_activate_device (gpointer user_data)
priv = NM_POLICY_GET_PRIVATE (policy);
data->autoactivate_id = 0;
- priv->pending_activation_checks = g_slist_remove (priv->pending_activation_checks, data);
// FIXME: if a device is already activating (or activated) with a connection
// but another connection now overrides the current one for that device,
@@ -1014,21 +1015,6 @@ auto_activate_device (gpointer user_data)
}
static ActivateData *
-activate_data_new (NMPolicy *policy, NMDevice *device)
-{
- ActivateData *data;
-
- data = g_malloc0 (sizeof (ActivateData));
- data->policy = policy;
- data->device = g_object_ref (device);
- data->autoactivate_id = g_idle_add (auto_activate_device, data);
-
- nm_device_add_pending_action (device, "autoactivate");
-
- return data;
-}
-
-static ActivateData *
find_pending_activation (GSList *list, NMDevice *device)
{
GSList *iter;
@@ -1232,6 +1232,7 @@ schedule_activate_check (NMPolicy *policy, NMDevice *device, guint delay_seconds
{
NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (policy);
ActivateData *data;
+ const GSList *active_connections, *iter;
if (nm_manager_get_state (priv->manager) == NM_STATE_ASLEEP)
return;
@@ -1226,11 +1212,33 @@ schedule_activate_check (NMPolicy *policy, NMDevice *device)
if (!nm_device_autoconnect_allowed (device))
return;
+ if (find_pending_activation (priv->pending_activation_checks, device))
+ return;
+
+ active_connections = nm_manager_get_active_connections (priv->manager);
+ for (iter = active_connections; iter; iter = iter->next) {
+ if (nm_active_connection_get_device (NM_ACTIVE_CONNECTION (iter->data)) == device)
+ return;
+ }
- /* Schedule an auto-activation if there isn't one already for this device */
- if (find_pending_activation (priv->pending_activation_checks, device) == NULL) {
- data = activate_data_new (policy, device);
- priv->pending_activation_checks = g_slist_append (priv->pending_activation_checks, data);
- }
+
+ nm_device_add_pending_action (device, "autoactivate");
+
+ data = g_malloc0 (sizeof (ActivateData));
+ data->policy = policy;
+ data->device = g_object_ref (device);
+ data->autoactivate_id = g_idle_add (auto_activate_device, data);
+ priv->pending_activation_checks = g_slist_append (priv->pending_activation_checks, data);
+}
+
+static void
+clear_pending_activate_check (NMPolicy *policy, NMDevice *device)
+{
+ NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (policy);
+ ActivateData *data;
+
+ data = find_pending_activation (priv->pending_activation_checks, device);
+ if (data && data->autoactivate_id)
+ activate_data_free (data);
}
static gboolean
@@ -1676,15 +1675,10 @@ device_removed (NMManager *manager, NMDevice *device, gpointer user_data)
{
NMPolicy *policy = (NMPolicy *) user_data;
NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (policy);
- ActivateData *tmp;
GSList *iter;
/* Clear any idle callbacks for this device */
- tmp = find_pending_activation (priv->pending_activation_checks, device);
- if (tmp) {
- priv->pending_activation_checks = g_slist_remove (priv->pending_activation_checks, tmp);
- activate_data_free (tmp);
- }
+ clear_pending_activate_check (policy, device);
/* Clear any signal handlers for this device */
iter = priv->dev_ids;
--
1.7.11.7
From 58500b3b8bf8f06b04f1d349daa1cae4e46915b8 Mon Sep 17 00:00:00 2001
From: Thomas Haller <thaller@redhat.com>
Date: Wed, 9 Apr 2014 14:05:08 +0200
Subject: [PATCH] core: fix freeing pending activations in dispose() of device
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
activate_data_free() deletes the data from priv->pending_activation_checks,
thus iterating over the list with g_slist_free_full() causes a double
free or invalid memory access.
This bug does not hit easily, because the policy only get's disposed
when NM shuts down and then there are likely no pending activations
queued.
Fixes regression introduced by commit 4f0c70e94534abafde6a0459af74b68a7da724d9.
Signed-off-by: Thomas Haller <thaller@redhat.com>
Signed-off-by: Jiří Klimeš <jklimes@redhat.com>
---
src/nm-policy.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/nm-policy.c b/src/nm-policy.c
index f569b75..f454d90 100644
--- a/src/nm-policy.c
+++ b/src/nm-policy.c
@@ -2165,8 +2165,8 @@ dispose (GObject *object)
g_clear_object (&priv->lookup_addr);
g_clear_object (&priv->resolver);
- g_slist_free_full (priv->pending_activation_checks, (GDestroyNotify) activate_data_free);
- priv->pending_activation_checks = NULL;
+ while (priv->pending_activation_checks)
+ activate_data_free (priv->pending_activation_checks->data);
g_slist_free_full (priv->pending_secondaries, (GDestroyNotify) pending_secondary_data_free);
priv->pending_secondaries = NULL;
--
1.7.11.7