capabilities: merge branch 'th/caps-rh1375967'

https://github.com/NetworkManager/NetworkManager/pull/9
https://bugzilla.redhat.com/show_bug.cgi?id=1375967
This commit is contained in:
Thomas Haller 2016-09-23 15:48:40 +02:00
commit 0b48ad4e48
13 changed files with 192 additions and 18 deletions

View file

@ -380,6 +380,15 @@
-->
<property name="Version" type="s" access="read"/>
<!--
Capabilities:
The current set of capabilities. See <link
linkend="NMCapability">NMCapability</link> for currently
defined capability numbers.
-->
<property name="Capabilities" type="au" access="read"/>
<!--
State:

View file

@ -144,9 +144,10 @@ GPtrArray *_nm_utils_copy_array (const GPtrArray *array,
GDestroyNotify free_func);
GPtrArray *_nm_utils_copy_object_array (const GPtrArray *array);
gssize _nm_utils_ptrarray_find_first (gpointer *list, gssize len, gconstpointer needle);
gssize _nm_utils_ptrarray_find_first (gconstpointer *list, gssize len, gconstpointer needle);
gssize _nm_utils_ptrarray_find_binary_search (gpointer *list, gsize len, gpointer needle, GCompareDataFunc cmpfcn, gpointer user_data);
gssize _nm_utils_ptrarray_find_binary_search (gconstpointer *list, gsize len, gconstpointer needle, GCompareDataFunc cmpfcn, gpointer user_data);
gssize _nm_utils_array_find_binary_search (gconstpointer list, gsize elem_size, gsize len, gconstpointer needle, GCompareDataFunc cmpfcn, gpointer user_data);
gssize _nm_utils_strv_find_first (char **list, gssize len, const char *needle);

View file

@ -83,6 +83,16 @@
#define NM_DBUS_INTERFACE_SECRET_AGENT NM_DBUS_INTERFACE ".SecretAgent"
#define NM_DBUS_PATH_SECRET_AGENT "/org/freedesktop/NetworkManager/SecretAgent"
/**
* NMCapability:
* @NM_CAPABILITY_TEAM: Teams can be managed
*
* #NMCapability names the numbers in the Capabilities property.
**/
typedef enum {
NM_CAPABILITY_TEAM = 1,
} NMCapability;
/**
* NMState:
* @NM_STATE_UNKNOWN: networking state is unknown

View file

@ -667,10 +667,8 @@ _nm_utils_copy_object_array (const GPtrArray *array)
return _nm_utils_copy_array (array, g_object_ref, g_object_unref);
}
/* have @list of type 'gpointer *' instead of 'gconstpointer *' to
* reduce the necessity for annoying const-casts. */
gssize
_nm_utils_ptrarray_find_first (gpointer *list, gssize len, gconstpointer needle)
_nm_utils_ptrarray_find_first (gconstpointer *list, gssize len, gconstpointer needle)
{
gssize i;
@ -694,7 +692,7 @@ _nm_utils_ptrarray_find_first (gpointer *list, gssize len, gconstpointer needle)
}
gssize
_nm_utils_ptrarray_find_binary_search (gpointer *list, gsize len, gpointer needle, GCompareDataFunc cmpfcn, gpointer user_data)
_nm_utils_ptrarray_find_binary_search (gconstpointer *list, gsize len, gconstpointer needle, GCompareDataFunc cmpfcn, gpointer user_data)
{
gssize imin, imax, imid;
int cmp;
@ -726,6 +724,40 @@ _nm_utils_ptrarray_find_binary_search (gpointer *list, gsize len, gpointer needl
return ~imin;
}
gssize
_nm_utils_array_find_binary_search (gconstpointer list, gsize elem_size, gsize len, gconstpointer needle, GCompareDataFunc cmpfcn, gpointer user_data)
{
gssize imin, imax, imid;
int cmp;
g_return_val_if_fail (list || !len, ~((gssize) 0));
g_return_val_if_fail (cmpfcn, ~((gssize) 0));
g_return_val_if_fail (elem_size > 0, ~((gssize) 0));
imin = 0;
if (len == 0)
return ~imin;
imax = len - 1;
while (imin <= imax) {
imid = imin + (imax - imin) / 2;
cmp = cmpfcn (&((const char *) list)[elem_size * imid], needle, user_data);
if (cmp == 0)
return imid;
if (cmp < 0)
imin = imid + 1;
else
imax = imid - 1;
}
/* return the inverse of @imin. This is a negative number, but
* also is ~imin the position where the value should be inserted. */
return ~imin;
}
GVariant *
_nm_utils_bytes_to_dbus (const GValue *prop_value)
{

View file

@ -4960,9 +4960,9 @@ _test_find_binary_search_do (const int *array, gsize len)
{
gsize i;
gssize idx;
gs_free gpointer *parray = g_new (gpointer, len);
const int needle = 0;
gpointer pneedle = GINT_TO_POINTER (needle);
gs_free gconstpointer *parray = g_new (gconstpointer, len);
const int NEEDLE = 0;
gconstpointer pneedle = GINT_TO_POINTER (NEEDLE);
gssize expected_result;
for (i = 0; i < len; i++)
@ -5006,16 +5006,56 @@ _test_find_binary_search_do (const int *array, gsize len)
}
}
}
static void
_test_find_binary_search_do_uint32 (const int *int_array, gsize len)
{
gssize idx;
const int OFFSET = 100;
const int NEEDLE = 0 + OFFSET;
gssize expected_result = -1;
guint32 array[len];
/* the test data has negative values. Shift them... */
for (idx = 0; idx < len; idx++) {
int v = int_array[idx];
g_assert (v > -OFFSET);
g_assert (v < OFFSET);
g_assert (idx == 0 || v > int_array[idx - 1]);
array[idx] = (guint32) (int_array[idx] + OFFSET);
if (array[idx] == NEEDLE)
expected_result = idx;
}
idx = _nm_utils_array_find_binary_search (array,
sizeof (guint32),
len,
&NEEDLE,
nm_cmp_uint32_p_with_data,
NULL);
if (expected_result >= 0)
g_assert_cmpint (expected_result, ==, idx);
else {
gssize idx2 = ~idx;
g_assert_cmpint (idx, <, 0);
g_assert (idx2 >= 0);
g_assert (idx2 <= len);
g_assert (idx2 - 1 < 0 || array[idx2 - 1] < NEEDLE);
g_assert (idx2 >= len || array[idx2] > NEEDLE);
}
}
#define test_find_binary_search_do(...) \
G_STMT_START { \
const int _array[] = { __VA_ARGS__ } ; \
const int _array[] = { __VA_ARGS__ }; \
_test_find_binary_search_do (_array, G_N_ELEMENTS (_array)); \
_test_find_binary_search_do_uint32 (_array, G_N_ELEMENTS (_array)); \
} G_STMT_END
static void
test_nm_utils_ptrarray_find_binary_search (void)
{
#define _NOT(idx) (~ ((gssize) (idx)))
test_find_binary_search_do ( 0);
test_find_binary_search_do ( -1, 0);
test_find_binary_search_do ( -2, -1, 0);

View file

@ -1083,3 +1083,7 @@ global:
nm_vpn_plugin_info_new_search_file;
nm_vpn_plugin_info_supports_hints;
} libnm_1_2_0;
libnm_1_6_0 {
nm_capability_get_type;
} libnm_1_4_0;

View file

@ -516,6 +516,19 @@ nm_strcmp_p_with_data (gconstpointer a, gconstpointer b, gpointer user_data)
return strcmp (s1, s2);
}
static inline int
nm_cmp_uint32_p_with_data (gconstpointer p_a, gconstpointer p_b, gpointer user_data)
{
const guint32 a = *((const guint32 *) p_a);
const guint32 b = *((const guint32 *) p_b);
if (a < b)
return -1;
if (a > b)
return 1;
return 0;
}
/*****************************************************************************/
/* Taken from systemd's UNIQ_T and UNIQ macros. */

View file

@ -9,6 +9,7 @@ AM_CPPFLAGS = \
-I${top_builddir}/src \
-I${top_srcdir}/src/devices \
-I${top_srcdir}/src/platform \
-I${top_srcdir}/src/settings \
-I${top_builddir}/introspection \
-I${top_srcdir}/shared \
-I$(top_builddir)/shared \
@ -54,4 +55,3 @@ check-local:
$(call check_so_symbols,$(builddir)/.libs/libnm-device-plugin-team.so)
endif

View file

@ -23,6 +23,7 @@
#include <string.h>
#include <gmodule.h>
#include "nm-manager.h"
#include "nm-device-factory.h"
#include "nm-team-factory.h"
#include "nm-device-team.h"
@ -41,6 +42,7 @@ G_DEFINE_TYPE_EXTENDED (NMTeamFactory, nm_team_factory, G_TYPE_OBJECT, 0,
G_MODULE_EXPORT NMDeviceFactory *
nm_device_factory_create (GError **error)
{
nm_manager_set_capability (nm_manager_get (), NM_CAPABILITY_TEAM);
return (NMDeviceFactory *) g_object_new (NM_TYPE_TEAM_FACTORY, NULL);
}

View file

@ -100,6 +100,8 @@ typedef struct {
} RadioState;
typedef struct {
GArray *capabilities;
GSList *active_connections;
GSList *authorizing_connections;
guint ac_cleanup_id;
@ -180,6 +182,7 @@ static guint signals[LAST_SIGNAL] = { 0 };
NM_GOBJECT_PROPERTIES_DEFINE (NMManager,
PROP_VERSION,
PROP_CAPABILITIES,
PROP_STATE,
PROP_STARTUP,
PROP_NETWORKING_ENABLED,
@ -5439,6 +5442,39 @@ dbus_connection_changed_cb (NMBusManager *dbus_mgr,
/**********************************************************************/
void
nm_manager_set_capability (NMManager *self,
NMCapability cap)
{
NMManagerPrivate *priv;
guint32 cap_i;
gssize idx;
g_return_if_fail (NM_IS_MANAGER (self));
if (cap < 1 || cap > NM_CAPABILITY_TEAM)
g_return_if_reached ();
cap_i = (guint32) cap;
priv = NM_MANAGER_GET_PRIVATE (self);
idx = _nm_utils_array_find_binary_search (&g_array_index (priv->capabilities, guint32, 0),
sizeof (guint32),
priv->capabilities->len,
&cap_i,
nm_cmp_uint32_p_with_data,
NULL);
if (idx >= 0)
return;
nm_assert ((~idx) <= (gssize) priv->capabilities->len);
g_array_insert_val (priv->capabilities, ~idx, cap_i);
_notify (self, PROP_CAPABILITIES);
}
/**********************************************************************/
NM_DEFINE_SINGLETON_REGISTER (NMManager);
NMManager *
@ -5556,6 +5592,8 @@ nm_manager_init (NMManager *self)
guint i;
GFile *file;
priv->capabilities = g_array_new (FALSE, FALSE, sizeof (guint32));
/* Initialize rfkill structures and states */
memset (priv->radio_states, 0, sizeof (priv->radio_states));
@ -5643,6 +5681,12 @@ get_property (GObject *object, guint prop_id,
case PROP_VERSION:
g_value_set_string (value, VERSION);
break;
case PROP_CAPABILITIES:
g_value_set_variant (value, g_variant_new_fixed_array (G_VARIANT_TYPE ("u"),
priv->capabilities->data,
priv->capabilities->len,
sizeof (guint32)));
break;
case PROP_STATE:
nm_manager_update_state (self);
g_value_set_uint (value, priv->state);
@ -5862,6 +5906,16 @@ dispose (GObject *object)
G_OBJECT_CLASS (nm_manager_parent_class)->dispose (object);
}
static void
finalize (GObject *object)
{
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE ((NMManager *) object);
g_array_free (priv->capabilities, TRUE);
G_OBJECT_CLASS (nm_manager_parent_class)->finalize (object);
}
static void
nm_manager_class_init (NMManagerClass *manager_class)
{
@ -5875,6 +5929,7 @@ nm_manager_class_init (NMManagerClass *manager_class)
object_class->set_property = set_property;
object_class->get_property = get_property;
object_class->dispose = dispose;
object_class->finalize = finalize;
/* properties */
obj_properties[PROP_VERSION] =
@ -5883,6 +5938,13 @@ nm_manager_class_init (NMManagerClass *manager_class)
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS);
obj_properties[PROP_CAPABILITIES] =
g_param_spec_variant (NM_MANAGER_CAPABILITIES, "", "",
G_VARIANT_TYPE ("au"),
NULL,
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS);
obj_properties[PROP_STATE] =
g_param_spec_uint (NM_MANAGER_STATE, "", "",
0, NM_STATE_DISCONNECTED, 0,
@ -6120,4 +6182,3 @@ nm_manager_class_init (NMManagerClass *manager_class)
"CheckpointRollback", impl_manager_checkpoint_rollback,
NULL);
}

View file

@ -33,6 +33,7 @@
#define NM_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_MANAGER, NMManagerClass))
#define NM_MANAGER_VERSION "version"
#define NM_MANAGER_CAPABILITIES "capabilities"
#define NM_MANAGER_STATE "state"
#define NM_MANAGER_STARTUP "startup"
#define NM_MANAGER_NETWORKING_ENABLED "networking-enabled"
@ -111,5 +112,6 @@ gboolean nm_manager_deactivate_connection (NMManager *manager,
NMDeviceStateReason reason,
GError **error);
void nm_manager_set_capability (NMManager *self, NMCapability cap);
#endif /* __NETWORKMANAGER_MANAGER_H__ */

View file

@ -296,7 +296,7 @@ _route_index_find (const VTableIP *vtable, const RouteIndex *index, const NMPlat
{
gssize idx, idx2;
idx = _nm_utils_ptrarray_find_binary_search ((gpointer *) index->entries, index->len, (gpointer) needle, (GCompareDataFunc) _vx_route_id_cmp_full, (gpointer) vtable);
idx = _nm_utils_ptrarray_find_binary_search ((gconstpointer *) index->entries, index->len, needle, (GCompareDataFunc) _vx_route_id_cmp_full, (gpointer) vtable);
if (idx < 0)
return idx;

View file

@ -3028,7 +3028,7 @@ delayed_action_handle_one (NMPlatform *platform)
g_ptr_array_remove_index_fast (priv->delayed_action.list_master_connected, 0);
if (priv->delayed_action.list_master_connected->len == 0)
priv->delayed_action.flags &= ~DELAYED_ACTION_TYPE_MASTER_CONNECTED;
nm_assert (_nm_utils_ptrarray_find_first (priv->delayed_action.list_master_connected->pdata, priv->delayed_action.list_master_connected->len, user_data) < 0);
nm_assert (_nm_utils_ptrarray_find_first ((gconstpointer *) priv->delayed_action.list_master_connected->pdata, priv->delayed_action.list_master_connected->len, user_data) < 0);
_LOGt_delayed_action (DELAYED_ACTION_TYPE_MASTER_CONNECTED, user_data, "handle");
delayed_action_handle_MASTER_CONNECTED (platform, GPOINTER_TO_INT (user_data));
@ -3069,7 +3069,7 @@ delayed_action_handle_one (NMPlatform *platform)
g_ptr_array_remove_index_fast (priv->delayed_action.list_refresh_link, 0);
if (priv->delayed_action.list_refresh_link->len == 0)
priv->delayed_action.flags &= ~DELAYED_ACTION_TYPE_REFRESH_LINK;
nm_assert (_nm_utils_ptrarray_find_first (priv->delayed_action.list_refresh_link->pdata, priv->delayed_action.list_refresh_link->len, user_data) < 0);
nm_assert (_nm_utils_ptrarray_find_first ((gconstpointer *) priv->delayed_action.list_refresh_link->pdata, priv->delayed_action.list_refresh_link->len, user_data) < 0);
_LOGt_delayed_action (DELAYED_ACTION_TYPE_REFRESH_LINK, user_data, "handle");
@ -3118,11 +3118,11 @@ delayed_action_schedule (NMPlatform *platform, DelayedActionType action_type, gp
switch (action_type) {
case DELAYED_ACTION_TYPE_REFRESH_LINK:
if (_nm_utils_ptrarray_find_first (priv->delayed_action.list_refresh_link->pdata, priv->delayed_action.list_refresh_link->len, user_data) < 0)
if (_nm_utils_ptrarray_find_first ((gconstpointer *) priv->delayed_action.list_refresh_link->pdata, priv->delayed_action.list_refresh_link->len, user_data) < 0)
g_ptr_array_add (priv->delayed_action.list_refresh_link, user_data);
break;
case DELAYED_ACTION_TYPE_MASTER_CONNECTED:
if (_nm_utils_ptrarray_find_first (priv->delayed_action.list_master_connected->pdata, priv->delayed_action.list_master_connected->len, user_data) < 0)
if (_nm_utils_ptrarray_find_first ((gconstpointer *) priv->delayed_action.list_master_connected->pdata, priv->delayed_action.list_master_connected->len, user_data) < 0)
g_ptr_array_add (priv->delayed_action.list_master_connected, user_data);
break;
case DELAYED_ACTION_TYPE_WAIT_FOR_NL_RESPONSE: