mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-05-06 07:58:00 +02:00
libnm: merge branch 'th/bgo737725-libnm-private-dbus-connection'
https://bugzilla.gnome.org/show_bug.cgi?id=737725 Signed-off-by: Thomas Haller <thaller@redhat.com>
This commit is contained in:
commit
d4cd8b5785
4 changed files with 128 additions and 13 deletions
|
|
@ -41,6 +41,51 @@ _nm_dbus_bus_type (void)
|
||||||
return nm_bus;
|
return nm_bus;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct {
|
||||||
|
GMutex mutex;
|
||||||
|
GWeakRef weak_ref;
|
||||||
|
} private_connection;
|
||||||
|
|
||||||
|
static void
|
||||||
|
_private_dbus_connection_closed_cb (GDBusConnection *connection,
|
||||||
|
gboolean remote_peer_vanished,
|
||||||
|
GError *error,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
GDBusConnection *p;
|
||||||
|
|
||||||
|
g_mutex_lock (&private_connection.mutex);
|
||||||
|
p = g_weak_ref_get (&private_connection.weak_ref);
|
||||||
|
if (connection == p) {
|
||||||
|
g_signal_handlers_disconnect_by_func (G_OBJECT (connection), G_CALLBACK (_private_dbus_connection_closed_cb), NULL);
|
||||||
|
g_weak_ref_set (&private_connection.weak_ref, NULL);
|
||||||
|
}
|
||||||
|
if (p)
|
||||||
|
g_object_unref (p);
|
||||||
|
g_mutex_unlock (&private_connection.mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
static GDBusConnection *
|
||||||
|
_private_dbus_connection_internalize (GDBusConnection *connection)
|
||||||
|
{
|
||||||
|
GDBusConnection *p;
|
||||||
|
|
||||||
|
g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), NULL);
|
||||||
|
g_return_val_if_fail (!g_dbus_connection_is_closed (connection), NULL);
|
||||||
|
|
||||||
|
g_mutex_lock (&private_connection.mutex);
|
||||||
|
p = g_weak_ref_get (&private_connection.weak_ref);
|
||||||
|
if (p) {
|
||||||
|
g_object_unref (connection);
|
||||||
|
connection = p;
|
||||||
|
} else {
|
||||||
|
g_weak_ref_set (&private_connection.weak_ref, connection);
|
||||||
|
g_signal_connect (connection, "closed", G_CALLBACK (_private_dbus_connection_closed_cb), NULL);
|
||||||
|
}
|
||||||
|
g_mutex_unlock (&private_connection.mutex);
|
||||||
|
return connection;
|
||||||
|
}
|
||||||
|
|
||||||
GDBusConnection *
|
GDBusConnection *
|
||||||
_nm_dbus_new_connection (GCancellable *cancellable, GError **error)
|
_nm_dbus_new_connection (GCancellable *cancellable, GError **error)
|
||||||
{
|
{
|
||||||
|
|
@ -49,12 +94,17 @@ _nm_dbus_new_connection (GCancellable *cancellable, GError **error)
|
||||||
/* If running as root try the private bus first */
|
/* If running as root try the private bus first */
|
||||||
if (0 == geteuid ()) {
|
if (0 == geteuid ()) {
|
||||||
GError *local = NULL;
|
GError *local = NULL;
|
||||||
|
GDBusConnection *p;
|
||||||
|
|
||||||
|
p = g_weak_ref_get (&private_connection.weak_ref);
|
||||||
|
if (p)
|
||||||
|
return p;
|
||||||
|
|
||||||
connection = g_dbus_connection_new_for_address_sync ("unix:path=" NMRUNDIR "/private",
|
connection = g_dbus_connection_new_for_address_sync ("unix:path=" NMRUNDIR "/private",
|
||||||
G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT,
|
G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT,
|
||||||
NULL, cancellable, &local);
|
NULL, cancellable, &local);
|
||||||
if (connection)
|
if (connection)
|
||||||
return connection;
|
return _private_dbus_connection_internalize (connection);
|
||||||
|
|
||||||
if (g_error_matches (local, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
|
if (g_error_matches (local, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
|
||||||
g_propagate_error (error, local);
|
g_propagate_error (error, local);
|
||||||
|
|
@ -92,6 +142,7 @@ new_connection_async_got_private (GObject *source, GAsyncResult *result, gpointe
|
||||||
|
|
||||||
connection = g_dbus_connection_new_for_address_finish (result, &error);
|
connection = g_dbus_connection_new_for_address_finish (result, &error);
|
||||||
if (connection) {
|
if (connection) {
|
||||||
|
connection = _private_dbus_connection_internalize (connection);
|
||||||
g_simple_async_result_set_op_res_gpointer (simple, connection, g_object_unref);
|
g_simple_async_result_set_op_res_gpointer (simple, connection, g_object_unref);
|
||||||
g_simple_async_result_complete (simple);
|
g_simple_async_result_complete (simple);
|
||||||
g_object_unref (simple);
|
g_object_unref (simple);
|
||||||
|
|
@ -111,6 +162,36 @@ new_connection_async_got_private (GObject *source, GAsyncResult *result, gpointe
|
||||||
new_connection_async_got_system, simple);
|
new_connection_async_got_system, simple);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_nm_dbus_new_connection_async_do (GSimpleAsyncResult *simple, GCancellable *cancellable)
|
||||||
|
{
|
||||||
|
g_dbus_connection_new_for_address ("unix:path=" NMRUNDIR "/private",
|
||||||
|
G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT,
|
||||||
|
NULL,
|
||||||
|
cancellable,
|
||||||
|
new_connection_async_got_private, simple);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
_nm_dbus_new_connection_async_get_private (gpointer user_data)
|
||||||
|
{
|
||||||
|
GSimpleAsyncResult *simple = user_data;
|
||||||
|
GDBusConnection *p;
|
||||||
|
|
||||||
|
p = g_weak_ref_get (&private_connection.weak_ref);
|
||||||
|
if (!p) {
|
||||||
|
/* The connection is gone. Create a new one async... */
|
||||||
|
_nm_dbus_new_connection_async_do (simple,
|
||||||
|
g_object_get_data (G_OBJECT (simple), "cancellable"));
|
||||||
|
} else {
|
||||||
|
g_simple_async_result_set_op_res_gpointer (simple, p, g_object_unref);
|
||||||
|
g_simple_async_result_complete (simple);
|
||||||
|
g_object_unref (simple);
|
||||||
|
}
|
||||||
|
|
||||||
|
return G_SOURCE_REMOVE;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
_nm_dbus_new_connection_async (GCancellable *cancellable,
|
_nm_dbus_new_connection_async (GCancellable *cancellable,
|
||||||
GAsyncReadyCallback callback,
|
GAsyncReadyCallback callback,
|
||||||
|
|
@ -122,15 +203,18 @@ _nm_dbus_new_connection_async (GCancellable *cancellable,
|
||||||
|
|
||||||
/* If running as root try the private bus first */
|
/* If running as root try the private bus first */
|
||||||
if (0 == geteuid ()) {
|
if (0 == geteuid ()) {
|
||||||
|
GDBusConnection *p;
|
||||||
|
|
||||||
if (cancellable) {
|
if (cancellable) {
|
||||||
g_object_set_data_full (G_OBJECT (simple), "cancellable",
|
g_object_set_data_full (G_OBJECT (simple), "cancellable",
|
||||||
g_object_ref (cancellable), g_object_unref);
|
g_object_ref (cancellable), g_object_unref);
|
||||||
}
|
}
|
||||||
g_dbus_connection_new_for_address ("unix:path=" NMRUNDIR "/private",
|
p = g_weak_ref_get (&private_connection.weak_ref);
|
||||||
G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT,
|
if (p) {
|
||||||
NULL,
|
g_object_unref (p);
|
||||||
cancellable,
|
g_idle_add (_nm_dbus_new_connection_async_get_private, simple);
|
||||||
new_connection_async_got_private, simple);
|
} else
|
||||||
|
_nm_dbus_new_connection_async_do (simple, cancellable);
|
||||||
} else {
|
} else {
|
||||||
g_bus_get (_nm_dbus_bus_type (),
|
g_bus_get (_nm_dbus_bus_type (),
|
||||||
cancellable,
|
cancellable,
|
||||||
|
|
|
||||||
|
|
@ -72,7 +72,6 @@ static void reload_complete (NMObject *object);
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
GDBusConnection *connection;
|
GDBusConnection *connection;
|
||||||
gboolean private_connection;
|
|
||||||
gboolean nm_running;
|
gboolean nm_running;
|
||||||
|
|
||||||
char *path;
|
char *path;
|
||||||
|
|
@ -93,6 +92,7 @@ typedef struct {
|
||||||
enum {
|
enum {
|
||||||
PROP_0,
|
PROP_0,
|
||||||
PROP_PATH,
|
PROP_PATH,
|
||||||
|
PROP_DBUS_CONNECTION,
|
||||||
PROP_NM_RUNNING,
|
PROP_NM_RUNNING,
|
||||||
|
|
||||||
LAST_PROP
|
LAST_PROP
|
||||||
|
|
@ -175,7 +175,8 @@ init_sync (GInitable *initable, GCancellable *cancellable, GError **error)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
priv->connection = _nm_dbus_new_connection (cancellable, error);
|
if (!priv->connection)
|
||||||
|
priv->connection = _nm_dbus_new_connection (cancellable, error);
|
||||||
if (!priv->connection)
|
if (!priv->connection)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
|
@ -380,6 +381,10 @@ set_property (GObject *object, guint prop_id,
|
||||||
/* Construct only */
|
/* Construct only */
|
||||||
priv->path = g_value_dup_string (value);
|
priv->path = g_value_dup_string (value);
|
||||||
break;
|
break;
|
||||||
|
case PROP_DBUS_CONNECTION:
|
||||||
|
/* Construct only */
|
||||||
|
priv->connection = g_value_dup_object (value);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
|
|
@ -396,6 +401,9 @@ get_property (GObject *object, guint prop_id,
|
||||||
case PROP_PATH:
|
case PROP_PATH:
|
||||||
g_value_set_string (value, priv->path);
|
g_value_set_string (value, priv->path);
|
||||||
break;
|
break;
|
||||||
|
case PROP_DBUS_CONNECTION:
|
||||||
|
g_value_set_object (value, priv->connection);
|
||||||
|
break;
|
||||||
case PROP_NM_RUNNING:
|
case PROP_NM_RUNNING:
|
||||||
g_value_set_boolean (value, priv->nm_running);
|
g_value_set_boolean (value, priv->nm_running);
|
||||||
break;
|
break;
|
||||||
|
|
@ -435,6 +443,19 @@ nm_object_class_init (NMObjectClass *nm_object_class)
|
||||||
G_PARAM_CONSTRUCT_ONLY |
|
G_PARAM_CONSTRUCT_ONLY |
|
||||||
G_PARAM_STATIC_STRINGS));
|
G_PARAM_STATIC_STRINGS));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* NMObject:dbus-connection: (skip)
|
||||||
|
*
|
||||||
|
* The #GDBusConnection of the object.
|
||||||
|
**/
|
||||||
|
g_object_class_install_property
|
||||||
|
(object_class, PROP_DBUS_CONNECTION,
|
||||||
|
g_param_spec_object (NM_OBJECT_DBUS_CONNECTION, "", "",
|
||||||
|
G_TYPE_DBUS_CONNECTION,
|
||||||
|
G_PARAM_READWRITE |
|
||||||
|
G_PARAM_CONSTRUCT_ONLY |
|
||||||
|
G_PARAM_STATIC_STRINGS));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* NMObject:manager-running: (skip)
|
* NMObject:manager-running: (skip)
|
||||||
*
|
*
|
||||||
|
|
@ -499,9 +520,12 @@ _nm_object_class_add_interface (NMObjectClass *object_class,
|
||||||
NMObjectClassPrivate *cpriv;
|
NMObjectClassPrivate *cpriv;
|
||||||
|
|
||||||
g_return_if_fail (NM_IS_OBJECT_CLASS (object_class));
|
g_return_if_fail (NM_IS_OBJECT_CLASS (object_class));
|
||||||
|
g_return_if_fail (interface);
|
||||||
|
|
||||||
cpriv = NM_OBJECT_CLASS_GET_PRIVATE (object_class);
|
cpriv = NM_OBJECT_CLASS_GET_PRIVATE (object_class);
|
||||||
|
|
||||||
|
g_return_if_fail (g_slist_find_custom (cpriv->interfaces, interface, (GCompareFunc) g_strcmp0) == NULL);
|
||||||
|
|
||||||
cpriv->interfaces = g_slist_prepend (cpriv->interfaces, g_strdup (interface));
|
cpriv->interfaces = g_slist_prepend (cpriv->interfaces, g_strdup (interface));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -668,6 +692,7 @@ _nm_object_create (GType type, GDBusConnection *connection, const char *path)
|
||||||
|
|
||||||
object = g_object_new (type,
|
object = g_object_new (type,
|
||||||
NM_OBJECT_PATH, path,
|
NM_OBJECT_PATH, path,
|
||||||
|
NM_OBJECT_DBUS_CONNECTION, connection,
|
||||||
NULL);
|
NULL);
|
||||||
/* Cache the object before initializing it (and in particular, loading its
|
/* Cache the object before initializing it (and in particular, loading its
|
||||||
* property values); this is necessary to make circular references work (eg,
|
* property values); this is necessary to make circular references work (eg,
|
||||||
|
|
@ -692,6 +717,7 @@ typedef struct {
|
||||||
NMObjectCreateCallbackFunc callback;
|
NMObjectCreateCallbackFunc callback;
|
||||||
gpointer user_data;
|
gpointer user_data;
|
||||||
NMObjectTypeFuncData *type_data;
|
NMObjectTypeFuncData *type_data;
|
||||||
|
GDBusConnection *connection;
|
||||||
} NMObjectTypeAsyncData;
|
} NMObjectTypeAsyncData;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
@ -700,6 +726,7 @@ create_async_complete (GObject *object, NMObjectTypeAsyncData *async_data)
|
||||||
async_data->callback (object, async_data->path, async_data->user_data);
|
async_data->callback (object, async_data->path, async_data->user_data);
|
||||||
|
|
||||||
g_free (async_data->path);
|
g_free (async_data->path);
|
||||||
|
g_object_unref (async_data->connection);
|
||||||
g_slice_free (NMObjectTypeAsyncData, async_data);
|
g_slice_free (NMObjectTypeAsyncData, async_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -747,6 +774,7 @@ create_async_got_type (NMObjectTypeAsyncData *async_data, GType type)
|
||||||
|
|
||||||
object = g_object_new (type,
|
object = g_object_new (type,
|
||||||
NM_OBJECT_PATH, async_data->path,
|
NM_OBJECT_PATH, async_data->path,
|
||||||
|
NM_OBJECT_DBUS_CONNECTION, async_data->connection,
|
||||||
NULL);
|
NULL);
|
||||||
g_async_initable_init_async (G_ASYNC_INITABLE (object), G_PRIORITY_DEFAULT,
|
g_async_initable_init_async (G_ASYNC_INITABLE (object), G_PRIORITY_DEFAULT,
|
||||||
NULL, create_async_inited, async_data);
|
NULL, create_async_inited, async_data);
|
||||||
|
|
@ -813,6 +841,7 @@ _nm_object_create_async (GType type, GDBusConnection *connection, const char *pa
|
||||||
async_data->path = g_strdup (path);
|
async_data->path = g_strdup (path);
|
||||||
async_data->callback = callback;
|
async_data->callback = callback;
|
||||||
async_data->user_data = user_data;
|
async_data->user_data = user_data;
|
||||||
|
async_data->connection = g_object_ref (connection);
|
||||||
|
|
||||||
async_data->type_data = g_hash_table_lookup (type_funcs, GSIZE_TO_POINTER (type));
|
async_data->type_data = g_hash_table_lookup (type_funcs, GSIZE_TO_POINTER (type));
|
||||||
if (async_data->type_data) {
|
if (async_data->type_data) {
|
||||||
|
|
|
||||||
|
|
@ -56,6 +56,7 @@ typedef enum {
|
||||||
GQuark nm_object_error_quark (void);
|
GQuark nm_object_error_quark (void);
|
||||||
|
|
||||||
#define NM_OBJECT_PATH "path"
|
#define NM_OBJECT_PATH "path"
|
||||||
|
#define NM_OBJECT_DBUS_CONNECTION "dbus-connection"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
GObject parent;
|
GObject parent;
|
||||||
|
|
|
||||||
|
|
@ -110,11 +110,12 @@ private_server_message_filter (DBusConnection *conn,
|
||||||
void *data)
|
void *data)
|
||||||
{
|
{
|
||||||
PrivateServer *s = data;
|
PrivateServer *s = data;
|
||||||
|
int fd;
|
||||||
|
|
||||||
/* Clean up after the connection */
|
/* Clean up after the connection */
|
||||||
if (dbus_message_is_signal (message, DBUS_INTERFACE_LOCAL, "Disconnected")) {
|
if (dbus_message_is_signal (message, DBUS_INTERFACE_LOCAL, "Disconnected")) {
|
||||||
nm_log_dbg (LOGD_CORE, "(%s) closed connection %p on private socket.",
|
nm_log_dbg (LOGD_CORE, "(%s) closed connection %p on private socket (fd %d).",
|
||||||
s->tag, conn);
|
s->tag, conn, dbus_connection_get_unix_fd (conn, &fd) ? fd : -1);
|
||||||
|
|
||||||
/* Emit this for the manager */
|
/* Emit this for the manager */
|
||||||
g_signal_emit (s->manager,
|
g_signal_emit (s->manager,
|
||||||
|
|
@ -158,8 +159,8 @@ private_server_new_connection (DBusServer *server,
|
||||||
sender = g_strdup_printf ("x:y:%d", counter++);
|
sender = g_strdup_printf ("x:y:%d", counter++);
|
||||||
g_hash_table_insert (s->connections, dbus_connection_ref (conn), sender);
|
g_hash_table_insert (s->connections, dbus_connection_ref (conn), sender);
|
||||||
|
|
||||||
nm_log_dbg (LOGD_CORE, "(%s) accepted connection %p on private socket (fd %"G_GINT64_FORMAT").",
|
nm_log_dbg (LOGD_CORE, "(%s) accepted connection %p on private socket (fd %d).",
|
||||||
s->tag, conn, dbus_connection_get_unix_fd (conn, &fd) ? fd : G_MININT64);
|
s->tag, conn, dbus_connection_get_unix_fd (conn, &fd) ? fd : -1);
|
||||||
|
|
||||||
/* Emit this for the manager */
|
/* Emit this for the manager */
|
||||||
g_signal_emit (s->manager,
|
g_signal_emit (s->manager,
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue