diff options
author | Thomas Haller <thaller@redhat.com> | 2019-04-07 21:45:44 +0200 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2019-04-09 20:40:18 +0200 |
commit | 5d86f605263200667f2c848f89f3b8831f20bb65 (patch) | |
tree | e1cd4d24c9991ec4610666ea24e023645004adff | |
parent | 5e77b2d6604245b5b63891e9e02a320df7e4b93a (diff) | |
download | NetworkManager-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.c | 166 |
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); } |