[Dnsmasq-discuss] [PATCH] Use nanosecond granularity when checking for file changes.
Karl Vogel
karl.vogel at gmail.com
Tue Sep 30 12:46:02 BST 2014
On some setups, the resolv.conf file might be updated/changed
within the 1 second granularity that st_mtime provides, therefor
also keep track of the nanoseconds.
NOTE: not all filesystems have nanosecond timestamps, but in that
case, the nanosecond field will be set to 0 by the kernel.
---
src/dnsmasq.c | 20 +++++++++++---------
src/dnsmasq.h | 7 ++++++-
src/option.c | 3 ++-
3 files changed, 19 insertions(+), 11 deletions(-)
diff --git a/src/dnsmasq.c b/src/dnsmasq.c
index f4a89fc..065dd61 100644
--- a/src/dnsmasq.c
+++ b/src/dnsmasq.c
@@ -1288,7 +1288,7 @@ static void poll_resolv(int force, int do_reload, time_t now)
{
struct resolvc *res, *latest;
struct stat statbuf;
- time_t last_change = 0;
+ struct timespec last_change = { 0 };
/* There may be more than one possible file.
Go through and find the one which changed _last_.
Warn of any which can't be read. */
@@ -1301,7 +1301,8 @@ static void poll_resolv(int force, int do_reload, time_t now)
{
if (force)
{
- res->mtime = 0;
+ res->mtime.tv_sec = 0;
+ res->mtime.tv_nsec = 0;
continue;
}
@@ -1309,7 +1310,7 @@ static void poll_resolv(int force, int do_reload, time_t now)
my_syslog(LOG_WARNING, _("failed to access %s: %s"), res->name, strerror(errno));
res->logged = 1;
- if (res->mtime != 0)
+ if (res->mtime.tv_sec != 0 && res->mtime.tv_nsec != 0)
{
/* existing file evaporated, force selection of the latest
file even if its mtime hasn't changed since we last looked */
@@ -1320,12 +1321,12 @@ static void poll_resolv(int force, int do_reload, time_t now)
else
{
res->logged = 0;
- if (force || (statbuf.st_mtime != res->mtime))
- {
- res->mtime = statbuf.st_mtime;
- if (difftime(statbuf.st_mtime, last_change) > 0.0)
+ if (force || timespeccmp(&statbuf.st_mtim, &res->mtime, !=))
+ {
+ res->mtime = statbuf.st_mtim;
+ if (timespeccmp(&statbuf.st_mtim, &last_change, >))
{
- last_change = statbuf.st_mtime;
+ last_change = statbuf.st_mtim;
latest = res;
}
}
@@ -1344,7 +1345,8 @@ static void poll_resolv(int force, int do_reload, time_t now)
}
else
{
- latest->mtime = 0;
+ latest->mtime.tv_sec = 0;
+ latest->mtime.tv_nsec = 0;
if (!warned)
{
my_syslog(LOG_WARNING, _("no servers found in %s, will retry"), latest->name);
diff --git a/src/dnsmasq.h b/src/dnsmasq.h
index e74b15a..ee8017b 100644
--- a/src/dnsmasq.h
+++ b/src/dnsmasq.h
@@ -136,6 +136,11 @@ extern int capget(cap_user_header_t header, cap_user_data_t data);
#include <priv.h>
#endif
+#define timespeccmp(a, b, CMP) \
+ (((a)->tv_sec == (b)->tv_sec) ? \
+ ((a)->tv_nsec CMP (b)->tv_nsec) : \
+ ((a)->tv_sec CMP (b)->tv_sec))
+
/* daemon is function in the C library.... */
#define daemon dnsmasq_daemon
@@ -539,7 +544,7 @@ struct iname {
struct resolvc {
struct resolvc *next;
int is_default, logged;
- time_t mtime;
+ struct timespec mtime;
char *name;
};
diff --git a/src/option.c b/src/option.c
index 45d8875..c990a2a 100644
--- a/src/option.c
+++ b/src/option.c
@@ -1625,7 +1625,8 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
new->next = list;
new->name = name;
new->is_default = 0;
- new->mtime = 0;
+ new->mtime.tv_sec = 0;
+ new->mtime.tv_nsec = 0;
new->logged = 0;
list = new;
}
--
1.7.1
More information about the Dnsmasq-discuss
mailing list