[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [patches] [PATCH] Reload resolv.conf for all threads
- To: Maxim Kuvyrkov <maxim@xxxxxxxxxxxxxxxx>
- Subject: Re: [patches] [PATCH] Reload resolv.conf for all threads
- From: Michael Schroeder <mls@xxxxxxx>
- Date: Thu, 16 Sep 2010 19:02:25 +0200
On Thu, Sep 16, 2010 at 08:05:33PM +0400, Maxim Kuvyrkov wrote:
> On 9/15/10 4:11 AM, Aurelien Jarno wrote:
> >When resolv.conf is modified, the resolver code noticed that and reload
> >it. However on a multithread program, the thread which notices the
> >change doesn't ask all the other to re-initialize their resolver. The
> >patch below fixes the issue.
> >
> >I submit it here, as this part of the code is EGLIBC specific and not p
> >art of GLIBC (though present in most distributions).
>
> Michael (CC'ed) is the author of the code in question.
(Uh, that was a long time ago.) I think your patch is correct.
It's similar to a different patch from Sebastian Kienzl
<seb@xxxxxxxx>, which we currently use in our glibc:
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 <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
@@ -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);
Cheers,
Michael.
--
Michael Schroeder mls@xxxxxxx
SUSE LINUX Products GmbH, GF Markus Rex, HRB 16746 AG Nuernberg
main(_){while(_=~getchar())putchar(~_-1/(~(_|32)/13*2-11)*13);}