summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2016-09-23 15:48:40 +0200
committerThomas Haller <thaller@redhat.com>2016-09-23 15:50:43 +0200
commit0b48ad4e48c22ca4d392d5d64701df268ad5ed8e (patch)
treea97715e2cf1ab50fb57a1dc1707a0b037b38783e
parente59ed6451f0cd0a6f59a7448c89f97081b7ace1e (diff)
parente80b0a98c02509048c9caf62059d3cd2b51a9225 (diff)
downloadNetworkManager-0b48ad4e48c22ca4d392d5d64701df268ad5ed8e.tar.gz
capabilities: merge branch 'th/caps-rh1375967'
https://github.com/NetworkManager/NetworkManager/pull/9 https://bugzilla.redhat.com/show_bug.cgi?id=1375967
-rw-r--r--introspection/nm-manager.xml9
-rw-r--r--libnm-core/nm-core-internal.h5
-rw-r--r--libnm-core/nm-dbus-interface.h10
-rw-r--r--libnm-core/nm-utils.c40
-rw-r--r--libnm-core/tests/test-general.c50
-rw-r--r--libnm/libnm.ver4
-rw-r--r--shared/nm-utils/nm-macros-internal.h13
-rw-r--r--src/devices/team/Makefile.am2
-rw-r--r--src/devices/team/nm-team-factory.c2
-rw-r--r--src/nm-manager.c63
-rw-r--r--src/nm-manager.h2
-rw-r--r--src/nm-route-manager.c2
-rw-r--r--src/platform/nm-linux-platform.c8
13 files changed, 192 insertions, 18 deletions
diff --git a/introspection/nm-manager.xml b/introspection/nm-manager.xml
index cf178c3951..f3fb847831 100644
--- a/introspection/nm-manager.xml
+++ b/introspection/nm-manager.xml
@@ -381,6 +381,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:
The overall state of the NetworkManager daemon.
diff --git a/libnm-core/nm-core-internal.h b/libnm-core/nm-core-internal.h
index e491bce6da..471353e741 100644
--- a/libnm-core/nm-core-internal.h
+++ b/libnm-core/nm-core-internal.h
@@ -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);
diff --git a/libnm-core/nm-dbus-interface.h b/libnm-core/nm-dbus-interface.h
index e5b1b3d6b8..5e63cc069d 100644
--- a/libnm-core/nm-dbus-interface.h
+++ b/libnm-core/nm-dbus-interface.h
@@ -84,6 +84,16 @@
#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
* @NM_STATE_ASLEEP: networking is not enabled
diff --git a/libnm-core/nm-utils.c b/libnm-core/nm-utils.c
index df75d56557..818b0c43ec 100644
--- a/libnm-core/nm-utils.c
+++ b/libnm-core/nm-utils.c
@@ -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)
{
diff --git a/libnm-core/tests/test-general.c b/libnm-core/tests/test-general.c
index 5dfc897114..e71dd8bc56 100644
--- a/libnm-core/tests/test-general.c
+++ b/libnm-core/tests/test-general.c
@@ -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);
diff --git a/libnm/libnm.ver b/libnm/libnm.ver
index cc2fc7df62..6c149f6587 100644
--- a/libnm/libnm.ver
+++ b/libnm/libnm.ver
@@ -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;
diff --git a/shared/nm-utils/nm-macros-internal.h b/shared/nm-utils/nm-macros-internal.h
index 9e9f5d8f3c..003a9e974f 100644
--- a/shared/nm-utils/nm-macros-internal.h
+++ b/shared/nm-utils/nm-macros-internal.h
@@ -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. */
diff --git a/src/devices/team/Makefile.am b/src/devices/team/Makefile.am
index 00d824915d..f0ed8201be 100644
--- a/src/devices/team/Makefile.am
+++ b/src/devices/team/Makefile.am
@@ -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
-
diff --git a/src/devices/team/nm-team-factory.c b/src/devices/team/nm-team-factory.c
index 971efe8722..edb1329995 100644
--- a/src/devices/team/nm-team-factory.c
+++ b/src/devices/team/nm-team-factory.c
@@ -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);
}
diff --git a/src/nm-manager.c b/src/nm-manager.c
index 836ab76857..2335a731bf 100644
--- a/src/nm-manager.c
+++ b/src/nm-manager.c
@@ -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);
@@ -5863,6 +5907,16 @@ dispose (GObject *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)
{
GObjectClass *object_class = G_OBJECT_CLASS (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);
}
-
diff --git a/src/nm-manager.h b/src/nm-manager.h
index d7aabff16b..11c4eb4a18 100644
--- a/src/nm-manager.h
+++ b/src/nm-manager.h
@@ -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__ */
diff --git a/src/nm-route-manager.c b/src/nm-route-manager.c
index 2d4c7d9595..95113f8c84 100644
--- a/src/nm-route-manager.c
+++ b/src/nm-route-manager.c
@@ -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;
diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c
index c30eed9447..cedc220a75 100644
--- a/src/platform/nm-linux-platform.c
+++ b/src/platform/nm-linux-platform.c
@@ -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: