Subject: Re: re-reading /etc/resolv.conf on change
To: Manuel Bouyer <bouyer@antioche.eu.org>
From: Greg A. Woods <woods@weird.com>
List: tech-userlevel
Date: 01/06/2004 15:59:44
[ On Tuesday, January 6, 2004 at 20:50:40 (+0100), Manuel Bouyer wrote: ]
> Subject: Re: re-reading /etc/resolv.conf on change
>
> I can see 3 ways of doing it:
> - the back-end fstat() PATH_RESCONF and call res_init() when needed

That's the best way.

But you need to make that stat(), not fstat(), and make sure to compare
not just st_mtime, but also st_ino and st_dev.  There's no need to hold
the file open and several reasons not to, not the least of which is that
it won't work in face of certain symlink arrangements.  You don't want
to open() the file just to fstat() it either (especially since you're
not going to be passing that fd to res_init()).

You could also keep a static time(2) value along with the static struct
stat results and only do another stat() if at least 5 seconds (or even
up to 60 seconds) has elapsed since the last call.  The time(2) call is
less expensive than the stat(2), and it's not unheard of for
applications to make many gethostby*() calls per second if they can get
their results that fast, and there's no way st_mtime can change more
than once per second and no possible human factors reason to check more
than once every 5 seconds.

(eventually gethostbyname_r() et al or their nsdispatch() callers will
either need per-thread copies of the struct stat (and time_t) or a lock
around a shared copy, and they will call res_ninit() instead)

> - the back-end always calls res_init(), and res_init() always reload the
>   config.

That's the only sane alternative, but it is quite a bit more expensive
in CPU cycles to process the file, as well as incurring the obvious
open()/read()/close() calls and their associated I/Os.

-- 
						Greg A. Woods

+1 416 218-0098                  VE3TCP            RoboHack <woods@robohack.ca>
Planix, Inc. <woods@planix.com>          Secrets of the Weird <woods@weird.com>