core: refactor nm_manager_get_activatable_connections() to return an array

... instead of a GSList.
This commit is contained in:
Thomas Haller 2017-02-03 15:13:03 +01:00
parent 0861f47a1c
commit b3b1793f3d
3 changed files with 60 additions and 36 deletions

View file

@ -423,28 +423,34 @@ find_ac_for_connection (NMManager *manager, NMConnection *connection)
return NULL;
}
static gboolean
_get_activatable_connections_filter (NMSettings *settings,
NMSettingsConnection *connection,
gpointer user_data)
{
return !find_ac_for_connection (user_data, NM_CONNECTION (connection));
}
/* Filter out connections that are already active.
* nm_settings_get_connections_sorted() returns sorted list. We need to preserve the
* order so that we didn't change auto-activation order (recent timestamps
* are first).
* Caller is responsible for freeing the returned list with g_slist_free().
*/
GSList *
nm_manager_get_activatable_connections (NMManager *manager)
NMSettingsConnection **
nm_manager_get_activatable_connections (NMManager *manager, guint *out_len, gboolean sort)
{
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
gs_free NMSettingsConnection **all_connections = nm_settings_get_connections_sorted (priv->settings, NULL);
GSList *connections = NULL;
NMSettingsConnection *connection;
guint i;
NMSettingsConnection **connections;
guint len;
for (i = 0; all_connections[i]; i++) {
connection = all_connections[i];
if (!find_ac_for_connection (manager, NM_CONNECTION (connection)))
connections = g_slist_prepend (connections, connection);
}
return g_slist_reverse (connections);
connections = nm_settings_get_connections_clone (priv->settings, &len,
_get_activatable_connections_filter,
manager);
if (sort && len > 1)
g_qsort_with_data (connections, len, sizeof (connections[0]), nm_settings_connection_cmp_default_p_with_data, NULL);
NM_SET_OUT (out_len, len);
return connections;
}
static NMActiveConnection *
@ -1687,7 +1693,7 @@ static NMSettingsConnection *
get_existing_connection (NMManager *self, NMDevice *device, gboolean *out_generated)
{
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
gs_free_slist GSList *connections = nm_manager_get_activatable_connections (self);
gs_free_slist GSList *connections = NULL;
NMConnection *connection = NULL;
NMSettingsConnection *matched;
NMSettingsConnection *added = NULL;
@ -1737,7 +1743,17 @@ get_existing_connection (NMManager *self, NMDevice *device, gboolean *out_genera
* When no configured connection matches the generated connection, we keep
* the generated connection instead.
*/
connections = g_slist_sort (connections, (GCompareFunc) nm_settings_connection_cmp_timestamp);
{
gs_free NMSettingsConnection **cons = NULL;
guint i, len;
/* XXX: this code will go away soon. Copy the array over to a GSList
* and don't bother for now. */
cons = nm_manager_get_activatable_connections (self, &len, TRUE);
for (i = len; i > 0; )
connections = g_slist_prepend (connections, cons[--i]);
connections = g_slist_sort (connections, (GCompareFunc) nm_settings_connection_cmp_timestamp);
}
matched = NM_SETTINGS_CONNECTION (nm_utils_match_connection (connections,
connection,
nm_device_has_carrier (device),
@ -2674,14 +2690,15 @@ ensure_master_active_connection (NMManager *self,
* activate it on the device.
*/
if (master_state == NM_DEVICE_STATE_DISCONNECTED || !nm_device_is_real (master_device)) {
GSList *connections;
gs_free NMSettingsConnection **connections = NULL;
guint i;
g_assert (master_connection == NULL);
/* Find a compatible connection and activate this device using it */
connections = nm_manager_get_activatable_connections (self);
for (iter = connections; iter; iter = g_slist_next (iter)) {
NMSettingsConnection *candidate = NM_SETTINGS_CONNECTION (iter->data);
connections = nm_manager_get_activatable_connections (self, NULL, TRUE);
for (i = 0; connections[i]; i++) {
NMSettingsConnection *candidate = connections[i];
/* Ensure eg bond/team slave and the candidate master is a
* bond/team master
@ -2697,11 +2714,9 @@ ensure_master_active_connection (NMManager *self,
master_device,
subject,
error);
g_slist_free (connections);
return master_ac;
}
}
g_slist_free (connections);
g_set_error (error,
NM_MANAGER_ERROR,

View file

@ -84,7 +84,10 @@ gboolean nm_manager_start (NMManager *manager,
void nm_manager_stop (NMManager *manager);
NMState nm_manager_get_state (NMManager *manager);
const GSList *nm_manager_get_active_connections (NMManager *manager);
GSList * nm_manager_get_activatable_connections (NMManager *manager);
NMSettingsConnection **nm_manager_get_activatable_connections (NMManager *manager,
guint *out_len,
gboolean sort);
void nm_manager_write_device_state (NMManager *manager);

View file

@ -953,6 +953,19 @@ activate_data_free (ActivateData *data)
g_slice_free (ActivateData, data);
}
static int
_auto_activate_device_cmp (gconstpointer pa, gconstpointer pb, gpointer user_data)
{
NMSettingsConnection *a = NM_SETTINGS_CONNECTION (*((NMSettingsConnection **) pa));
NMSettingsConnection *b = NM_SETTINGS_CONNECTION (*((NMSettingsConnection **) pb));
int i;
i = nm_utils_cmp_connection_by_autoconnect_priority (NM_CONNECTION (a), NM_CONNECTION (b));
if (i != 0)
return i;
return nm_settings_connection_cmp_default (a, b);
}
static void
auto_activate_device (NMPolicy *self,
NMDevice *device)
@ -960,9 +973,8 @@ auto_activate_device (NMPolicy *self,
NMPolicyPrivate *priv;
NMSettingsConnection *best_connection;
gs_free char *specific_object = NULL;
GPtrArray *connections;
GSList *connection_list;
guint i;
gs_free NMSettingsConnection **connections = NULL;
guint i, len;
nm_assert (NM_IS_POLICY (self));
nm_assert (NM_IS_DEVICE (device));
@ -976,21 +988,16 @@ auto_activate_device (NMPolicy *self,
if (nm_device_get_act_request (device))
return;
connection_list = nm_manager_get_activatable_connections (priv->manager);
if (!connection_list)
connections = nm_manager_get_activatable_connections (priv->manager, &len, FALSE);
if (!connections[0])
return;
connections = _nm_utils_copy_slist_to_array (connection_list, NULL, NULL);
g_slist_free (connection_list);
/* sort is stable (which is important at this point) so that connections
* with same priority are still sorted by last-connected-timestamp. */
g_ptr_array_sort_with_data (connections, nm_utils_cmp_connection_by_autoconnect_priority_p_with_data, NULL);
g_qsort_with_data (connections, len, sizeof (connections[0]), _auto_activate_device_cmp, NULL);
/* Find the first connection that should be auto-activated */
best_connection = NULL;
for (i = 0; i < connections->len; i++) {
NMSettingsConnection *candidate = NM_SETTINGS_CONNECTION (connections->pdata[i]);
for (i = 0; i < len; i++) {
NMSettingsConnection *candidate = NM_SETTINGS_CONNECTION (connections[i]);
if (!nm_settings_connection_can_autoconnect (candidate))
continue;
@ -999,7 +1006,6 @@ auto_activate_device (NMPolicy *self,
break;
}
}
g_ptr_array_free (connections, TRUE);
if (best_connection) {
GError *error = NULL;