diff options
| author | Michael Biebl <biebl@debian.org> | 2012-06-29 20:12:44 +0200 |
|---|---|---|
| committer | Michael Biebl <biebl@debian.org> | 2012-06-29 20:12:44 +0200 |
| commit | 867254ea7c2b193fecf8cd36cc6e5dc53c290d92 (patch) | |
| tree | 7c698b403882736ab70c3efd524c3460f08c391c /src/dns-manager | |
| parent | de06e5715e780baade318f3490ac7a4c9ce84e32 (diff) | |
Imported Upstream version 0.9.5.95 upstream/0.9.5.95
Diffstat (limited to 'src/dns-manager')
| -rw-r--r-- | src/dns-manager/Makefile.am | 2 | ||||
| -rw-r--r-- | src/dns-manager/Makefile.in | 14 | ||||
| -rw-r--r-- | src/dns-manager/nm-dns-manager.c | 161 | ||||
| -rw-r--r-- | src/dns-manager/nm-dns-manager.h | 4 | ||||
| -rw-r--r-- | src/dns-manager/nm-dns-plugin.c | 9 |
5 files changed, 127 insertions, 63 deletions
diff --git a/src/dns-manager/Makefile.am b/src/dns-manager/Makefile.am index 331f85c4..fd31b140 100644 --- a/src/dns-manager/Makefile.am +++ b/src/dns-manager/Makefile.am @@ -1,5 +1,6 @@ INCLUDES = \ -I${top_srcdir}/src/logging \ + -I${top_srcdir}/src/posix-signals \ -I${top_srcdir}/libnm-util \ -I${top_builddir}/libnm-util \ -I${top_srcdir}/src \ @@ -28,6 +29,7 @@ libdns_manager_la_CPPFLAGS = \ libdns_manager_la_LIBADD = \ $(top_builddir)/src/logging/libnm-logging.la \ + $(top_builddir)/src/posix-signals/libnm-posix-signals.la \ $(LIBNL_LIBS) \ $(DBUS_LIBS) \ $(GLIB_LIBS) diff --git a/src/dns-manager/Makefile.in b/src/dns-manager/Makefile.in index c9b8b0b3..ddcce666 100644 --- a/src/dns-manager/Makefile.in +++ b/src/dns-manager/Makefile.in @@ -47,7 +47,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/compiler_warnings.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/nls.m4 \ $(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/progtest.m4 \ - $(top_srcdir)/configure.ac + $(top_srcdir)/m4/vapigen.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d @@ -58,6 +58,7 @@ LTLIBRARIES = $(noinst_LTLIBRARIES) am__DEPENDENCIES_1 = libdns_manager_la_DEPENDENCIES = \ $(top_builddir)/src/logging/libnm-logging.la \ + $(top_builddir)/src/posix-signals/libnm-posix-signals.la \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) am_libdns_manager_la_OBJECTS = libdns_manager_la-nm-dns-manager.lo \ @@ -172,6 +173,10 @@ INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@ INTLTOOL_MERGE = @INTLTOOL_MERGE@ INTLTOOL_PERL = @INTLTOOL_PERL@ INTLTOOL_UPDATE = @INTLTOOL_UPDATE@ +INTLTOOL_V_MERGE = @INTLTOOL_V_MERGE@ +INTLTOOL_V_MERGE_OPTIONS = @INTLTOOL_V_MERGE_OPTIONS@ +INTLTOOL__v_MERGE_ = @INTLTOOL__v_MERGE_@ +INTLTOOL__v_MERGE_0 = @INTLTOOL__v_MERGE_0@ INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ INTROSPECTION_CFLAGS = @INTROSPECTION_CFLAGS@ INTROSPECTION_COMPILER = @INTROSPECTION_COMPILER@ @@ -267,6 +272,9 @@ UDEV_BASE_DIR = @UDEV_BASE_DIR@ USE_NLS = @USE_NLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ +VAPIGEN = @VAPIGEN@ +VAPIGEN_MAKEFILE = @VAPIGEN_MAKEFILE@ +VAPIGEN_VAPIDIR = @VAPIGEN_VAPIDIR@ VERSION = @VERSION@ XGETTEXT = @XGETTEXT@ XGETTEXT_015 = @XGETTEXT_015@ @@ -305,6 +313,8 @@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ +intltool__v_merge_options_ = @intltool__v_merge_options_@ +intltool__v_merge_options_0 = @intltool__v_merge_options_0@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ @@ -327,6 +337,7 @@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ INCLUDES = \ -I${top_srcdir}/src/logging \ + -I${top_srcdir}/src/posix-signals \ -I${top_srcdir}/libnm-util \ -I${top_builddir}/libnm-util \ -I${top_srcdir}/src \ @@ -354,6 +365,7 @@ libdns_manager_la_CPPFLAGS = \ libdns_manager_la_LIBADD = \ $(top_builddir)/src/logging/libnm-logging.la \ + $(top_builddir)/src/posix-signals/libnm-posix-signals.la \ $(LIBNL_LIBS) \ $(DBUS_LIBS) \ $(GLIB_LIBS) diff --git a/src/dns-manager/nm-dns-manager.c b/src/dns-manager/nm-dns-manager.c index 6272e374..38ef08ea 100644 --- a/src/dns-manager/nm-dns-manager.c +++ b/src/dns-manager/nm-dns-manager.c @@ -16,7 +16,7 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Copyright (C) 2004 - 2005 Colin Walters <walters@redhat.com> - * Copyright (C) 2004 - 2011 Red Hat, Inc. + * Copyright (C) 2004 - 2012 Red Hat, Inc. * Copyright (C) 2005 - 2008 Novell, Inc. * and others */ @@ -42,6 +42,7 @@ #include "nm-logging.h" #include "backends/nm-backend.h" #include "NetworkManagerUtils.h" +#include "nm-posix-signals.h" #include "nm-dns-plugin.h" #include "nm-dns-dnsmasq.h" @@ -61,6 +62,8 @@ G_DEFINE_TYPE(NMDnsManager, nm_dns_manager, G_TYPE_OBJECT) NM_TYPE_DNS_MANAGER, \ NMDnsManagerPrivate)) +#define HASH_LEN 20 + typedef struct { gboolean disposed; @@ -70,14 +73,10 @@ typedef struct { NMIP6Config *ip6_device_config; GSList *configs; char *hostname; + guint updates_queue; - /* 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]; + guint8 hash[HASH_LEN]; /* SHA1 hash of current DNS config */ + guint8 prev_hash[HASH_LEN]; /* Hash when begin_updates() was called */ GSList *plugins; @@ -218,6 +217,12 @@ netconfig_child_setup (gpointer user_data G_GNUC_UNUSED) { pid_t pid = getpid (); setpgid (pid, pid); + + /* + * We blocked signals in main(). We need to restore original signal + * mask for netconfig here so that it can receive signals. + */ + nm_unblock_posix_signals (NULL); } static GPid @@ -529,34 +534,43 @@ out: } static void -compute_hash (NMDnsManager *self, gpointer *hash) +compute_hash (NMDnsManager *self, guint8 buffer[HASH_LEN]) { NMDnsManagerPrivate *priv = NM_DNS_MANAGER_GET_PRIVATE (self); - gpointer check[HLEN]; + GChecksum *sum; GSList *iter; - int i = 0; + gsize len = HASH_LEN; - memset (check, 0, sizeof (check)); + sum = g_checksum_new (G_CHECKSUM_SHA1); + g_assert (len == g_checksum_type_get_length (G_CHECKSUM_SHA1)); if (priv->ip4_vpn_config) - check[i++] = priv->ip4_vpn_config; + nm_ip4_config_hash (priv->ip4_vpn_config, sum, TRUE); if (priv->ip4_device_config) - check[i++] = priv->ip4_device_config; + nm_ip4_config_hash (priv->ip4_device_config, sum, TRUE); if (priv->ip6_vpn_config) - check[i++] = priv->ip6_vpn_config; + nm_ip6_config_hash (priv->ip6_vpn_config, sum, TRUE); if (priv->ip6_device_config) - check[i++] = priv->ip6_device_config; + nm_ip6_config_hash (priv->ip6_device_config, sum, TRUE); - /* 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; + /* add any other configs we know about */ + for (iter = priv->configs; iter; 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)) + continue; + + if (NM_IS_IP4_CONFIG (iter->data)) + nm_ip4_config_hash (NM_IP4_CONFIG (iter->data), sum, TRUE); + else if (NM_IS_IP6_CONFIG (iter->data)) + nm_ip6_config_hash (NM_IP6_CONFIG (iter->data), sum, TRUE); } - memcpy (hash, check, sizeof (check)); + + memset (buffer, 0, sizeof (buffer)); + g_checksum_get_digest (sum, buffer, &len); + g_checksum_free (sum); } static gboolean @@ -581,6 +595,8 @@ update_dns (NMDnsManager *self, priv = NM_DNS_MANAGER_GET_PRIVATE (self); + nm_log_dbg (LOGD_DNS, "updating resolv.conf"); + if (iface && (iface != priv->last_iface)) { g_free (priv->last_iface); priv->last_iface = g_strdup (iface); @@ -784,23 +800,6 @@ 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, @@ -831,10 +830,7 @@ 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)) { + if (!priv->updates_queue && !update_dns (mgr, iface, FALSE, &error)) { nm_log_warn (LOGD_DNS, "could not commit DNS changes: (%d) %s", error ? error->code : -1, error && error->message ? error->message : "(unknown)"); @@ -871,10 +867,7 @@ 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)) { + if (!priv->updates_queue && !update_dns (mgr, iface, FALSE, &error)) { nm_log_warn (LOGD_DNS, "could not commit DNS changes: (%d) %s", error ? error->code : -1, error && error->message ? error->message : "(unknown)"); @@ -901,8 +894,6 @@ nm_dns_manager_add_ip6_config (NMDnsManager *mgr, switch (cfg_type) { case NM_DNS_IP_CONFIG_TYPE_VPN: - /* FIXME: not quite yet... */ - g_return_val_if_fail (cfg_type != NM_DNS_IP_CONFIG_TYPE_VPN, FALSE); priv->ip6_vpn_config = config; break; case NM_DNS_IP_CONFIG_TYPE_BEST_DEVICE: @@ -916,10 +907,7 @@ 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)) { + if (!priv->updates_queue && !update_dns (mgr, iface, FALSE, &error)) { nm_log_warn (LOGD_DNS, "could not commit DNS changes: (%d) %s", error ? error->code : -1, error && error->message ? error->message : "(unknown)"); @@ -956,10 +944,7 @@ 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)) { + if (!priv->updates_queue && !update_dns (mgr, iface, FALSE, &error)) { nm_log_warn (LOGD_DNS, "could not commit DNS changes: (%d) %s", error ? error->code : -1, error && error->message ? error->message : "(unknown)"); @@ -997,7 +982,7 @@ nm_dns_manager_set_hostname (NMDnsManager *mgr, * wants one. But hostname changes are system-wide and *not* tied to a * specific interface, so netconfig can't really handle this. Fake it. */ - if (!update_dns (mgr, priv->last_iface, FALSE, &error)) { + if (!priv->updates_queue && !update_dns (mgr, priv->last_iface, FALSE, &error)) { nm_log_warn (LOGD_DNS, "could not commit DNS changes: (%d) %s", error ? error->code : -1, error && error->message ? error->message : "(unknown)"); @@ -1005,6 +990,58 @@ nm_dns_manager_set_hostname (NMDnsManager *mgr, } } +void +nm_dns_manager_begin_updates (NMDnsManager *mgr, const char *func) +{ + NMDnsManagerPrivate *priv; + + g_return_if_fail (mgr != NULL); + priv = NM_DNS_MANAGER_GET_PRIVATE (mgr); + + /* Save current hash when starting a new batch */ + if (priv->updates_queue == 0) + memcpy (priv->prev_hash, priv->hash, sizeof (priv->hash)); + + priv->updates_queue++; + + nm_log_dbg (LOGD_DNS, "(%s): queueing DNS updates (%d)", func, priv->updates_queue); +} + +void +nm_dns_manager_end_updates (NMDnsManager *mgr, const char *func) +{ + NMDnsManagerPrivate *priv; + GError *error = NULL; + gboolean changed; + guint8 new[HASH_LEN]; + + g_return_if_fail (mgr != NULL); + + priv = NM_DNS_MANAGER_GET_PRIVATE (mgr); + g_return_if_fail (priv->updates_queue > 0); + + compute_hash (mgr, new); + changed = (memcmp (new, priv->prev_hash, sizeof (new)) != 0) ? TRUE : FALSE; + nm_log_dbg (LOGD_DNS, "(%s): DNS configuration %s", __func__, changed ? "changed" : "did not change"); + + priv->updates_queue--; + if ((priv->updates_queue > 0) || (changed == FALSE)) { + nm_log_dbg (LOGD_DNS, "(%s): no DNS changes to commit (%d)", func, priv->updates_queue); + return; + } + + /* Commit all the outstanding changes */ + nm_log_dbg (LOGD_DNS, "(%s): committing DNS changes (%d)", func, priv->updates_queue); + if (!update_dns (mgr, priv->last_iface, FALSE, &error)) { + nm_log_warn (LOGD_DNS, "could not commit DNS changes: (%d) %s", + error ? error->code : -1, + error && error->message ? error->message : "(unknown)"); + g_clear_error (&error); + } + + memset (priv->prev_hash, 0, sizeof (priv->prev_hash)); +} + static void load_plugins (NMDnsManager *self, const char **plugins) { @@ -1079,8 +1116,10 @@ nm_dns_manager_error_quark (void) } static void -nm_dns_manager_init (NMDnsManager *mgr) +nm_dns_manager_init (NMDnsManager *self) { + /* Set the initial hash */ + compute_hash (self, NM_DNS_MANAGER_GET_PRIVATE (self)->hash); } static void diff --git a/src/dns-manager/nm-dns-manager.h b/src/dns-manager/nm-dns-manager.h index 25d2a981..f559865b 100644 --- a/src/dns-manager/nm-dns-manager.h +++ b/src/dns-manager/nm-dns-manager.h @@ -66,6 +66,10 @@ GType nm_dns_manager_get_type (void); NMDnsManager * nm_dns_manager_get (const char **plugins); +/* Allow changes to be batched together */ +void nm_dns_manager_begin_updates (NMDnsManager *mgr, const char *func); +void nm_dns_manager_end_updates (NMDnsManager *mgr, const char *func); + gboolean nm_dns_manager_add_ip4_config (NMDnsManager *mgr, const char *iface, NMIP4Config *config, diff --git a/src/dns-manager/nm-dns-plugin.c b/src/dns-manager/nm-dns-plugin.c index e997948e..b26f2b94 100644 --- a/src/dns-manager/nm-dns-plugin.c +++ b/src/dns-manager/nm-dns-plugin.c @@ -13,7 +13,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright (C) 2010 Red Hat, Inc. + * Copyright (C) 2010 - 2012 Red Hat, Inc. * */ @@ -27,6 +27,7 @@ #include "nm-dns-plugin.h" #include "nm-logging.h" +#include "nm-posix-signals.h" typedef struct { gboolean disposed; @@ -141,6 +142,12 @@ child_setup (gpointer user_data G_GNUC_UNUSED) /* We are in the child process at this point */ pid_t pid = getpid (); setpgid (pid, pid); + + /* + * We blocked signals in main(). We need to restore original signal + * mask for DNS plugin here so that it can receive signals. + */ + nm_unblock_posix_signals (NULL); } GPid |