diff options
author | Thomas Haller <thaller@redhat.com> | 2017-02-04 20:42:42 +0100 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2017-02-10 15:26:45 +0100 |
commit | ecd3263e4011879a960419ed04d5f526c90d55e8 (patch) | |
tree | e1d8ee1d74874ddb091cf37365d6c41e630d183b | |
parent | 6ad8011e2dd3533860a4d98bd5de2528eecdd6cf (diff) | |
download | NetworkManager-ecd3263e4011879a960419ed04d5f526c90d55e8.tar.gz |
dns: fix shutdown to restore non-cached DNS config
The DNS manager and other singletons have the problem that
they are not properly destroyed on exit, that is, we leak
most of the instances. That should be eventually fixed and
all resources/memory should be released.
Anyway, fix the shutdown procedure by adding an explict command
nm_dns_manager_shutdown(). We should not rely on cleanup actions
to take place when the last reference is dropped, because then
we get complex interactions where we must ensure that everybody
drops the references at the right pointer.
Since the previous shutdown action was effectively never performed,
it is not quite clear what we actually want to do on shutdown.
For now, move the code to nm_dns_manager_stop(). We will see if
that is the desired behavior.
-rw-r--r-- | src/dns/nm-dns-manager.c | 56 | ||||
-rw-r--r-- | src/dns/nm-dns-manager.h | 2 | ||||
-rw-r--r-- | src/main.c | 3 |
3 files changed, 46 insertions, 15 deletions
diff --git a/src/dns/nm-dns-manager.c b/src/dns/nm-dns-manager.c index cbf8d5fb6b..c990243ec7 100644 --- a/src/dns/nm-dns-manager.c +++ b/src/dns/nm-dns-manager.c @@ -130,7 +130,10 @@ typedef struct { GPtrArray *configs; GVariant *config_variant; NMDnsIPConfigData *best_conf4, *best_conf6; - gboolean need_sort; + + bool need_sort:1; + bool dns_touched:1; + bool is_stopped:1; char *hostname; guint updates_queue; @@ -144,8 +147,6 @@ typedef struct { NMConfig *config; - gboolean dns_touched; - struct { guint64 ts; guint num_restarts; @@ -1124,6 +1125,11 @@ update_dns (NMDnsManager *self, priv = NM_DNS_MANAGER_GET_PRIVATE (self); + if (priv->is_stopped) { + _LOGD ("update-dns: not updating resolv.conf (is stopped)"); + return TRUE; + } + nm_clear_g_source (&priv->plugin_ratelimit.timer); if (NM_IN_SET (priv->rc_manager, NM_DNS_MANAGER_RESOLV_CONF_MAN_UNMANAGED, @@ -1546,6 +1552,35 @@ nm_dns_manager_end_updates (NMDnsManager *self, const char *func) memset (priv->prev_hash, 0, sizeof (priv->prev_hash)); } +void +nm_dns_manager_stop (NMDnsManager *self) +{ + NMDnsManagerPrivate *priv; + GError *error = NULL; + + priv = NM_DNS_MANAGER_GET_PRIVATE (self); + + if (priv->is_stopped) + g_return_if_reached (); + + _LOGT ("stopping..."); + + /* 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. But if we haven't done any + * DNS updates yet, there's no reason to touch resolv.conf on shutdown. + */ + if (priv->dns_touched) { + if (!update_dns (self, TRUE, &error)) { + _LOGW ("could not commit DNS changes on shutdown: %s", error->message); + g_clear_error (&error); + } + priv->dns_touched = FALSE; + } + + priv->is_stopped = TRUE; +} + /*****************************************************************************/ static gboolean @@ -2028,23 +2063,14 @@ dispose (GObject *object) NMDnsManager *self = NM_DNS_MANAGER (object); NMDnsManagerPrivate *priv = NM_DNS_MANAGER_GET_PRIVATE (self); NMDnsIPConfigData *data; - GError *error = NULL; guint i; _LOGT ("disposing"); - _clear_plugin (self); + if (!priv->is_stopped) + nm_dns_manager_stop (self); - /* 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. But if we haven't done any - * DNS updates yet, there's no reason to touch resolv.conf on shutdown. - */ - if (priv->dns_touched && !update_dns (self, TRUE, &error)) { - _LOGW ("could not commit DNS changes on shutdown: %s", error->message); - g_clear_error (&error); - priv->dns_touched = FALSE; - } + _clear_plugin (self); if (priv->config) { g_signal_handlers_disconnect_by_func (priv->config, config_changed_cb, self); diff --git a/src/dns/nm-dns-manager.h b/src/dns/nm-dns-manager.h index 2fc2031b71..451ca4a658 100644 --- a/src/dns/nm-dns-manager.h +++ b/src/dns/nm-dns-manager.h @@ -120,4 +120,6 @@ typedef enum { gboolean nm_dns_manager_get_resolv_conf_explicit (NMDnsManager *self); +void nm_dns_manager_stop (NMDnsManager *self); + #endif /* __NETWORKMANAGER_DNS_MANAGER_H__ */ diff --git a/src/main.c b/src/main.c index 20e6f30ff3..57902dd652 100644 --- a/src/main.c +++ b/src/main.c @@ -49,6 +49,7 @@ #include "nm-auth-manager.h" #include "nm-core-internal.h" #include "nm-exported-object.h" +#include "dns/nm-dns-manager.h" #include "systemd/nm-sd.h" #if !defined(NM_DIST_VERSION) @@ -434,6 +435,8 @@ done: nm_config_state_set (config, TRUE, TRUE); + nm_dns_manager_stop (nm_dns_manager_get ()); + if (global_opt.pidfile && wrote_pidfile) unlink (global_opt.pidfile); |