From 9aaedfde6bebef2360b479399919de6b083e481cb3d4961db51eafdd3c41967d Mon Sep 17 00:00:00 2001 From: Petr Baudis Date: Thu, 18 Mar 2010 13:37:59 +0000 Subject: [PATCH] - Fix /etc/resolv.conf change detection for multi-threaded applications (by Sebastian Kienzl) OBS-URL: https://build.opensuse.org/package/show/Base:System/glibc?expand=0&rev=20 --- glibc-2.4.90-nscd.diff | 37 ++++++++---- glibc-resolv-reload.diff | 124 +++++++++++++++++++++++++++++++++++++++ glibc.changes | 11 ++++ glibc.spec | 47 ++++++++++++++- resolv.dynamic.diff | 33 ----------- 5 files changed, 205 insertions(+), 47 deletions(-) create mode 100644 glibc-resolv-reload.diff delete mode 100644 resolv.dynamic.diff diff --git a/glibc-2.4.90-nscd.diff b/glibc-2.4.90-nscd.diff index f66d910..ce178a1 100644 --- a/glibc-2.4.90-nscd.diff +++ b/glibc-2.4.90-nscd.diff @@ -1,7 +1,7 @@ Index: nscd/cache.c =================================================================== ---- nscd/cache.c.orig -+++ nscd/cache.c +--- nscd/cache.c.orig 2010-01-18 18:01:41.000000000 +0100 ++++ nscd/cache.c 2010-02-14 14:58:08.000000000 +0100 @@ -267,28 +267,31 @@ prune_cache (struct database_dyn *table, if (table->inotify_descr < 0 && table->check_file && now != LONG_MAX) { @@ -47,8 +47,8 @@ Index: nscd/cache.c Note that for the initial step, finding the entries to be removed, Index: nscd/connections.c =================================================================== ---- nscd/connections.c.orig -+++ nscd/connections.c +--- nscd/connections.c.orig 2010-01-18 18:01:41.000000000 +0100 ++++ nscd/connections.c 2010-02-14 14:58:08.000000000 +0100 @@ -119,6 +119,7 @@ struct database_dyn dbs[lastdb] = .suggested_module = DEFAULT_SUGGESTED_MODULE, .reset_res = 0, @@ -94,8 +94,8 @@ Index: nscd/connections.c Index: nscd/nscd.conf =================================================================== ---- nscd/nscd.conf.orig -+++ nscd/nscd.conf +--- nscd/nscd.conf.orig 2010-01-18 18:01:41.000000000 +0100 ++++ nscd/nscd.conf 2010-02-14 14:58:08.000000000 +0100 @@ -61,11 +61,11 @@ auto-propagate group yes @@ -113,8 +113,8 @@ Index: nscd/nscd.conf Index: nscd/nscd.h =================================================================== ---- nscd/nscd.h.orig -+++ nscd/nscd.h +--- nscd/nscd.h.orig 2010-01-18 18:01:41.000000000 +0100 ++++ nscd/nscd.h 2010-02-14 14:59:07.000000000 +0100 @@ -80,8 +80,10 @@ struct database_dyn int propagate; int reset_res; @@ -128,9 +128,24 @@ Index: nscd/nscd.h Index: nscd/nscd_stat.c =================================================================== ---- nscd/nscd_stat.c.orig -+++ nscd/nscd_stat.c -@@ -302,7 +302,7 @@ receive_print_stats (void) +--- nscd/nscd_stat.c.orig 2010-01-18 18:01:41.000000000 +0100 ++++ nscd/nscd_stat.c 2010-02-14 15:02:41.000000000 +0100 +@@ -37,8 +37,13 @@ + #endif /* HAVE_SELINUX */ + + +-/* We use this to make sure the receiver is the same. */ ++/* We use this to make sure the receiver is the same. Capture mtime ++ of this file if possible. */ ++#if defined(__TIMESTAMP__) ++static const char compilation[21] = __TIMESTAMP__; ++#else + static const char compilation[21] = __DATE__ " " __TIME__; ++#endif + + /* Statistic data for one database. */ + struct dbstat +@@ -302,7 +307,7 @@ receive_print_stats (void) data.dbs[i].maxnsearched, data.dbs[i].rdlockdelayed, data.dbs[i].wrlockdelayed, diff --git a/glibc-resolv-reload.diff b/glibc-resolv-reload.diff new file mode 100644 index 0000000..d2013a5 --- /dev/null +++ b/glibc-resolv-reload.diff @@ -0,0 +1,124 @@ +From libc-alpha-return-22754-pasky=ucw.cz@sourceware.org Tue Mar 16 00:47:00 2010 +Return-Path: +X-Original-To: pasky@pasky.or.cz +Delivered-To: pasky@pasky.or.cz +Received: from nikam.ms.mff.cuni.cz (nikam-dmz.ms.mff.cuni.cz [195.113.20.16]) + by machine.or.cz (Postfix) with ESMTPS id C1B8586202A + for ; Tue, 16 Mar 2010 00:47:00 +0100 (CET) +Received: by nikam.ms.mff.cuni.cz (Postfix) + id 9CDEC9AC7A4; Tue, 16 Mar 2010 00:47:00 +0100 (CET) +Delivered-To: pasky@kam.mff.cuni.cz +Received: from jabberwock.ucw.cz (jabberwock.ucw.cz [89.250.246.4]) + by nikam.ms.mff.cuni.cz (Postfix) with ESMTP id 99F0E9AC77B + for ; Tue, 16 Mar 2010 00:47:00 +0100 (CET) +Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) + by jabberwock.ucw.cz (Postfix) with SMTP id 14E1ACF040 + for ; Tue, 16 Mar 2010 00:46:59 +0100 (CET) +Received: (qmail 18956 invoked by alias); 15 Mar 2010 23:46:58 -0000 +Delivered-To: moderator for libc-alpha@sourceware.org +Received: (qmail 15843 invoked by uid 22791); 15 Mar 2010 17:23:15 -0000 +X-SWARE-Spam-Status: No, hits=-2.6 required=5.0 + tests=BAYES_00 +X-Spam-Check-By: sourceware.org +Message-ID: <4B9E6CFA.7020002@riot.org> +Date: Mon, 15 Mar 2010 18:23:06 +0100 +From: Sebastian Kienzl +User-Agent: Thunderbird 2.0.0.23 (Windows/20090812) +MIME-Version: 1.0 +To: libc-alpha@sourceware.org +Subject: Reloading of /etc/resolv.conf +Content-Type: multipart/mixed; + boundary="------------060407080409020101000002" +Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm +Precedence: bulk +List-Id: +List-Unsubscribe: +List-Subscribe: +List-Archive: +List-Post: +List-Help: , +Sender: libc-alpha-owner@sourceware.org +Delivered-To: mailing list libc-alpha@sourceware.org + +This is a multi-part message in MIME format. +--------------060407080409020101000002 +Content-Type: text/plain; charset=ISO-8859-15; format=flowed +Content-Transfer-Encoding: 7bit + +Hello! + +There's a patch in the wild against the resolver which makes it reload +/etc/resolv.conf on change, see +http://sources.redhat.com/ml/libc-alpha/2004-09/msg00130.html + +However, this patch actually doesn't work properly for multi-threaded +programs, as only one thread will notice the change and refresh its +resolver state. I've attached a proper patch. It's for 2.5 but it should +work with current versions, too. + +Even though the patch may not be interesting for upstream, I decided to +let you know about this problem, since the mentioned patch seems to be +used by at least Debian and Ubuntu. + +Regards, +Seb. + + + +--------------060407080409020101000002 +Content-Type: text/plain; + name="glibc-2.5-resolvconf.patch" +Content-Transfer-Encoding: 7bit +Content-Disposition: inline; + filename="glibc-2.5-resolvconf.patch" + +diff -ur resolv.orig/res_libc.c resolv/res_libc.c +--- resolv.orig/res_libc.c 2005-11-01 01:06:40.000000000 +0100 ++++ resolv/res_libc.c 2010-03-15 14:13:18.000000000 +0100 +@@ -22,7 +22,7 @@ + #include + #include + #include +- ++#include + + /* The following bit is copied from res_data.c (where it is #ifdef'ed + out) since res_init() should go into libc.so but the rest of that +@@ -89,12 +89,34 @@ + return (__res_vinit(&_res, 1)); + } + ++static time_t resconf_mtime; ++__libc_lock_define_initialized (static, resconf_mtime_lock); ++ ++/* Check if the modification time of resolv.conf has changed. ++ If so, have all threads re-initialize their resolver states */ ++static void ++__res_check_resconf (void) ++{ ++ struct stat statbuf; ++ if (stat (_PATH_RESCONF, &statbuf) == 0) { ++ __libc_lock_lock (resconf_mtime_lock); ++ if (statbuf.st_mtime != resconf_mtime) { ++ resconf_mtime = statbuf.st_mtime; ++ atomicinclock (lock); ++ atomicinc (__res_initstamp); ++ atomicincunlock (lock); ++ } ++ __libc_lock_unlock (resconf_mtime_lock); ++ } ++} ++ + /* Initialize resp if RES_INIT is not yet set or if res_init in some other + thread requested re-initializing. */ + int + __res_maybe_init (res_state resp, int preinit) + { + if (resp->options & RES_INIT) { ++ __res_check_resconf (); + if (__res_initstamp != resp->_u._ext.initstamp) { + if (resp->nscount > 0) { + __res_iclose (resp, true); + + +--------------060407080409020101000002-- diff --git a/glibc.changes b/glibc.changes index 6b9a5c9..9b84cba 100644 --- a/glibc.changes +++ b/glibc.changes @@ -1,3 +1,14 @@ +------------------------------------------------------------------- +Thu Mar 18 14:29:42 CET 2010 - pbaudis@suse.cz + +- Fix /etc/resolv.conf change detection for multi-threaded applications + (by Sebastian Kienzl) + +------------------------------------------------------------------- +Sun Feb 14 15:33:33 CET 2010 - rguenther@suse.de + +- avoid spurious differences in nscd on rebuilds. + ------------------------------------------------------------------- Mon Jan 25 17:35:25 CET 2010 - meissner@suse.de diff --git a/glibc.spec b/glibc.spec index 40ac766..d3fe297 100644 --- a/glibc.spec +++ b/glibc.spec @@ -82,7 +82,7 @@ NoSource: 0 Patch0: glibc-2.3-SuSE.diff Patch1: glibc-2.3.90-noversion.diff Patch2: glibc-2.3.90-fnmatch.diff -Patch3: resolv.dynamic.diff +Patch3: glibc-resolv-reload.diff Patch4: glibc-2.3.locales.diff.bz2 Patch5: crypt_blowfish-1.0-suse.diff Patch7: glibc-version.diff @@ -310,9 +310,14 @@ rm sysdeps/x86_64/fpu/s_sincos.S %patch20 %patch21 %patch22 +# avoid changing nscd_stat.c mtime to avoid code generation +# differences on each rebuild +touch -r nscd/nscd_stat.c nscd/s-stamp %patch23 %patch24 %patch25 +touch -r nscd/s-stamp nscd/nscd_stat.c +rm nscd/s-stamp %patch26 %patch27 %patch29 @@ -359,12 +364,13 @@ rm sysdeps/x86_64/fpu/s_sincos.S # rm -fv sysdeps/powerpc/powerpc32/power4/hp-timing.c sysdeps/powerpc/powerpc32/power4/hp-timing.h find . -name configure | xargs touch + + ####################################################################### ### ### BUILD ### ####################################################################### - %build if [ -x /bin/uname.bin ]; then /bin/uname.bin -a @@ -436,6 +442,7 @@ PARALLEL="%{?jobs:-j%jobs}" # fails to build otherwise - need to recheck and fix %define enable_stackguard_randomization 0 %endif + configure_and_build_glibc() { local dirname="$1"; shift local cflags="$1"; shift @@ -459,6 +466,7 @@ configure_and_build_glibc() { make $PARALLEL cd .. } + %if !%{optimize_power} # # Build base glibc @@ -488,10 +496,12 @@ configure_and_build_glibc() { configure_and_build_glibc ppc-cell-be "$BuildFlags -mcpu=cell" "$add_ons" --disable-runbinaries %endif %endif # optimize_power + # # Build html documentation # make -C cc-base html + # # Build glibc_post_upgrade binary # @@ -510,6 +520,8 @@ $BuildCC -static -Os -g $RPM_SOURCE_DIR/glibc_post_upgrade.c -o glibc_post_upgra %endif %endif '-DLIBDIR="/%{_lib}"' '-DGCONV_MODULES_DIR="%{_prefix}/%{_lib}/gconv"' + + ####################################################################### ### ### CHECK @@ -531,6 +543,8 @@ $BuildCC -static -Os -g $RPM_SOURCE_DIR/glibc_post_upgrade.c -o glibc_post_upgra %endif %endif make -C cc-base check-abi || echo check-abi failed + + ####################################################################### ### ### INSTALL @@ -548,12 +562,15 @@ make -C cc-base check-abi || echo check-abi failed # debugging tools currently require these sections directly inside the main # files - specifically valgrind and PurifyPlus. export STRIP_KEEP_SYMTAB=*.so* + # Make sure we will create the gconv-modules.cache mkdir -p $RPM_BUILD_ROOT%{_libdir}/gconv touch $RPM_BUILD_ROOT%{_libdir}/gconv/gconv-modules.cache + # Install base glibc # Do not install in parallel, timezone Makefile will fail make install_root=$RPM_BUILD_ROOT install -C cc-base + # Install power-optimized glibc %if %{optimize_power} # run ldconfig to create the library symlinks @@ -592,6 +609,7 @@ make install_root=$RPM_BUILD_ROOT install -C cc-base fi %endif %endif # optimize_power + # Install locales %if %{build_locales} # Do not install locales in parallel! @@ -601,31 +619,45 @@ make install_root=$RPM_BUILD_ROOT install -C cc-base %endif # Create file list for glibc-locale package %{find_lang} libc + # Prepare obsolete/, used only on some architectures: export RPM_BUILD_ROOT mkdir -p $RPM_BUILD_ROOT/%{_lib}/obsolete + # NPTL is not usable outside of glibc, so include # the generic one (RH#162634) cp -av bits/stdio-lock.h $RPM_BUILD_ROOT%{_prefix}/include/bits/stdio-lock.h + %ifarch s390x # s390x is different ... mkdir $RPM_BUILD_ROOT/lib ln -sf ../%{_lib}/ld-%{version}.so $RPM_BUILD_ROOT/lib/ld64.so.1 %endif + + # Miscelanna: + install -m 0700 glibc_post_upgrade $RPM_BUILD_ROOT%{_sbindir} + install -m 644 $RPM_SOURCE_DIR/bindresvport.blacklist $RPM_BUILD_ROOT/etc install -m 644 $RPM_SOURCE_DIR/nsswitch.conf $RPM_BUILD_ROOT/etc install -m 644 posix/gai.conf $RPM_BUILD_ROOT/etc + mkdir -p $RPM_BUILD_ROOT/etc/default install -m 644 nis/nss $RPM_BUILD_ROOT/etc/default/ + mkdir -p $RPM_BUILD_ROOT/usr/include/resolv install -m 0644 resolv/mapv4v6addr.h $RPM_BUILD_ROOT/usr/include/resolv/ install -m 0644 resolv/mapv4v6hostent.h $RPM_BUILD_ROOT/usr/include/resolv/ + mkdir -p $RPM_BUILD_ROOT/usr/share/doc/glibc cp -p manual/libc/*.html $RPM_BUILD_ROOT/usr/share/doc/glibc + cd manpages; make install_root=$RPM_BUILD_ROOT install; cd .. + + # nscd tools: + cp nscd/nscd.conf $RPM_BUILD_ROOT/etc mkdir -p $RPM_BUILD_ROOT/etc/apparmor.d cp $RPM_SOURCE_DIR/usr.sbin.nscd $RPM_BUILD_ROOT/etc/apparmor.d @@ -635,6 +667,7 @@ ln -sf /etc/init.d/nscd $RPM_BUILD_ROOT/usr/sbin/rcnscd mkdir -p $RPM_BUILD_ROOT/var/run/nscd touch $RPM_BUILD_ROOT/var/run/nscd/{passwd,group,hosts} touch $RPM_BUILD_ROOT/var/run/nscd/{socket,nscd.pid} + # # Create ld.so.conf # @@ -674,23 +707,29 @@ mkdir -p $RPM_BUILD_ROOT/var/cache/ldconfig # Empty the ld.so.cache: rm -f $RPM_BUILD_ROOT/etc/ld.so.cache touch $RPM_BUILD_ROOT/etc/ld.so.cache + # libNoVersion belongs only to glibc-obsolete: %ifarch %ix86 rm -f $RPM_BUILD_ROOT%{_libdir}/libNoVersion* mkdir -p $RPM_BUILD_ROOT/%{_lib}/obsolete/noversion mv -v $RPM_BUILD_ROOT/%{_lib}/libNoVersion* $RPM_BUILD_ROOT/%{_lib}/obsolete/noversion/ %endif + # Don't look at ldd! We don't wish a /bin/sh requires chmod 644 $RPM_BUILD_ROOT/usr/bin/ldd + # Remove timezone data, now coming in standalone package: for i in sbin/sln usr/bin/tzselect usr/sbin/zic usr/sbin/zdump etc/localtime; do rm -f $RPM_BUILD_ROOT/$i done rm -rf $RPM_BUILD_ROOT/usr/share/zoneinfo + # Remove the buildflags tracking section and the build-id for o in $RPM_BUILD_ROOT/%{_libdir}/crt[1in].o $RPM_BUILD_ROOT/%{_libdir}/lib*_nonshared.a; do objcopy -R ".comment.SUSE.OPTs" -R ".note.gnu.build-id" $o done + + ####################################################################### ### ### ... @@ -727,13 +766,15 @@ done %restart_on_update nscd %insserv_cleanup exit 0 + + ####################################################################### ### ### FILES ### ####################################################################### -# glibc +# glibc %files %defattr(-,root,root) %doc LICENSES diff --git a/resolv.dynamic.diff b/resolv.dynamic.diff deleted file mode 100644 index f9c45e7..0000000 --- a/resolv.dynamic.diff +++ /dev/null @@ -1,33 +0,0 @@ -Index: resolv/res_libc.c -=================================================================== ---- resolv/res_libc.c.orig -+++ resolv/res_libc.c -@@ -22,6 +22,7 @@ - #include - #include - #include -+#include - - - /* The following bit is copied from res_data.c (where it is #ifdef'ed -@@ -95,6 +96,20 @@ int - __res_maybe_init (res_state resp, int preinit) - { - if (resp->options & RES_INIT) { -+ static time_t last_mtime, last_check; -+ time_t now; -+ struct stat statbuf; -+ -+ time (&now); -+ if (now != last_check) { -+ last_check = now; -+ if (stat (_PATH_RESCONF, &statbuf) == 0 && last_mtime != statbuf.st_mtime) { -+ last_mtime = statbuf.st_mtime; -+ atomicinclock (lock); -+ atomicinc (__res_initstamp); -+ atomicincunlock (lock); -+ } -+ } - if (__res_initstamp != resp->_u._ext.initstamp) { - if (resp->nscount > 0) - __res_iclose (resp, true);