platform: merge branch 'th/platform-no-sync-socket-bgo759490'
https://bugzilla.gnome.org/show_bug.cgi?id=759490
This commit is contained in:
@@ -34,46 +34,57 @@ struct NMMultiIndex {
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
GHashTable *index;
|
||||
/* when storing the first item for a multi-index id, we don't yet create
|
||||
* the hashtable @index. Instead we store it inplace to @value0. Note that
|
||||
* &values_data->value0 is a NULL terminated array with one item that is
|
||||
* suitable to be returned directly from nm_multi_index_lookup(). */
|
||||
union {
|
||||
gpointer value0;
|
||||
gpointer *values;
|
||||
};
|
||||
GHashTable *index;
|
||||
} ValuesData;
|
||||
|
||||
/******************************************************************************************/
|
||||
|
||||
static ValuesData *
|
||||
_values_data_create (void)
|
||||
{
|
||||
ValuesData *values_data;
|
||||
|
||||
values_data = g_slice_new (ValuesData);
|
||||
values_data->index = g_hash_table_new (NULL, NULL);
|
||||
values_data->values = NULL;
|
||||
return values_data;
|
||||
}
|
||||
|
||||
static void
|
||||
_values_data_destroy (ValuesData *values_data)
|
||||
{
|
||||
if (values_data) {
|
||||
if (values_data->index) {
|
||||
g_free (values_data->values);
|
||||
g_hash_table_unref (values_data->index);
|
||||
}
|
||||
g_slice_free (ValuesData, values_data);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_values_data_contains (ValuesData *values_data, gconstpointer value)
|
||||
{
|
||||
return values_data->index
|
||||
? g_hash_table_contains (values_data->index, value)
|
||||
: value == values_data->value0;
|
||||
}
|
||||
|
||||
static void
|
||||
_values_data_populate_array (ValuesData *values_data)
|
||||
_values_data_get_data (ValuesData *values_data,
|
||||
void *const**out_data,
|
||||
guint *out_len)
|
||||
{
|
||||
guint i, len;
|
||||
gpointer *values;
|
||||
GHashTableIter iter;
|
||||
|
||||
nm_assert (values_data);
|
||||
|
||||
if (!values_data->index) {
|
||||
NM_SET_OUT (out_data, &values_data->value0);
|
||||
NM_SET_OUT (out_len, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
nm_assert (values_data->index && g_hash_table_size (values_data->index) > 0);
|
||||
|
||||
if (values_data->values)
|
||||
return;
|
||||
|
||||
if (!values_data->values) {
|
||||
len = g_hash_table_size (values_data->index);
|
||||
values = g_new (gpointer, len + 1);
|
||||
|
||||
@@ -84,6 +95,11 @@ _values_data_populate_array (ValuesData *values_data)
|
||||
values[i] = NULL;
|
||||
|
||||
values_data->values = values;
|
||||
NM_SET_OUT (out_len, len);
|
||||
} else if (out_len)
|
||||
NM_SET_OUT (out_len, g_hash_table_size (values_data->index));
|
||||
|
||||
NM_SET_OUT (out_data, values_data->values);
|
||||
}
|
||||
|
||||
/******************************************************************************************/
|
||||
@@ -104,6 +120,7 @@ nm_multi_index_lookup (const NMMultiIndex *index,
|
||||
guint *out_len)
|
||||
{
|
||||
ValuesData *values_data;
|
||||
void *const*values;
|
||||
|
||||
g_return_val_if_fail (index, NULL);
|
||||
g_return_val_if_fail (id, NULL);
|
||||
@@ -114,10 +131,8 @@ nm_multi_index_lookup (const NMMultiIndex *index,
|
||||
*out_len = 0;
|
||||
return NULL;
|
||||
}
|
||||
_values_data_populate_array (values_data);
|
||||
if (out_len)
|
||||
*out_len = g_hash_table_size (values_data->index);
|
||||
return values_data->values;
|
||||
_values_data_get_data (values_data, &values, out_len);
|
||||
return values;
|
||||
}
|
||||
|
||||
gboolean
|
||||
@@ -132,8 +147,7 @@ nm_multi_index_contains (const NMMultiIndex *index,
|
||||
g_return_val_if_fail (value, FALSE);
|
||||
|
||||
values_data = g_hash_table_lookup (index->hash, id);
|
||||
return values_data
|
||||
&& g_hash_table_contains (values_data->index, value);
|
||||
return values_data && _values_data_contains (values_data, value);
|
||||
}
|
||||
|
||||
const NMMultiIndexId *
|
||||
@@ -157,7 +171,7 @@ nm_multi_index_lookup_first_by_value (const NMMultiIndex *index,
|
||||
|
||||
g_hash_table_iter_init (&iter, index->hash);
|
||||
while (g_hash_table_iter_next (&iter, (gpointer *) &id, (gpointer *) &values_data)) {
|
||||
if (g_hash_table_contains (values_data->index, value))
|
||||
if (_values_data_contains (values_data, value))
|
||||
return id;
|
||||
}
|
||||
return NULL;
|
||||
@@ -172,18 +186,19 @@ nm_multi_index_foreach (const NMMultiIndex *index,
|
||||
GHashTableIter iter;
|
||||
const NMMultiIndexId *id;
|
||||
ValuesData *values_data;
|
||||
guint len;
|
||||
void *const*values;
|
||||
|
||||
g_return_if_fail (index);
|
||||
g_return_if_fail (foreach_func);
|
||||
|
||||
g_hash_table_iter_init (&iter, index->hash);
|
||||
while (g_hash_table_iter_next (&iter, (gpointer *) &id, (gpointer *) &values_data)) {
|
||||
if ( value
|
||||
&& !g_hash_table_contains (values_data->index, value))
|
||||
if (value && !_values_data_contains (values_data, value))
|
||||
continue;
|
||||
|
||||
_values_data_populate_array (values_data);
|
||||
if (!foreach_func (id, values_data->values, g_hash_table_size (values_data->index), user_data))
|
||||
_values_data_get_data (values_data, &values, &len);
|
||||
if (!foreach_func (id, values, len, user_data))
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -214,14 +229,11 @@ nm_multi_index_iter_next (NMMultiIndexIter *iter,
|
||||
|
||||
while (g_hash_table_iter_next (&iter->_iter, (gpointer *) &id, (gpointer *) &values_data)) {
|
||||
if ( !iter->_value
|
||||
|| g_hash_table_contains (values_data->index, iter->_value)) {
|
||||
_values_data_populate_array (values_data);
|
||||
|| _values_data_contains (values_data, iter->_value)) {
|
||||
if (out_values || out_len)
|
||||
_values_data_get_data (values_data, out_values, out_len);
|
||||
if (out_id)
|
||||
*out_id = id;
|
||||
if (out_values)
|
||||
*out_values = values_data->values;
|
||||
if (out_len)
|
||||
*out_len = g_hash_table_size (values_data->index);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
@@ -243,10 +255,13 @@ nm_multi_index_id_iter_init (NMMultiIndexIdIter *iter,
|
||||
|
||||
values_data = g_hash_table_lookup (index->hash, id);
|
||||
if (!values_data)
|
||||
iter->_state = 2;
|
||||
else if (values_data->index) {
|
||||
iter->_state = 1;
|
||||
else {
|
||||
iter->_state = 0;
|
||||
g_hash_table_iter_init (&iter->_iter, values_data->index);
|
||||
} else {
|
||||
iter->_state = 0;
|
||||
iter->_value = values_data->value0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -255,13 +270,19 @@ nm_multi_index_id_iter_next (NMMultiIndexIdIter *iter,
|
||||
void **out_value)
|
||||
{
|
||||
g_return_val_if_fail (iter, FALSE);
|
||||
g_return_val_if_fail (iter->_state <= 1, FALSE);
|
||||
|
||||
if (iter->_state == 0)
|
||||
return g_hash_table_iter_next (&iter->_iter, out_value, NULL);
|
||||
else {
|
||||
switch (iter->_state) {
|
||||
case 0:
|
||||
iter->_state = 2;
|
||||
NM_SET_OUT (out_value, iter->_value);
|
||||
return TRUE;
|
||||
case 1:
|
||||
return g_hash_table_iter_next (&iter->_iter, out_value, NULL);
|
||||
case 2:
|
||||
iter->_state = 3;
|
||||
return FALSE;
|
||||
default:
|
||||
g_return_val_if_reached (FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -291,15 +312,24 @@ _do_add (NMMultiIndex *index,
|
||||
if (!id_new)
|
||||
g_return_val_if_reached (FALSE);
|
||||
|
||||
values_data = _values_data_create ();
|
||||
g_hash_table_replace (values_data->index, (gpointer) value, (gpointer) value);
|
||||
values_data = g_slice_new0 (ValuesData);
|
||||
values_data->value0 = (gpointer) value;
|
||||
|
||||
g_hash_table_insert (index->hash, id_new, values_data);
|
||||
} else {
|
||||
if (!values_data->index) {
|
||||
if (values_data->value0 == value)
|
||||
return FALSE;
|
||||
values_data->index = g_hash_table_new (NULL, NULL);
|
||||
g_hash_table_replace (values_data->index, (gpointer) value, (gpointer) value);
|
||||
g_hash_table_replace (values_data->index, values_data->value0, values_data->value0);
|
||||
values_data->values = NULL;
|
||||
} else {
|
||||
if (!nm_g_hash_table_replace (values_data->index, (gpointer) value, (gpointer) value))
|
||||
return FALSE;
|
||||
g_clear_pointer (&values_data->values, g_free);
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -314,13 +344,19 @@ _do_remove (NMMultiIndex *index,
|
||||
if (!values_data)
|
||||
return FALSE;
|
||||
|
||||
if (values_data->index) {
|
||||
if (!g_hash_table_remove (values_data->index, value))
|
||||
return FALSE;
|
||||
|
||||
if (g_hash_table_size (values_data->index) == 0)
|
||||
g_hash_table_remove (index->hash, id);
|
||||
else
|
||||
g_clear_pointer (&values_data->values, g_free);
|
||||
} else {
|
||||
if (values_data->value0 != value)
|
||||
return FALSE;
|
||||
g_hash_table_remove (index->hash, id);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@@ -39,7 +39,10 @@ typedef struct {
|
||||
} NMMultiIndexIter;
|
||||
|
||||
typedef struct {
|
||||
union {
|
||||
GHashTableIter _iter;
|
||||
gpointer _value;
|
||||
};
|
||||
guint _state;
|
||||
} NMMultiIndexIdIter;
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -1072,6 +1072,24 @@ nmp_cache_id_init_routes_visible (NMPCacheId *id,
|
||||
return id;
|
||||
}
|
||||
|
||||
NMPCacheId *
|
||||
nmp_cache_id_init_link_by_ifname (NMPCacheId *id,
|
||||
const char *ifname)
|
||||
{
|
||||
gsize l;
|
||||
|
||||
_nmp_cache_id_init (id, NMP_CACHE_ID_TYPE_LINK_BY_IFNAME);
|
||||
|
||||
if ( !ifname
|
||||
|| (l = strlen (ifname)) > sizeof (id->link_by_ifname.ifname_short))
|
||||
g_return_val_if_reached (id);
|
||||
|
||||
/* the trailing NUL is dropped!! */
|
||||
memcpy (id->link_by_ifname.ifname_short, ifname, l);
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
|
||||
static gboolean
|
||||
@@ -1095,6 +1113,23 @@ _nmp_object_init_cache_id (const NMPObject *obj, NMPCacheIdType id_type, NMPCach
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_vt_cmd_obj_init_cache_id_link (const NMPObject *obj, NMPCacheIdType id_type, NMPCacheId *id, const NMPCacheId **out_id)
|
||||
{
|
||||
switch (id_type) {
|
||||
case NMP_CACHE_ID_TYPE_LINK_BY_IFNAME:
|
||||
if (obj->link.name[0]) {
|
||||
*out_id = nmp_cache_id_init_link_by_ifname (id, obj->link.name);
|
||||
return TRUE;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
*out_id = NULL;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_vt_cmd_obj_init_cache_id_ipx_address (const NMPObject *obj, NMPCacheIdType id_type, NMPCacheId *id, const NMPCacheId **out_id)
|
||||
{
|
||||
@@ -1356,7 +1391,7 @@ nmp_cache_lookup_link_full (const NMPCache *cache,
|
||||
const NMPObject *obj;
|
||||
const NMPlatformObject *const *list;
|
||||
guint i, len;
|
||||
NMPCacheId cache_id;
|
||||
NMPCacheId cache_id, *p_cache_id;
|
||||
|
||||
if (ifindex > 0) {
|
||||
obj = nmp_cache_lookup_obj (cache, nmp_object_stackinit_id_link (&obj_needle, ifindex));
|
||||
@@ -1371,7 +1406,14 @@ nmp_cache_lookup_link_full (const NMPCache *cache,
|
||||
} else if (!ifname && !match_fn)
|
||||
return NULL;
|
||||
else {
|
||||
list = nmp_cache_lookup_multi (cache, nmp_cache_id_init_object_type (&cache_id, NMP_OBJECT_TYPE_LINK, visible_only), &len);
|
||||
if ( ifname
|
||||
&& strlen (ifname) <= sizeof (cache_id.link_by_ifname.ifname_short)) {
|
||||
p_cache_id = nmp_cache_id_init_link_by_ifname (&cache_id, ifname);
|
||||
ifname = NULL;
|
||||
} else
|
||||
p_cache_id = nmp_cache_id_init_object_type (&cache_id, NMP_OBJECT_TYPE_LINK, visible_only);
|
||||
|
||||
list = nmp_cache_lookup_multi (cache, p_cache_id, &len);
|
||||
for (i = 0; i < len; i++) {
|
||||
obj = NMP_OBJECT_UP_CAST (list[i]);
|
||||
|
||||
@@ -1933,6 +1975,7 @@ const NMPClass _nmp_classes[NMP_OBJECT_TYPE_MAX] = {
|
||||
.rtm_gettype = RTM_GETLINK,
|
||||
.signal_type_id = NM_PLATFORM_SIGNAL_ID_LINK,
|
||||
.signal_type = NM_PLATFORM_SIGNAL_LINK_CHANGED,
|
||||
.cmd_obj_init_cache_id = _vt_cmd_obj_init_cache_id_link,
|
||||
.cmd_obj_cmp = _vt_cmd_obj_cmp_link,
|
||||
.cmd_obj_copy = _vt_cmd_obj_copy_link,
|
||||
.cmd_obj_stackinit_id = _vt_cmd_obj_stackinit_id_link,
|
||||
|
@@ -64,6 +64,9 @@ typedef enum { /*< skip >*/
|
||||
/* all the objects of a certain type */
|
||||
NMP_CACHE_ID_TYPE_OBJECT_TYPE,
|
||||
|
||||
/* index for the link objects by ifname. */
|
||||
NMP_CACHE_ID_TYPE_LINK_BY_IFNAME,
|
||||
|
||||
/* all the visible objects of a certain type */
|
||||
NMP_CACHE_ID_TYPE_OBJECT_TYPE_VISIBLE_ONLY,
|
||||
|
||||
@@ -104,6 +107,11 @@ typedef struct {
|
||||
guint8 obj_type; /* NMPObjectType as guint8 */
|
||||
int ifindex;
|
||||
} object_type_by_ifindex;
|
||||
struct {
|
||||
/* NMP_CACHE_ID_TYPE_LINK_BY_IFNAME */
|
||||
guint8 _id_type;
|
||||
char ifname_short[IFNAMSIZ - 1]; /* don't include the trailing NUL so the struct fits in 4 bytes. */
|
||||
} link_by_ifname;
|
||||
};
|
||||
} NMPCacheId;
|
||||
|
||||
@@ -374,6 +382,7 @@ void nmp_cache_id_destroy (NMPCacheId *id);
|
||||
NMPCacheId *nmp_cache_id_init_object_type (NMPCacheId *id, NMPObjectType obj_type, gboolean visible_only);
|
||||
NMPCacheId *nmp_cache_id_init_addrroute_visible_by_ifindex (NMPCacheId *id, NMPObjectType obj_type, int ifindex);
|
||||
NMPCacheId *nmp_cache_id_init_routes_visible (NMPCacheId *id, NMPObjectType obj_type, gboolean with_default, gboolean with_non_default, int ifindex);
|
||||
NMPCacheId *nmp_cache_id_init_link_by_ifname (NMPCacheId *id, const char *ifname);
|
||||
|
||||
const NMPlatformObject *const *nmp_cache_lookup_multi (const NMPCache *cache, const NMPCacheId *cache_id, guint *out_len);
|
||||
GArray *nmp_cache_lookup_multi_to_array (const NMPCache *cache, NMPObjectType obj_type, const NMPCacheId *cache_id);
|
||||
|
@@ -32,16 +32,16 @@ test_bogus(void)
|
||||
g_assert (!nm_platform_link_get_type (NM_PLATFORM_GET, BOGUS_IFINDEX));
|
||||
g_assert (!nm_platform_link_get_type_name (NM_PLATFORM_GET, BOGUS_IFINDEX));
|
||||
|
||||
g_test_expect_message ("NetworkManager", G_LOG_LEVEL_WARNING, "*failure changing link: netlink error (No such device*");
|
||||
g_test_expect_message ("NetworkManager", G_LOG_LEVEL_WARNING, "*failure changing link: *");
|
||||
g_assert (!nm_platform_link_set_up (NM_PLATFORM_GET, BOGUS_IFINDEX, NULL));
|
||||
|
||||
g_test_expect_message ("NetworkManager", G_LOG_LEVEL_WARNING, "*failure changing link: netlink error (No such device*");
|
||||
g_test_expect_message ("NetworkManager", G_LOG_LEVEL_WARNING, "*failure changing link: *");
|
||||
g_assert (!nm_platform_link_set_down (NM_PLATFORM_GET, BOGUS_IFINDEX));
|
||||
|
||||
g_test_expect_message ("NetworkManager", G_LOG_LEVEL_WARNING, "*failure changing link: netlink error (No such device*");
|
||||
g_test_expect_message ("NetworkManager", G_LOG_LEVEL_WARNING, "*failure changing link: *");
|
||||
g_assert (!nm_platform_link_set_arp (NM_PLATFORM_GET, BOGUS_IFINDEX));
|
||||
|
||||
g_test_expect_message ("NetworkManager", G_LOG_LEVEL_WARNING, "*failure changing link: netlink error (No such device*");
|
||||
g_test_expect_message ("NetworkManager", G_LOG_LEVEL_WARNING, "*failure changing link: *");
|
||||
g_assert (!nm_platform_link_set_noarp (NM_PLATFORM_GET, BOGUS_IFINDEX));
|
||||
|
||||
g_assert (!nm_platform_link_is_up (NM_PLATFORM_GET, BOGUS_IFINDEX));
|
||||
@@ -52,7 +52,7 @@ test_bogus(void)
|
||||
g_assert (!addrlen);
|
||||
g_assert (!nm_platform_link_get_address (NM_PLATFORM_GET, BOGUS_IFINDEX, NULL));
|
||||
|
||||
g_test_expect_message ("NetworkManager", G_LOG_LEVEL_WARNING, "*failure changing link: netlink error (No such device*");
|
||||
g_test_expect_message ("NetworkManager", G_LOG_LEVEL_WARNING, "*failure changing link: *");
|
||||
g_assert (!nm_platform_link_set_mtu (NM_PLATFORM_GET, BOGUS_IFINDEX, MTU));
|
||||
|
||||
g_assert (!nm_platform_link_get_mtu (NM_PLATFORM_GET, BOGUS_IFINDEX));
|
||||
|
Reference in New Issue
Block a user