Page MenuHomeFreeBSD

D3867.id9335.diff
No OneTemporary

D3867.id9335.diff

Index: include/resolv.h
===================================================================
--- include/resolv.h
+++ include/resolv.h
@@ -176,7 +176,8 @@
int res_h_errno; /*%< last one set for this context */
int _vcsock; /*%< PRIVATE: for res_send VC i/o */
u_int _flags; /*%< PRIVATE: see below */
- u_int _pad; /*%< make _u 64 bit aligned */
+ u_short reload_period; /*%< seconds between stat(resolv.conf)*/
+ u_short _pad; /*%< make _u 64 bit aligned */
union {
/* On an 32-bit arch this means 512b total. */
char pad[72 - 4*sizeof (int) - 3*sizeof (void *)];
@@ -188,6 +189,8 @@
} _ext;
} _u;
u_char *_rnd; /*%< PRIVATE: random state */
+ struct timespec conf_mtim; /*%< mod time of loaded resolv.conf */
+ time_t conf_stat; /*%< time of last stat(resolv.conf) */
};
typedef struct __res_state *res_state;
Index: lib/libc/resolv/res_init.c
===================================================================
--- lib/libc/resolv/res_init.c
+++ lib/libc/resolv/res_init.c
@@ -78,6 +78,7 @@
#include <sys/types.h>
#include <sys/param.h>
#include <sys/socket.h>
+#include <sys/stat.h>
#include <sys/time.h>
#include <netinet/in.h>
@@ -227,6 +228,7 @@
statp->pfcode = 0;
statp->_vcsock = -1;
statp->_flags = 0;
+ statp->reload_period = 2;
statp->qhook = NULL;
statp->rhook = NULL;
statp->_u._ext.nscount = 0;
@@ -321,6 +323,22 @@
nserv = 0;
if ((fp = fopen(_PATH_RESCONF, "re")) != NULL) {
+ struct stat sb;
+ struct timespec now;
+
+ if (_fstat(fileno(fp), &sb) == 0) {
+ statp->conf_mtim = sb.st_mtim;
+ if (clock_gettime(CLOCK_MONOTONIC_FAST, &now) == 0) {
+ statp->conf_stat = now.tv_sec;
+ } else {
+ statp->conf_stat = 0;
+ }
+ } else {
+ statp->conf_mtim.tv_sec = 0;
+ statp->conf_mtim.tv_nsec = 0;
+ statp->conf_stat = 0;
+ }
+
/* read the config file */
while (fgets(buf, sizeof(buf), fp) != NULL) {
/* skip comments */
@@ -666,6 +684,10 @@
} else if (!strncmp(cp, "no-check-names",
sizeof("no-check-names") - 1)) {
statp->options |= RES_NOCHECKNAME;
+ } else if (!strncmp(cp, "reload-period:",
+ sizeof("reload-period:") - 1)) {
+ statp->reload_period = (u_short)
+ atoi(cp + sizeof("reload-period:") - 1);
}
#ifdef RES_USE_EDNS0
else if (!strncmp(cp, "edns0", sizeof("edns0") - 1)) {
Index: lib/libc/resolv/res_state.c
===================================================================
--- lib/libc/resolv/res_state.c
+++ lib/libc/resolv/res_state.c
@@ -26,6 +26,8 @@
*/
#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/time.h>
#include <netinet/in.h>
#include <arpa/nameser.h>
#include <resolv.h>
@@ -59,13 +61,38 @@
res_thr_keycreated = thr_keycreate(&res_key, free_res) == 0;
}
+static res_state
+res_check_reload(res_state statp)
+{
+ struct timespec now;
+ struct stat sb;
+
+ if ((statp->options & RES_INIT) == 0 || statp->reload_period == 0) {
+ return (statp);
+ }
+
+ if (clock_gettime(CLOCK_MONOTONIC_FAST, &now) != 0 ||
+ (now.tv_sec - statp->conf_stat) < statp->reload_period) {
+ return (statp);
+ }
+
+ statp->conf_stat = now.tv_sec;
+ if (stat(_PATH_RESCONF, &sb) == 0 &&
+ (sb.st_mtim.tv_sec != statp->conf_mtim.tv_sec ||
+ sb.st_mtim.tv_nsec != statp->conf_mtim.tv_nsec)) {
+ statp->options &= ~RES_INIT;
+ }
+
+ return (statp);
+}
+
res_state
__res_state(void)
{
res_state statp;
if (thr_main() != 0)
- return (&_res);
+ return res_check_reload(&_res);
if (thr_once(&res_init_once, res_keycreate) != 0 ||
!res_thr_keycreated)
@@ -73,7 +100,7 @@
statp = thr_getspecific(res_key);
if (statp != NULL)
- return (statp);
+ return res_check_reload(statp);
statp = calloc(1, sizeof(*statp));
if (statp == NULL)
return (&_res);
Index: share/man/man5/resolver.5
===================================================================
--- share/man/man5/resolver.5
+++ share/man/man5/resolver.5
@@ -28,7 +28,7 @@
.\" @(#)resolver.5 8.1 (Berkeley) 6/5/93
.\" $FreeBSD$
.\"
-.Dd December 25, 2013
+.Dd October 12, 2015
.Dt RESOLVER 5
.Os
.Sh NAME
@@ -175,6 +175,18 @@
and
.Sy search
rules with the given name.
+.It Sy reload-period: Ns Ar n
+By default, the resolver tests the modification time of
+.Pa /etc/resolv.conf
+and automatically reloads the file if it has changed.
+To avoid any potential performance impact of calling
+.Xr stat 2
+at a high rate,
+the test is done only once every two seconds (or longer).
+This option sets the period of this test to
+.Ar n
+seconds.
+A period of zero disables the test.
.El
.Pp
Options may also be specified as a space or tab separated list using the
@@ -191,7 +203,7 @@
the last instance will override.
.Pp
The keyword and value must appear on a single line, and the keyword
-(e.g.\&
+(e.g.,\&
.Sy nameserver )
must start the line.
The value follows the keyword, separated by white space.

File Metadata

Mime Type
text/plain
Expires
Thu, Jun 18, 2:48 AM (5 h, 4 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
34042161
Default Alt Text
D3867.id9335.diff (4 KB)

Event Timeline