summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2019-04-07 21:45:44 +0200
committerThomas Haller <thaller@redhat.com>2019-04-09 20:40:18 +0200
commit5d86f605263200667f2c848f89f3b8831f20bb65 (patch)
treee1cd4d24c9991ec4610666ea24e023645004adff
parent5e77b2d6604245b5b63891e9e02a320df7e4b93a (diff)
downloadNetworkManager-5d86f605263200667f2c848f89f3b8831f20bb65.tar.gz
dns: use GDBusConnection instead of GDBusProxy in "nm-dns-systemd-resolved.c"
The proxy does nothing for us, except overhead. We can directly subscribe to "NameOwnerChanged" signals on the GDBusConnection. Also, instead of asynchronously creating the GDBusProxy, asynchronously call "GetNameOwner". That's what the proxy does anyway. GDBusConnection is actually a decent API. We don't need another layer on top of that, for functionality that we don't use. Also, don't use G_BUS_TYPE_SYSTEM, but use the GDBusConnection that also the bus-manager uses. For all practical purposes, that is the connection was want to use also in NMDnsSystemdResolved.
-rw-r--r--src/dns/nm-dns-systemd-resolved.c166
1 files changed, 106 insertions, 60 deletions
diff --git a/src/dns/nm-dns-systemd-resolved.c b/src/dns/nm-dns-systemd-resolved.c
index a1cf4f89df..573f047b47 100644
--- a/src/dns/nm-dns-systemd-resolved.c
+++ b/src/dns/nm-dns-systemd-resolved.c
@@ -44,8 +44,9 @@
#include "NetworkManagerUtils.h"
#include "nm-dbus-compat.h"
-#define SYSTEMD_RESOLVED_DBUS_SERVICE "org.freedesktop.resolve1"
-#define SYSTEMD_RESOLVED_DBUS_PATH "/org/freedesktop/resolve1"
+#define SYSTEMD_RESOLVED_DBUS_SERVICE "org.freedesktop.resolve1"
+#define SYSTEMD_RESOLVED_MANAGER_IFACE "org.freedesktop.resolve1.Manager"
+#define SYSTEMD_RESOLVED_DBUS_PATH "/org/freedesktop/resolve1"
/*****************************************************************************/
@@ -63,13 +64,14 @@ typedef struct {
/*****************************************************************************/
typedef struct {
- GDBusProxy *resolve;
- GCancellable *init_cancellable;
- GCancellable *update_cancellable;
+ GDBusConnection *dbus_connection;
+ GCancellable *cancellable;
CList request_queue_lst_head;
+ guint name_owner_changed_id;
bool send_updates_warn_ratelimited:1;
bool try_start_blocked:1;
bool dbus_has_owner:1;
+ bool dbus_initied:1;
} NMDnsSystemdResolvedPrivate;
struct _NMDnsSystemdResolved {
@@ -130,7 +132,7 @@ call_done (GObject *source, GAsyncResult *r, gpointer user_data)
NMDnsSystemdResolved *self = (NMDnsSystemdResolved *) user_data;
NMDnsSystemdResolvedPrivate *priv;
- v = g_dbus_proxy_call_finish (G_DBUS_PROXY (source), r, &error);
+ v = g_dbus_connection_call_finish (G_DBUS_CONNECTION (source), r, &error);
if ( !v
&& g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
return;
@@ -286,8 +288,8 @@ send_updates (NMDnsSystemdResolved *self)
return;
}
- if (!priv->resolve) {
- _LOGT ("send-updates: D-Bus proxy not ready");
+ if (!priv->dbus_initied) {
+ _LOGT ("send-updates: D-Bus connection not ready");
return;
}
@@ -302,7 +304,7 @@ send_updates (NMDnsSystemdResolved *self)
_LOGT ("send-updates: no name owner. Try start service...");
priv->try_start_blocked = TRUE;
- g_dbus_connection_call (g_dbus_proxy_get_connection (priv->resolve),
+ g_dbus_connection_call (priv->dbus_connection,
DBUS_SERVICE_DBUS,
DBUS_PATH_DBUS,
DBUS_INTERFACE_DBUS,
@@ -320,9 +322,9 @@ send_updates (NMDnsSystemdResolved *self)
_LOGT ("send-updates: start %lu requests",
c_list_length (&priv->request_queue_lst_head));
- nm_clear_g_cancellable (&priv->update_cancellable);
+ nm_clear_g_cancellable (&priv->cancellable);
- priv->update_cancellable = g_cancellable_new ();
+ priv->cancellable = g_cancellable_new ();
while ((request_item = c_list_first_entry (&priv->request_queue_lst_head,
RequestItem,
@@ -335,14 +337,18 @@ send_updates (NMDnsSystemdResolved *self)
* But this is hard to avoid, because we'd have to check the error failure to detect the reason
* and retry. The race is not critical, because at worst it results in logging a warning
* about failure to start systemd.resolved. */
- g_dbus_proxy_call (priv->resolve,
- request_item->operation,
- request_item->argument,
- G_DBUS_CALL_FLAGS_NONE,
- -1,
- priv->update_cancellable,
- call_done,
- self);
+ g_dbus_connection_call (priv->dbus_connection,
+ SYSTEMD_RESOLVED_DBUS_SERVICE,
+ SYSTEMD_RESOLVED_DBUS_PATH,
+ SYSTEMD_RESOLVED_MANAGER_IFACE,
+ request_item->operation,
+ request_item->argument,
+ NULL,
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ priv->cancellable,
+ call_done,
+ self);
_request_item_free (request_item);
}
}
@@ -416,12 +422,12 @@ get_name (NMDnsPlugin *plugin)
/*****************************************************************************/
static void
-name_owner_changed (NMDnsSystemdResolved *self)
+name_owner_changed (NMDnsSystemdResolved *self,
+ const char *owner)
{
NMDnsSystemdResolvedPrivate *priv = NM_DNS_SYSTEMD_RESOLVED_GET_PRIVATE (self);
- gs_free char *owner = NULL;
- owner = g_dbus_proxy_get_name_owner (priv->resolve);
+ owner = nm_str_not_empty (owner);
if (!owner)
_LOGT ("D-Bus name for systemd-resolved has no owner");
@@ -436,42 +442,64 @@ name_owner_changed (NMDnsSystemdResolved *self)
}
static void
-name_owner_changed_cb (GObject *object,
- GParamSpec *pspec,
+name_owner_changed_cb (GDBusConnection *connection,
+ const char *sender_name,
+ const char *object_path,
+ const char *interface_name,
+ const char *signal_name,
+ GVariant *parameters,
gpointer user_data)
{
- name_owner_changed (user_data);
+ NMDnsSystemdResolved *self = user_data;
+ NMDnsSystemdResolvedPrivate *priv = NM_DNS_SYSTEMD_RESOLVED_GET_PRIVATE (self);
+ const char *new_owner;
+
+ if (!g_variant_is_of_type (parameters, G_VARIANT_TYPE ("(sss)")))
+ return;
+
+ g_variant_get (parameters,
+ "(&s&s&s)",
+ NULL,
+ NULL,
+ &new_owner);
+
+ if (!priv->dbus_initied) {
+ /* There was a race and we got a NameOwnerChanged signal before GetNameOwner
+ * returns. */
+ priv->dbus_initied = TRUE;
+ nm_clear_g_cancellable (&priv->cancellable);
+ }
+
+ name_owner_changed (user_data, new_owner);
}
static void
-resolved_proxy_created (GObject *source, GAsyncResult *r, gpointer user_data)
+get_name_owner_cb (GObject *source,
+ GAsyncResult *res,
+ gpointer user_data)
{
- NMDnsSystemdResolved *self = (NMDnsSystemdResolved *) user_data;
+ NMDnsSystemdResolved *self;
NMDnsSystemdResolvedPrivate *priv;
+ gs_unref_variant GVariant *ret = NULL;
gs_free_error GError *error = NULL;
- GDBusProxy *resolve;
+ const char *owner = NULL;
- resolve = g_dbus_proxy_new_finish (r, &error);
- if ( !resolve
+ ret = g_dbus_connection_call_finish (G_DBUS_CONNECTION (source), res, &error);
+ if ( !ret
&& g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
return;
- priv = NM_DNS_SYSTEMD_RESOLVED_GET_PRIVATE (self);
- g_clear_object (&priv->init_cancellable);
- if (!resolve) {
- _LOGW ("failure to create D-Bus proxy for systemd-resolved: %s", error->message);
- g_signal_emit_by_name (self, NM_DNS_PLUGIN_FAILED);
- return;
- }
+ if (ret)
+ g_variant_get (ret, "(&s)", &owner);
- _LOGT ("D-Bus proxy for systemd-resolved created");
+ self = user_data;
+ priv = NM_DNS_SYSTEMD_RESOLVED_GET_PRIVATE (self);
- g_signal_connect (resolve, "notify::g-name-owner",
- G_CALLBACK (name_owner_changed_cb), self);
+ g_clear_object (&priv->cancellable);
- priv->resolve = resolve;
+ priv->dbus_initied = TRUE;
- name_owner_changed (self);
+ name_owner_changed (self, owner);
}
/*****************************************************************************/
@@ -485,7 +513,7 @@ nm_dns_systemd_resolved_is_running (NMDnsSystemdResolved *self)
priv = NM_DNS_SYSTEMD_RESOLVED_GET_PRIVATE (self);
- return priv->resolve
+ return priv->dbus_initied
&& ( priv->dbus_has_owner
|| !priv->try_start_blocked);
}
@@ -499,18 +527,35 @@ nm_dns_systemd_resolved_init (NMDnsSystemdResolved *self)
c_list_init (&priv->request_queue_lst_head);
- priv->init_cancellable = g_cancellable_new ();
- g_dbus_proxy_new_for_bus (G_BUS_TYPE_SYSTEM,
- G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES
- | G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS
- | G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START_AT_CONSTRUCTION,
- NULL,
- SYSTEMD_RESOLVED_DBUS_SERVICE,
- SYSTEMD_RESOLVED_DBUS_PATH,
- SYSTEMD_RESOLVED_DBUS_SERVICE ".Manager",
- priv->init_cancellable,
- resolved_proxy_created,
- self);
+ priv->dbus_connection = nm_g_object_ref (nm_dbus_manager_get_dbus_connection (nm_dbus_manager_get ()));
+ if (!priv->dbus_connection) {
+ _LOGD ("no D-Bus connection");
+ return;
+ }
+
+ priv->name_owner_changed_id = g_dbus_connection_signal_subscribe (priv->dbus_connection,
+ DBUS_SERVICE_DBUS,
+ DBUS_INTERFACE_DBUS,
+ "NameOwnerChanged",
+ DBUS_PATH_DBUS,
+ SYSTEMD_RESOLVED_DBUS_SERVICE,
+ G_DBUS_SIGNAL_FLAGS_NONE,
+ name_owner_changed_cb,
+ self,
+ NULL);
+ priv->cancellable = g_cancellable_new ();
+ g_dbus_connection_call (priv->dbus_connection,
+ DBUS_SERVICE_DBUS,
+ DBUS_PATH_DBUS,
+ DBUS_INTERFACE_DBUS,
+ "GetNameOwner",
+ g_variant_new ("(s)", SYSTEMD_RESOLVED_DBUS_SERVICE),
+ G_VARIANT_TYPE ("(s)"),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ priv->cancellable,
+ get_name_owner_cb,
+ self);
}
NMDnsPlugin *
@@ -527,13 +572,14 @@ dispose (GObject *object)
free_pending_updates (self);
- if (priv->resolve) {
- g_signal_handlers_disconnect_by_func (priv->resolve, name_owner_changed_cb, self);
- g_clear_object (&priv->resolve);
+ if (priv->name_owner_changed_id != 0) {
+ g_dbus_connection_signal_unsubscribe (priv->dbus_connection,
+ nm_steal_int (&priv->name_owner_changed_id));
}
- nm_clear_g_cancellable (&priv->init_cancellable);
- nm_clear_g_cancellable (&priv->update_cancellable);
+ nm_clear_g_cancellable (&priv->cancellable);
+
+ g_clear_object (&priv->dbus_connection);
G_OBJECT_CLASS (nm_dns_systemd_resolved_parent_class)->dispose (object);
}