[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[patches] Track resolv.conf, avoid need for explicit res_init() or nscd in long-running applications



Hi.  The issue at hand might be a bit controversial, as upstream
patches go.  I'm not the author to the patch below, but Thorsten
K. is, a long-time glibc contributor, with glibc copyright
papers in place.  I only wrote the ChangeLog entry, as I
couldn't find one.

The problem is that for functions that require DNS lookups such
as getaddrinfo and the legacy gethostbyname, libc caches the
reading of resolv.conf.  For a long-running application that's
disaster: a very real DHCP hiccup was the trigger for the
internal bug-report.

I'd like to suggest that the patch attached to the message at
<http://sources.redhat.com/ml/libc-alpha/2004-09/msg00130.html>
inlined below, be committed.  Perhaps this may be construed as
counter to EGLIBC policy; a change in behavior, applicable to
upstream glibc but explicitly not included.

Alternatives have been suggested
- make applications call res_init (see
  <http://sourceware.org/bugzilla/show_bug.cgi?id=3675>)
- use nscd (see the thread at the URL above, specifically
  <http://sources.redhat.com/ml/libc-alpha/2004-09/msg00129.html>)

Still, arguments for including the patch are
- requiring res_init to keep getaddrinfo working is kind of
  nonobvious and not POSIX (an "out-of-band" requirement; I
  can't find any current documentation that mentions this
  requirement).
- many GNU/Linux distributions (well, at least Debian and
  derivatives) have patched glibc downstream as per above (not
  to mention BSD systems where this is the unpatched behavior)
  making it a de-facto behavior.  Behavior of the host therefore
  unexpectedly differs from the target here, surprising
  developers.
- requiring embedded systems with small resources to run nscd
  just to track resolv.conf is wasteful
- the "original" glibc behavior is not usable

Seeing the results from the quoted links and from earlier
experience, I don't see the point in trying to argue upstream
(nor will I here, I think), just asking now, so that others
perhaps don't have to ask here again.  I hope I covered it.

Oh, and thank you for eglibc!

	* resolv/res_libc.c (__res_maybe_init): Re-initialize if
	_PATH_RESCONF has been modified since last init.

--- resolv/res_libc.c	6 Aug 2004 17:52:53 -0000	1.20
+++ resolv/res_libc.c	9 Aug 2004 15:14:47 -0000
@@ -22,7 +22,7 @@
 #include <arpa/nameser.h>
 #include <resolv.h>
 #include <bits/libc-lock.h>
-
+#include <sys/stat.h>
 
 /* 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
@@ -100,8 +100,17 @@ res_init(void) {
 int
 __res_maybe_init (res_state resp, int preinit)
 {
-	if (resp->options & RES_INIT) {
-		if (__res_initstamp != resp->_u._ext.initstamp) {
+  static time_t last_mtime;
+  struct stat statbuf;
+  int ret;
+
+		
+  if (resp->options & RES_INIT) {
+	ret = stat (_PATH_RESCONF, &statbuf);
+		if (__res_initstamp != resp->_u._ext.initstamp
+		  || (ret == 0) && (last_mtime != statbuf.st_mtime))
+		  {
+		        last_mtime = statbuf.st_mtime;
 			if (resp->nscount > 0) {
 				__res_nclose (resp);
 				for (int ns = 0; ns < MAXNS; ns++) {


brgds, H-P