summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2019-09-21 14:59:59 +0200
committerThomas Haller <thaller@redhat.com>2019-09-21 14:59:59 +0200
commitbf8118b8290d498f71068d9b77628cf7cb668400 (patch)
tree0d6bd7ab84d6777ba291fdcd4ebbcd8b4d195624
parente1cda0150ca9f78b19967542234227cbf1853b18 (diff)
parent30ce0079a8ab4570914531572e761bb691a9cf4a (diff)
downloadNetworkManager-bf8118b8290d498f71068d9b77628cf7cb668400.tar.gz
libnm: merge branch 'th/libnm-dbus-rework-1'
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/merge_requests/258
-rw-r--r--Makefile.am2
-rw-r--r--libnm/nm-dbus-helpers.c57
-rw-r--r--libnm/nm-dbus-helpers.h11
-rw-r--r--libnm/nm-device.c5
-rw-r--r--libnm/nm-manager.c34
-rw-r--r--libnm/nm-secret-agent-old.c28
-rw-r--r--shared/meson.build1
-rw-r--r--shared/nm-glib-aux/nm-macros-internal.h14
-rw-r--r--shared/nm-glib-aux/nm-ref-string.c187
-rw-r--r--shared/nm-glib-aux/nm-ref-string.h52
10 files changed, 275 insertions, 116 deletions
diff --git a/Makefile.am b/Makefile.am
index f863b29f34..48e0cd55df 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -373,6 +373,8 @@ shared_nm_glib_aux_libnm_glib_aux_la_SOURCES = \
shared/nm-glib-aux/nm-obj.h \
shared/nm-glib-aux/nm-random-utils.c \
shared/nm-glib-aux/nm-random-utils.h \
+ shared/nm-glib-aux/nm-ref-string.c \
+ shared/nm-glib-aux/nm-ref-string.h \
shared/nm-glib-aux/nm-secret-utils.c \
shared/nm-glib-aux/nm-secret-utils.h \
shared/nm-glib-aux/nm-shared-utils.c \
diff --git a/libnm/nm-dbus-helpers.c b/libnm/nm-dbus-helpers.c
index 84312d2c31..978d5e2a82 100644
--- a/libnm/nm-dbus-helpers.c
+++ b/libnm/nm-dbus-helpers.c
@@ -26,63 +26,6 @@ _nm_dbus_bus_type (void)
return nm_bus;
}
-GDBusConnection *
-_nm_dbus_new_connection (GCancellable *cancellable, GError **error)
-{
- return g_bus_get_sync (_nm_dbus_bus_type (), cancellable, error);
-}
-
-static void
-new_connection_async_got_system (GObject *source, GAsyncResult *result, gpointer user_data)
-{
- GSimpleAsyncResult *simple = user_data;
- GDBusConnection *connection;
- GError *error = NULL;
-
- connection = g_bus_get_finish (result, &error);
- if (connection)
- g_simple_async_result_set_op_res_gpointer (simple, connection, g_object_unref);
- else
- g_simple_async_result_take_error (simple, error);
-
- g_simple_async_result_complete (simple);
- g_object_unref (simple);
-}
-
-void
-_nm_dbus_new_connection_async (GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- GSimpleAsyncResult *simple;
-
- simple = g_simple_async_result_new (NULL, callback, user_data, _nm_dbus_new_connection_async);
- if (cancellable)
- g_simple_async_result_set_check_cancellable (simple, cancellable);
-
- g_bus_get (_nm_dbus_bus_type (),
- cancellable,
- new_connection_async_got_system, simple);
-}
-
-GDBusConnection *
-_nm_dbus_new_connection_finish (GAsyncResult *result,
- GError **error)
-{
- GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
-
- if (g_simple_async_result_propagate_error (simple, error))
- return NULL;
-
- return g_object_ref (g_simple_async_result_get_op_res_gpointer (simple));
-}
-
-gboolean
-_nm_dbus_is_connection_private (GDBusConnection *connection)
-{
- return g_dbus_connection_get_unique_name (connection) == NULL;
-}
-
/* D-Bus has an upper limit on number of Match rules and it's rather easy
* to hit as the proxy likes to add one for each object. Let's remove the Match
* rule the proxy added and ensure a less granular rule is present instead.
diff --git a/libnm/nm-dbus-helpers.h b/libnm/nm-dbus-helpers.h
index 381f35f68d..42e67e1c65 100644
--- a/libnm/nm-dbus-helpers.h
+++ b/libnm/nm-dbus-helpers.h
@@ -14,17 +14,6 @@
GBusType _nm_dbus_bus_type (void);
-GDBusConnection *_nm_dbus_new_connection (GCancellable *cancellable,
- GError **error);
-
-void _nm_dbus_new_connection_async (GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data);
-GDBusConnection *_nm_dbus_new_connection_finish (GAsyncResult *result,
- GError **error);
-
-gboolean _nm_dbus_is_connection_private (GDBusConnection *connection);
-
void _nm_dbus_proxy_replace_match (GDBusProxy *proxy);
void _nm_dbus_bind_properties (gpointer object,
diff --git a/libnm/nm-device.c b/libnm/nm-device.c
index 49a929fa85..f6663fbd23 100644
--- a/libnm/nm-device.c
+++ b/libnm/nm-device.c
@@ -444,11 +444,6 @@ set_property (GObject *object,
gboolean b;
switch (prop_id) {
- case PROP_MANAGED:
- b = g_value_get_boolean (value);
- if (priv->managed != b)
- nm_device_set_managed (NM_DEVICE (object), b);
- break;
case PROP_AUTOCONNECT:
b = g_value_get_boolean (value);
if (priv->autoconnect != b)
diff --git a/libnm/nm-manager.c b/libnm/nm-manager.c
index b4111cd040..00ecdccbef 100644
--- a/libnm/nm-manager.c
+++ b/libnm/nm-manager.c
@@ -369,26 +369,6 @@ update_permissions (NMManager *self, GVariant *permissions)
g_list_free (keys);
}
-static gboolean
-get_permissions_sync (NMManager *self, GError **error)
-{
- NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
- GVariant *permissions;
-
- if (nmdbus_manager_call_get_permissions_sync (priv->proxy,
- &permissions,
- NULL, error)) {
- update_permissions (self, permissions);
- g_variant_unref (permissions);
- return TRUE;
- } else {
- if (error && *error)
- g_dbus_error_strip_remote_error (*error);
- update_permissions (self, NULL);
- return FALSE;
- }
-}
-
static void
get_permissions_reply (GObject *object,
GAsyncResult *result,
@@ -1756,19 +1736,25 @@ constructed (GObject *object)
static gboolean
init_sync (GInitable *initable, GCancellable *cancellable, GError **error)
{
- NMManager *manager = NM_MANAGER (initable);
- GError *local_error = NULL;
+ NMManager *self = NM_MANAGER (initable);
+ NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
+ gs_free_error GError *local_error = NULL;
+ gs_unref_variant GVariant *permissions = NULL;
if (!nm_manager_parent_initable_iface->init (initable, cancellable, error)) {
/* Never happens. */
g_return_val_if_reached (FALSE);
}
- if (!get_permissions_sync (manager, &local_error)) {
+ if (!nmdbus_manager_call_get_permissions_sync (priv->proxy,
+ &permissions,
+ NULL,
+ &local_error)) {
+ g_dbus_error_strip_remote_error (local_error);
g_warning ("Unable to get permissions: %s\n", local_error->message);
- g_error_free (local_error);
}
+ update_permissions (self, permissions);
return TRUE;
}
diff --git a/libnm/nm-secret-agent-old.c b/libnm/nm-secret-agent-old.c
index 39742c0ea1..3c08987a97 100644
--- a/libnm/nm-secret-agent-old.c
+++ b/libnm/nm-secret-agent-old.c
@@ -47,7 +47,6 @@ typedef struct {
bool registered:1;
bool registering:1;
- bool private_bus:1;
bool session_bus:1;
bool auto_register:1;
bool suppress_auto:1;
@@ -141,12 +140,6 @@ verify_sender (NMSecretAgentOld *self,
g_return_val_if_fail (context != NULL, FALSE);
- /* Private bus connection is always to NetworkManager, which is always
- * UID 0.
- */
- if (priv->private_bus)
- return TRUE;
-
/* Verify that the sender is the same as NetworkManager's bus name owner. */
owner = g_dbus_proxy_get_name_owner (G_DBUS_PROXY (priv->manager_proxy));
@@ -451,8 +444,6 @@ check_nm_running (NMSecretAgentOld *self, GError **error)
NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self);
gs_free char *owner = NULL;
- if (priv->private_bus)
- return TRUE;
owner = g_dbus_proxy_get_name_owner (G_DBUS_PROXY (priv->manager_proxy));
if (owner)
return TRUE;
@@ -981,14 +972,10 @@ init_common (NMSecretAgentOld *self)
{
NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self);
- priv->private_bus = _nm_dbus_is_connection_private (priv->bus);
-
- if (priv->private_bus == FALSE) {
- priv->session_bus = _nm_dbus_bus_type () == G_BUS_TYPE_SESSION;
+ priv->session_bus = _nm_dbus_bus_type () == G_BUS_TYPE_SESSION;
- g_signal_connect (priv->manager_proxy, "notify::g-name-owner",
- G_CALLBACK (name_owner_changed), self);
- }
+ g_signal_connect (priv->manager_proxy, "notify::g-name-owner",
+ G_CALLBACK (name_owner_changed), self);
}
typedef struct {
@@ -1052,7 +1039,7 @@ init_async_got_bus (GObject *initable, GAsyncResult *result, gpointer user_data)
NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (init_data->self);
GError *error = NULL;
- priv->bus = _nm_dbus_new_connection_finish (result, &error);
+ priv->bus = g_bus_get_finish (result, &error);
if (!priv->bus) {
init_async_complete (init_data, error);
return;
@@ -1150,7 +1137,7 @@ init_sync (GInitable *initable, GCancellable *cancellable, GError **error)
NMSecretAgentOld *self = NM_SECRET_AGENT_OLD (initable);
NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self);
- priv->bus = _nm_dbus_new_connection (cancellable, error);
+ priv->bus = g_bus_get_sync (_nm_dbus_bus_type (), cancellable, error);
if (!priv->bus)
return FALSE;
@@ -1193,7 +1180,10 @@ init_async (GAsyncInitable *initable, int io_priority,
if (cancellable)
g_simple_async_result_set_check_cancellable (init_data->simple, cancellable);
- _nm_dbus_new_connection_async (cancellable, init_async_got_bus, init_data);
+ g_bus_get (_nm_dbus_bus_type (),
+ cancellable,
+ init_async_got_bus,
+ init_data);
}
static gboolean
diff --git a/shared/meson.build b/shared/meson.build
index d542804eb4..aa10f792f8 100644
--- a/shared/meson.build
+++ b/shared/meson.build
@@ -185,6 +185,7 @@ shared_nm_glib_aux = static_library(
'nm-glib-aux/nm-json-aux.c',
'nm-glib-aux/nm-keyfile-aux.c',
'nm-glib-aux/nm-random-utils.c',
+ 'nm-glib-aux/nm-ref-string.c',
'nm-glib-aux/nm-secret-utils.c',
'nm-glib-aux/nm-shared-utils.c',
'nm-glib-aux/nm-time-utils.c'),
diff --git a/shared/nm-glib-aux/nm-macros-internal.h b/shared/nm-glib-aux/nm-macros-internal.h
index 619625942b..5c3b06717e 100644
--- a/shared/nm-glib-aux/nm-macros-internal.h
+++ b/shared/nm-glib-aux/nm-macros-internal.h
@@ -1975,4 +1975,18 @@ nm_close (int fd)
#define NM_PID_T_INVAL ((pid_t) -1)
+/*****************************************************************************/
+
+NM_AUTO_DEFINE_FCN_VOID0 (GMutex *, _nm_auto_unlock_g_mutex, g_mutex_unlock)
+
+#define nm_auto_unlock_g_mutex nm_auto (_nm_auto_unlock_g_mutex)
+
+#define _NM_G_MUTEX_LOCKED(lock, uniq) \
+ nm_auto_unlock_g_mutex GMutex *NM_UNIQ_T(nm_lock, uniq) = (lock)
+
+#define NM_G_MUTEX_LOCKED(lock) \
+ _NM_G_MUTEX_LOCKED (lock, NM_UNIQ)
+
+/*****************************************************************************/
+
#endif /* __NM_MACROS_INTERNAL_H__ */
diff --git a/shared/nm-glib-aux/nm-ref-string.c b/shared/nm-glib-aux/nm-ref-string.c
new file mode 100644
index 0000000000..6259758c9e
--- /dev/null
+++ b/shared/nm-glib-aux/nm-ref-string.c
@@ -0,0 +1,187 @@
+// SPDX-License-Identifier: LGPL-2.1+
+
+#include "nm-default.h"
+
+#include "nm-ref-string.h"
+
+/*****************************************************************************/
+
+typedef struct {
+ NMRefString r;
+ volatile int ref_count;
+ char str_data[];
+} RefString;
+
+G_LOCK_DEFINE_STATIC (gl_lock);
+static GHashTable *gl_hash;
+
+/* the first field of NMRefString is a pointer to the NUL terminated string.
+ * This also allows to compare strings with nm_pstr_equal(), although, pointer
+ * equality might be better. */
+G_STATIC_ASSERT (G_STRUCT_OFFSET (NMRefString, str) == 0);
+G_STATIC_ASSERT (G_STRUCT_OFFSET (RefString, r) == 0);
+G_STATIC_ASSERT (G_STRUCT_OFFSET (RefString, r.str) == 0);
+
+/*****************************************************************************/
+
+static guint
+_ref_string_hash (gconstpointer ptr)
+{
+ const RefString *a = ptr;
+ NMHashState h;
+
+ nm_hash_init (&h, 1463435489u);
+ nm_hash_update (&h, a->r.str, a->r.len);
+ return nm_hash_complete (&h);
+}
+
+static gboolean
+_ref_string_equal (gconstpointer pa, gconstpointer pb)
+{
+ const RefString *a = pa;
+ const RefString *b = pb;
+
+ return a->r.len == b->r.len
+ && memcmp (a->r.str, b->r.str, a->r.len) == 0;
+}
+
+/*****************************************************************************/
+
+static void
+_ASSERT (const RefString *rstr0)
+{
+ int r;
+
+ nm_assert (rstr0);
+
+ G_LOCK (gl_lock);
+ r = g_atomic_int_get (&rstr0->ref_count);
+
+ nm_assert (r > 0);
+ nm_assert (r < G_MAXINT);
+
+ nm_assert (rstr0 == g_hash_table_lookup (gl_hash, rstr0));
+ G_UNLOCK (gl_lock);
+}
+
+/**
+ * nm_ref_string_new_len:
+ * @cstr: the string to intern. Must contain @len bytes.
+ * If @len is zero, @cstr may be %NULL. Note that it is
+ * accetable that the string contains a NUL character
+ * within the first @len bytes. That is, the string is
+ * not treated as a NUL terminated string, but as binary.
+ * Also, contrary to strncpy(), this will read all the
+ * first @len bytes. It won't stop at the first NUL.
+ * @len: the length of the string (usually there is no NUL character
+ * within the first @len bytes, but that would be acceptable as well
+ * to add binary data).
+ *
+ * Note that the resulting NMRefString instance will always be NUL terminated
+ * (at position @len).
+ *
+ * Note that NMRefString are always interned/deduplicated. If such a string
+ * already exists, the existing instance will be refered and returned.
+ *
+ *
+ * Since all NMRefString are shared and interned, you may use
+ * pointer equality to compare them. Note that if a NMRefString contains
+ * a NUL character (meaning, if
+ *
+ * strlen (nm_ref_string_get_str (str)) != nm_ref_string_get_len (str)
+ *
+ * ), then pointer in-equality does not mean that the NUL terminated strings
+ * are also unequal. In other words, for strings that contain NUL characters,
+ *
+ * if (str1 != str2)
+ * assert (!nm_streq0 (nm_ref_string_get_str (str1), nm_ref_string_get_str (str2)));
+ *
+ * might not hold!
+ *
+ *
+ * NMRefString is thread-safe.
+ *
+ * Returns: (transfer full): the interned string. This is
+ * never %NULL, but note that %NULL is also a valid NMRefString.
+ * The result must be unrefed with nm_ref_string_unref().
+ */
+NMRefString *
+nm_ref_string_new_len (const char *cstr, gsize len)
+{
+ RefString *rstr0;
+
+ G_LOCK (gl_lock);
+
+ if (G_UNLIKELY (!gl_hash)) {
+ gl_hash = g_hash_table_new_full (_ref_string_hash, _ref_string_equal, g_free, NULL);
+ rstr0 = NULL;
+ } else {
+ NMRefString rr_lookup = {
+ .len = len,
+ .str = cstr,
+ };
+
+ rstr0 = g_hash_table_lookup (gl_hash, &rr_lookup);
+ }
+
+ if (rstr0) {
+ nm_assert (({
+ int r = g_atomic_int_get (&rstr0->ref_count);
+
+ (r >= 0 && r < G_MAXINT);
+ }));
+ g_atomic_int_inc (&rstr0->ref_count);
+ } else {
+ rstr0 = g_malloc (sizeof (RefString) + 1 + len);
+ rstr0->ref_count = 1;
+ *((gsize *) rstr0->r.len) = len;
+ *((const char **) rstr0->r.str) = rstr0->str_data;
+ if (len > 0)
+ memcpy (rstr0->str_data, cstr, len);
+ rstr0->str_data[len] = '\0';
+
+ if (!g_hash_table_add (gl_hash, rstr0))
+ nm_assert_not_reached ();
+ }
+
+ G_UNLOCK (gl_lock);
+
+ return &rstr0->r;
+}
+
+NMRefString *
+nm_ref_string_ref (NMRefString *rstr)
+{
+ RefString *const rstr0 = (RefString *) rstr;
+
+ if (!rstr)
+ return NULL;
+
+ _ASSERT (rstr0);
+
+ g_atomic_int_inc (&rstr0->ref_count);
+ return &rstr0->r;
+}
+
+void
+_nm_ref_string_unref_non_null (NMRefString *rstr)
+{
+ RefString *const rstr0 = (RefString *) rstr;
+
+ _ASSERT (rstr0);
+
+ if (G_LIKELY (!g_atomic_int_dec_and_test (&rstr0->ref_count)))
+ return;
+
+ G_LOCK (gl_lock);
+
+ /* in the fast-path above, we already decremented the ref-count to zero.
+ * We need recheck that the ref-count is still zero. */
+
+ if (g_atomic_int_get (&rstr0->ref_count) == 0)
+ g_hash_table_remove (gl_hash, rstr0);
+
+ G_UNLOCK (gl_lock);
+}
+
+/*****************************************************************************/
diff --git a/shared/nm-glib-aux/nm-ref-string.h b/shared/nm-glib-aux/nm-ref-string.h
new file mode 100644
index 0000000000..2a0b072df8
--- /dev/null
+++ b/shared/nm-glib-aux/nm-ref-string.h
@@ -0,0 +1,52 @@
+// SPDX-License-Identifier: LGPL-2.1+
+
+#ifndef __NM_REF_STRING_H__
+#define __NM_REF_STRING_H__
+
+/*****************************************************************************/
+
+typedef struct {
+ const char *const str;
+ const gsize len;
+} NMRefString;
+
+/*****************************************************************************/
+
+NMRefString *nm_ref_string_new_len (const char *cstr, gsize len);
+
+static inline NMRefString *
+nm_ref_string_new (const char *cstr)
+{
+ return cstr
+ ? nm_ref_string_new_len (cstr, strlen (cstr))
+ : NULL;
+}
+
+NMRefString *nm_ref_string_ref (NMRefString *rstr);
+void _nm_ref_string_unref_non_null (NMRefString *rstr);
+
+static inline void
+nm_ref_string_unref (NMRefString *rstr)
+{
+ if (rstr)
+ _nm_ref_string_unref_non_null (rstr);
+}
+
+NM_AUTO_DEFINE_FCN_VOID0 (NMRefString *, _nm_auto_ref_string, _nm_ref_string_unref_non_null)
+#define nm_auto_ref_string nm_auto(_nm_auto_ref_string)
+
+/*****************************************************************************/
+
+static inline const char *
+nm_ref_string_get_str (NMRefString *rstr)
+{
+ return rstr ? rstr->str : NULL;
+}
+
+static inline gsize
+nm_ref_string_get_len (NMRefString *rstr)
+{
+ return rstr ? rstr->len : 0u;
+}
+
+#endif /* __NM_REF_STRING_H__ */