mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-02-25 18:50:36 +01:00
dns: only write out new DNS config if it really changed
Use a pseudo-hash to quickly check whether the DNS config has really changed or not. This is certainly better than the 500 line patch I did then scrapped in favor of this approach... yay. This helps ensure that we don't kill then respawn caching DNS servers more often than we have to.
This commit is contained in:
parent
9d0775448c
commit
57f6feb102
1 changed files with 72 additions and 2 deletions
|
|
@ -43,6 +43,7 @@
|
|||
#include "nm-system.h"
|
||||
#include "NetworkManagerUtils.h"
|
||||
|
||||
#include "nm-dns-plugin.h"
|
||||
#include "nm-dns-dnsmasq.h"
|
||||
|
||||
#ifdef HAVE_SELINUX
|
||||
|
|
@ -53,8 +54,6 @@
|
|||
#define RESOLV_CONF "/etc/resolv.conf"
|
||||
#endif
|
||||
|
||||
#define ADDR_BUF_LEN 50
|
||||
|
||||
G_DEFINE_TYPE(NMDnsManager, nm_dns_manager, G_TYPE_OBJECT)
|
||||
|
||||
#define NM_DNS_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), \
|
||||
|
|
@ -69,6 +68,14 @@ struct NMDnsManagerPrivate {
|
|||
GSList *configs;
|
||||
char *hostname;
|
||||
|
||||
/* poor man's hash; we assume that the IP4 config object won't change
|
||||
* after it's given to us, which is (at this time) a fair assumption. So
|
||||
* we track the order of the currently applied IP configs and if they
|
||||
* haven't changed we don't need to rewrite resolv.conf.
|
||||
*/
|
||||
#define HLEN 6
|
||||
gpointer hash[HLEN];
|
||||
|
||||
GSList *plugins;
|
||||
|
||||
/* This is a hack because SUSE's netconfig always wants changes
|
||||
|
|
@ -525,6 +532,37 @@ out:
|
|||
return *error ? FALSE : TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
compute_hash (NMDnsManager *self, gpointer *hash)
|
||||
{
|
||||
NMDnsManagerPrivate *priv = NM_DNS_MANAGER_GET_PRIVATE (self);
|
||||
gpointer check[HLEN];
|
||||
GSList *iter;
|
||||
int i = 0;
|
||||
|
||||
memset (check, 0, sizeof (check));
|
||||
|
||||
if (priv->ip4_vpn_config)
|
||||
check[i++] = priv->ip4_vpn_config;
|
||||
if (priv->ip4_device_config)
|
||||
check[i++] = priv->ip4_device_config;
|
||||
|
||||
if (priv->ip6_vpn_config)
|
||||
check[i++] = priv->ip6_vpn_config;
|
||||
if (priv->ip6_device_config)
|
||||
check[i++] = priv->ip6_device_config;
|
||||
|
||||
/* Add two more "other" configs if any exist */
|
||||
for (iter = priv->configs; iter && i < HLEN; iter = g_slist_next (iter)) {
|
||||
if ( (iter->data != priv->ip4_vpn_config)
|
||||
&& (iter->data != priv->ip4_device_config)
|
||||
&& (iter->data != priv->ip6_vpn_config)
|
||||
&& (iter->data != priv->ip6_device_config))
|
||||
check[i++] = iter->data;
|
||||
}
|
||||
memcpy (hash, check, sizeof (check));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
update_dns (NMDnsManager *self,
|
||||
const char *iface,
|
||||
|
|
@ -552,6 +590,9 @@ update_dns (NMDnsManager *self,
|
|||
priv->last_iface = g_strdup (iface);
|
||||
}
|
||||
|
||||
/* Update hash with config we're applying */
|
||||
compute_hash (self, priv->hash);
|
||||
|
||||
rc.nameservers = g_ptr_array_new ();
|
||||
rc.domain = NULL;
|
||||
rc.searches = g_ptr_array_new ();
|
||||
|
|
@ -734,6 +775,23 @@ plugin_failed (NMDnsPlugin *plugin, gpointer user_data)
|
|||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
config_changed (NMDnsManager *self)
|
||||
{
|
||||
NMDnsManagerPrivate *priv = NM_DNS_MANAGER_GET_PRIVATE (self);
|
||||
gpointer check[HLEN];
|
||||
|
||||
/* We only store HLEN configs; so if there are actually more than that,
|
||||
* we have to assume that the config has changed.
|
||||
*/
|
||||
if (g_slist_length (priv->configs) > HLEN)
|
||||
return TRUE;
|
||||
|
||||
/* Otherwise return TRUE if the configuration has changed */
|
||||
compute_hash (self, check);
|
||||
return memcmp (check, priv->hash, sizeof (check)) ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
nm_dns_manager_add_ip4_config (NMDnsManager *mgr,
|
||||
const char *iface,
|
||||
|
|
@ -764,6 +822,9 @@ nm_dns_manager_add_ip4_config (NMDnsManager *mgr,
|
|||
if (!g_slist_find (priv->configs, config))
|
||||
priv->configs = g_slist_append (priv->configs, g_object_ref (config));
|
||||
|
||||
if (!config_changed (mgr))
|
||||
return TRUE;
|
||||
|
||||
if (!update_dns (mgr, iface, FALSE, &error)) {
|
||||
nm_log_warn (LOGD_DNS, "could not commit DNS changes: (%d) %s",
|
||||
error ? error->code : -1,
|
||||
|
|
@ -801,6 +862,9 @@ nm_dns_manager_remove_ip4_config (NMDnsManager *mgr,
|
|||
|
||||
g_object_unref (config);
|
||||
|
||||
if (config_changed (mgr))
|
||||
return TRUE;
|
||||
|
||||
if (!update_dns (mgr, iface, FALSE, &error)) {
|
||||
nm_log_warn (LOGD_DNS, "could not commit DNS changes: (%d) %s",
|
||||
error ? error->code : -1,
|
||||
|
|
@ -843,6 +907,9 @@ nm_dns_manager_add_ip6_config (NMDnsManager *mgr,
|
|||
if (!g_slist_find (priv->configs, config))
|
||||
priv->configs = g_slist_append (priv->configs, g_object_ref (config));
|
||||
|
||||
if (config_changed (mgr))
|
||||
return TRUE;
|
||||
|
||||
if (!update_dns (mgr, iface, FALSE, &error)) {
|
||||
nm_log_warn (LOGD_DNS, "could not commit DNS changes: (%d) %s",
|
||||
error ? error->code : -1,
|
||||
|
|
@ -880,6 +947,9 @@ nm_dns_manager_remove_ip6_config (NMDnsManager *mgr,
|
|||
|
||||
g_object_unref (config);
|
||||
|
||||
if (config_changed (mgr))
|
||||
return TRUE;
|
||||
|
||||
if (!update_dns (mgr, iface, FALSE, &error)) {
|
||||
nm_log_warn (LOGD_DNS, "could not commit DNS changes: (%d) %s",
|
||||
error ? error->code : -1,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue