diff options
author | Thomas Haller <thaller@redhat.com> | 2019-10-04 13:56:36 +0200 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2019-10-16 08:56:00 +0200 |
commit | e6e6057a13b5cd6ac558085fd951511ffaafb79a (patch) | |
tree | b3bfa3376ed81eaecfe21e997242d2380aa698c1 | |
parent | ba2e1d52ad4f28bc91d67bf670a53405311d8215 (diff) | |
download | NetworkManager-e6e6057a13b5cd6ac558085fd951511ffaafb79a.tar.gz |
libnm: add helper functions for refactoring D-Bus calls in libnm
We will drop GDBusProxy and the gdbus-codegen classes. First, we need to
replace all D-Bus calls from nmdbus_*() API with plain uses of GDBusConnection.
For that, add accessors to get the dbus-connection and the name-owner.
This API is not beautiful, it's an interim solution for now.
-rw-r--r-- | libnm/nm-client.c | 48 | ||||
-rw-r--r-- | libnm/nm-dbus-helpers.h | 2 | ||||
-rw-r--r-- | libnm/nm-object-private.h | 48 | ||||
-rw-r--r-- | libnm/nm-object.c | 209 |
4 files changed, 299 insertions, 8 deletions
diff --git a/libnm/nm-client.c b/libnm/nm-client.c index 7785628624..e2c1ea751f 100644 --- a/libnm/nm-client.c +++ b/libnm/nm-client.c @@ -100,6 +100,7 @@ typedef struct { NMDnsManager *dns_manager; GDBusObjectManager *object_manager; GCancellable *new_object_manager_cancellable; + char *name_owner_cached; struct udev *udev; bool udev_inited:1; } NMClientPrivate; @@ -168,6 +169,41 @@ NM_CACHED_QUARK_FCN ("nm-client-error-quark", nm_client_error_quark) /*****************************************************************************/ +GDBusConnection * +_nm_client_get_dbus_connection (NMClient *client) +{ + NMClientPrivate *priv; + + nm_assert (NM_IS_CLIENT (client)); + + priv = NM_CLIENT_GET_PRIVATE (client); + + if (!priv->object_manager) + return NULL; + + return g_dbus_object_manager_client_get_connection (G_DBUS_OBJECT_MANAGER_CLIENT (priv->object_manager)); +} + +const char * +_nm_client_get_dbus_name_owner (NMClient *client) +{ + NMClientPrivate *priv; + + nm_assert (NM_IS_CLIENT (client)); + + priv = NM_CLIENT_GET_PRIVATE (client); + + nm_clear_g_free (&priv->name_owner_cached); + + if (!priv->object_manager) + return NULL; + + priv->name_owner_cached = g_dbus_object_manager_client_get_name_owner (G_DBUS_OBJECT_MANAGER_CLIENT (priv->object_manager)); + return priv->name_owner_cached; +} + +/*****************************************************************************/ + static void nm_client_init (NMClient *client) { @@ -176,15 +212,11 @@ nm_client_init (NMClient *client) static gboolean _nm_client_check_nm_running (NMClient *client, GError **error) { - if (nm_client_get_nm_running (client)) - return TRUE; - else { - g_set_error_literal (error, - NM_CLIENT_ERROR, - NM_CLIENT_ERROR_MANAGER_NOT_RUNNING, - "NetworkManager is not running"); + if (!nm_client_get_nm_running (client)) { + _nm_object_set_error_nm_not_running (error); return FALSE; } + return TRUE; } /** @@ -3468,6 +3500,8 @@ dispose (GObject *object) udev_unref (priv->udev); priv->udev = NULL; } + + nm_clear_g_free (&priv->name_owner_cached); } static void diff --git a/libnm/nm-dbus-helpers.h b/libnm/nm-dbus-helpers.h index 8f823f0e87..5a0fb756ab 100644 --- a/libnm/nm-dbus-helpers.h +++ b/libnm/nm-dbus-helpers.h @@ -12,6 +12,8 @@ #include "nm-std-aux/nm-dbus-compat.h" +#define NM_DBUS_DEFAULT_TIMEOUT_MSEC 25000 + GBusType _nm_dbus_bus_type (void); void _nm_dbus_proxy_replace_match (GDBusProxy *proxy); diff --git a/libnm/nm-object-private.h b/libnm/nm-object-private.h index eb9e0f1407..863b228fae 100644 --- a/libnm/nm-object-private.h +++ b/libnm/nm-object-private.h @@ -34,7 +34,50 @@ GDBusObjectManager *_nm_object_get_dbus_object_manager (NMObject *object); GQuark _nm_object_obj_nm_quark (void); -/* DBus property accessors */ +GDBusConnection *_nm_object_get_dbus_connection (gpointer self); + +const char *_nm_object_get_dbus_name_owner (gpointer self); + +GDBusConnection *_nm_client_get_dbus_connection (NMClient *client); + +const char *_nm_client_get_dbus_name_owner (NMClient *client); + +void _nm_object_dbus_call (gpointer self, + gpointer source_tag, + GCancellable *cancellable, + GAsyncReadyCallback user_callback, + gpointer user_callback_data, + const char *object_path, + const char *interface_name, + const char *method_name, + GVariant *parameters, + const GVariantType *reply_type, + GDBusCallFlags flags, + int timeout_msec, + GAsyncReadyCallback internal_callback); + +GVariant *_nm_object_dbus_call_sync (gpointer self, + GCancellable *cancellable, + const char *object_path, + const char *interface_name, + const char *method_name, + GVariant *parameters, + const GVariantType *reply_type, + GDBusCallFlags flags, + int timeout_msec, + gboolean strip_dbus_error, + GError **error); + +gboolean _nm_object_dbus_call_sync_void (gpointer self, + GCancellable *cancellable, + const char *object_path, + const char *interface_name, + const char *method_name, + GVariant *parameters, + GDBusCallFlags flags, + int timeout_msec, + gboolean strip_dbus_error, + GError **error); void _nm_object_set_property (NMObject *object, const char *interface, @@ -45,6 +88,9 @@ void _nm_object_set_property (NMObject *object, GDBusProxy *_nm_object_get_proxy (NMObject *object, const char *interface); +GError *_nm_object_new_error_nm_not_running (void); +void _nm_object_set_error_nm_not_running (GError **error); + struct udev; void _nm_device_set_udev (NMDevice *device, struct udev *udev); diff --git a/libnm/nm-object.c b/libnm/nm-object.c index 8c91e7a38e..bbe97eb6cd 100644 --- a/libnm/nm-object.c +++ b/libnm/nm-object.c @@ -69,6 +69,8 @@ typedef struct { CList pending; /* ordered list of pending property updates. */ GPtrArray *proxies; + + char *name_owner_cached; } NMObjectPrivate; enum { @@ -127,6 +129,211 @@ _nm_object_get_proxy (NMObject *object, return G_DBUS_PROXY (proxy); } +/*****************************************************************************/ + +GDBusConnection * +_nm_object_get_dbus_connection (gpointer self) +{ + NMObjectPrivate *priv; + + nm_assert (NM_IS_OBJECT (self)); + + priv = NM_OBJECT_GET_PRIVATE (self); + + return g_dbus_object_manager_client_get_connection (G_DBUS_OBJECT_MANAGER_CLIENT (priv->object_manager)); +} + +const char * +_nm_object_get_dbus_name_owner (gpointer self) +{ + NMObjectPrivate *priv; + + nm_assert (NM_IS_OBJECT (self)); + + priv = NM_OBJECT_GET_PRIVATE (self); + + nm_clear_g_free (&priv->name_owner_cached); + priv->name_owner_cached = g_dbus_object_manager_client_get_name_owner (G_DBUS_OBJECT_MANAGER_CLIENT (priv->object_manager)); + return priv->name_owner_cached; +} + +static gboolean +_get_dbus_params (gpointer self, + GDBusConnection **out_dbus_connection, + const char **out_name_owner) +{ + const char *name_owner; + GDBusConnection *dbus_connection = NULL; + + if (NM_IS_OBJECT (self)) { + name_owner = _nm_object_get_dbus_name_owner (self); + if (name_owner) + dbus_connection = _nm_object_get_dbus_connection (self); + } else { + nm_assert (NM_IS_CLIENT (self)); + name_owner = _nm_client_get_dbus_name_owner (self); + if (name_owner) + dbus_connection = _nm_client_get_dbus_connection (self); + } + + *out_dbus_connection = dbus_connection; + *out_name_owner = name_owner; + return !!name_owner; +} + +void +_nm_object_dbus_call (gpointer self, + gpointer source_tag, + GCancellable *cancellable, + GAsyncReadyCallback user_callback, + gpointer user_callback_data, + const char *object_path, + const char *interface_name, + const char *method_name, + GVariant *parameters, + const GVariantType *reply_type, + GDBusCallFlags flags, + int timeout_msec, + GAsyncReadyCallback internal_callback) +{ + gs_unref_object GTask *task = NULL; + const char *name_owner; + GDBusConnection *dbus_connection; + + nm_assert (G_IS_OBJECT (self)); + nm_assert (source_tag); + nm_assert (!cancellable || G_IS_CANCELLABLE (cancellable)); + nm_assert (internal_callback); + nm_assert (object_path); + nm_assert (interface_name); + nm_assert (method_name); + nm_assert (parameters); + nm_assert (reply_type); + + task = nm_g_task_new (self, cancellable, source_tag, user_callback, user_callback_data); + + if (!_get_dbus_params (self, &dbus_connection, &name_owner)) { + nm_g_variant_unref_floating (parameters); + g_task_return_error (task, _nm_object_new_error_nm_not_running ()); + return; + } + + g_dbus_connection_call (dbus_connection, + name_owner, + object_path, + interface_name, + method_name, + parameters, + reply_type, + flags, + timeout_msec, + cancellable, + internal_callback, + g_steal_pointer (&task)); +} + +GVariant * +_nm_object_dbus_call_sync (gpointer self, + GCancellable *cancellable, + const char *object_path, + const char *interface_name, + const char *method_name, + GVariant *parameters, + const GVariantType *reply_type, + GDBusCallFlags flags, + int timeout_msec, + gboolean strip_dbus_error, + GError **error) +{ + gs_unref_variant GVariant *ret = NULL; + GDBusConnection *dbus_connection; + const char *name_owner; + + nm_assert (G_IS_OBJECT (self)); + nm_assert (!cancellable || G_IS_CANCELLABLE (cancellable)); + nm_assert (!error || !*error); + nm_assert (object_path); + nm_assert (interface_name); + nm_assert (method_name); + nm_assert (parameters); + nm_assert (reply_type); + + if (!_get_dbus_params (self, &dbus_connection, &name_owner)) { + nm_g_variant_unref_floating (parameters); + _nm_object_set_error_nm_not_running (error); + return NULL; + } + + ret = g_dbus_connection_call_sync (dbus_connection, + name_owner, + object_path, + interface_name, + method_name, + parameters, + reply_type, + flags, + timeout_msec, + cancellable, + error); + if (!ret) { + if (error && strip_dbus_error) + g_dbus_error_strip_remote_error (*error); + return NULL; + } + + return g_steal_pointer (&ret); +} + +gboolean +_nm_object_dbus_call_sync_void (gpointer self, + GCancellable *cancellable, + const char *object_path, + const char *interface_name, + const char *method_name, + GVariant *parameters, + GDBusCallFlags flags, + int timeout_msec, + gboolean strip_dbus_error, + GError **error) +{ + gs_unref_variant GVariant *ret = NULL; + + ret = _nm_object_dbus_call_sync (self, + cancellable, + object_path, + interface_name, + method_name, + parameters, + G_VARIANT_TYPE ("()"), + flags, + timeout_msec, + strip_dbus_error, + error); + return !!ret; +} + +/*****************************************************************************/ + +GError * +_nm_object_new_error_nm_not_running (void) +{ + return g_error_new_literal (NM_CLIENT_ERROR, + NM_CLIENT_ERROR_MANAGER_NOT_RUNNING, + "NetworkManager is not running"); +} + +void +_nm_object_set_error_nm_not_running (GError **error) +{ + if (error) { + if (*error) + g_return_if_reached (); + *error = _nm_object_new_error_nm_not_running (); + } +} + +/*****************************************************************************/ + typedef enum { NOTIFY_SIGNAL_PENDING_NONE, NOTIFY_SIGNAL_PENDING_ADDED, @@ -1251,6 +1458,8 @@ finalize (GObject *object) g_slist_free_full (priv->property_tables, (GDestroyNotify) g_hash_table_destroy); + g_free (priv->name_owner_cached); + G_OBJECT_CLASS (nm_object_parent_class)->finalize (object); } |