diff options
author | Thomas Haller <thaller@redhat.com> | 2016-03-22 10:31:23 +0100 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2016-03-22 17:35:57 +0100 |
commit | 9712cd418aa3b64187e670019f07331832ef83cb (patch) | |
tree | a15643f79c87f2dba9bb1b45a566ee62d0d382c6 | |
parent | aea086d068d4fbad3fa5ab65c9734fd07eeaa34f (diff) | |
download | NetworkManager-th/dns-resolv-conf-file-bgo764004.tar.gz |
dns: always reload the dns configuration mode on SIGHUPth/dns-resolv-conf-file-bgo764004
-rw-r--r-- | src/dns-manager/nm-dns-manager.c | 65 |
1 files changed, 53 insertions, 12 deletions
diff --git a/src/dns-manager/nm-dns-manager.c b/src/dns-manager/nm-dns-manager.c index 87a8a1e0a8..20b967621e 100644 --- a/src/dns-manager/nm-dns-manager.c +++ b/src/dns-manager/nm-dns-manager.c @@ -125,6 +125,9 @@ typedef struct { NMDnsManagerResolvConfMode resolv_conf_mode; NMDnsManagerResolvConfManager rc_manager; + char *last_mode; + bool last_immutable:1; + bool mode_initialized:1; NMDnsPlugin *plugin; NMConfig *config; @@ -1363,6 +1366,26 @@ nm_dns_manager_end_updates (NMDnsManager *self, const char *func) /******************************************************************/ +static bool +_get_resconf_immutable (int *immutable_cached) +{ + int fd, flags; + int immutable; + + immutable = *immutable_cached; + if (!NM_IN_SET (immutable, FALSE, TRUE)) { + immutable = FALSE; + fd = open (_PATH_RESCONF, O_RDONLY); + if (fd != -1) { + if (ioctl (fd, FS_IOC_GETFLAGS, &flags) != -1) + immutable = NM_FLAGS_HAS (flags, FS_IMMUTABLE_FL); + close (fd); + } + *immutable_cached = immutable; + } + return immutable; +} + NM_DEFINE_SINGLETON_GETTER (NMDnsManager, nm_dns_manager_get, NM_TYPE_DNS_MANAGER); static void @@ -1370,25 +1393,34 @@ init_resolv_conf_mode (NMDnsManager *self) { NMDnsManagerPrivate *priv = NM_DNS_MANAGER_GET_PRIVATE (self); const char *mode, *mode_unknown; - int fd, flags; - gboolean immutable = FALSE; + int immutable = -1; + + mode = nm_config_data_get_dns_mode (nm_config_get_data (priv->config)); + if ( priv->mode_initialized + && nm_streq0 (mode, priv->last_mode) + && ( nm_streq0 (mode, "none") + || priv->last_immutable == _get_resconf_immutable (&immutable))) { + /* we call init_resolv_conf_mode() on every SIGHUP to possibly reload + * when either "mode" or "immutable" changed. However, we don't want to + * re-create the plugin, when the paramters didn't actually change. So + * detect that we would recreate the same plugin and return early. */ + return; + } + + priv->mode_initialized = TRUE; + g_free (priv->last_mode); + priv->last_mode = g_strdup (mode); + priv->last_immutable = FALSE; g_clear_object (&priv->plugin); priv->resolv_conf_mode = NM_DNS_MANAGER_RESOLV_CONF_UNMANAGED; - mode = nm_config_data_get_dns_mode (nm_config_get_data (priv->config)); - if (!g_strcmp0 (mode, "none")) { + if (nm_streq0 (mode, "none")) { _LOGI ("%s%s", "set resolv-conf-mode: ", "none"); return; } - fd = open (_PATH_RESCONF, O_RDONLY); - if (fd != -1) { - if (ioctl (fd, FS_IOC_GETFLAGS, &flags) == -1) - flags = 0; - close (fd); - immutable = NM_FLAGS_HAS (flags, FS_IMMUTABLE_FL); - } + priv->last_immutable = _get_resconf_immutable (&immutable); if (NM_IN_STRSET (mode, "dnsmasq", "unbound")) { if (!immutable) @@ -1461,8 +1493,15 @@ config_changed_cb (NMConfig *config, { GError *error = NULL; - if (NM_FLAGS_HAS (changes, NM_CONFIG_CHANGE_DNS_MODE)) + if (NM_FLAGS_ANY (changes, NM_CONFIG_CHANGE_DNS_MODE | + NM_CONFIG_CHANGE_SIGHUP)) { + /* reload the resolv-conf mode also on SIGHUP (when DNS_MODE didn't change). + * The reason is, that the configuration also depends on whether resolv.conf + * is immutable, thus, without the configuration changing, we always want to + * re-configure the mode. */ init_resolv_conf_mode (self); + } + if (NM_FLAGS_HAS (changes, NM_CONFIG_CHANGE_RC_MANAGER)) init_resolv_conf_manager (self); @@ -1513,6 +1552,8 @@ dispose (GObject *object) g_clear_object (&priv->plugin); } + g_clear_pointer (&priv->last_mode, g_free); + /* 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 |