diff --git a/src/dns-manager/nm-dns-manager.c b/src/dns-manager/nm-dns-manager.c index 32800d0b01..fc58232702 100644 --- a/src/dns-manager/nm-dns-manager.c +++ b/src/dns-manager/nm-dns-manager.c @@ -61,7 +61,9 @@ G_DEFINE_TYPE(NMDnsManager, nm_dns_manager, G_TYPE_OBJECT) NM_TYPE_DNS_MANAGER, \ NMDnsManagerPrivate)) -struct NMDnsManagerPrivate { +typedef struct { + gboolean disposed; + NMIP4Config *ip4_vpn_config; NMIP4Config *ip4_device_config; NMIP6Config *ip6_vpn_config; @@ -84,7 +86,7 @@ struct NMDnsManagerPrivate { * associated with a network interface (like hostnames). */ char *last_iface; -}; +} NMDnsManagerPrivate; typedef struct { @@ -1074,18 +1076,46 @@ nm_dns_manager_init (NMDnsManager *mgr) } static void -nm_dns_manager_finalize (GObject *object) +dispose (GObject *object) +{ + NMDnsManager *self = NM_DNS_MANAGER (object); + NMDnsManagerPrivate *priv = NM_DNS_MANAGER_GET_PRIVATE (self); + GError *error = NULL; + + if (priv->disposed == FALSE) { + priv->disposed = TRUE; + + g_slist_foreach (priv->plugins, (GFunc) g_object_unref, NULL); + g_slist_free (priv->plugins); + priv->plugins = NULL; + + /* If we're quitting leave a valid resolv.conf in place, not one + * pointing to 127.0.0.1 if any plugins were active. Thus update + * DNS after disposing of all plugins. + */ + if (!update_dns (self, priv->last_iface, TRUE, &error)) { + nm_log_warn (LOGD_DNS, "could not commit DNS changes on shutdown: (%d) %s", + error ? error->code : -1, + error && error->message ? error->message : "(unknown)"); + g_clear_error (&error); + } + + g_slist_foreach (priv->configs, (GFunc) g_object_unref, NULL); + g_slist_free (priv->configs); + priv->configs = NULL; + } + + G_OBJECT_CLASS (nm_dns_manager_parent_class)->dispose (object); +} + +static void +finalize (GObject *object) { NMDnsManagerPrivate *priv = NM_DNS_MANAGER_GET_PRIVATE (object); - g_slist_foreach (priv->configs, (GFunc) g_object_unref, NULL); - g_slist_free (priv->configs); g_free (priv->hostname); g_free (priv->last_iface); - g_slist_foreach (priv->plugins, (GFunc) g_object_unref, NULL); - g_slist_free (priv->plugins); - G_OBJECT_CLASS (nm_dns_manager_parent_class)->finalize (object); } @@ -1094,7 +1124,8 @@ nm_dns_manager_class_init (NMDnsManagerClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); - object_class->finalize = nm_dns_manager_finalize; + object_class->dispose = dispose; + object_class->finalize = finalize; g_type_class_add_private (object_class, sizeof (NMDnsManagerPrivate)); } diff --git a/src/dns-manager/nm-dns-manager.h b/src/dns-manager/nm-dns-manager.h index 66ee594044..25d2a98158 100644 --- a/src/dns-manager/nm-dns-manager.h +++ b/src/dns-manager/nm-dns-manager.h @@ -54,8 +54,6 @@ G_BEGIN_DECLS #define NM_IS_DNS_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), NM_TYPE_DNS_MANAGER)) #define NM_DNS_MANAGER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), NM_TYPE_DNS_MANAGER, NMDnsManagerClass)) -typedef struct NMDnsManagerPrivate NMDnsManagerPrivate; - typedef struct { GObject parent; } NMDnsManager;