summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2018-03-27 10:27:17 +0200
committerThomas Haller <thaller@redhat.com>2018-03-27 10:27:17 +0200
commit759f2bcedb7985996493311e37ec5eacf1586106 (patch)
tree886a18399ff81a192301e0252d978a80f4bba51e
parent0ed5cd5442887010a5ef465df4ffde5a13ef25ec (diff)
parente49a32936c6b7544750e60c6ec0816049f8fdfb9 (diff)
downloadNetworkManager-759f2bcedb7985996493311e37ec5eacf1586106.tar.gz
core: merge branch 'th/dbus-cache-properties'
https://github.com/NetworkManager/NetworkManager/pull/82
-rw-r--r--libnm-core/nm-keyfile-writer.c8
-rw-r--r--libnm-core/nm-setting-ip-config.c2
-rw-r--r--libnm-core/nm-setting-user.c19
-rw-r--r--shared/nm-utils/nm-shared-utils.c39
-rw-r--r--shared/nm-utils/nm-shared-utils.h18
-rw-r--r--src/devices/nm-device.c4
-rw-r--r--src/devices/nm-device.h1
-rw-r--r--src/devices/nm-lldp-listener.c45
-rw-r--r--src/devices/wifi/nm-device-iwd.c178
-rw-r--r--src/devices/wifi/nm-device-iwd.h2
-rw-r--r--src/devices/wifi/nm-device-olpc-mesh.c8
-rw-r--r--src/devices/wifi/nm-device-wifi.c110
-rw-r--r--src/devices/wifi/nm-device-wifi.h2
-rw-r--r--src/devices/wifi/nm-iwd-manager.c9
-rw-r--r--src/devices/wifi/nm-wifi-ap.c155
-rw-r--r--src/devices/wifi/nm-wifi-ap.h25
-rw-r--r--src/devices/wifi/nm-wifi-common.c31
-rw-r--r--src/devices/wifi/nm-wifi-common.h5
-rw-r--r--src/dns/nm-dns-manager.c34
-rw-r--r--src/dns/nm-dns-systemd-resolved.c12
-rw-r--r--src/nm-checkpoint-manager.c8
-rw-r--r--src/nm-checkpoint.c27
-rw-r--r--src/nm-config-data.c258
-rw-r--r--src/nm-config-data.h18
-rw-r--r--src/nm-dbus-manager.c117
-rw-r--r--src/nm-dbus-utils.c7
-rw-r--r--src/nm-dbus-utils.h3
-rw-r--r--src/nm-manager.c339
-rw-r--r--src/nm-manager.h2
-rw-r--r--src/nm-policy.c40
-rw-r--r--src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c11
-rw-r--r--src/tests/config/test-config.c2
32 files changed, 775 insertions, 764 deletions
diff --git a/libnm-core/nm-keyfile-writer.c b/libnm-core/nm-keyfile-writer.c
index 8af7c086e7..f92faef5bb 100644
--- a/libnm-core/nm-keyfile-writer.c
+++ b/libnm-core/nm-keyfile-writer.c
@@ -338,13 +338,9 @@ write_hash_of_string (GKeyFile *file,
}
hash = g_value_get_boxed (value);
- keys = (const char **) g_hash_table_get_keys_as_array (hash, &l);
- if (!keys)
- return;
-
- g_qsort_with_data (keys, l, sizeof (const char *), nm_strcmp_p_with_data, NULL);
- for (i = 0; keys[i]; i++) {
+ keys = nm_utils_strdict_get_keys (hash, TRUE, &l);
+ for (i = 0; i < l; i++) {
const char *property, *data;
gboolean write_item = TRUE;
diff --git a/libnm-core/nm-setting-ip-config.c b/libnm-core/nm-setting-ip-config.c
index e62e8c63ea..e581aee557 100644
--- a/libnm-core/nm-setting-ip-config.c
+++ b/libnm-core/nm-setting-ip-config.c
@@ -1129,7 +1129,7 @@ _nm_ip_route_get_attributes_direct (NMIPRoute *route)
*
* Returns: (array length=out_length) (transfer container): a %NULL-terminated array
* of attribute names or %NULL if there are no attributes. The order of the returned
- * names is undefined.
+ * names depends on @sorted.
**/
const char **
_nm_ip_route_get_attribute_names (const NMIPRoute *route, gboolean sorted, guint *out_length)
diff --git a/libnm-core/nm-setting-user.c b/libnm-core/nm-setting-user.c
index 8fc96b278f..ccc030aacd 100644
--- a/libnm-core/nm-setting-user.c
+++ b/libnm-core/nm-setting-user.c
@@ -226,7 +226,6 @@ nm_setting_user_get_keys (NMSettingUser *setting, guint *out_len)
{
NMSettingUser *self = setting;
NMSettingUserPrivate *priv;
- guint len;
g_return_val_if_fail (NM_IS_SETTING_USER (self), NULL);
@@ -237,19 +236,13 @@ nm_setting_user_get_keys (NMSettingUser *setting, guint *out_len)
return priv->keys;
}
- if (!priv->data || !g_hash_table_size (priv->data)) {
- NM_SET_OUT (out_len, 0);
- return (const char **) &priv->keys;
- }
+ priv->keys = nm_utils_strdict_get_keys (priv->data,
+ TRUE,
+ out_len);
- priv->keys = (const char **) g_hash_table_get_keys_as_array (priv->data, &len);
- g_qsort_with_data (priv->keys,
- len,
- sizeof (const char *),
- nm_strcmp_p_with_data,
- NULL);
- NM_SET_OUT (out_len, len);
- return priv->keys;
+ /* don't return %NULL, but hijack the @keys fields as a pseudo
+ * empty strv array. */
+ return priv->keys ?: ((const char **) &priv->keys);
}
/*****************************************************************************/
diff --git a/shared/nm-utils/nm-shared-utils.c b/shared/nm-utils/nm-shared-utils.c
index 25b867538c..556594aca3 100644
--- a/shared/nm-utils/nm-shared-utils.c
+++ b/shared/nm-utils/nm-shared-utils.c
@@ -1149,31 +1149,34 @@ nm_utils_named_values_from_str_dict (GHashTable *hash, guint *out_len)
return values;
}
-const char **
-nm_utils_strdict_get_keys (const GHashTable *hash,
- gboolean sorted,
- guint *out_length)
+gpointer *
+nm_utils_hash_keys_to_array (GHashTable *hash,
+ GCompareDataFunc compare_func,
+ gpointer user_data,
+ guint *out_len)
{
- const char **names;
- guint length;
+ guint len;
+ gpointer *keys;
+ /* by convention, we never return an empty array. In that
+ * case, always %NULL. */
if ( !hash
- || !g_hash_table_size ((GHashTable *) hash)) {
- NM_SET_OUT (out_length, 0);
+ || g_hash_table_size (hash) == 0) {
+ NM_SET_OUT (out_len, 0);
return NULL;
}
- names = (const char **) g_hash_table_get_keys_as_array ((GHashTable *) hash, &length);
- if ( sorted
- && length > 1) {
- g_qsort_with_data (names,
- length,
- sizeof (char *),
- nm_strcmp_p_with_data,
- NULL);
+ keys = g_hash_table_get_keys_as_array (hash, &len);
+ if ( len > 1
+ && compare_func) {
+ g_qsort_with_data (keys,
+ len,
+ sizeof (gpointer),
+ compare_func,
+ user_data);
}
- NM_SET_OUT (out_length, length);
- return names;
+ NM_SET_OUT (out_len, len);
+ return keys;
}
char **
diff --git a/shared/nm-utils/nm-shared-utils.h b/shared/nm-utils/nm-shared-utils.h
index 122f1187bd..37f0621389 100644
--- a/shared/nm-utils/nm-shared-utils.h
+++ b/shared/nm-utils/nm-shared-utils.h
@@ -460,9 +460,21 @@ typedef struct {
NMUtilsNamedValue *nm_utils_named_values_from_str_dict (GHashTable *hash, guint *out_len);
-const char **nm_utils_strdict_get_keys (const GHashTable *hash,
- gboolean sorted,
- guint *out_length);
+gpointer *nm_utils_hash_keys_to_array (GHashTable *hash,
+ GCompareDataFunc compare_func,
+ gpointer user_data,
+ guint *out_len);
+
+static inline const char **
+nm_utils_strdict_get_keys (const GHashTable *hash,
+ gboolean sorted,
+ guint *out_length)
+{
+ return (const char **) nm_utils_hash_keys_to_array ((GHashTable *) hash,
+ sorted ? nm_strcmp_p_with_data : NULL,
+ NULL,
+ out_length);
+}
char **nm_utils_strv_make_deep_copied (const char **strv);
diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c
index fc7c76b94d..d6ac3f9df5 100644
--- a/src/devices/nm-device.c
+++ b/src/devices/nm-device.c
@@ -14377,6 +14377,8 @@ nm_device_init (NMDevice *self)
self->_priv = priv;
+ c_list_init (&self->devices_lst);
+
c_list_init (&priv->slaves);
priv->netns = g_object_ref (NM_NETNS_GET);
@@ -14495,6 +14497,8 @@ dispose (GObject *object)
_LOGD (LOGD_DEVICE, "disposing");
+ nm_assert (c_list_is_empty (&self->devices_lst));
+
nm_clear_g_cancellable (&priv->deactivating_cancellable);
nm_device_assume_state_reset (self);
diff --git a/src/devices/nm-device.h b/src/devices/nm-device.h
index 4ed852bc65..f783cffbf3 100644
--- a/src/devices/nm-device.h
+++ b/src/devices/nm-device.h
@@ -174,6 +174,7 @@ struct _NMDevicePrivate;
struct _NMDevice {
NMDBusObject parent;
struct _NMDevicePrivate *_priv;
+ CList devices_lst;
};
/* The flags have an relaxing meaning, that means, specifying more flags, can make
diff --git a/src/devices/nm-lldp-listener.c b/src/devices/nm-lldp-listener.c
index 2ed2a7d9fa..f637825b5a 100644
--- a/src/devices/nm-lldp-listener.c
+++ b/src/devices/nm-lldp-listener.c
@@ -286,19 +286,21 @@ lldp_neighbor_id_hash (gconstpointer ptr)
}
static int
-lldp_neighbor_id_cmp (gconstpointer a, gconstpointer b)
+lldp_neighbor_id_cmp (const LldpNeighbor *x, const LldpNeighbor *y)
{
- const LldpNeighbor *x = a, *y = b;
- int c;
-
- if (x->chassis_id_type != y->chassis_id_type)
- return x->chassis_id_type < y->chassis_id_type ? -1 : 1;
- if (x->port_id_type != y->port_id_type)
- return x->port_id_type < y->port_id_type ? -1 : 1;
- c = g_strcmp0 (x->chassis_id, y->chassis_id);
- if (c == 0)
- c = g_strcmp0 (x->port_id, y->port_id);
- return c < 0 ? -1 : (c > 0 ? 1 : 0);
+ NM_CMP_SELF (x, y);
+ NM_CMP_FIELD (x, y, chassis_id_type);
+ NM_CMP_FIELD (x, y, port_id_type);
+ NM_CMP_FIELD_STR0 (x, y, chassis_id);
+ NM_CMP_FIELD_STR0 (x, y, port_id);
+ return 0;
+}
+
+static int
+lldp_neighbor_id_cmp_p (gconstpointer a, gconstpointer b, gpointer user_data)
+{
+ return lldp_neighbor_id_cmp (*((const LldpNeighbor *const*) a),
+ *((const LldpNeighbor *const*) b));
}
static gboolean
@@ -838,20 +840,23 @@ GVariant *
nm_lldp_listener_get_neighbors (NMLldpListener *self)
{
NMLldpListenerPrivate *priv;
- GVariantBuilder array_builder;
- GList *neighbors, *iter;
g_return_val_if_fail (NM_IS_LLDP_LISTENER (self), FALSE);
priv = NM_LLDP_LISTENER_GET_PRIVATE (self);
- if (!priv->variant) {
+ if (G_UNLIKELY (!priv->variant)) {
+ GVariantBuilder array_builder;
+ gs_free LldpNeighbor **neighbors = NULL;
+ guint i, n;
+
g_variant_builder_init (&array_builder, G_VARIANT_TYPE ("aa{sv}"));
- neighbors = g_hash_table_get_keys (priv->lldp_neighbors);
- neighbors = g_list_sort (neighbors, lldp_neighbor_id_cmp);
- for (iter = neighbors; iter; iter = iter->next)
- g_variant_builder_add_value (&array_builder, lldp_neighbor_to_variant (iter->data));
- g_list_free (neighbors);
+ neighbors = (LldpNeighbor **) nm_utils_hash_keys_to_array (priv->lldp_neighbors,
+ lldp_neighbor_id_cmp_p,
+ NULL,
+ &n);
+ for (i = 0; i < n; i++)
+ g_variant_builder_add_value (&array_builder, lldp_neighbor_to_variant (neighbors[i]));
priv->variant = g_variant_ref_sink (g_variant_builder_end (&array_builder));
}
return priv->variant;
diff --git a/src/devices/wifi/nm-device-iwd.c b/src/devices/wifi/nm-device-iwd.c
index 40980b06f0..eeff5bd32d 100644
--- a/src/devices/wifi/nm-device-iwd.c
+++ b/src/devices/wifi/nm-device-iwd.c
@@ -40,6 +40,7 @@
#include "nm-core-internal.h"
#include "nm-config.h"
#include "nm-iwd-manager.h"
+#include "nm-dbus-manager.h"
#include "devices/nm-device-logging.h"
_LOG_DECLARE_SELF(NMDeviceIwd);
@@ -66,8 +67,7 @@ static guint signals[LAST_SIGNAL] = { 0 };
typedef struct {
GDBusObject * dbus_obj;
GDBusProxy * dbus_proxy;
- GHashTable * aps;
- GHashTable * new_aps;
+ CList aps_lst_head;
NMWifiAP * current_ap;
GCancellable * cancellable;
NMDeviceWifiCapabilities capabilities;
@@ -104,6 +104,8 @@ G_DEFINE_TYPE (NMDeviceIwd, nm_device_iwd, NM_TYPE_DEVICE)
static void schedule_periodic_scan (NMDeviceIwd *self,
NMDeviceState current_state);
+/*****************************************************************************/
+
static void
_ap_dump (NMDeviceIwd *self,
NMLogLevel log_level,
@@ -119,20 +121,6 @@ _ap_dump (NMDeviceIwd *self,
nm_wifi_ap_to_string (ap, buf, sizeof (buf), now_s));
}
-static void
-_emit_access_point_added_removed (NMDeviceIwd *self,
- NMWifiAP *ap,
- gboolean is_added /* or else is removed */)
-{
- nm_dbus_object_emit_signal (NM_DBUS_OBJECT (self),
- &nm_interface_info_device_wireless,
- is_added
- ? &nm_signal_info_wireless_access_point_added
- : &nm_signal_info_wireless_access_point_removed,
- "(o)",
- nm_dbus_object_get_path (NM_DBUS_OBJECT (ap)));
-}
-
/* Callers ensure we're not removing current_ap */
static void
ap_add_remove (NMDeviceIwd *self,
@@ -143,23 +131,25 @@ ap_add_remove (NMDeviceIwd *self,
NMDeviceIwdPrivate *priv = NM_DEVICE_IWD_GET_PRIVATE (self);
if (is_adding) {
- g_hash_table_insert (priv->aps,
- (gpointer) nm_dbus_object_export (NM_DBUS_OBJECT (ap)),
- g_object_ref (ap));
+ g_object_ref (ap);
+ ap->wifi_device = NM_DEVICE (self);
+ c_list_link_tail (&priv->aps_lst_head, &ap->aps_lst);
+ nm_dbus_object_export (NM_DBUS_OBJECT (ap));
_ap_dump (self, LOGL_DEBUG, ap, "added", 0);
- } else
+ nm_device_wifi_emit_signal_access_point (NM_DEVICE (self), ap, TRUE);
+ } else {
+ ap->wifi_device = NULL;
+ c_list_unlink (&ap->aps_lst);
_ap_dump (self, LOGL_DEBUG, ap, "removed", 0);
+ }
- _emit_access_point_added_removed (self, ap, is_adding);
+ _notify (self, PROP_ACCESS_POINTS);
if (!is_adding) {
- g_hash_table_remove (priv->aps, nm_dbus_object_get_path (NM_DBUS_OBJECT (ap)));
- nm_dbus_object_unexport (NM_DBUS_OBJECT (ap));
- g_object_unref (ap);
+ nm_device_wifi_emit_signal_access_point (NM_DEVICE (self), ap, FALSE);
+ nm_dbus_object_clear_and_unexport (&ap);
}
- _notify (self, PROP_ACCESS_POINTS);
-
nm_device_emit_recheck_auto_activate (NM_DEVICE (self));
if (recheck_available_connections)
nm_device_recheck_available_connections (NM_DEVICE (self));
@@ -194,59 +184,20 @@ set_current_ap (NMDeviceIwd *self, NMWifiAP *new_ap, gboolean recheck_available_
_notify (self, PROP_MODE);
}
-static gboolean
-update_ap_func (gpointer key, gpointer value, gpointer user_data)
-{
- NMWifiAP *ap = value;
- NMDeviceIwd *self = user_data;
- NMDeviceIwdPrivate *priv = NM_DEVICE_IWD_GET_PRIVATE (self);
- NMWifiAP *new_ap = NULL;
-
- if (priv->new_aps)
- new_ap = g_hash_table_lookup (priv->new_aps,
- nm_wifi_ap_get_supplicant_path (ap));
-
- if (new_ap) {
- g_hash_table_steal (priv->new_aps,
- nm_wifi_ap_get_supplicant_path (ap));
-
- if (nm_wifi_ap_set_strength (ap, nm_wifi_ap_get_strength (new_ap)))
- _ap_dump (self, LOGL_TRACE, ap, "updated", 0);
-
- g_object_unref (new_ap);
- return FALSE;
- }
-
- if (ap == priv->current_ap)
- /* Normally IWD will prevent the current AP from being
- * removed from the list and set a low signal strength,
- * but just making sure.
- */
- return FALSE;
-
- _ap_dump (self, LOGL_DEBUG, ap, "removed", 0);
-
- _emit_access_point_added_removed (self, ap, FALSE);
-
- nm_dbus_object_unexport (NM_DBUS_OBJECT (ap));
- g_object_unref (ap);
-
- return TRUE;
-}
-
static void
remove_all_aps (NMDeviceIwd *self)
{
NMDeviceIwdPrivate *priv = NM_DEVICE_IWD_GET_PRIVATE (self);
+ NMWifiAP *ap, *ap_safe;
- if (!g_hash_table_size (priv->aps))
+ if (c_list_is_empty (&priv->aps_lst_head))
return;
set_current_ap (self, NULL, FALSE);
- g_hash_table_foreach_remove (priv->aps, update_ap_func, self);
+ c_list_for_each_entry_safe (ap, ap_safe, &priv->aps_lst_head, aps_lst)
+ ap_add_remove (self, FALSE, ap, FALSE);
- _notify (self, PROP_ACCESS_POINTS);
nm_device_emit_recheck_auto_activate (NM_DEVICE (self));
nm_device_recheck_available_connections (NM_DEVICE (self));
}
@@ -285,9 +236,10 @@ get_ordered_networks_cb (GObject *source, GAsyncResult *res, gpointer user_data)
GVariantIter *networks;
const gchar *path, *name, *type;
int16_t signal;
- NMWifiAP *ap;
+ NMWifiAP *ap, *ap_safe;
gboolean changed = FALSE;
GHashTableIter ap_iter;
+ gs_unref_hashtable GHashTable *new_aps = NULL;
variant = _nm_dbus_proxy_call_finish (G_DBUS_PROXY (source), res,
G_VARIANT_TYPE ("(a(osns))"),
@@ -298,7 +250,7 @@ get_ordered_networks_cb (GObject *source, GAsyncResult *res, gpointer user_data)
return;
}
- priv->new_aps = g_hash_table_new (nm_str_hash, g_str_equal);
+ new_aps = g_hash_table_new_full (nm_str_hash, g_str_equal, NULL, g_object_unref);
g_variant_get (variant, "(a(osns))", &networks);
@@ -348,27 +300,47 @@ get_ordered_networks_cb (GObject *source, GAsyncResult *res, gpointer user_data)
nm_wifi_ap_set_strength (ap, nm_wifi_utils_level_to_quality (signal / 100));
nm_wifi_ap_set_freq (ap, 2417);
nm_wifi_ap_set_max_bitrate (ap, 65000);
- g_hash_table_insert (priv->new_aps,
+ g_hash_table_insert (new_aps,
(gpointer) nm_wifi_ap_get_supplicant_path (ap),
ap);
}
g_variant_iter_free (networks);
- if (g_hash_table_foreach_remove (priv->aps, update_ap_func, self))
+ c_list_for_each_entry_safe (ap, ap_safe, &priv->aps_lst_head, aps_lst) {
+
+ ap = g_hash_table_lookup (new_aps,
+ nm_wifi_ap_get_supplicant_path (ap));
+ if (ap) {
+ if (nm_wifi_ap_set_strength (ap, nm_wifi_ap_get_strength (ap))) {
+ _ap_dump (self, LOGL_TRACE, ap, "updated", 0);
+ changed = TRUE;
+ }
+ g_hash_table_remove (new_aps,
+ nm_wifi_ap_get_supplicant_path (ap));
+ continue;
+ }
+
+ if (ap == priv->current_ap) {
+ /* Normally IWD will prevent the current AP from being
+ * removed from the list and set a low signal strength,
+ * but just making sure.
+ */
+ continue;
+ }
+
+ ap_add_remove (self, FALSE, ap, FALSE);
changed = TRUE;
+ }
- g_hash_table_iter_init (&ap_iter, priv->new_aps);
+ g_hash_table_iter_init (&ap_iter, new_aps);
while (g_hash_table_iter_next (&ap_iter, NULL, (gpointer) &ap)) {
ap_add_remove (self, TRUE, ap, FALSE);
+ g_hash_table_iter_remove (&ap_iter);
changed = TRUE;
}
- g_hash_table_destroy (priv->new_aps);
- priv->new_aps = NULL;
-
if (changed) {
- _notify (self, PROP_ACCESS_POINTS);
nm_device_emit_recheck_auto_activate (NM_DEVICE (self));
nm_device_recheck_available_connections (NM_DEVICE (self));
}
@@ -585,13 +557,6 @@ check_connection_compatible (NMDevice *device, NMConnection *connection)
return TRUE;
}
-static NMWifiAP *
-get_ap_by_path (NMDeviceIwd *self, const char *path)
-{
- g_return_val_if_fail (path != NULL, NULL);
- return g_hash_table_lookup (NM_DEVICE_IWD_GET_PRIVATE (self)->aps, path);
-}
-
static gboolean
check_connection_available (NMDevice *device,
NMConnection *connection,
@@ -629,7 +594,7 @@ check_connection_available (NMDevice *device,
if (specific_object) {
NMWifiAP *ap;
- ap = get_ap_by_path (self, specific_object);
+ ap = nm_wifi_ap_lookup_for_device (NM_DEVICE (self), specific_object);
return ap ? nm_wifi_ap_check_compatible (ap, connection) : FALSE;
}
@@ -637,7 +602,7 @@ check_connection_available (NMDevice *device,
return TRUE;
/* Check at least one AP is compatible with this connection */
- return !!nm_wifi_aps_find_first_compatible (priv->aps, connection, TRUE);
+ return !!nm_wifi_aps_find_first_compatible (&priv->aps_lst_head, connection);
}
static gboolean
@@ -691,7 +656,7 @@ complete_connection (NMDevice *device,
}
/* Find a compatible AP in the scan list */
- ap = nm_wifi_aps_find_first_compatible (priv->aps, connection, FALSE);
+ ap = nm_wifi_aps_find_first_compatible (&priv->aps_lst_head, connection);
if (!ap) {
g_set_error_literal (error,
NM_DEVICE_ERROR,
@@ -700,7 +665,7 @@ complete_connection (NMDevice *device,
return FALSE;
}
} else {
- ap = get_ap_by_path (self, specific_object);
+ ap = nm_wifi_ap_lookup_for_device (NM_DEVICE (self), specific_object);
if (!ap) {
g_set_error (error,
NM_DEVICE_ERROR,
@@ -859,7 +824,7 @@ can_auto_connect (NMDevice *device,
return FALSE;
}
- ap = nm_wifi_aps_find_first_compatible (priv->aps, connection, FALSE);
+ ap = nm_wifi_aps_find_first_compatible (&priv->aps_lst_head, connection);
if (ap) {
/* All good; connection is usable */
NM_SET_OUT (specific_object, g_strdup (nm_dbus_object_get_path (NM_DBUS_OBJECT (ap))));
@@ -869,10 +834,10 @@ can_auto_connect (NMDevice *device,
return FALSE;
}
-GHashTable *
+const CList *
_nm_device_iwd_get_aps (NMDeviceIwd *self)
{
- return NM_DEVICE_IWD_GET_PRIVATE (self)->aps;
+ return &NM_DEVICE_IWD_GET_PRIVATE (self)->aps_lst_head;
}
static gboolean
@@ -1247,9 +1212,9 @@ act_stage1_prepare (NMDevice *device, NMDeviceStateReason *out_failure_reason)
g_return_val_if_fail (s_wireless, NM_ACT_STAGE_RETURN_FAILURE);
ap_path = nm_active_connection_get_specific_object (NM_ACTIVE_CONNECTION (req));
- ap = ap_path ? get_ap_by_path (self, ap_path) : NULL;
+ ap = ap_path ? nm_wifi_ap_lookup_for_device (NM_DEVICE (self), ap_path) : NULL;
if (!ap) {
- ap = nm_wifi_aps_find_first_compatible (priv->aps, connection, FALSE);
+ ap = nm_wifi_aps_find_first_compatible (&priv->aps_lst_head, connection);
/* TODO: assuming hidden networks aren't supported do we need
* to consider the case of APs that are not in the scan list
@@ -1540,8 +1505,7 @@ get_property (GObject *object, guint prop_id,
{
NMDeviceIwd *self = NM_DEVICE_IWD (object);
NMDeviceIwdPrivate *priv = NM_DEVICE_IWD_GET_PRIVATE (self);
- gsize i;
- char **list;
+ const char **list;
switch (prop_id) {
case PROP_MODE:
@@ -1557,10 +1521,8 @@ get_property (GObject *object, guint prop_id,
g_value_set_uint (value, priv->capabilities);
break;
case PROP_ACCESS_POINTS:
- list = (char **) nm_wifi_aps_get_sorted_paths (priv->aps, TRUE);
- for (i = 0; list[i]; i++)
- list[i] = g_strdup (list[i]);
- g_value_take_boxed (value, list);
+ list = nm_wifi_aps_get_paths (&priv->aps_lst_head, TRUE);
+ g_value_take_boxed (value, nm_utils_strv_make_deep_copied (list));
break;
case PROP_ACTIVE_ACCESS_POINT:
nm_dbus_utils_g_value_set_object_path (value, priv->current_ap);
@@ -1830,7 +1792,7 @@ nm_device_iwd_init (NMDeviceIwd *self)
{
NMDeviceIwdPrivate *priv = NM_DEVICE_IWD_GET_PRIVATE (self);
- priv->aps = g_hash_table_new (nm_str_hash, g_str_equal);
+ c_list_init (&priv->aps_lst_head);
/* Make sure the manager is running */
(void) nm_iwd_manager_get ();
@@ -1867,19 +1829,8 @@ dispose (GObject *object)
remove_all_aps (self);
G_OBJECT_CLASS (nm_device_iwd_parent_class)->dispose (object);
-}
-
-static void
-finalize (GObject *object)
-{
- NMDeviceIwd *self = NM_DEVICE_IWD (object);
- NMDeviceIwdPrivate *priv = NM_DEVICE_IWD_GET_PRIVATE (self);
-
- nm_assert (g_hash_table_size (priv->aps) == 0);
-
- g_hash_table_unref (priv->aps);
- G_OBJECT_CLASS (nm_device_iwd_parent_class)->finalize (object);
+ nm_assert (c_list_is_empty (&priv->aps_lst_head));
}
static void
@@ -1894,7 +1845,6 @@ nm_device_iwd_class_init (NMDeviceIwdClass *klass)
object_class->get_property = get_property;
object_class->set_property = set_property;
object_class->dispose = dispose;
- object_class->finalize = finalize;
dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS (&nm_interface_info_device_wireless);
diff --git a/src/devices/wifi/nm-device-iwd.h b/src/devices/wifi/nm-device-iwd.h
index 6d4ff06bfc..699ba1bb2b 100644
--- a/src/devices/wifi/nm-device-iwd.h
+++ b/src/devices/wifi/nm-device-iwd.h
@@ -53,7 +53,7 @@ void nm_device_iwd_set_dbus_object (NMDeviceIwd *device, GDBusObject *object);
gboolean nm_device_iwd_agent_psk_query (NMDeviceIwd *device,
GDBusMethodInvocation *invocation);
-GHashTable *_nm_device_iwd_get_aps (NMDeviceIwd *self);
+const CList *_nm_device_iwd_get_aps (NMDeviceIwd *self);
void _nm_device_iwd_request_scan (NMDeviceIwd *self,
GVariant *options,
diff --git a/src/devices/wifi/nm-device-olpc-mesh.c b/src/devices/wifi/nm-device-olpc-mesh.c
index c3d070d98d..d655406437 100644
--- a/src/devices/wifi/nm-device-olpc-mesh.c
+++ b/src/devices/wifi/nm-device-olpc-mesh.c
@@ -387,7 +387,8 @@ static void
find_companion (NMDeviceOlpcMesh *self)
{
NMDeviceOlpcMeshPrivate *priv = NM_DEVICE_OLPC_MESH_GET_PRIVATE (self);
- const GSList *list;
+ const CList *all_devices;
+ NMDevice *candidate;
if (priv->companion)
return;
@@ -395,8 +396,9 @@ find_companion (NMDeviceOlpcMesh *self)
nm_device_add_pending_action (NM_DEVICE (self), NM_PENDING_ACTION_WAITING_FOR_COMPANION, TRUE);
/* Try to find the companion if it's already known to the NMManager */
- for (list = nm_manager_get_devices (priv->manager); list ; list = g_slist_next (list)) {
- if (check_companion (self, NM_DEVICE (list->data))) {
+ all_devices = nm_manager_get_devices (priv->manager);
+ c_list_for_each_entry (candidate, all_devices, devices_lst) {
+ if (check_companion (self, candidate)) {
nm_device_queue_recheck_available (NM_DEVICE (self),
NM_DEVICE_STATE_REASON_NONE,
NM_DEVICE_STATE_REASON_NONE);
diff --git a/src/devices/wifi/nm-device-wifi.c b/src/devices/wifi/nm-device-wifi.c
index 7c64d594b7..de4af42cfc 100644
--- a/src/devices/wifi/nm-device-wifi.c
+++ b/src/devices/wifi/nm-device-wifi.c
@@ -32,6 +32,7 @@
#include "nm-common-macros.h"
#include "devices/nm-device.h"
#include "devices/nm-device-private.h"
+#include "nm-dbus-manager.h"
#include "nm-utils.h"
#include "NetworkManagerUtils.h"
#include "nm-act-request.h"
@@ -86,7 +87,8 @@ static guint signals[LAST_SIGNAL] = { 0 };
typedef struct {
gint8 invalid_strength_counter;
- GHashTable * aps;
+ CList aps_lst_head;
+
NMWifiAP * current_ap;
guint32 rate;
bool enabled:1; /* rfkilled or not */
@@ -344,30 +346,6 @@ supplicant_interface_release (NMDeviceWifi *self)
_notify_scanning (self);
}
-static NMWifiAP *
-get_ap_by_path (NMDeviceWifi *self, const char *path)
-{
- g_return_val_if_fail (path != NULL, NULL);
- return g_hash_table_lookup (NM_DEVICE_WIFI_GET_PRIVATE (self)->aps, path);
-
-}
-
-static NMWifiAP *
-get_ap_by_supplicant_path (NMDeviceWifi *self, const char *path)
-{
- GHashTableIter iter;
- NMWifiAP *ap;
-
- g_return_val_if_fail (path != NULL, NULL);
-
- g_hash_table_iter_init (&iter, NM_DEVICE_WIFI_GET_PRIVATE (self)->aps);
- while (g_hash_table_iter_next (&iter, NULL, (gpointer) &ap)) {
- if (g_strcmp0 (path, nm_wifi_ap_get_supplicant_path (ap)) == 0)
- return ap;
- }
- return NULL;
-}
-
static void
update_seen_bssids_cache (NMDeviceWifi *self, NMWifiAP *ap)
{
@@ -488,28 +466,25 @@ ap_add_remove (NMDeviceWifi *self,
NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
if (is_adding) {
- g_hash_table_insert (priv->aps,
- (gpointer) nm_dbus_object_export (NM_DBUS_OBJECT (ap)),
- g_object_ref (ap));
+ g_object_ref (ap);
+ ap->wifi_device = NM_DEVICE (self);
+ c_list_link_tail (&priv->aps_lst_head, &ap->aps_lst);
+ nm_dbus_object_export (NM_DBUS_OBJECT (ap));
_ap_dump (self, LOGL_DEBUG, ap, "added", 0);
- } else
+ nm_device_wifi_emit_signal_access_point (NM_DEVICE (self), ap, TRUE);
+ } else {
+ ap->wifi_device = NULL;
+ c_list_unlink (&ap->aps_lst);
_ap_dump (self, LOGL_DEBUG, ap, "removed", 0);
+ }
- nm_dbus_object_emit_signal (NM_DBUS_OBJECT (self),
- &nm_interface_info_device_wireless,
- is_adding
- ? &nm_signal_info_wireless_access_point_added
- : &nm_signal_info_wireless_access_point_removed,
- "(o)",
- nm_dbus_object_get_path (NM_DBUS_OBJECT (ap)));
+ _notify (self, PROP_ACCESS_POINTS);
if (!is_adding) {
- g_hash_table_remove (priv->aps, nm_dbus_object_get_path (NM_DBUS_OBJECT (ap)));
+ nm_device_wifi_emit_signal_access_point (NM_DEVICE (self), ap, FALSE);
nm_dbus_object_clear_and_unexport (&ap);
}
- _notify (self, PROP_ACCESS_POINTS);
-
nm_device_emit_recheck_auto_activate (NM_DEVICE (self));
if (recheck_available_connections)
nm_device_recheck_available_connections (NM_DEVICE (self));
@@ -519,20 +494,15 @@ static void
remove_all_aps (NMDeviceWifi *self)
{
NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
- GHashTableIter iter;
NMWifiAP *ap;
- if (!g_hash_table_size (priv->aps))
+ if (c_list_is_empty (&priv->aps_lst_head))
return;
set_current_ap (self, NULL, FALSE);
-again:
- g_hash_table_iter_init (&iter, priv->aps);
- if (g_hash_table_iter_next (&iter, NULL, (gpointer) &ap)) {
+ while ((ap = c_list_first_entry (&priv->aps_lst_head, NMWifiAP, aps_lst)))
ap_add_remove (self, FALSE, ap, FALSE);
- goto again;
- }
nm_device_recheck_available_connections (NM_DEVICE (self));
}
@@ -702,7 +672,7 @@ check_connection_available (NMDevice *device,
if (specific_object) {
NMWifiAP *ap;
- ap = get_ap_by_path (self, specific_object);
+ ap = nm_wifi_ap_lookup_for_device (NM_DEVICE (self), specific_object);
return ap ? nm_wifi_ap_check_compatible (ap, connection) : FALSE;
}
@@ -726,7 +696,7 @@ check_connection_available (NMDevice *device,
return TRUE;
/* check at least one AP is compatible with this connection */
- return !!nm_wifi_aps_find_first_compatible (priv->aps, connection, TRUE);
+ return !!nm_wifi_aps_find_first_compatible (&priv->aps_lst_head, connection);
}
static gboolean
@@ -774,7 +744,7 @@ complete_connection (NMDevice *device,
if (!nm_streq0 (mode, NM_SETTING_WIRELESS_MODE_AP)) {
/* Find a compatible AP in the scan list */
- ap = nm_wifi_aps_find_first_compatible (priv->aps, connection, FALSE);
+ ap = nm_wifi_aps_find_first_compatible (&priv->aps_lst_head, connection);
/* If we still don't have an AP, then the WiFI settings needs to be
* fully specified by the client. Might not be able to find an AP
@@ -796,7 +766,7 @@ complete_connection (NMDevice *device,
return FALSE;
ap = NULL;
} else {
- ap = get_ap_by_path (self, specific_object);
+ ap = nm_wifi_ap_lookup_for_device (NM_DEVICE (self), specific_object);
if (!ap) {
g_set_error (error,
NM_DEVICE_ERROR,
@@ -988,7 +958,7 @@ can_auto_connect (NMDevice *device,
return FALSE;
}
- ap = nm_wifi_aps_find_first_compatible (priv->aps, connection, FALSE);
+ ap = nm_wifi_aps_find_first_compatible (&priv->aps_lst_head, connection);
if (ap) {
/* All good; connection is usable */
NM_SET_OUT (specific_object, g_strdup (nm_dbus_object_get_path (NM_DBUS_OBJECT (ap))));
@@ -998,10 +968,10 @@ can_auto_connect (NMDevice *device,
return FALSE;
}
-GHashTable *
+const CList *
_nm_device_wifi_get_aps (NMDeviceWifi *self)
{
- return NM_DEVICE_WIFI_GET_PRIVATE (self)->aps;
+ return &NM_DEVICE_WIFI_GET_PRIVATE (self)->aps_lst_head;
}
static void
@@ -1472,17 +1442,15 @@ ap_list_dump (gpointer user_data)
priv->ap_dump_id = 0;
if (_LOGD_ENABLED (LOGD_WIFI_SCAN)) {
- gs_free NMWifiAP **list = NULL;
- gsize i;
+ NMWifiAP *ap;
gint32 now_s = nm_utils_get_monotonic_timestamp_s ();
_LOGD (LOGD_WIFI_SCAN, "APs: [now:%u last:%u next:%u]",
now_s,
priv->last_scan,
priv->scheduled_scan_time);
- list = nm_wifi_aps_get_sorted (priv->aps, TRUE);
- for (i = 0; list[i]; i++)
- _ap_dump (self, LOGL_DEBUG, list[i], "dump", now_s);
+ c_list_for_each_entry (ap, &priv->aps_lst_head, aps_lst)
+ _ap_dump (self, LOGL_DEBUG, ap, "dump", now_s);
}
return G_SOURCE_REMOVE;
}
@@ -1553,7 +1521,7 @@ supplicant_iface_bss_updated_cb (NMSupplicantInterface *iface,
if (NM_DEVICE_WIFI_GET_PRIVATE (self)->mode == NM_802_11_MODE_AP)
return;
- found_ap = get_ap_by_supplicant_path (self, object_path);
+ found_ap = nm_wifi_aps_find_by_supplicant_path (&priv->aps_lst_head, object_path);
if (found_ap) {
if (!nm_wifi_ap_update_from_properties (found_ap, object_path, properties))
return;
@@ -1609,7 +1577,7 @@ supplicant_iface_bss_removed_cb (NMSupplicantInterface *iface,
g_return_if_fail (object_path != NULL);
priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
- ap = get_ap_by_supplicant_path (self, object_path);
+ ap = nm_wifi_aps_find_by_supplicant_path (&priv->aps_lst_head, object_path);
if (!ap)
return;
@@ -2153,7 +2121,7 @@ supplicant_iface_notify_current_bss (NMSupplicantInterface *iface,
current_bss = nm_supplicant_interface_get_current_bss (iface);
if (current_bss)
- new_ap = get_ap_by_supplicant_path (self, current_bss);
+ new_ap = nm_wifi_aps_find_by_supplicant_path (&priv->aps_lst_head, current_bss);
if (new_ap != priv->current_ap) {
const char *new_bssid = NULL;
@@ -2514,11 +2482,11 @@ act_stage1_prepare (NMDevice *device, NMDeviceStateReason *out_failure_reason)
/* AP mode never uses a specific object or existing scanned AP */
if (priv->mode != NM_802_11_MODE_AP) {
ap_path = nm_active_connection_get_specific_object (NM_ACTIVE_CONNECTION (req));
- ap = ap_path ? get_ap_by_path (self, ap_path) : NULL;
+ ap = ap_path ? nm_wifi_ap_lookup_for_device (NM_DEVICE (self), ap_path) : NULL;
if (ap)
goto done;
- ap = nm_wifi_aps_find_first_compatible (priv->aps, connection, FALSE);
+ ap = nm_wifi_aps_find_first_compatible (&priv->aps_lst_head, connection);
}
if (ap) {
@@ -3134,8 +3102,7 @@ get_property (GObject *object, guint prop_id,
{
NMDeviceWifi *self = NM_DEVICE_WIFI (object);
NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
- gsize i;
- char **list;
+ const char **list;
switch (prop_id) {
case PROP_MODE:
@@ -3148,10 +3115,8 @@ get_property (GObject *object, guint prop_id,
g_value_set_uint (value, priv->capabilities);
break;
case PROP_ACCESS_POINTS:
- list = (char **) nm_wifi_aps_get_sorted_paths (priv->aps, TRUE);
- for (i = 0; list[i]; i++)
- list[i] = g_strdup (list[i]);
- g_value_take_boxed (value, list);
+ list = nm_wifi_aps_get_paths (&priv->aps_lst_head, TRUE);
+ g_value_take_boxed (value, nm_utils_strv_make_deep_copied (list));
break;
case PROP_ACTIVE_ACCESS_POINT:
nm_dbus_utils_g_value_set_object_path (value, priv->current_ap);
@@ -3190,8 +3155,9 @@ nm_device_wifi_init (NMDeviceWifi *self)
{
NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
+ c_list_init (&priv->aps_lst_head);
+
priv->mode = NM_802_11_MODE_INFRA;
- priv->aps = g_hash_table_new (nm_str_hash, g_str_equal);
}
static void
@@ -3249,9 +3215,7 @@ finalize (GObject *object)
NMDeviceWifi *self = NM_DEVICE_WIFI (object);
NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
- nm_assert (g_hash_table_size (priv->aps) == 0);
-
- g_hash_table_unref (priv->aps);
+ nm_assert (c_list_is_empty (&priv->aps_lst_head));
G_OBJECT_CLASS (nm_device_wifi_parent_class)->finalize (object);
}
diff --git a/src/devices/wifi/nm-device-wifi.h b/src/devices/wifi/nm-device-wifi.h
index 632bbac1f4..c13b00defc 100644
--- a/src/devices/wifi/nm-device-wifi.h
+++ b/src/devices/wifi/nm-device-wifi.h
@@ -47,7 +47,7 @@ GType nm_device_wifi_get_type (void);
NMDevice * nm_device_wifi_new (const char *iface, NMDeviceWifiCapabilities capabilities);
-GHashTable *_nm_device_wifi_get_aps (NMDeviceWifi *self);
+const CList *_nm_device_wifi_get_aps (NMDeviceWifi *self);
void _nm_device_wifi_request_scan (NMDeviceWifi *self,
GVariant *options,
diff --git a/src/devices/wifi/nm-iwd-manager.c b/src/devices/wifi/nm-iwd-manager.c
index 0007b0fff5..ea903bc724 100644
--- a/src/devices/wifi/nm-iwd-manager.c
+++ b/src/devices/wifi/nm-iwd-manager.c
@@ -460,17 +460,16 @@ name_owner_changed (GObject *object, GParamSpec *pspec, gpointer user_data)
g_clear_object (&priv->object_manager);
prepare_object_manager (self);
} else {
- const GSList *devices, *iter;
+ const CList *all_devices;
+ NMDevice *device;
if (!priv->running)
return;
priv->running = false;
- devices = nm_manager_get_devices (priv->nm_manager);
- for (iter = devices; iter; iter = iter->next) {
- NMDevice *device = NM_DEVICE (iter->data);
-
+ all_devices = nm_manager_get_devices (priv->nm_manager);
+ c_list_for_each_entry (device, all_devices, devices_lst) {
if (!NM_IS_DEVICE_IWD (device))
continue;
diff --git a/src/devices/wifi/nm-wifi-ap.c b/src/devices/wifi/nm-wifi-ap.c
index 60767032cd..dd6d1deb6e 100644
--- a/src/devices/wifi/nm-wifi-ap.c
+++ b/src/devices/wifi/nm-wifi-ap.c
@@ -33,6 +33,8 @@
#include "nm-utils.h"
#include "nm-core-internal.h"
#include "platform/nm-platform.h"
+#include "devices/nm-device.h"
+#include "nm-dbus-manager.h"
#define PROTO_WPA "wpa"
#define PROTO_RSN "rsn"
@@ -52,7 +54,7 @@ NM_GOBJECT_PROPERTIES_DEFINE (NMWifiAP,
PROP_LAST_SEEN,
);
-typedef struct {
+struct _NMWifiAPPrivate {
char *supplicant_path; /* D-Bus object path of this AP from wpa_supplicant */
/* Scanned or cached values */
@@ -71,20 +73,17 @@ typedef struct {
bool fake:1; /* Whether or not the AP is from a scan */
bool hotspot:1; /* Whether the AP is a local device's hotspot network */
gint32 last_seen; /* Timestamp when the AP was seen lastly (obtained via nm_utils_get_monotonic_timestamp_s()) */
-} NMWifiAPPrivate;
-
-struct _NMWifiAP {
- NMDBusObject parent;
- NMWifiAPPrivate _priv;
};
+typedef struct _NMWifiAPPrivate NMWifiAPPrivate;
+
struct _NMWifiAPClass {
NMDBusObjectClass parent;
};
G_DEFINE_TYPE (NMWifiAP, nm_wifi_ap, NM_TYPE_DBUS_OBJECT)
-#define NM_WIFI_AP_GET_PRIVATE(self) _NM_GET_PRIVATE(self, NMWifiAP, NM_IS_WIFI_AP)
+#define NM_WIFI_AP_GET_PRIVATE(self) _NM_GET_PRIVATE_PTR(self, NMWifiAP, NM_IS_WIFI_AP)
/*****************************************************************************/
@@ -96,25 +95,6 @@ nm_wifi_ap_get_supplicant_path (NMWifiAP *ap)
return NM_WIFI_AP_GET_PRIVATE (ap)->supplicant_path;
}
-guint64
-nm_wifi_ap_get_id (NMWifiAP *ap)
-{
- const char *path;
- guint64 i;
-
- g_return_val_if_fail (NM_IS_WIFI_AP (ap), 0);
-
- path = nm_dbus_object_get_path (NM_DBUS_OBJECT (ap));
- g_return_val_if_fail (path, 0);
-
- nm_assert (g_str_has_prefix (path, NM_DBUS_PATH_ACCESS_POINT"/"));
-
- i = _nm_utils_ascii_str_to_int64 (&path[NM_STRLEN (NM_DBUS_PATH_ACCESS_POINT"/")], 10, 1, G_MAXINT64, 0);
-
- nm_assert (i);
- return i;
-}
-
const GByteArray *
nm_wifi_ap_get_ssid (const NMWifiAP *ap)
{
@@ -1178,9 +1158,15 @@ get_property (GObject *object, guint prop_id,
/*****************************************************************************/
static void
-nm_wifi_ap_init (NMWifiAP *ap)
+nm_wifi_ap_init (NMWifiAP *self)
{
- NMWifiAPPrivate *priv = NM_WIFI_AP_GET_PRIVATE (ap);
+ NMWifiAPPrivate *priv;
+
+ priv = G_TYPE_INSTANCE_GET_PRIVATE (self, NM_TYPE_WIFI_AP, NMWifiAPPrivate);
+
+ self->_priv = priv;
+
+ c_list_init (&self->aps_lst);
priv->mode = NM_802_11_MODE_INFRA;
priv->flags = NM_802_11_AP_FLAGS_NONE;
@@ -1340,7 +1326,11 @@ error:
static void
finalize (GObject *object)
{
- NMWifiAPPrivate *priv = NM_WIFI_AP_GET_PRIVATE ((NMWifiAP *) object);
+ NMWifiAP *self = NM_WIFI_AP (object);
+ NMWifiAPPrivate *priv = NM_WIFI_AP_GET_PRIVATE (self);
+
+ nm_assert (!self->wifi_device);
+ nm_assert (c_list_is_empty (&self->aps_lst));
g_free (priv->supplicant_path);
if (priv->ssid)
@@ -1391,6 +1381,8 @@ nm_wifi_ap_class_init (NMWifiAPClass *ap_class)
GObjectClass *object_class = G_OBJECT_CLASS (ap_class);
NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS (ap_class);
+ g_type_class_add_private (object_class, sizeof (NMWifiAPPrivate));
+
dbus_object_class->export_path = NM_DBUS_EXPORT_PATH_NUMBERED (NM_DBUS_PATH_ACCESS_POINT);
dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS (&interface_info_access_point);
@@ -1459,86 +1451,81 @@ nm_wifi_ap_class_init (NMWifiAPClass *ap_class)
/*****************************************************************************/
-static int
-ap_id_compare (gconstpointer p_a, gconstpointer p_b, gpointer user_data)
-{
- guint64 a_id = nm_wifi_ap_get_id (*((NMWifiAP **) p_a));
- guint64 b_id = nm_wifi_ap_get_id (*((NMWifiAP **) p_b));
-
- return a_id < b_id ? -1 : (a_id == b_id ? 0 : 1);
-}
-
-NMWifiAP **
-nm_wifi_aps_get_sorted (GHashTable *aps, gboolean include_without_ssid)
+const char **
+nm_wifi_aps_get_paths (const CList *aps_lst_head, gboolean include_without_ssid)
{
- NMWifiAP **list;
- GHashTableIter iter;
NMWifiAP *ap;
gsize i, n;
+ const char **list;
+ const char *path;
- n = g_hash_table_size (aps);
- list = g_new (NMWifiAP *, n + 1);
+ n = c_list_length (aps_lst_head);
+ list = g_new (const char *, n + 1);
i = 0;
if (n > 0) {
- g_hash_table_iter_init (&iter, aps);
- while (g_hash_table_iter_next (&iter, NULL, (gpointer) &ap)) {
+ c_list_for_each_entry (ap, aps_lst_head, aps_lst) {
nm_assert (i < n);
- if ( include_without_ssid
- || nm_wifi_ap_get_ssid (ap))
- list[i++] = ap;
+ if ( !include_without_ssid
+ && !nm_wifi_ap_get_ssid (ap))
+ continue;
+
+ path = nm_dbus_object_get_path (NM_DBUS_OBJECT (ap));
+ nm_assert (path);
+
+ list[i++] = path;
}
nm_assert (i <= n);
nm_assert (!include_without_ssid || i == n);
-
- g_qsort_with_data (list,
- i,
- sizeof (gpointer),
- ap_id_compare,
- NULL);
}
list[i] = NULL;
return list;
}
-const char **
-nm_wifi_aps_get_sorted_paths (GHashTable *aps, gboolean include_without_ssid)
+NMWifiAP *
+nm_wifi_aps_find_first_compatible (const CList *aps_lst_head,
+ NMConnection *connection)
{
- gpointer *list;
- gsize i, j;
-
- list = (gpointer *) nm_wifi_aps_get_sorted (aps, include_without_ssid);
- for (i = 0, j = 0; list[i]; i++) {
- NMWifiAP *ap = list[i];
- const char *path;
-
- /* update @list inplace to hold instead the export-path. */
- path = nm_dbus_object_get_path (NM_DBUS_OBJECT (ap));
- nm_assert (path);
- list[j++] = (gpointer) path;
+ NMWifiAP *ap;
+
+ g_return_val_if_fail (connection, NULL);
+
+ c_list_for_each_entry (ap, aps_lst_head, aps_lst) {
+ if (nm_wifi_ap_check_compatible (ap, connection))
+ return ap;
}
- return (const char **) list;
+ return NULL;
}
NMWifiAP *
-nm_wifi_aps_find_first_compatible (GHashTable *aps,
- NMConnection *connection,
- gboolean allow_unstable_order)
+nm_wifi_aps_find_by_supplicant_path (const CList *aps_lst_head, const char *path)
{
- GHashTableIter iter;
NMWifiAP *ap;
- NMWifiAP *cand_ap = NULL;
- g_return_val_if_fail (connection != NULL, NULL);
+ g_return_val_if_fail (path != NULL, NULL);
- g_hash_table_iter_init (&iter, aps);
- while (g_hash_table_iter_next (&iter, NULL, (gpointer) &ap)) {
- if (!nm_wifi_ap_check_compatible (ap, connection))
- continue;
- if (allow_unstable_order)
+ c_list_for_each_entry (ap, aps_lst_head, aps_lst) {
+ if (nm_streq0 (path, nm_wifi_ap_get_supplicant_path (ap)))
return ap;
- if (!cand_ap || (nm_wifi_ap_get_id (cand_ap) < nm_wifi_ap_get_id (ap)))
- cand_ap = ap;
}
- return cand_ap;
+ return NULL;
+}
+
+/*****************************************************************************/
+
+NMWifiAP *
+nm_wifi_ap_lookup_for_device (NMDevice *device, const char *exported_path)
+{
+ NMWifiAP *ap;
+
+ g_return_val_if_fail (NM_IS_DEVICE (device), NULL);
+
+ ap = (NMWifiAP *) nm_dbus_manager_lookup_object (nm_dbus_object_get_manager (NM_DBUS_OBJECT (device)),
+ exported_path);
+ if ( !ap
+ || !NM_IS_WIFI_AP (ap)
+ || ap->wifi_device != device)
+ return NULL;
+
+ return ap;
}
diff --git a/src/devices/wifi/nm-wifi-ap.h b/src/devices/wifi/nm-wifi-ap.h
index 314f2265f1..4fdeee935c 100644
--- a/src/devices/wifi/nm-wifi-ap.h
+++ b/src/devices/wifi/nm-wifi-ap.h
@@ -44,7 +44,13 @@
#define NM_WIFI_AP_STRENGTH "strength"
#define NM_WIFI_AP_LAST_SEEN "last-seen"
-typedef struct _NMWifiAP NMWifiAP;
+typedef struct {
+ NMDBusObject parent;
+ NMDevice *wifi_device;
+ CList aps_lst;
+ struct _NMWifiAPPrivate *_priv;
+} NMWifiAP;
+
typedef struct _NMWifiAPClass NMWifiAPClass;
GType nm_wifi_ap_get_type (void);
@@ -66,7 +72,6 @@ gboolean nm_wifi_ap_complete_connection (NMWifiAP *self,
GError **error);
const char * nm_wifi_ap_get_supplicant_path (NMWifiAP *ap);
-guint64 nm_wifi_ap_get_id (NMWifiAP *ap);
const GByteArray *nm_wifi_ap_get_ssid (const NMWifiAP *ap);
gboolean nm_wifi_ap_set_ssid (NMWifiAP *ap,
const guint8 *ssid,
@@ -95,12 +100,14 @@ const char *nm_wifi_ap_to_string (const NMWifiAP *self,
gulong buf_len,
gint32 now_s);
-NMWifiAP **nm_wifi_aps_get_sorted (GHashTable *aps,
- gboolean include_without_ssid);
-const char **nm_wifi_aps_get_sorted_paths (GHashTable *aps,
- gboolean include_without_ssid);
-NMWifiAP *nm_wifi_aps_find_first_compatible (GHashTable *aps,
- NMConnection *connection,
- gboolean allow_unstable_order);
+const char **nm_wifi_aps_get_paths (const CList *aps_lst_head,
+ gboolean include_without_ssid);
+
+NMWifiAP *nm_wifi_aps_find_first_compatible (const CList *aps_lst_head,
+ NMConnection *connection);
+
+NMWifiAP *nm_wifi_aps_find_by_supplicant_path (const CList *aps_lst_head, const char *path);
+
+NMWifiAP *nm_wifi_ap_lookup_for_device (NMDevice *device, const char *exported_path);
#endif /* __NM_WIFI_AP_H__ */
diff --git a/src/devices/wifi/nm-wifi-common.c b/src/devices/wifi/nm-wifi-common.c
index 005aac9d60..47c0ce6784 100644
--- a/src/devices/wifi/nm-wifi-common.c
+++ b/src/devices/wifi/nm-wifi-common.c
@@ -25,6 +25,7 @@
#include "devices/nm-device.h"
#include "nm-wifi-ap.h"
#include "nm-device-wifi.h"
+#include "nm-dbus-manager.h"
#if WITH_IWD
#include "nm-device-iwd.h"
@@ -32,7 +33,23 @@
/*****************************************************************************/
-static GHashTable *
+void
+nm_device_wifi_emit_signal_access_point (NMDevice *device,
+ NMWifiAP *ap,
+ gboolean is_added /* or else is_removed */)
+{
+ nm_dbus_object_emit_signal (NM_DBUS_OBJECT (device),
+ &nm_interface_info_device_wireless,
+ is_added
+ ? &nm_signal_info_wireless_access_point_added
+ : &nm_signal_info_wireless_access_point_removed,
+ "(o)",
+ nm_dbus_object_get_path (NM_DBUS_OBJECT (ap)));
+}
+
+/*****************************************************************************/
+
+static const CList *
_dispatch_get_aps (NMDevice *device)
{
#if WITH_IWD
@@ -70,12 +87,12 @@ impl_device_wifi_get_access_points (NMDBusObject *obj,
{
gs_free const char **list = NULL;
GVariant *v;
- GHashTable *aps;
+ const CList *all_aps;
/* NOTE: this handler is called both for NMDevicwWifi and NMDeviceIwd. */
- aps = _dispatch_get_aps (NM_DEVICE (obj));
- list = nm_wifi_aps_get_sorted_paths (aps, FALSE);
+ all_aps = _dispatch_get_aps (NM_DEVICE (obj));
+ list = nm_wifi_aps_get_paths (all_aps, FALSE);
v = g_variant_new_objv (list, -1);
g_dbus_method_invocation_return_value (invocation,
g_variant_new_tuple (&v, 1));
@@ -92,12 +109,12 @@ impl_device_wifi_get_all_access_points (NMDBusObject *obj,
{
gs_free const char **list = NULL;
GVariant *v;
- GHashTable *aps;
+ const CList *all_aps;
/* NOTE: this handler is called both for NMDevicwWifi and NMDeviceIwd. */
- aps = _dispatch_get_aps (NM_DEVICE (obj));
- list = nm_wifi_aps_get_sorted_paths (aps, TRUE);
+ all_aps = _dispatch_get_aps (NM_DEVICE (obj));
+ list = nm_wifi_aps_get_paths (all_aps, TRUE);
v = g_variant_new_objv (list, -1);
g_dbus_method_invocation_return_value (invocation,
g_variant_new_tuple (&v, 1));
diff --git a/src/devices/wifi/nm-wifi-common.h b/src/devices/wifi/nm-wifi-common.h
index 4df4a5903b..91cbeb558d 100644
--- a/src/devices/wifi/nm-wifi-common.h
+++ b/src/devices/wifi/nm-wifi-common.h
@@ -22,9 +22,14 @@
#define __NM_WIFI_COMMON_H__
#include "nm-dbus-utils.h"
+#include "nm-wifi-ap.h"
/*****************************************************************************/
+void nm_device_wifi_emit_signal_access_point (NMDevice *device,
+ NMWifiAP *ap,
+ gboolean is_added /* or else is_removed */);
+
extern const NMDBusInterfaceInfoExtended nm_interface_info_device_wireless;
extern const GDBusSignalInfo nm_signal_info_wireless_access_point_added;
extern const GDBusSignalInfo nm_signal_info_wireless_access_point_removed;
diff --git a/src/dns/nm-dns-manager.c b/src/dns/nm-dns-manager.c
index 56be5aab35..ea8ce2d805 100644
--- a/src/dns/nm-dns-manager.c
+++ b/src/dns/nm-dns-manager.c
@@ -970,30 +970,36 @@ merge_global_dns_config (NMResolvConfData *rc, NMGlobalDnsConfig *global_conf)
const char *const *searches;
const char *const *options;
const char *const *servers;
- gint i;
+ guint i;
if (!global_conf)
return FALSE;
searches = nm_global_dns_config_get_searches (global_conf);
- options = nm_global_dns_config_get_options (global_conf);
-
- for (i = 0; searches && searches[i]; i++) {
- if (domain_is_routing (searches[i]))
- continue;
- if (!domain_is_valid (searches[i], FALSE))
- continue;
- add_string_item (rc->searches, searches[i], TRUE);
+ if (searches) {
+ for (i = 0; searches[i]; i++) {
+ if (domain_is_routing (searches[i]))
+ continue;
+ if (!domain_is_valid (searches[i], FALSE))
+ continue;
+ add_string_item (rc->searches, searches[i], TRUE);
+ }
}
- for (i = 0; options && options[i]; i++)
- add_string_item (rc->options, options[i], TRUE);
+ options = nm_global_dns_config_get_options (global_conf);
+ if (options) {
+ for (i = 0; options[i]; i++)
+ add_string_item (rc->options, options[i], TRUE);
+ }
default_domain = nm_global_dns_config_lookup_domain (global_conf, "*");
- g_assert (default_domain);
+ nm_assert (default_domain);
+
servers = nm_global_dns_domain_get_servers (default_domain);
- for (i = 0; servers && servers[i]; i++)
- add_string_item (rc->nameservers, servers[i], TRUE);
+ if (servers) {
+ for (i = 0; servers[i]; i++)
+ add_string_item (rc->nameservers, servers[i], TRUE);
+ }
return TRUE;
}
diff --git a/src/dns/nm-dns-systemd-resolved.c b/src/dns/nm-dns-systemd-resolved.c
index 2e790d0b14..7da27e5f7f 100644
--- a/src/dns/nm-dns-systemd-resolved.c
+++ b/src/dns/nm-dns-systemd-resolved.c
@@ -330,14 +330,10 @@ update (NMDnsPlugin *plugin,
free_pending_updates (self);
- interfaces_keys = g_hash_table_get_keys_as_array (interfaces, &interfaces_len);
- if (interfaces_len > 1) {
- g_qsort_with_data (interfaces_keys,
- interfaces_len,
- sizeof (gpointer),
- nm_cmp_int2ptr_p_with_data,
- NULL);
- }
+ interfaces_keys = nm_utils_hash_keys_to_array (interfaces,
+ nm_cmp_int2ptr_p_with_data,
+ NULL,
+ &interfaces_len);
for (i = 0; i < interfaces_len; i++) {
InterfaceConfig *ic = g_hash_table_lookup (interfaces, GINT_TO_POINTER (interfaces_keys[i]));
diff --git a/src/nm-checkpoint-manager.c b/src/nm-checkpoint-manager.c
index 44c1f49f48..7345f9a41d 100644
--- a/src/nm-checkpoint-manager.c
+++ b/src/nm-checkpoint-manager.c
@@ -174,14 +174,12 @@ nm_checkpoint_manager_create (NMCheckpointManager *self,
if (!device_paths || !device_paths[0]) {
const char *device_path;
- const GSList *iter;
+ const CList *all_devices;
GPtrArray *paths;
paths = g_ptr_array_new ();
- for (iter = nm_manager_get_devices (manager);
- iter;
- iter = g_slist_next (iter)) {
- device = NM_DEVICE (iter->data);
+ all_devices = nm_manager_get_devices (manager);
+ c_list_for_each_entry (device, all_devices, devices_lst) {
if (!nm_device_is_real (device))
continue;
device_path = nm_dbus_object_get_path (NM_DBUS_OBJECT (device));
diff --git a/src/nm-checkpoint.c b/src/nm-checkpoint.c
index 402d217f87..d85d2d5499 100644
--- a/src/nm-checkpoint.c
+++ b/src/nm-checkpoint.c
@@ -348,21 +348,20 @@ next_dev:
}
if (NM_FLAGS_HAS (priv->flags, NM_CHECKPOINT_CREATE_FLAG_DISCONNECT_NEW_DEVICES)) {
- const GSList *list;
+ const CList *all_devices;
NMDeviceState state;
- NMDevice *dev;
-
- for (list = nm_manager_get_devices (priv->manager); list ; list = g_slist_next (list)) {
- dev = list->data;
- if (!g_hash_table_contains (priv->devices, dev)) {
- state = nm_device_get_state (dev);
- if ( state > NM_DEVICE_STATE_DISCONNECTED
- && state < NM_DEVICE_STATE_DEACTIVATING) {
- _LOGD ("rollback: disconnecting new device %s", nm_device_get_iface (dev));
- nm_device_state_changed (dev,
- NM_DEVICE_STATE_DEACTIVATING,
- NM_DEVICE_STATE_REASON_USER_REQUESTED);
- }
+
+ all_devices = nm_manager_get_devices (priv->manager);
+ c_list_for_each_entry (device, all_devices, devices_lst) {
+ if (g_hash_table_contains (priv->devices, device))
+ continue;
+ state = nm_device_get_state (device);
+ if ( state > NM_DEVICE_STATE_DISCONNECTED
+ && state < NM_DEVICE_STATE_DEACTIVATING) {
+ _LOGD ("rollback: disconnecting new device %s", nm_device_get_iface (device));
+ nm_device_state_changed (device,
+ NM_DEVICE_STATE_DEACTIVATING,
+ NM_DEVICE_STATE_REASON_USER_REQUESTED);
}
}
diff --git a/src/nm-config-data.c b/src/nm-config-data.c
index e71ac95a63..638d5f3cbd 100644
--- a/src/nm-config-data.c
+++ b/src/nm-config-data.c
@@ -54,7 +54,7 @@ struct _NMGlobalDnsConfig {
char **searches;
char **options;
GHashTable *domains;
- char **domain_list;
+ const char **domain_list;
gboolean internal;
};
@@ -705,54 +705,53 @@ nm_config_data_log (const NMConfigData *self,
/*****************************************************************************/
-const char *const *
-nm_global_dns_config_get_searches (const NMGlobalDnsConfig *dns)
+const char *const*
+nm_global_dns_config_get_searches (const NMGlobalDnsConfig *dns_config)
{
- g_return_val_if_fail (dns, NULL);
+ g_return_val_if_fail (dns_config, NULL);
- return (const char *const *) dns->searches;
+ return (const char *const*) dns_config->searches;
}
const char *const *
-nm_global_dns_config_get_options (const NMGlobalDnsConfig *dns)
+nm_global_dns_config_get_options (const NMGlobalDnsConfig *dns_config)
{
- g_return_val_if_fail (dns, NULL);
+ g_return_val_if_fail (dns_config, NULL);
- return (const char *const *) dns->options;
+ return (const char *const*) dns_config->options;
}
guint
-nm_global_dns_config_get_num_domains (const NMGlobalDnsConfig *dns)
+nm_global_dns_config_get_num_domains (const NMGlobalDnsConfig *dns_config)
{
- g_return_val_if_fail (dns, 0);
- g_return_val_if_fail (dns->domains, 0);
+ g_return_val_if_fail (dns_config, 0);
- return g_hash_table_size (dns->domains);
+ return dns_config->domains ? g_hash_table_size (dns_config->domains) : 0;
}
NMGlobalDnsDomain *
-nm_global_dns_config_get_domain (const NMGlobalDnsConfig *dns, guint i)
+nm_global_dns_config_get_domain (const NMGlobalDnsConfig *dns_config, guint i)
{
NMGlobalDnsDomain *domain;
- g_return_val_if_fail (dns, NULL);
- g_return_val_if_fail (dns->domains, NULL);
- g_return_val_if_fail (dns->domain_list, NULL);
- g_return_val_if_fail (i < g_strv_length (dns->domain_list), NULL);
+ g_return_val_if_fail (dns_config, NULL);
+ g_return_val_if_fail (dns_config->domains, NULL);
+ g_return_val_if_fail (i < g_hash_table_size (dns_config->domains), NULL);
- domain = g_hash_table_lookup (dns->domains, dns->domain_list[i]);
- g_return_val_if_fail (domain, NULL);
+ nm_assert (NM_PTRARRAY_LEN (dns_config->domain_list) == g_hash_table_size (dns_config->domains));
+
+ domain = g_hash_table_lookup (dns_config->domains, dns_config->domain_list[i]);
+ nm_assert (domain);
return domain;
}
-NMGlobalDnsDomain *nm_global_dns_config_lookup_domain (const NMGlobalDnsConfig *dns, const char *name)
+NMGlobalDnsDomain *nm_global_dns_config_lookup_domain (const NMGlobalDnsConfig *dns_config, const char *name)
{
- g_return_val_if_fail (dns, NULL);
- g_return_val_if_fail (dns->domains, NULL);
+ g_return_val_if_fail (dns_config, NULL);
g_return_val_if_fail (name, NULL);
- return g_hash_table_lookup (dns->domains, name);
+ return dns_config->domains ? g_hash_table_lookup (dns_config->domains, name) : NULL;
}
const char *
@@ -775,55 +774,73 @@ const char *const *
nm_global_dns_domain_get_options (const NMGlobalDnsDomain *domain)
{
g_return_val_if_fail (domain, NULL);
+
return (const char *const *) domain->options;
}
gboolean
-nm_global_dns_config_is_internal (const NMGlobalDnsConfig *dns)
+nm_global_dns_config_is_internal (const NMGlobalDnsConfig *dns_config)
{
- return dns->internal;
+ return dns_config->internal;
}
gboolean
-nm_global_dns_config_is_empty (const NMGlobalDnsConfig *dns)
+nm_global_dns_config_is_empty (const NMGlobalDnsConfig *dns_config)
{
- g_return_val_if_fail (dns, TRUE);
- g_return_val_if_fail (dns->domains, TRUE);
+ g_return_val_if_fail (dns_config, TRUE);
- return (!dns->searches || g_strv_length (dns->searches) == 0)
- && (!dns->options || g_strv_length (dns->options) == 0)
- && g_hash_table_size (dns->domains) == 0;
+ return !dns_config->searches
+ && !dns_config->options
+ && !dns_config->domain_list;
}
void
-nm_global_dns_config_update_checksum (const NMGlobalDnsConfig *dns, GChecksum *sum)
+nm_global_dns_config_update_checksum (const NMGlobalDnsConfig *dns_config, GChecksum *sum)
{
NMGlobalDnsDomain *domain;
- GList *keys, *key;
guint i;
+ guint8 v8;
- g_return_if_fail (dns);
- g_return_if_fail (dns->domains);
+ g_return_if_fail (dns_config);
g_return_if_fail (sum);
- for (i = 0; dns->searches && dns->searches[i]; i++)
- g_checksum_update (sum, (guchar *) dns->searches[i], strlen (dns->searches[i]));
- for (i = 0; dns->options && dns->options[i]; i++)
- g_checksum_update (sum, (guchar *) dns->options[i], strlen (dns->options[i]));
+ v8 = NM_HASH_COMBINE_BOOLS (guint8,
+ !dns_config->searches,
+ !dns_config->options,
+ !dns_config->domain_list);
+ g_checksum_update (sum, (guchar *) &v8, 1);
- keys = g_list_sort (g_hash_table_get_keys (dns->domains), (GCompareFunc) strcmp);
- for (key = keys; key; key = g_list_next (key)) {
+ if (dns_config->searches) {
+ for (i = 0; dns_config->searches[i]; i++)
+ g_checksum_update (sum, (guchar *) dns_config->searches[i], strlen (dns_config->searches[i]) + 1);
+ }
+ if (dns_config->options) {
+ for (i = 0; dns_config->options[i]; i++)
+ g_checksum_update (sum, (guchar *) dns_config->options[i], strlen (dns_config->options[i]) + 1);
+ }
- domain = g_hash_table_lookup (dns->domains, key->data);
- g_assert (domain != NULL);
- g_checksum_update (sum, (guchar *) domain->name, strlen (domain->name));
+ if (dns_config->domain_list) {
+ for (i = 0; dns_config->domain_list[i]; i++) {
+ domain = g_hash_table_lookup (dns_config->domains, dns_config->domain_list[i]);
+ nm_assert (domain);
- for (i = 0; domain->servers && domain->servers[i]; i++)
- g_checksum_update (sum, (guchar *) domain->servers[i], strlen (domain->servers[i]));
- for (i = 0; domain->options && domain->options[i]; i++)
- g_checksum_update (sum, (guchar *) domain->options[i], strlen (domain->options[i]));
+ v8 = NM_HASH_COMBINE_BOOLS (guint8,
+ !domain->servers,
+ !domain->options);
+ g_checksum_update (sum, (guchar *) &v8, 1);
+
+ g_checksum_update (sum, (guchar *) domain->name, strlen (domain->name) + 1);
+
+ if (domain->servers) {
+ for (i = 0; domain->servers && domain->servers[i]; i++)
+ g_checksum_update (sum, (guchar *) domain->servers[i], strlen (domain->servers[i]) + 1);
+ }
+ if (domain->options) {
+ for (i = 0; domain->options[i]; i++)
+ g_checksum_update (sum, (guchar *) domain->options[i], strlen (domain->options[i]) + 1);
+ }
+ }
}
- g_list_free (keys);
}
static void
@@ -838,14 +855,15 @@ global_dns_domain_free (NMGlobalDnsDomain *domain)
}
void
-nm_global_dns_config_free (NMGlobalDnsConfig *conf)
-{
- if (conf) {
- g_strfreev (conf->searches);
- g_strfreev (conf->options);
- g_free (conf->domain_list);
- g_hash_table_unref (conf->domains);
- g_free (conf);
+nm_global_dns_config_free (NMGlobalDnsConfig *dns_config)
+{
+ if (dns_config) {
+ g_strfreev (dns_config->searches);
+ g_strfreev (dns_config->options);
+ g_free (dns_config->domain_list);
+ if (dns_config->domains)
+ g_hash_table_unref (dns_config->domains);
+ g_free (dns_config);
}
}
@@ -858,18 +876,22 @@ nm_config_data_get_global_dns_config (const NMConfigData *self)
}
static void
-global_dns_config_update_domain_list (NMGlobalDnsConfig *dns)
+global_dns_config_seal_domains (NMGlobalDnsConfig *dns_config)
{
- guint length;
+ nm_assert (dns_config);
+ nm_assert (dns_config->domains);
+ nm_assert (!dns_config->domain_list);
- g_free (dns->domain_list);
- dns->domain_list = (char **) g_hash_table_get_keys_as_array (dns->domains, &length);
+ if (g_hash_table_size (dns_config->domains) == 0)
+ nm_clear_pointer (&dns_config->domains, g_hash_table_unref);
+ else
+ dns_config->domain_list = nm_utils_strdict_get_keys (dns_config->domains, TRUE, NULL);
}
static NMGlobalDnsConfig *
load_global_dns (GKeyFile *keyfile, gboolean internal)
{
- NMGlobalDnsConfig *conf;
+ NMGlobalDnsConfig *dns_config;
char *group, *domain_prefix;
gs_strfreev char **groups = NULL;
int g, i, j, domain_prefix_len;
@@ -887,13 +909,18 @@ load_global_dns (GKeyFile *keyfile, gboolean internal)
if (!nm_config_keyfile_has_global_dns_config (keyfile, internal))
return NULL;
- conf = g_malloc0 (sizeof (NMGlobalDnsConfig));
- conf->domains = g_hash_table_new_full (nm_str_hash, g_str_equal,
- g_free, (GDestroyNotify) global_dns_domain_free);
+ dns_config = g_malloc0 (sizeof (NMGlobalDnsConfig));
+ dns_config->domains = g_hash_table_new_full (nm_str_hash, g_str_equal,
+ g_free, (GDestroyNotify) global_dns_domain_free);
strv = g_key_file_get_string_list (keyfile, group, "searches", NULL, NULL);
- if (strv)
- conf->searches = _nm_utils_strv_cleanup (strv, TRUE, TRUE, TRUE);
+ if (strv) {
+ _nm_utils_strv_cleanup (strv, TRUE, TRUE, TRUE);
+ if (!strv[0])
+ g_free (strv);
+ else
+ dns_config->searches = strv;
+ }
strv = g_key_file_get_string_list (keyfile, group, "options", NULL, NULL);
if (strv) {
@@ -904,8 +931,12 @@ load_global_dns (GKeyFile *keyfile, gboolean internal)
else
g_free (strv[i]);
}
- strv[j] = NULL;
- conf->options = strv;
+ if (j == 0)
+ g_free (strv);
+ else {
+ strv[j] = NULL;
+ dns_config->options = strv;
+ }
}
groups = g_key_file_get_groups (keyfile, NULL);
@@ -928,20 +959,23 @@ load_global_dns (GKeyFile *keyfile, gboolean internal)
else
g_free (strv[i]);
}
- if (j) {
+ if (j == 0)
+ g_free (strv);
+ else {
strv[j] = NULL;
servers = strv;
}
- else
- g_free (strv);
}
if (!servers)
continue;
strv = g_key_file_get_string_list (keyfile, groups[g], "options", NULL, NULL);
- if (strv)
+ if (strv) {
options = _nm_utils_strv_cleanup (strv, TRUE, TRUE, TRUE);
+ if (!options[0])
+ nm_clear_g_free (&options);
+ }
name = strdup (&groups[g][domain_prefix_len]);
domain = g_malloc0 (sizeof (NMGlobalDnsDomain));
@@ -949,7 +983,7 @@ load_global_dns (GKeyFile *keyfile, gboolean internal)
domain->servers = servers;
domain->options = options;
- g_hash_table_insert (conf->domains, strdup (name), domain);
+ g_hash_table_insert (dns_config->domains, strdup (name), domain);
if (!strcmp (name, "*"))
default_found = TRUE;
@@ -958,59 +992,61 @@ load_global_dns (GKeyFile *keyfile, gboolean internal)
if (!default_found) {
nm_log_dbg (LOGD_CORE, "%s global DNS configuration is missing default domain, ignore it",
internal ? "internal" : "user");
- nm_global_dns_config_free (conf);
+ nm_global_dns_config_free (dns_config);
return NULL;
}
- conf->internal = internal;
- global_dns_config_update_domain_list (conf);
- return conf;
+ dns_config->internal = internal;
+ global_dns_config_seal_domains (dns_config);
+ return dns_config;
}
void
-nm_global_dns_config_to_dbus (const NMGlobalDnsConfig *dns, GValue *value)
+nm_global_dns_config_to_dbus (const NMGlobalDnsConfig *dns_config, GValue *value)
{
GVariantBuilder conf_builder, domains_builder, domain_builder;
- NMGlobalDnsDomain *domain;
- GHashTableIter iter;
+ guint i;
g_variant_builder_init (&conf_builder, G_VARIANT_TYPE ("a{sv}"));
- if (!dns)
+ if (!dns_config)
goto out;
- if (dns->searches) {
+ if (dns_config->searches) {
g_variant_builder_add (&conf_builder, "{sv}", "searches",
- g_variant_new_strv ((const char *const *) dns->searches, -1));
+ g_variant_new_strv ((const char *const *) dns_config->searches, -1));
}
- if (dns->options) {
+ if (dns_config->options) {
g_variant_builder_add (&conf_builder, "{sv}", "options",
- g_variant_new_strv ((const char *const *) dns->options, -1));
+ g_variant_new_strv ((const char *const *) dns_config->options, -1));
}
g_variant_builder_init (&domains_builder, G_VARIANT_TYPE ("a{sv}"));
+ if (dns_config->domain_list) {
+ for (i = 0; dns_config->domain_list[i]; i++) {
+ NMGlobalDnsDomain *domain;
- g_hash_table_iter_init (&iter, dns->domains);
- while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &domain)) {
+ domain = g_hash_table_lookup (dns_config->domains, dns_config->domain_list[i]);
- g_variant_builder_init (&domain_builder, G_VARIANT_TYPE ("a{sv}"));
+ g_variant_builder_init (&domain_builder, G_VARIANT_TYPE ("a{sv}"));
- if (domain->servers) {
- g_variant_builder_add (&domain_builder, "{sv}", "servers",
- g_variant_new_strv ((const char *const *) domain->servers, -1));
- }
- if (domain->options) {
- g_variant_builder_add (&domain_builder, "{sv}", "options",
- g_variant_new_strv ((const char *const *) domain->options, -1));
- }
+ if (domain->servers) {
+ g_variant_builder_add (&domain_builder, "{sv}", "servers",
+ g_variant_new_strv ((const char *const *) domain->servers, -1));
+ }
+ if (domain->options) {
+ g_variant_builder_add (&domain_builder, "{sv}", "options",
+ g_variant_new_strv ((const char *const *) domain->options, -1));
+ }
- g_variant_builder_add (&domains_builder, "{sv}", domain->name,
- g_variant_builder_end (&domain_builder));
+ g_variant_builder_add (&domains_builder, "{sv}", domain->name,
+ g_variant_builder_end (&domain_builder));
+ }
}
-
g_variant_builder_add (&conf_builder, "{sv}", "domains",
g_variant_builder_end (&domains_builder));
+
out:
g_value_take_variant (value, g_variant_builder_end (&conf_builder));
}
@@ -1044,15 +1080,20 @@ global_dns_domain_from_dbus (char *name, GVariant *variant)
else
g_free (strv[i]);
}
- if (j) {
+ if (j == 0)
+ g_free (strv);
+ else {
strv[j] = NULL;
+ g_strfreev (domain->servers);
domain->servers = strv;
- } else
- g_free (strv);
+ }
} else if ( !g_strcmp0 (key, "options")
&& g_variant_is_of_type (val, G_VARIANT_TYPE ("as"))) {
strv = g_variant_dup_strv (val, NULL);
+ g_strfreev (domain->options);
domain->options = _nm_utils_strv_cleanup (strv, TRUE, TRUE, TRUE);
+ if (!domain->options[0])
+ nm_clear_g_free (&domain->options);
}
g_variant_unref (val);
@@ -1111,11 +1152,12 @@ nm_global_dns_config_from_dbus (const GValue *value, GError **error)
else
g_free (strv[i]);
}
-
- if (strv)
+ if (j == 0)
+ g_free (strv);
+ else {
strv[j] = NULL;
-
- dns_config->options = strv;
+ dns_config->options = strv;
+ }
} else if ( !g_strcmp0 (key, "domains")
&& g_variant_is_of_type (val, G_VARIANT_TYPE ("a{sv}"))) {
NMGlobalDnsDomain *domain;
@@ -1145,7 +1187,7 @@ nm_global_dns_config_from_dbus (const GValue *value, GError **error)
return NULL;
}
- global_dns_config_update_domain_list (dns_config);
+ global_dns_config_seal_domains (dns_config);
return dns_config;
}
diff --git a/src/nm-config-data.h b/src/nm-config-data.h
index 87cb83ba12..a11b38b206 100644
--- a/src/nm-config-data.h
+++ b/src/nm-config-data.h
@@ -206,18 +206,18 @@ gboolean nm_config_data_is_intern_atomic_group (const NMConfigData *self, const
GKeyFile *nm_config_data_clone_keyfile_intern (const NMConfigData *self);
-const char *const *nm_global_dns_config_get_searches (const NMGlobalDnsConfig *dns);
-const char *const *nm_global_dns_config_get_options (const NMGlobalDnsConfig *dns);
-guint nm_global_dns_config_get_num_domains (const NMGlobalDnsConfig *dns);
-NMGlobalDnsDomain *nm_global_dns_config_get_domain (const NMGlobalDnsConfig *dns, guint i);
-NMGlobalDnsDomain *nm_global_dns_config_lookup_domain (const NMGlobalDnsConfig *dns, const char *name);
+const char *const *nm_global_dns_config_get_searches (const NMGlobalDnsConfig *dns_config);
+const char *const *nm_global_dns_config_get_options (const NMGlobalDnsConfig *dns_config);
+guint nm_global_dns_config_get_num_domains (const NMGlobalDnsConfig *dns_config);
+NMGlobalDnsDomain *nm_global_dns_config_get_domain (const NMGlobalDnsConfig *dns_config, guint i);
+NMGlobalDnsDomain *nm_global_dns_config_lookup_domain (const NMGlobalDnsConfig *dns_config, const char *name);
const char *nm_global_dns_domain_get_name (const NMGlobalDnsDomain *domain);
const char *const *nm_global_dns_domain_get_servers (const NMGlobalDnsDomain *domain);
const char *const *nm_global_dns_domain_get_options (const NMGlobalDnsDomain *domain);
-gboolean nm_global_dns_config_is_internal (const NMGlobalDnsConfig *dns);
-gboolean nm_global_dns_config_is_empty (const NMGlobalDnsConfig *dns);
-void nm_global_dns_config_update_checksum (const NMGlobalDnsConfig *dns, GChecksum *sum);
-void nm_global_dns_config_free (NMGlobalDnsConfig *conf);
+gboolean nm_global_dns_config_is_internal (const NMGlobalDnsConfig *dns_config);
+gboolean nm_global_dns_config_is_empty (const NMGlobalDnsConfig *dns_config);
+void nm_global_dns_config_update_checksum (const NMGlobalDnsConfig *dns_config, GChecksum *sum);
+void nm_global_dns_config_free (NMGlobalDnsConfig *dns_config);
NMGlobalDnsConfig *nm_global_dns_config_from_dbus (const GValue *value, GError **error);
void nm_global_dns_config_to_dbus (const NMGlobalDnsConfig *dns_config, GValue *value);
diff --git a/src/nm-dbus-manager.c b/src/nm-dbus-manager.c
index e0977b1fc9..70e17d1edc 100644
--- a/src/nm-dbus-manager.c
+++ b/src/nm-dbus-manager.c
@@ -46,11 +46,16 @@
/*****************************************************************************/
typedef struct {
+ GVariant *value;
+} PropertyCacheData;
+
+typedef struct {
CList registration_lst;
NMDBusObject *obj;
NMDBusObjectClass *klass;
guint info_idx;
guint registration_id;
+ PropertyCacheData property_cache[];
} RegistrationData;
/* we require that @path is the first member of NMDBusManagerData
@@ -105,9 +110,8 @@ NM_DEFINE_SINGLETON_GETTER (NMDBusManager, nm_dbus_manager_get, NM_TYPE_DBUS_MAN
static const GDBusInterfaceInfo interface_info_objmgr;
static const GDBusSignalInfo signal_info_objmgr_interfaces_added;
static const GDBusSignalInfo signal_info_objmgr_interfaces_removed;
-
-static void _objmgr_emit_interfaces_added (NMDBusManager *self,
- NMDBusObject *obj);
+static GVariantBuilder *_obj_collect_properties_all (NMDBusObject *obj,
+ GVariantBuilder *builder);
/*****************************************************************************/
@@ -807,7 +811,8 @@ dbus_vtable_method_call (GDBusConnection *connection,
nm_assert (nm_streq (property_interface, interface_info->parent.name));
property_info = (const NMDBusPropertyInfoExtended *) nm_dbus_utils_interface_info_lookup_property (&interface_info->parent,
- property_name);
+ property_name,
+ NULL);
if ( !property_info
|| !NM_FLAGS_HAS (property_info->parent.flags, G_DBUS_PROPERTY_INFO_FLAGS_WRITABLE))
g_return_if_reached ();
@@ -855,6 +860,33 @@ dbus_vtable_method_call (GDBusConnection *connection,
}
static GVariant *
+_obj_get_property (RegistrationData *reg_data,
+ guint property_idx,
+ gboolean refetch)
+{
+ const NMDBusInterfaceInfoExtended *interface_info = _reg_data_get_interface_info (reg_data);
+ const NMDBusPropertyInfoExtended *property_info;
+ GVariant *value;
+
+ property_info = (const NMDBusPropertyInfoExtended *) (interface_info->parent.properties[property_idx]);
+
+ if (refetch)
+ nm_clear_g_variant (&reg_data->property_cache[property_idx].value);
+ else {
+ value = reg_data->property_cache[property_idx].value;
+ if (value)
+ goto out;
+ }
+
+ value = nm_dbus_utils_get_property (G_OBJECT (reg_data->obj),
+ property_info->parent.signature,
+ property_info->property_name);
+ reg_data->property_cache[property_idx].value = value;
+out:
+ return g_variant_ref (value);
+}
+
+static GVariant *
dbus_vtable_get_property (GDBusConnection *connection,
const char *sender,
const char *object_path,
@@ -865,16 +897,14 @@ dbus_vtable_get_property (GDBusConnection *connection,
{
RegistrationData *reg_data = user_data;
const NMDBusInterfaceInfoExtended *interface_info = _reg_data_get_interface_info (reg_data);
- const NMDBusPropertyInfoExtended *property_info;
+ guint property_idx;
- property_info = (const NMDBusPropertyInfoExtended *) nm_dbus_utils_interface_info_lookup_property (&interface_info->parent,
- property_name);
- if (!property_info)
+ if (!nm_dbus_utils_interface_info_lookup_property (&interface_info->parent,
+ property_name,
+ &property_idx))
g_return_val_if_reached (NULL);
- return nm_dbus_utils_get_property (G_OBJECT (reg_data->obj),
- property_info->parent.signature,
- property_info->property_name);
+ return _obj_get_property (reg_data, property_idx, FALSE);
}
static const GDBusInterfaceVTable dbus_vtable = {
@@ -896,6 +926,7 @@ _obj_register (NMDBusManager *self,
GType gtype;
NMDBusObjectClass *klasses[10];
const NMDBusInterfaceInfoExtended *const*prev_interface_infos = NULL;
+ GVariantBuilder builder;
nm_assert (c_list_is_empty (&obj->internal.registration_lst_head));
nm_assert (priv->connection);
@@ -930,8 +961,9 @@ _obj_register (NMDBusManager *self,
RegistrationData *reg_data;
gs_free_error GError *error = NULL;
guint registration_id;
+ guint prop_len = NM_PTRARRAY_LEN (interface_info->parent.properties);
- reg_data = g_slice_new (RegistrationData);
+ reg_data = g_malloc0 (sizeof (RegistrationData) + (sizeof (PropertyCacheData) * prop_len));
registration_id = g_dbus_connection_register_object (priv->connection,
obj->internal.path,
@@ -972,7 +1004,15 @@ _obj_register (NMDBusManager *self,
*
* In general, it's ok to export an object with frozen signals. But you better make sure
* that all properties are in a self-consistent state when exporting the object. */
- _objmgr_emit_interfaces_added (self, obj);
+ g_dbus_connection_emit_signal (priv->connection,
+ NULL,
+ OBJECT_MANAGER_SERVER_BASE_PATH,
+ interface_info_objmgr.name,
+ signal_info_objmgr_interfaces_added.name,
+ g_variant_new ("(oa{sa{sv}})",
+ obj->internal.path,
+ _obj_collect_properties_all (obj, &builder)),
+ NULL);
}
static void
@@ -997,14 +1037,23 @@ _obj_unregister (NMDBusManager *self,
g_variant_builder_init (&builder, G_VARIANT_TYPE ("as"));
while ((reg_data = c_list_last_entry (&obj->internal.registration_lst_head, RegistrationData, registration_lst))) {
+ const NMDBusInterfaceInfoExtended *interface_info = _reg_data_get_interface_info (reg_data);
+ guint i;
+
g_variant_builder_add (&builder,
"s",
- _reg_data_get_interface_info (reg_data)->parent.name);
+ interface_info->parent.name);
c_list_unlink_stale (&reg_data->registration_lst);
if (!g_dbus_connection_unregister_object (priv->connection, reg_data->registration_id))
nm_assert_not_reached ();
+
+ if (interface_info->parent.properties) {
+ for (i = 0; interface_info->parent.properties[i]; i++)
+ nm_clear_g_variant (&reg_data->property_cache[i].value);
+ }
+
g_type_class_unref (reg_data->klass);
- g_slice_free (RegistrationData, reg_data);
+ g_free (reg_data);
}
g_dbus_connection_emit_signal (priv->connection,
@@ -1142,9 +1191,7 @@ _nm_dbus_manager_obj_notify (NMDBusObject *obj,
if (!nm_streq (property_info->property_name, pspec->name))
continue;
- value = nm_dbus_utils_get_property (G_OBJECT (obj),
- property_info->parent.signature,
- property_info->property_name);
+ value = _obj_get_property (reg_data, i, TRUE);
if ( property_info->include_in_legacy_property_changed
&& any_legacy_signals) {
@@ -1277,9 +1324,10 @@ _nm_dbus_manager_obj_emit_signal (NMDBusObject *obj,
static GVariantBuilder *
_obj_collect_properties_per_interface (NMDBusObject *obj,
- const NMDBusInterfaceInfoExtended *interface_info,
+ RegistrationData *reg_data,
GVariantBuilder *builder)
{
+ const NMDBusInterfaceInfoExtended *interface_info = _reg_data_get_interface_info (reg_data);
guint i;
g_variant_builder_init (builder, G_VARIANT_TYPE ("a{sv}"));
@@ -1288,9 +1336,7 @@ _obj_collect_properties_per_interface (NMDBusObject *obj,
const NMDBusPropertyInfoExtended *property_info = (const NMDBusPropertyInfoExtended *) interface_info->parent.properties[i];
gs_unref_variant GVariant *variant = NULL;
- variant = nm_dbus_utils_get_property (G_OBJECT (obj),
- property_info->parent.signature,
- property_info->property_name);
+ variant = _obj_get_property (reg_data, i, FALSE);
g_variant_builder_add (builder,
"{sv}",
property_info->parent.name,
@@ -1309,14 +1355,13 @@ _obj_collect_properties_all (NMDBusObject *obj,
g_variant_builder_init (builder, G_VARIANT_TYPE ("a{sa{sv}}"));
c_list_for_each_entry (reg_data, &obj->internal.registration_lst_head, registration_lst) {
- const NMDBusInterfaceInfoExtended *interface_info = _reg_data_get_interface_info (reg_data);
GVariantBuilder properties_builder;
g_variant_builder_add (builder,
"{sa{sv}}",
- interface_info->parent.name,
+ _reg_data_get_interface_info (reg_data)->parent.name,
_obj_collect_properties_per_interface (obj,
- interface_info,
+ reg_data,
&properties_builder));
}
@@ -1324,28 +1369,6 @@ _obj_collect_properties_all (NMDBusObject *obj,
}
static void
-_objmgr_emit_interfaces_added (NMDBusManager *self,
- NMDBusObject *obj)
-{
- NMDBusManagerPrivate *priv = NM_DBUS_MANAGER_GET_PRIVATE (self);
- GVariantBuilder builder;
-
- nm_assert (NM_IS_DBUS_OBJECT (obj));
- nm_assert (priv->connection);
- nm_assert (priv->objmgr_registration_id);
-
- g_dbus_connection_emit_signal (priv->connection,
- NULL,
- OBJECT_MANAGER_SERVER_BASE_PATH,
- interface_info_objmgr.name,
- signal_info_objmgr_interfaces_added.name,
- g_variant_new ("(oa{sa{sv}})",
- obj->internal.path,
- _obj_collect_properties_all (obj, &builder)),
- NULL);
-}
-
-static void
dbus_vtable_objmgr_method_call (GDBusConnection *connection,
const char *sender,
const char *object_path,
diff --git a/src/nm-dbus-utils.c b/src/nm-dbus-utils.c
index 514dc798c6..eab6cb6125 100644
--- a/src/nm-dbus-utils.c
+++ b/src/nm-dbus-utils.c
@@ -35,7 +35,8 @@ const GDBusSignalInfo nm_signal_info_property_changed_legacy = NM_DEFINE_GDBUS_S
GDBusPropertyInfo *
nm_dbus_utils_interface_info_lookup_property (const GDBusInterfaceInfo *interface_info,
- const char *property_name)
+ const char *property_name,
+ guint *property_idx)
{
guint i;
@@ -48,8 +49,10 @@ nm_dbus_utils_interface_info_lookup_property (const GDBusInterfaceInfo *interfac
for (i = 0; interface_info->properties[i]; i++) {
GDBusPropertyInfo *info = interface_info->properties[i];
- if (nm_streq (info->name, property_name))
+ if (nm_streq (info->name, property_name)) {
+ NM_SET_OUT (property_idx, i);
return info;
+ }
}
}
diff --git a/src/nm-dbus-utils.h b/src/nm-dbus-utils.h
index 0a28bebcae..4b0ec5c477 100644
--- a/src/nm-dbus-utils.h
+++ b/src/nm-dbus-utils.h
@@ -152,7 +152,8 @@ extern const GDBusSignalInfo nm_signal_info_property_changed_legacy;
/*****************************************************************************/
GDBusPropertyInfo *nm_dbus_utils_interface_info_lookup_property (const GDBusInterfaceInfo *interface_info,
- const char *property_name);
+ const char *property_name,
+ guint *property_idx);
GDBusMethodInfo *nm_dbus_utils_interface_info_lookup_method (const GDBusInterfaceInfo *interface_info,
const char *method_name);
diff --git a/src/nm-manager.c b/src/nm-manager.c
index 1b18f44942..b941be66f8 100644
--- a/src/nm-manager.c
+++ b/src/nm-manager.c
@@ -128,7 +128,8 @@ typedef struct {
NMActiveConnection *activating_connection;
NMMetered metered;
- GSList *devices;
+ CList devices_lst_head;
+
NMState state;
NMConfig *config;
NMConnectivityState connectivity_state;
@@ -798,18 +799,20 @@ nm_manager_get_activatable_connections (NMManager *manager, guint *out_len, gboo
}
static NMActiveConnection *
-active_connection_get_by_path (NMManager *manager, const char *path)
+active_connection_get_by_path (NMManager *self, const char *path)
{
- NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
+ NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
NMActiveConnection *ac;
- nm_assert (path);
+ ac = (NMActiveConnection *) nm_dbus_manager_lookup_object (nm_dbus_object_get_manager (NM_DBUS_OBJECT (self)),
+ path);
+ if ( !ac
+ || !NM_IS_ACTIVE_CONNECTION (ac)
+ || c_list_is_empty (&ac->active_connections_lst))
+ return NULL;
- c_list_for_each_entry (ac, &priv->active_connections_lst_head, active_connections_lst) {
- if (nm_streq0 (path, nm_dbus_object_get_path (NM_DBUS_OBJECT (ac))))
- return ac;
- }
- return NULL;
+ nm_assert (c_list_contains (&priv->active_connections_lst_head, &ac->active_connections_lst));
+ return ac;
}
/*****************************************************************************/
@@ -925,27 +928,31 @@ impl_manager_reload (NMDBusObject *obj,
/*****************************************************************************/
NMDevice *
-nm_manager_get_device_by_path (NMManager *manager, const char *path)
+nm_manager_get_device_by_path (NMManager *self, const char *path)
{
- GSList *iter;
+ NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
+ NMDevice *device;
- g_return_val_if_fail (path != NULL, NULL);
+ g_return_val_if_fail (path, NULL);
- for (iter = NM_MANAGER_GET_PRIVATE (manager)->devices; iter; iter = iter->next) {
- if (!strcmp (nm_dbus_object_get_path (NM_DBUS_OBJECT (iter->data)), path))
- return NM_DEVICE (iter->data);
- }
- return NULL;
+ device = (NMDevice *) nm_dbus_manager_lookup_object (nm_dbus_object_get_manager (NM_DBUS_OBJECT (self)),
+ path);
+ if ( !device
+ || !NM_IS_DEVICE (device)
+ || c_list_is_empty (&device->devices_lst))
+ return NULL;
+
+ nm_assert (c_list_contains (&priv->devices_lst_head, &device->devices_lst));
+ return device;
}
NMDevice *
-nm_manager_get_device_by_ifindex (NMManager *manager, int ifindex)
+nm_manager_get_device_by_ifindex (NMManager *self, int ifindex)
{
- GSList *iter;
-
- for (iter = NM_MANAGER_GET_PRIVATE (manager)->devices; iter; iter = iter->next) {
- NMDevice *device = NM_DEVICE (iter->data);
+ NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
+ NMDevice *device;
+ c_list_for_each_entry (device, &priv->devices_lst_head, devices_lst) {
if (nm_device_get_ifindex (device) == ifindex)
return device;
}
@@ -954,19 +961,24 @@ nm_manager_get_device_by_ifindex (NMManager *manager, int ifindex)
}
static NMDevice *
-find_device_by_permanent_hw_addr (NMManager *manager, const char *hwaddr)
+find_device_by_permanent_hw_addr (NMManager *self, const char *hwaddr)
{
- GSList *iter;
+ NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
+ NMDevice *device;
const char *device_addr;
+ guint8 hwaddr_bin[NM_UTILS_HWADDR_LEN_MAX];
+ gsize hwaddr_len;
g_return_val_if_fail (hwaddr != NULL, NULL);
- if (nm_utils_hwaddr_valid (hwaddr, -1)) {
- for (iter = NM_MANAGER_GET_PRIVATE (manager)->devices; iter; iter = iter->next) {
- device_addr = nm_device_get_permanent_hw_address (NM_DEVICE (iter->data));
- if (device_addr && nm_utils_hwaddr_matches (hwaddr, -1, device_addr, -1))
- return NM_DEVICE (iter->data);
- }
+ if (!_nm_utils_hwaddr_aton (hwaddr, hwaddr_bin, sizeof (hwaddr_bin), &hwaddr_len))
+ return NULL;
+
+ c_list_for_each_entry (device, &priv->devices_lst_head, devices_lst) {
+ device_addr = nm_device_get_permanent_hw_address (device);
+ if ( device_addr
+ && nm_utils_hwaddr_matches (hwaddr_bin, hwaddr_len, device_addr, -1))
+ return device;
}
return NULL;
}
@@ -974,16 +986,15 @@ find_device_by_permanent_hw_addr (NMManager *manager, const char *hwaddr)
static NMDevice *
find_device_by_ip_iface (NMManager *self, const gchar *iface)
{
- GSList *iter;
-
- g_return_val_if_fail (iface != NULL, NULL);
+ NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
+ NMDevice *device;
- for (iter = NM_MANAGER_GET_PRIVATE (self)->devices; iter; iter = g_slist_next (iter)) {
- NMDevice *candidate = iter->data;
+ g_return_val_if_fail (iface, NULL);
- if ( nm_device_is_real (candidate)
- && g_strcmp0 (nm_device_get_ip_iface (candidate), iface) == 0)
- return candidate;
+ c_list_for_each_entry (device, &priv->devices_lst_head, devices_lst) {
+ if ( nm_device_is_real (device)
+ && nm_streq0 (nm_device_get_ip_iface (device), iface))
+ return device;
}
return NULL;
}
@@ -1011,12 +1022,11 @@ find_device_by_iface (NMManager *self,
{
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
NMDevice *fallback = NULL;
- GSList *iter;
+ NMDevice *candidate;
g_return_val_if_fail (iface != NULL, NULL);
- for (iter = priv->devices; iter; iter = iter->next) {
- NMDevice *candidate = iter->data;
+ c_list_for_each_entry (candidate, &priv->devices_lst_head, devices_lst) {
if (strcmp (nm_device_get_iface (candidate), iface))
continue;
@@ -1222,7 +1232,7 @@ static void
check_if_startup_complete (NMManager *self)
{
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
- GSList *iter;
+ NMDevice *device;
if (!priv->startup)
return;
@@ -1235,12 +1245,10 @@ check_if_startup_complete (NMManager *self)
return;
}
- for (iter = priv->devices; iter; iter = iter->next) {
- NMDevice *dev = iter->data;
-
- if (nm_device_has_pending_action (dev)) {
+ c_list_for_each_entry (device, &priv->devices_lst_head, devices_lst) {
+ if (nm_device_has_pending_action (device)) {
_LOGD (LOGD_CORE, "check_if_startup_complete returns FALSE because of %s",
- nm_device_get_iface (dev));
+ nm_device_get_iface (device));
return;
}
}
@@ -1252,8 +1260,8 @@ check_if_startup_complete (NMManager *self)
/* we no longer care about these signals. Startup-complete only
* happens once. */
g_signal_handlers_disconnect_by_func (priv->settings, G_CALLBACK (settings_startup_complete_changed), self);
- for (iter = priv->devices; iter; iter = iter->next) {
- g_signal_handlers_disconnect_by_func (iter->data,
+ c_list_for_each_entry (device, &priv->devices_lst_head, devices_lst) {
+ g_signal_handlers_disconnect_by_func (device,
G_CALLBACK (device_has_pending_action_changed),
self);
}
@@ -1285,18 +1293,18 @@ _parent_notify_changed (NMManager *self,
NMDevice *device,
gboolean device_removed)
{
- GSList *iter;
+ NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
+ NMDevice *candidate;
nm_assert (NM_IS_DEVICE (device));
- nm_assert (NM_IS_MANAGER (self));
- for (iter = NM_MANAGER_GET_PRIVATE (self)->devices; iter; ) {
- if (nm_device_parent_notify_changed (iter->data, device, device_removed)) {
+again:
+ c_list_for_each_entry (candidate, &priv->devices_lst_head, devices_lst) {
+ if (nm_device_parent_notify_changed (candidate, device, device_removed)) {
/* in the unlikely event that this changes anything, we start iterating
* again, to be sure that the device list is up-to-date. */
- iter = NM_MANAGER_GET_PRIVATE (self)->devices;
- } else
- iter = iter->next;
+ goto again;
+ }
}
}
@@ -1336,7 +1344,8 @@ remove_device (NMManager *self,
g_signal_handlers_disconnect_matched (device, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, self);
nm_settings_device_removed (priv->settings, device, quitting);
- priv->devices = g_slist_remove (priv->devices, device);
+
+ c_list_unlink (&device->devices_lst);
_parent_notify_changed (self, device, TRUE);
@@ -1393,7 +1402,7 @@ find_parent_device_for_connection (NMManager *self, NMConnection *connection, NM
const char *parent_name = NULL;
NMSettingsConnection *parent_connection;
NMDevice *parent, *first_compatible = NULL;
- GSList *iter;
+ NMDevice *candidate;
g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL);
@@ -1426,9 +1435,7 @@ find_parent_device_for_connection (NMManager *self, NMConnection *connection, NM
/* Check if the parent connection is currently activated or is comaptible
* with some known device.
*/
- for (iter = priv->devices; iter; iter = iter->next) {
- NMDevice *candidate = iter->data;
-
+ c_list_for_each_entry (candidate, &priv->devices_lst_head, devices_lst) {
/* Unmanaged devices are not compatible with any connection */
if (!nm_device_get_managed (candidate, FALSE))
continue;
@@ -1544,18 +1551,15 @@ NMDevice *
nm_manager_get_device (NMManager *self, const char *ifname, NMDeviceType device_type)
{
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
- GSList *iter;
- NMDevice *d;
+ NMDevice *device;
g_return_val_if_fail (ifname, NULL);
g_return_val_if_fail (device_type != NM_DEVICE_TYPE_UNKNOWN, NULL);
- for (iter = priv->devices; iter; iter = iter->next) {
- d = iter->data;
-
- if ( nm_device_get_device_type (d) == device_type
- && nm_streq0 (nm_device_get_iface (d), ifname))
- return d;
+ c_list_for_each_entry (device, &priv->devices_lst_head, devices_lst) {
+ if ( nm_device_get_device_type (device) == device_type
+ && nm_streq0 (nm_device_get_iface (device), ifname))
+ return device;
}
return NULL;
@@ -1591,9 +1595,9 @@ system_create_virtual_device (NMManager *self, NMConnection *connection)
NMDeviceFactory *factory;
gs_free NMSettingsConnection **connections = NULL;
guint i;
- GSList *iter;
gs_free char *iface = NULL;
NMDevice *device = NULL, *parent = NULL;
+ NMDevice *dev_candidate;
GError *error = NULL;
NMLogLevel log_level;
@@ -1609,17 +1613,15 @@ system_create_virtual_device (NMManager *self, NMConnection *connection)
}
/* See if there's a device that is already compatible with this connection */
- for (iter = priv->devices; iter; iter = g_slist_next (iter)) {
- NMDevice *candidate = iter->data;
-
- if (nm_device_check_connection_compatible (candidate, connection)) {
- if (nm_device_is_real (candidate)) {
+ c_list_for_each_entry (dev_candidate, &priv->devices_lst_head, devices_lst) {
+ if (nm_device_check_connection_compatible (dev_candidate, connection)) {
+ if (nm_device_is_real (dev_candidate)) {
_LOG3D (LOGD_DEVICE, connection, "already created virtual interface name %s",
iface);
return NULL;
}
- device = candidate;
+ device = dev_candidate;
break;
}
}
@@ -1840,10 +1842,10 @@ system_unmanaged_devices_changed_cb (NMSettings *settings,
{
NMManager *self = NM_MANAGER (user_data);
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
- const GSList *iter;
+ NMDevice *device;
- for (iter = priv->devices; iter; iter = g_slist_next (iter))
- nm_device_set_unmanaged_by_user_settings (NM_DEVICE (iter->data));
+ c_list_for_each_entry (device, &priv->devices_lst_head, devices_lst)
+ nm_device_set_unmanaged_by_user_settings (device);
}
static void
@@ -1889,7 +1891,7 @@ manager_update_radio_enabled (NMManager *self,
gboolean enabled)
{
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
- GSList *iter;
+ NMDevice *device;
/* Do nothing for radio types not yet implemented */
if (!rstate->prop)
@@ -1902,9 +1904,7 @@ manager_update_radio_enabled (NMManager *self,
return;
/* enable/disable wireless devices as required */
- for (iter = priv->devices; iter; iter = iter->next) {
- NMDevice *device = NM_DEVICE (iter->data);
-
+ c_list_for_each_entry (device, &priv->devices_lst_head, devices_lst) {
if (nm_device_get_rfkill_type (device) == rstate->rtype) {
_LOG2D (LOGD_RFKILL, device, "rfkill: setting radio %s", enabled ? "enabled" : "disabled");
nm_device_set_enabled (device, enabled);
@@ -2389,18 +2389,17 @@ device_ip_iface_changed (NMDevice *device,
GParamSpec *pspec,
NMManager *self)
{
+ NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
const char *ip_iface = nm_device_get_ip_iface (device);
NMDeviceType device_type = nm_device_get_device_type (device);
- GSList *iter;
+ NMDevice *candidate;
/* Remove NMDevice objects that are actually child devices of others,
* when the other device finally knows its IP interface name. For example,
* remove the PPP interface that's a child of a WWAN device, since it's
* not really a standalone NMDevice.
*/
- for (iter = NM_MANAGER_GET_PRIVATE (self)->devices; iter; iter = iter->next) {
- NMDevice *candidate = NM_DEVICE (iter->data);
-
+ c_list_for_each_entry (candidate, &priv->devices_lst_head, devices_lst) {
if ( candidate != device
&& g_strcmp0 (nm_device_get_iface (candidate), ip_iface) == 0
&& nm_device_get_device_type (candidate) == device_type
@@ -2458,10 +2457,10 @@ device_connectivity_changed (NMDevice *device,
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
NMConnectivityState best_state = NM_CONNECTIVITY_UNKNOWN;
NMConnectivityState state;
- const GSList *devices;
+ NMDevice *dev;
- for (devices = priv->devices; devices; devices = devices->next) {
- state = nm_device_get_connectivity_state (NM_DEVICE (devices->data));
+ c_list_for_each_entry (dev, &priv->devices_lst_head, devices_lst) {
+ state = nm_device_get_connectivity_state (dev);
if (state > best_state)
best_state = state;
}
@@ -2523,6 +2522,7 @@ add_device (NMManager *self, NMDevice *device, GError **error)
GSList *iter, *remove = NULL;
int ifindex;
const char *dbus_path;
+ NMDevice *candidate;
/* No duplicates */
ifindex = nm_device_get_ifindex (device);
@@ -2539,18 +2539,20 @@ add_device (NMManager *self, NMDevice *device, GError **error)
* FIXME: use parent/child device relationships instead of removing
* the child NMDevice entirely
*/
- for (iter = priv->devices; iter; iter = iter->next) {
- NMDevice *candidate = iter->data;
-
- iface = nm_device_get_ip_iface (candidate);
- if (nm_device_is_real (candidate) && nm_device_owns_iface (device, iface))
+ c_list_for_each_entry (candidate, &priv->devices_lst_head, devices_lst) {
+ if ( nm_device_is_real (candidate)
+ && (iface = nm_device_get_ip_iface (candidate))
+ && nm_device_owns_iface (device, iface))
remove = g_slist_prepend (remove, candidate);
}
for (iter = remove; iter; iter = iter->next)
remove_device (self, NM_DEVICE (iter->data), FALSE, FALSE);
g_slist_free (remove);
- priv->devices = g_slist_append (priv->devices, g_object_ref (device));
+ g_object_ref (device);
+
+ nm_assert (c_list_is_empty (&device->devices_lst));
+ c_list_link_tail (&priv->devices_lst_head, &device->devices_lst);
g_signal_connect (device, NM_DEVICE_STATE_CHANGED,
G_CALLBACK (manager_device_state_changed),
@@ -2664,12 +2666,11 @@ factory_component_added_cb (NMDeviceFactory *factory,
gpointer user_data)
{
NMManager *self = user_data;
- GSList *iter;
-
- g_return_val_if_fail (self, FALSE);
+ NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
+ NMDevice *device;
- for (iter = NM_MANAGER_GET_PRIVATE (self)->devices; iter; iter = iter->next) {
- if (nm_device_notify_component_added ((NMDevice *) iter->data, component))
+ c_list_for_each_entry (device, &priv->devices_lst_head, devices_lst) {
+ if (nm_device_notify_component_added (device, component))
return TRUE;
}
return FALSE;
@@ -2699,9 +2700,10 @@ platform_link_added (NMManager *self,
gboolean guess_assume,
const NMConfigDeviceStateData *dev_state)
{
+ NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
NMDeviceFactory *factory;
NMDevice *device = NULL;
- GSList *iter;
+ NMDevice *candidate;
g_return_if_fail (ifindex > 0);
@@ -2709,8 +2711,7 @@ platform_link_added (NMManager *self,
return;
/* Let unrealized devices try to realize themselves with the link */
- for (iter = NM_MANAGER_GET_PRIVATE (self)->devices; iter; iter = iter->next) {
- NMDevice *candidate = iter->data;
+ c_list_for_each_entry (candidate, &priv->devices_lst_head, devices_lst) {
gboolean compatible = TRUE;
gs_free_error GError *error = NULL;
@@ -2937,12 +2938,12 @@ rfkill_manager_rfkill_changed_cb (NMRfkillManager *rfkill_mgr,
nm_manager_rfkill_update (NM_MANAGER (user_data), rtype);
}
-const GSList *
+const CList *
nm_manager_get_devices (NMManager *manager)
{
g_return_val_if_fail (NM_IS_MANAGER (manager), NULL);
- return NM_MANAGER_GET_PRIVATE (manager)->devices;
+ return &NM_MANAGER_GET_PRIVATE (manager)->devices_lst_head;
}
static NMDevice *
@@ -2951,9 +2952,10 @@ nm_manager_get_best_device_for_connection (NMManager *self,
gboolean for_user_request,
GHashTable *unavailable_devices)
{
- const GSList *devices, *iter;
+ NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
NMActiveConnection *ac;
NMDevice *act_device;
+ NMDevice *device;
NMDeviceCheckConAvailableFlags flags;
ac = active_connection_find_first_by_connection (self, connection);
@@ -2966,9 +2968,7 @@ nm_manager_get_best_device_for_connection (NMManager *self,
flags = for_user_request ? NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST : NM_DEVICE_CHECK_CON_AVAILABLE_NONE;
/* Pick the first device that's compatible with the connection. */
- devices = nm_manager_get_devices (self);
- for (iter = devices; iter; iter = g_slist_next (iter)) {
- NMDevice *device = NM_DEVICE (iter->data);
+ c_list_for_each_entry (device, &priv->devices_lst_head, devices_lst) {
if (unavailable_devices && g_hash_table_contains (unavailable_devices, device))
continue;
@@ -2981,30 +2981,34 @@ nm_manager_get_best_device_for_connection (NMManager *self,
return NULL;
}
-static void
-_get_devices (NMManager *self,
- GDBusMethodInvocation *context,
- gboolean all_devices)
+static const char **
+_get_devices_paths (NMManager *self,
+ gboolean all_devices)
{
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
- gs_free const char **paths = NULL;
+ const char **paths = NULL;
guint i;
- GSList *iter;
+ NMDevice *device;
- paths = g_new (const char *, g_slist_length (priv->devices) + 1);
+ paths = g_new (const char *, c_list_length (&priv->devices_lst_head) + 1);
- for (i = 0, iter = priv->devices; iter; iter = iter->next) {
+ i = 0;
+ c_list_for_each_entry (device, &priv->devices_lst_head, devices_lst) {
const char *path;
- path = nm_dbus_object_get_path (NM_DBUS_OBJECT (iter->data));
- if ( path
- && (all_devices || nm_device_is_real (iter->data)))
- paths[i++] = path;
+ path = nm_dbus_object_get_path (NM_DBUS_OBJECT (device));
+ if (!path)
+ continue;
+
+ if ( !all_devices
+ && !nm_device_is_real (device))
+ continue;
+
+ paths[i++] = path;
}
paths[i++] = NULL;
- g_dbus_method_invocation_return_value (context,
- g_variant_new ("(^ao)", (char **) paths));
+ return paths;
}
static void
@@ -3017,8 +3021,11 @@ impl_manager_get_devices (NMDBusObject *obj,
GVariant *parameters)
{
NMManager *self = NM_MANAGER (obj);
+ gs_free const char **paths = NULL;
- _get_devices (self, invocation, FALSE);
+ paths = _get_devices_paths (self, FALSE);
+ g_dbus_method_invocation_return_value (invocation,
+ g_variant_new ("(^ao)", (char **) paths));
}
static void
@@ -3031,8 +3038,11 @@ impl_manager_get_all_devices (NMDBusObject *obj,
GVariant *parameters)
{
NMManager *self = NM_MANAGER (obj);
+ gs_free const char **paths = NULL;
- _get_devices (self, invocation, TRUE);
+ paths = _get_devices_paths (self, TRUE);
+ g_dbus_method_invocation_return_value (invocation,
+ g_variant_new ("(^ao)", (char **) paths));
}
static void
@@ -3137,7 +3147,6 @@ find_master (NMManager *self,
const char *master;
NMDevice *master_device = NULL;
NMSettingsConnection *master_connection = NULL;
- GSList *iter;
s_con = nm_connection_get_setting_connection (connection);
g_assert (s_con);
@@ -3166,10 +3175,10 @@ find_master (NMManager *self,
/* Try master as a connection UUID */
master_connection = nm_settings_get_connection_by_uuid (priv->settings, master);
if (master_connection) {
- /* Check if the master connection is activated on some device already */
- for (iter = priv->devices; iter; iter = g_slist_next (iter)) {
- NMDevice *candidate = NM_DEVICE (iter->data);
+ NMDevice *candidate;
+ /* Check if the master connection is activated on some device already */
+ c_list_for_each_entry (candidate, &priv->devices_lst_head, devices_lst) {
if (candidate == device)
continue;
@@ -3239,7 +3248,6 @@ ensure_master_active_connection (NMManager *self,
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
NMActiveConnection *master_ac = NULL;
NMDeviceState master_state;
- GSList *iter;
g_assert (connection);
g_assert (master_connection || master_device);
@@ -3315,10 +3323,10 @@ ensure_master_active_connection (NMManager *self,
NM_MANAGER_ERROR_DEPENDENCY_FAILED,
"Device unmanaged or not available for activation");
} else if (master_connection) {
- /* Find a compatible device and activate it using this connection */
- for (iter = priv->devices; iter; iter = g_slist_next (iter)) {
- NMDevice *candidate = NM_DEVICE (iter->data);
+ NMDevice *candidate;
+ /* Find a compatible device and activate it using this connection */
+ c_list_for_each_entry (candidate, &priv->devices_lst_head, devices_lst) {
if (candidate == device) {
/* A device obviously can't be its own master */
continue;
@@ -4891,7 +4899,7 @@ do_sleep_wake (NMManager *self, gboolean sleeping_changed)
{
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
gboolean suspending, waking_from_suspend;
- GSList *iter;
+ NMDevice *device;
suspending = sleeping_changed && priv->sleeping;
waking_from_suspend = sleeping_changed && !priv->sleeping;
@@ -4902,9 +4910,7 @@ do_sleep_wake (NMManager *self, gboolean sleeping_changed)
/* FIXME: are there still hardware devices that need to be disabled around
* suspend/resume?
*/
- for (iter = priv->devices; iter; iter = iter->next) {
- NMDevice *device = iter->data;
-
+ c_list_for_each_entry (device, &priv->devices_lst_head, devices_lst) {
/* FIXME: shouldn't we be unmanaging software devices if !suspending? */
if (nm_device_is_software (device))
continue;
@@ -4932,9 +4938,7 @@ do_sleep_wake (NMManager *self, gboolean sleeping_changed)
if (waking_from_suspend) {
sleep_devices_clear (self);
- for (iter = priv->devices; iter; iter = iter->next) {
- NMDevice *device = iter->data;
-
+ c_list_for_each_entry (device, &priv->devices_lst_head, devices_lst) {
if (nm_device_is_software (device))
continue;
@@ -4961,8 +4965,7 @@ do_sleep_wake (NMManager *self, gboolean sleeping_changed)
nm_manager_rfkill_update (self, RFKILL_TYPE_UNKNOWN);
/* Re-manage managed devices */
- for (iter = priv->devices; iter; iter = iter->next) {
- NMDevice *device = NM_DEVICE (iter->data);
+ c_list_for_each_entry (device, &priv->devices_lst_head, devices_lst) {
guint i;
if (nm_device_is_software (device)) {
@@ -5379,7 +5382,7 @@ impl_manager_set_logging (NMDBusObject *obj,
* that the caller is still alive so that clients are forced to wait and
* we'll be able to switch to polkit without breaking behavior.
*/
- if (!nm_dbus_manager_ensure_uid (nm_dbus_manager_get (),
+ if (!nm_dbus_manager_ensure_uid (nm_dbus_object_get_manager (NM_DBUS_OBJECT (self)),
invocation,
G_MAXULONG,
NM_MANAGER_ERROR,
@@ -5456,7 +5459,6 @@ check_connectivity_auth_done_cb (NMAuthChain *chain,
GError *error = NULL;
NMAuthCallResult result;
ConnectivityCheckData *data;
- const GSList *devices;
priv->auth_chains = g_slist_remove (priv->auth_chains, chain);
@@ -5473,13 +5475,15 @@ check_connectivity_auth_done_cb (NMAuthChain *chain,
NM_MANAGER_ERROR_PERMISSION_DENIED,
"Not authorized to recheck connectivity");
} else {
+ NMDevice *device;
+
/* it's allowed */
data = g_slice_new0 (ConnectivityCheckData);
data->context = context;
- for (devices = priv->devices; devices; devices = devices->next) {
+ c_list_for_each_entry (device, &priv->devices_lst_head, devices_lst) {
data->remaining++;
- nm_device_check_connectivity (NM_DEVICE (devices->data),
+ nm_device_check_connectivity (device,
device_connectivity_done,
data);
}
@@ -5525,15 +5529,14 @@ start_factory (NMDeviceFactory *factory, gpointer user_data)
void
nm_manager_write_device_state (NMManager *self)
{
- const GSList *devices;
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
+ NMDevice *device;
gs_unref_hashtable GHashTable *seen_ifindexes = NULL;
gint nm_owned;
seen_ifindexes = g_hash_table_new (nm_direct_hash, NULL);
- for (devices = priv->devices; devices; devices = devices->next) {
- NMDevice *device = NM_DEVICE (devices->data);
+ c_list_for_each_entry (device, &priv->devices_lst_head, devices_lst) {
int ifindex;
gboolean managed;
NMConfigDeviceStateManagedType managed_type;
@@ -5674,10 +5677,10 @@ void
nm_manager_stop (NMManager *self)
{
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
+ NMDevice *device;
- /* Remove all devices */
- while (priv->devices)
- remove_device (self, NM_DEVICE (priv->devices->data), TRUE, TRUE);
+ while ((device = c_list_first_entry (&priv->devices_lst_head, NMDevice, devices_lst)))
+ remove_device (self, device, TRUE, TRUE);
_active_connection_cleanup (self);
@@ -5689,21 +5692,20 @@ handle_firmware_changed (gpointer user_data)
{
NMManager *self = NM_MANAGER (user_data);
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
- GSList *iter;
+ NMDevice *device;
priv->fw_changed_id = 0;
/* Try to re-enable devices with missing firmware */
- for (iter = priv->devices; iter; iter = iter->next) {
- NMDevice *candidate = NM_DEVICE (iter->data);
- NMDeviceState state = nm_device_get_state (candidate);
+ c_list_for_each_entry (device, &priv->devices_lst_head, devices_lst) {
+ NMDeviceState state = nm_device_get_state (device);
- if ( nm_device_get_firmware_missing (candidate)
+ if ( nm_device_get_firmware_missing (device)
&& (state == NM_DEVICE_STATE_UNAVAILABLE)) {
- _LOG2I (LOGD_CORE, candidate, "firmware may now be available");
+ _LOG2I (LOGD_CORE, device, "firmware may now be available");
/* Re-set unavailable state to try bringing the device up again */
- nm_device_state_changed (candidate,
+ nm_device_state_changed (device,
NM_DEVICE_STATE_UNAVAILABLE,
NM_DEVICE_STATE_REASON_NONE);
}
@@ -6416,6 +6418,7 @@ nm_manager_init (NMManager *self)
GFile *file;
c_list_init (&priv->link_cb_lst);
+ c_list_init (&priv->devices_lst_head);
c_list_init (&priv->active_connections_lst_head);
c_list_init (&priv->delete_volatile_connection_lst_head);
@@ -6484,12 +6487,6 @@ nm_manager_init (NMManager *self)
priv->sleep_devices = g_hash_table_new (nm_direct_hash, NULL);
}
-static gboolean
-device_is_real (GObject *device, gpointer user_data)
-{
- return nm_device_is_real (NM_DEVICE (device));
-}
-
static void
get_property (GObject *object, guint prop_id,
GValue *value, GParamSpec *pspec)
@@ -6588,7 +6585,9 @@ get_property (GObject *object, guint prop_id,
g_value_set_boolean (value, priv->sleeping);
break;
case PROP_DEVICES:
- nm_dbus_utils_g_value_set_object_path_array (value, priv->devices, device_is_real, NULL);
+ g_value_take_boxed (value,
+ nm_utils_strv_make_deep_copied (_get_devices_paths (self,
+ FALSE)));
break;
case PROP_METERED:
g_value_set_uint (value, priv->metered);
@@ -6599,7 +6598,9 @@ get_property (GObject *object, guint prop_id,
nm_global_dns_config_to_dbus (dns_config, value);
break;
case PROP_ALL_DEVICES:
- nm_dbus_utils_g_value_set_object_path_array (value, priv->devices, NULL, NULL);
+ g_value_take_boxed (value,
+ nm_utils_strv_make_deep_copied (_get_devices_paths (self,
+ TRUE)));
break;
case PROP_CHECKPOINTS:
strv = NULL;
@@ -6700,7 +6701,7 @@ dispose (GObject *object)
g_clear_object (&priv->auth_mgr);
}
- g_assert (priv->devices == NULL);
+ nm_assert (c_list_is_empty (&priv->devices_lst_head));
nm_clear_g_source (&priv->ac_cleanup_id);
diff --git a/src/nm-manager.h b/src/nm-manager.h
index 57936dfb8b..638ceed6ea 100644
--- a/src/nm-manager.h
+++ b/src/nm-manager.h
@@ -105,7 +105,7 @@ void nm_manager_write_device_state (NMManager *manager);
/* Device handling */
-const GSList * nm_manager_get_devices (NMManager *manager);
+const CList * nm_manager_get_devices (NMManager *manager);
NMDevice * nm_manager_get_device_by_ifindex (NMManager *manager,
int ifindex);
diff --git a/src/nm-policy.c b/src/nm-policy.c
index 7cbf4864b0..72351efe06 100644
--- a/src/nm-policy.c
+++ b/src/nm-policy.c
@@ -385,7 +385,8 @@ get_best_ip_device (NMPolicy *self,
gboolean fully_activated)
{
NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self);
- const GSList *iter;
+ const CList *all_devices;
+ NMDevice *device;
NMDevice *best_device;
NMDevice *prev_device;
guint32 best_metric = G_MAXUINT32;
@@ -400,8 +401,8 @@ get_best_ip_device (NMPolicy *self,
? (fully_activated ? priv->default_device4 : priv->activating_device4)
: (fully_activated ? priv->default_device6 : priv->activating_device6);
- for (iter = nm_manager_get_devices (priv->manager); iter; iter = iter->next) {
- NMDevice *device = NM_DEVICE (iter->data);
+ all_devices = nm_manager_get_devices (priv->manager);
+ c_list_for_each_entry (device, all_devices, devices_lst) {
NMDeviceState state;
const NMPObject *r;
NMConnection *connection;
@@ -461,15 +462,16 @@ static gboolean
all_devices_not_active (NMPolicy *self)
{
NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self);
- const GSList *iter = nm_manager_get_devices (priv->manager);
+ const CList *all_devices;
+ NMDevice *device;
- while (iter != NULL) {
+ all_devices = nm_manager_get_devices (priv->manager);
+ c_list_for_each_entry (device, all_devices, devices_lst) {
NMDeviceState state;
- state = nm_device_get_state (NM_DEVICE (iter->data));
+ state = nm_device_get_state (device);
if ( state <= NM_DEVICE_STATE_DISCONNECTED
|| state >= NM_DEVICE_STATE_DEACTIVATING) {
- iter = g_slist_next (iter);
continue;
}
return FALSE;
@@ -2184,12 +2186,14 @@ schedule_activate_all_cb (gpointer user_data)
{
NMPolicy *self = user_data;
NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self);
- const GSList *iter;
+ const CList *all_devices;
+ NMDevice *device;
priv->schedule_activate_all_id = 0;
- for (iter = nm_manager_get_devices (priv->manager); iter; iter = g_slist_next (iter))
- schedule_activate_check (self, iter->data);
+ all_devices = nm_manager_get_devices (priv->manager);
+ c_list_for_each_entry (device, all_devices, devices_lst)
+ schedule_activate_check (self, device);
return G_SOURCE_REMOVE;
}
@@ -2223,7 +2227,8 @@ firewall_state_changed (NMFirewallManager *manager,
{
NMPolicy *self = (NMPolicy *) user_data;
NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self);
- const GSList *iter;
+ const CList *all_devices;
+ NMDevice *device;
if (initialized_now) {
/* the firewall manager was initializing, but all requests
@@ -2236,8 +2241,9 @@ firewall_state_changed (NMFirewallManager *manager,
return;
/* add interface of each device to correct zone */
- for (iter = nm_manager_get_devices (priv->manager); iter; iter = g_slist_next (iter))
- nm_device_update_firewall_zone (iter->data);
+ all_devices = nm_manager_get_devices (priv->manager);
+ c_list_for_each_entry (device, all_devices, devices_lst)
+ nm_device_update_firewall_zone (device);
}
static void
@@ -2282,14 +2288,14 @@ connection_updated (NMSettings *settings,
{
NMPolicyPrivate *priv = user_data;
NMPolicy *self = _PRIV_TO_SELF (priv);
- const GSList *iter;
+ const CList *all_devices;
NMDevice *device = NULL;
+ NMDevice *dev;
if (by_user) {
/* find device with given connection */
- for (iter = nm_manager_get_devices (priv->manager); iter; iter = g_slist_next (iter)) {
- NMDevice *dev = NM_DEVICE (iter->data);
-
+ all_devices = nm_manager_get_devices (priv->manager);
+ c_list_for_each_entry (dev, all_devices, devices_lst) {
if (nm_device_get_settings_connection (dev) == connection) {
device = dev;
break;
diff --git a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c
index 1484dd43c8..3c97a43e6f 100644
--- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c
+++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c
@@ -148,16 +148,7 @@ write_secrets (shvarFile *ifcfg,
/* we purge all existing secrets. */
svUnsetAll (keyfile, SV_KEY_TYPE_ANY);
- /* sort the keys. */
- secrets_keys = (const char **) g_hash_table_get_keys_as_array (secrets, &secrets_keys_n);
- if (secrets_keys_n > 1) {
- g_qsort_with_data (secrets_keys,
- secrets_keys_n,
- sizeof (const char *),
- nm_strcmp_p_with_data,
- NULL);
- }
-
+ secrets_keys = nm_utils_strdict_get_keys (secrets, TRUE, &secrets_keys_n);
for (i = 0; i < secrets_keys_n; i++) {
const char *k = secrets_keys[i];
const char *v = g_hash_table_lookup (secrets, k);
diff --git a/src/tests/config/test-config.c b/src/tests/config/test-config.c
index 8398841d39..a6b886ce43 100644
--- a/src/tests/config/test-config.c
+++ b/src/tests/config/test-config.c
@@ -254,7 +254,7 @@ test_config_global_dns (void)
NMConfig *config;
const NMGlobalDnsConfig *dns;
NMGlobalDnsDomain *domain;
- const char *const *strv;
+ const char *const*strv;
config = setup_config (NULL, SRCDIR "/NetworkManager.conf", "", NULL,
"/no/such/dir", "", NULL);