svn commit: r292462 - in stable/10: lib/libc/resolv share/man/man5
Eric van Gyzen
vangyzen at FreeBSD.org
Sat Dec 19 02:41:33 UTC 2015
Author: vangyzen
Date: Sat Dec 19 02:41:31 2015
New Revision: 292462
URL: https://svnweb.freebsd.org/changeset/base/292462
Log:
MFC r289315, r292216
resolver: automatically reload /etc/resolv.conf
On each resolver query, use stat(2) to see if the modification time
of /etc/resolv.conf has changed. If so, reload the file and reinitialize
the resolver library. However, only call stat(2) if at least two seconds
have passed since the last call to stat(2), since calling it on every
query could kill performance.
This new behavior is enabled by default. Add a "reload-period" option
to disable it or change the period of the test.
Document this behavior and option in resolv.conf(5).
Polish the man page just enough to appease igor.
Relnotes: yes
Sponsored by: Dell Inc.
Modified:
stable/10/lib/libc/resolv/res_init.c
stable/10/lib/libc/resolv/res_private.h
stable/10/lib/libc/resolv/res_state.c
stable/10/share/man/man5/resolver.5
Directory Properties:
stable/10/ (props changed)
Modified: stable/10/lib/libc/resolv/res_init.c
==============================================================================
--- stable/10/lib/libc/resolv/res_init.c Sat Dec 19 02:35:32 2015 (r292461)
+++ stable/10/lib/libc/resolv/res_init.c Sat Dec 19 02:41:31 2015 (r292462)
@@ -78,6 +78,7 @@ __FBSDID("$FreeBSD$");
#include <sys/types.h>
#include <sys/param.h>
#include <sys/socket.h>
+#include <sys/stat.h>
#include <sys/time.h>
#include <netinet/in.h>
@@ -238,6 +239,7 @@ __res_vinit(res_state statp, int preinit
statp->_u._ext.ext->nsaddrs[0].sin = statp->nsaddr;
strcpy(statp->_u._ext.ext->nsuffix, "ip6.arpa");
strcpy(statp->_u._ext.ext->nsuffix2, "ip6.int");
+ statp->_u._ext.ext->reload_period = 2;
} else {
/*
* Historically res_init() rarely, if at all, failed.
@@ -323,6 +325,18 @@ __res_vinit(res_state statp, int preinit
nserv = 0;
if ((fp = fopen(_PATH_RESCONF, "re")) != NULL) {
+ struct stat sb;
+ struct timespec now;
+
+ if (statp->_u._ext.ext != NULL) {
+ if (_fstat(fileno(fp), &sb) == 0) {
+ statp->_u._ext.ext->conf_mtim = sb.st_mtim;
+ if (clock_gettime(CLOCK_MONOTONIC_FAST, &now) == 0) {
+ statp->_u._ext.ext->conf_stat = now.tv_sec;
+ }
+ }
+ }
+
/* read the config file */
while (fgets(buf, sizeof(buf), fp) != NULL) {
/* skip comments */
@@ -583,9 +597,7 @@ res_setoptions(res_state statp, const ch
{
const char *cp = options;
int i;
-#ifndef _LIBC
struct __res_state_ext *ext = statp->_u._ext.ext;
-#endif
#ifdef DEBUG
if (statp->options & RES_DEBUG)
@@ -668,6 +680,12 @@ res_setoptions(res_state statp, const ch
} 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)) {
+ if (ext != NULL) {
+ ext->reload_period = (u_short)
+ atoi(cp + sizeof("reload-period:") - 1);
+ }
}
#ifdef RES_USE_EDNS0
else if (!strncmp(cp, "edns0", sizeof("edns0") - 1)) {
Modified: stable/10/lib/libc/resolv/res_private.h
==============================================================================
--- stable/10/lib/libc/resolv/res_private.h Sat Dec 19 02:35:32 2015 (r292461)
+++ stable/10/lib/libc/resolv/res_private.h Sat Dec 19 02:41:31 2015 (r292462)
@@ -1,3 +1,5 @@
+/* $FreeBSD$ */
+
#ifndef res_private_h
#define res_private_h
@@ -12,6 +14,9 @@ struct __res_state_ext {
} sort_list[MAXRESOLVSORT];
char nsuffix[64];
char nsuffix2[64];
+ struct timespec conf_mtim; /* mod time of loaded resolv.conf */
+ time_t conf_stat; /* time of last stat(resolv.conf) */
+ u_short reload_period; /* seconds between stat(resolv.conf) */
};
extern int
Modified: stable/10/lib/libc/resolv/res_state.c
==============================================================================
--- stable/10/lib/libc/resolv/res_state.c Sat Dec 19 02:35:32 2015 (r292461)
+++ stable/10/lib/libc/resolv/res_state.c Sat Dec 19 02:41:31 2015 (r292462)
@@ -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>
@@ -35,6 +37,8 @@
#include "reentrant.h"
#include "un-namespace.h"
+#include "res_private.h"
+
#undef _res
struct __res_state _res;
@@ -59,13 +63,44 @@ res_keycreate(void)
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;
+ struct __res_state_ext *ext;
+
+ if ((statp->options & RES_INIT) == 0) {
+ return (statp);
+ }
+
+ ext = statp->_u._ext.ext;
+ if (ext == NULL || ext->reload_period == 0) {
+ return (statp);
+ }
+
+ if (clock_gettime(CLOCK_MONOTONIC_FAST, &now) != 0 ||
+ (now.tv_sec - ext->conf_stat) < ext->reload_period) {
+ return (statp);
+ }
+
+ ext->conf_stat = now.tv_sec;
+ if (stat(_PATH_RESCONF, &sb) == 0 &&
+ (sb.st_mtim.tv_sec != ext->conf_mtim.tv_sec ||
+ sb.st_mtim.tv_nsec != ext->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 +108,7 @@ __res_state(void)
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);
Modified: stable/10/share/man/man5/resolver.5
==============================================================================
--- stable/10/share/man/man5/resolver.5 Sat Dec 19 02:35:32 2015 (r292461)
+++ stable/10/share/man/man5/resolver.5 Sat Dec 19 02:41:31 2015 (r292462)
@@ -32,7 +32,7 @@
.\" @(#)resolver.5 8.1 (Berkeley) 6/5/93
.\" $FreeBSD$
.\"
-.Dd December 25, 2013
+.Dd October 12, 2015
.Dt RESOLVER 5
.Os
.Sh NAME
@@ -179,6 +179,19 @@ the resolver from obeying the standard
and
.Sy search
rules with the given name.
+.It Sy reload-period: Ns Ar n
+The resolver checks the modification time of
+.Pa /etc/resolv.conf
+every
+.Ar n
+seconds.
+If
+.Pa /etc/resolv.conf
+has changed, it is automatically reloaded.
+The default for
+.Ar n
+is two seconds.
+Setting it to zero disables the file check.
.El
.Pp
Options may also be specified as a space or tab separated list using the
@@ -195,8 +208,7 @@ If more than one instance of these keywo
the last instance will override.
.Pp
The keyword and value must appear on a single line, and the keyword
-(e.g.\&
-.Sy nameserver )
+.Pq for example, Sy nameserver
must start the line.
The value follows the keyword, separated by white space.
.Sh FILES
More information about the svn-src-stable-10
mailing list