[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [patches] Track resolv.conf, avoid need for explicit res_init() or nscd in long-running applications
- To: joseph@xxxxxxxxxxxxxxxx
- Subject: Re: [patches] Track resolv.conf, avoid need for explicit res_init() or nscd in long-running applications
- From: Hans-Peter Nilsson <hans-peter.nilsson@xxxxxxxx>
- Date: Tue, 13 Oct 2009 16:41:52 +0200
> Date: Mon, 12 Oct 2009 17:58:56 +0000 (UTC)
> From: "Joseph S. Myers" <joseph@xxxxxxxxxxxxxxxx>
> This diff does not apply cleanly to current sources. Could you send a
> version that does (and is tested still to have the desired effect)?
Oops, a line or two changed between 2.9 and trunk, I missed
that. Sorry.
Updated patch follows, as harvested from Debian (still
misattributed there as Thorsten's, so I guess the authorship is
still with his colleague Michael Schroeder) and the previous
ChangeLog entry still applies.
I tested it with the following program pre/post the patch
applied to r9077 of eglibc trunk, built for
arm-axis-linux-gnueabi, changing to/from a bad /etc/resolv.conf
("nameserver" line pointing at the wrong host). The intended
result, the output changing to/from "gethostbyname badness: Host
name lookup failure" to displaying the IP address happened after
the patch only. NB: I'm probably not using the correct DNS
lookup idioms and sorry for using the obsolete gethostbyname. :)
BTW, something incompatibly happened between 2.9 and trunk
causing SEGV if I just point at libc.so.6 using LD_LIBRARY_PATH,
e.g.:
env LD_LIBRARY_PATH=/tmp ./ghbn
I had to also use the newly compiled dynamic linker and (cd /tmp)
./ld-linux.so.3 --library-path /tmp ./ghbn
Index: res_libc.c
===================================================================
--- res_libc.c (revision 9077)
+++ res_libc.c (working copy)
@@ -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
@@ -94,8 +94,15 @@ res_init(void) {
int
__res_maybe_init (res_state resp, int preinit)
{
+ static time_t last_mtime;
+ struct stat statbuf;
+ int ret;
+
if (resp->options & RES_INIT) {
- if (__res_initstamp != resp->_u._ext.initstamp) {
+ 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_iclose (resp, true);
return __res_vinit (resp, 1);
ghbn.c:
#include <stdlib.h>
#include <stdio.h>
#include <netdb.h>
#define NAME1 "eglibc.org"
#define NAME2 "gnu.org"
int main (void)
{
char digs[INET_ADDRSTRLEN];
struct hostent *hep;
hep = gethostbyname (NAME1);
if (hep == NULL)
fprintf (stderr, "gethostbyname badness: %s\n", hstrerror (h_errno));
else
{
inet_ntop (hep->h_addrtype, hep->h_addr, digs, sizeof digs);
printf ("%s is: %s\n", NAME1, digs);
}
printf ("Now do something to /etc/resolv.conf and press the \"any\" key\n");
getchar();
hep = gethostbyname (NAME2);
if (hep == NULL)
{
fprintf (stderr, "gethostbyname badness: %s\n", hstrerror (h_errno));
exit (1);
}
else
{
inet_ntop (hep->h_addrtype, hep->h_addr, digs, sizeof digs);
printf ("%s is: %s\n", NAME2, digs);
}
exit (0);
}
brgds, H-P