diff options
author | Thomas Haller <thaller@redhat.com> | 2016-09-06 14:35:45 +0200 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2016-09-08 12:49:11 +0200 |
commit | 7d3bfce1dcf20434f11535e6a13d36a0e9d7c43f (patch) | |
tree | 4200be57a57eb2f16517c30b1292320620a088ee | |
parent | 040bf6c1e8c9eb27d79934e686cf46f95f414005 (diff) | |
download | NetworkManager-7d3bfce1dcf20434f11535e6a13d36a0e9d7c43f.tar.gz |
dns/resolved: various fixes
- mode in init_resolv_conf_mode() must be initialized in
case it is NULL.
- drop the NULL sentinal from resolved_paths and make it
static.
- resolved_proxy_created() must handle the fact that @self
might be already destroyed.
- call_done() must not access @self before ensuring that
the call was not cancelled.
What's more, send_update() can be called by resolved_proxy_created(),
thus it must ensure that it has an @update_cancellable. Let
send_update() create and cancel the @update_cancellable().
Also, send_update() -- which now manages @update_cancellable
instead of update() -- must actually cancel the previous
cancellable, otherwise the callback again might access
a disposed @self.
Co-authored-by: Beniamino Galvani <bgalvani@redhat.com>
-rw-r--r-- | src/dns-manager/nm-dns-manager.c | 10 | ||||
-rw-r--r-- | src/dns-manager/nm-dns-systemd-resolved.c | 30 |
2 files changed, 22 insertions, 18 deletions
diff --git a/src/dns-manager/nm-dns-manager.c b/src/dns-manager/nm-dns-manager.c index 1abf13e5d7..c1d2bf77f6 100644 --- a/src/dns-manager/nm-dns-manager.c +++ b/src/dns-manager/nm-dns-manager.c @@ -1592,15 +1592,14 @@ NM_DEFINE_SINGLETON_GETTER (NMDnsManager, nm_dns_manager_get, NM_TYPE_DNS_MANAGE static gboolean _resolvconf_resolved_managed (void) { - GFile *f; - GFileInfo *info; - gboolean ret = FALSE; - const gchar *resolved_paths[] = { + static const char *const resolved_paths[] = { "/run/systemd/resolve/resolv.conf", "/lib/systemd/resolv.conf", "/usr/lib/systemd/resolv.conf", - NULL }; + GFile *f; + GFileInfo *info; + gboolean ret = FALSE; f = g_file_new_for_path (_PATH_RESCONF); info = g_file_query_info (f, @@ -1674,6 +1673,7 @@ again: priv->plugin = nm_dns_systemd_resolved_new (); plugin_changed = TRUE; } + mode = "systemd-resolved"; } else if (nm_streq0 (mode, "dnsmasq")) { if (force_reload_plugin || !NM_IS_DNS_DNSMASQ (priv->plugin)) { _clear_plugin (self); diff --git a/src/dns-manager/nm-dns-systemd-resolved.c b/src/dns-manager/nm-dns-systemd-resolved.c index f53520d7e1..6d9867b84a 100644 --- a/src/dns-manager/nm-dns-systemd-resolved.c +++ b/src/dns-manager/nm-dns-systemd-resolved.c @@ -83,7 +83,7 @@ call_done (GObject *source, GAsyncResult *r, gpointer user_data) { GVariant *v; GError *error = NULL; - NMDnsSystemdResolved *self = NM_DNS_SYSTEMD_RESOLVED (user_data); + NMDnsSystemdResolved *self = (NMDnsSystemdResolved *) user_data; v = g_dbus_proxy_call_finish (G_DBUS_PROXY (source), r, &error); @@ -251,9 +251,13 @@ send_updates (NMDnsSystemdResolved *self) NMDnsSystemdResolvedPrivate *priv = NM_DNS_SYSTEMD_RESOLVED_GET_PRIVATE (self); GVariant *v; + nm_clear_g_cancellable (&priv->update_cancellable); + if (!priv->resolve) return; + priv->update_cancellable = g_cancellable_new (); + while ((v = g_queue_pop_head (&priv->dns_updates)) != NULL) { g_dbus_proxy_call (priv->resolve, "SetLinkDNS", v, G_DBUS_CALL_FLAGS_NONE, @@ -276,7 +280,6 @@ update (NMDnsPlugin *plugin, const char *hostname) { NMDnsSystemdResolved *self = NM_DNS_SYSTEMD_RESOLVED (plugin); - NMDnsSystemdResolvedPrivate *priv = NM_DNS_SYSTEMD_RESOLVED_GET_PRIVATE (self); GArray *interfaces = g_array_new (TRUE, TRUE, sizeof (InterfaceConfig)); const NMDnsIPConfigData **c; int i; @@ -285,9 +288,6 @@ update (NMDnsPlugin *plugin, add_interface_configuration (self, interfaces, *c); free_pending_updates (self); - g_clear_object (&priv->update_cancellable); - - priv->update_cancellable = g_cancellable_new (); for (i = 0; i < interfaces->len; i++) { InterfaceConfig *ic = &g_array_index (interfaces, InterfaceConfig, i); @@ -328,21 +328,25 @@ nm_dns_systemd_resolved_new (void) static void resolved_proxy_created (GObject *source, GAsyncResult *r, gpointer user_data) { - NMDnsSystemdResolved *self = NM_DNS_SYSTEMD_RESOLVED (user_data); - NMDnsSystemdResolvedPrivate *priv = NM_DNS_SYSTEMD_RESOLVED_GET_PRIVATE (self); - GError *error = NULL; - - g_clear_object (&priv->init_cancellable); + NMDnsSystemdResolved *self = (NMDnsSystemdResolved *) user_data; + NMDnsSystemdResolvedPrivate *priv; + gs_free_error GError *error = NULL; + GDBusProxy *resolve; - priv->resolve = g_dbus_proxy_new_finish (r, &error); + resolve = g_dbus_proxy_new_finish (r, &error); + if ( !resolve + && g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + return; - if (priv->resolve == NULL) { + priv = NM_DNS_SYSTEMD_RESOLVED_GET_PRIVATE (self); + g_clear_object (&priv->init_cancellable); + if (!resolve) { _LOGW ("failed to connect to resolved via DBus: %s", error->message); g_signal_emit_by_name (self, NM_DNS_PLUGIN_FAILED); - g_error_free (error); return; } + priv->resolve = resolve; send_updates (self); } |