From 4f07972cbeba484b2e1ec32222da7971cb5b037b Mon Sep 17 00:00:00 2001 From: henning <> Date: Fri, 27 Oct 2006 12:22:41 +0000 Subject: [PATCH] use clock_gettime(CLOCK_MONOTONIC, ..) to get a monotonically increasing time, and make ntpd use that to send the next uery to an ntp peer and the like. this has the advantage that changes to the clock do not interfere with the intervals. for example, when we start on machines without an RTC and the initial settime (-s) kicks in, intervals were strange. idea from amandal@entrisphere.com, this implementation by me tested ckuethe, phessler, mbalmer, ok mbalmer --- src/usr.sbin/ntpd/client.c | 8 ++++---- src/usr.sbin/ntpd/ntp.c | 16 ++++++++-------- src/usr.sbin/ntpd/ntpd.h | 3 ++- src/usr.sbin/ntpd/sensors.c | 8 +++++--- src/usr.sbin/ntpd/util.c | 13 ++++++++++++- 5 files changed, 31 insertions(+), 17 deletions(-) diff --git a/src/usr.sbin/ntpd/client.c b/src/usr.sbin/ntpd/client.c index 8718b041..ce59154e 100644 --- a/src/usr.sbin/ntpd/client.c +++ b/src/usr.sbin/ntpd/client.c @@ -1,4 +1,4 @@ -/* $OpenBSD: client.c,v 1.73 2006/10/21 07:32:46 henning Exp $ */ +/* $OpenBSD: client.c,v 1.74 2006/10/27 12:22:41 henning Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer @@ -32,14 +32,14 @@ void set_deadline(struct ntp_peer *, time_t); void set_next(struct ntp_peer *p, time_t t) { - p->next = time(NULL) + t; + p->next = getmonotime() + t; p->deadline = 0; } void set_deadline(struct ntp_peer *p, time_t t) { - p->deadline = time(NULL) + t; + p->deadline = getmonotime() + t; p->next = 0; } @@ -247,7 +247,7 @@ client_dispatch(struct ntp_peer *p, u_int8_t settime) return (0); } p->reply[p->shift].error = (T2 - T1) - (T3 - T4); - p->reply[p->shift].rcvd = time(NULL); + p->reply[p->shift].rcvd = getmonotime(); p->reply[p->shift].good = 1; p->reply[p->shift].status.leap = (msg.status & LIMASK); diff --git a/src/usr.sbin/ntpd/ntp.c b/src/usr.sbin/ntpd/ntp.c index 0c3f8d01..6b81c088 100644 --- a/src/usr.sbin/ntpd/ntp.c +++ b/src/usr.sbin/ntpd/ntp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ntp.c,v 1.93 2006/10/24 12:23:39 henning Exp $ */ +/* $OpenBSD: ntp.c,v 1.94 2006/10/27 12:22:41 henning Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer @@ -201,7 +201,7 @@ ntp_main(int pipe_prnt[2], struct ntpd_conf *nconf) bzero(pfd, sizeof(struct pollfd) * pfd_elms); bzero(idx2peer, sizeof(void *) * idx2peer_elms); - nextaction = time(NULL) + 3600; + nextaction = getmonotime() + 3600; pfd[PFD_PIPE_MAIN].fd = ibuf_main->fd; pfd[PFD_PIPE_MAIN].events = POLLIN; pfd[PFD_HOTPLUG].fd = hotplugfd; @@ -217,7 +217,7 @@ ntp_main(int pipe_prnt[2], struct ntpd_conf *nconf) idx_peers = i; sent_cnt = trial_cnt = 0; TAILQ_FOREACH(p, &conf->ntp_peers, entry) { - if (p->next > 0 && p->next <= time(NULL)) { + if (p->next > 0 && p->next <= getmonotime()) { if (p->state > STATE_DNS_INPROGRESS) trial_cnt++; if (client_query(p) == 0) @@ -228,7 +228,7 @@ ntp_main(int pipe_prnt[2], struct ntpd_conf *nconf) if (p->deadline > 0 && p->deadline < nextaction) nextaction = p->deadline; - if (p->deadline > 0 && p->deadline <= time(NULL)) { + if (p->deadline > 0 && p->deadline <= getmonotime()) { timeout = error_interval(); log_debug("no reply from %s received in time, " "next query %ds", log_sockaddr( @@ -251,9 +251,9 @@ ntp_main(int pipe_prnt[2], struct ntpd_conf *nconf) } } - if (last_sensor_scan + SENSOR_SCAN_INTERVAL < time(NULL)) { + if (last_sensor_scan + SENSOR_SCAN_INTERVAL < getmonotime()) { sensor_scan(); - last_sensor_scan = time(NULL); + last_sensor_scan = getmonotime(); } sensors_cnt = 0; TAILQ_FOREACH(s, &conf->ntp_sensors, entry) { @@ -270,7 +270,7 @@ ntp_main(int pipe_prnt[2], struct ntpd_conf *nconf) if (ibuf_main->w.queued > 0) pfd[PFD_PIPE_MAIN].events |= POLLOUT; - timeout = nextaction - time(NULL); + timeout = nextaction - getmonotime(); if (timeout < 0) timeout = 0; @@ -315,7 +315,7 @@ ntp_main(int pipe_prnt[2], struct ntpd_conf *nconf) for (s = TAILQ_FIRST(&conf->ntp_sensors); s != NULL; s = next_s) { next_s = TAILQ_NEXT(s, entry); - if (s->next <= time(NULL)) + if (s->next <= getmonotime()) sensor_query(s); } } diff --git a/src/usr.sbin/ntpd/ntpd.h b/src/usr.sbin/ntpd/ntpd.h index 69c5477a..ca5262cf 100644 --- a/src/usr.sbin/ntpd/ntpd.h +++ b/src/usr.sbin/ntpd/ntpd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ntpd.h,v 1.77 2006/10/24 12:23:39 henning Exp $ */ +/* $OpenBSD: ntpd.h,v 1.78 2006/10/27 12:22:41 henning Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer @@ -297,6 +297,7 @@ void set_next(struct ntp_peer *, time_t); double gettime_corrected(void); double getoffset(void); double gettime(void); +time_t getmonotime(void); void d_to_tv(double, struct timeval *); double lfp_to_d(struct l_fixedpt); struct l_fixedpt d_to_lfp(double); diff --git a/src/usr.sbin/ntpd/sensors.c b/src/usr.sbin/ntpd/sensors.c index 309e0066..41b6dd51 100644 --- a/src/usr.sbin/ntpd/sensors.c +++ b/src/usr.sbin/ntpd/sensors.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sensors.c,v 1.24 2006/10/24 12:23:39 henning Exp $ */ +/* $OpenBSD: sensors.c,v 1.25 2006/10/27 12:22:41 henning Exp $ */ /* * Copyright (c) 2006 Henning Brauer @@ -101,7 +101,7 @@ sensor_add(struct sensor *sensor) if ((s = calloc(1, sizeof(*s))) == NULL) fatal("sensor_add calloc"); - s->next = time(NULL); + s->next = getmonotime(); s->weight = cs->weight; if ((s->device = strdup(sensor->device)) == NULL) fatal("sensor_add strdup"); @@ -128,7 +128,9 @@ sensor_query(struct ntp_sensor *s) int mib[3]; size_t len; - s->next = time(NULL) + SENSOR_QUERY_INTERVAL; + s->next = getmonotime() + SENSOR_QUERY_INTERVAL; + + /* rcvd is walltime here, monotime in client.c. not used elsewhere */ if (s->update.rcvd < time(NULL) - SENSOR_DATA_MAXAGE) s->update.good = 0; diff --git a/src/usr.sbin/ntpd/util.c b/src/usr.sbin/ntpd/util.c index 41d42eb9..68468710 100644 --- a/src/usr.sbin/ntpd/util.c +++ b/src/usr.sbin/ntpd/util.c @@ -1,4 +1,4 @@ -/* $OpenBSD: util.c,v 1.11 2006/06/07 06:29:03 otto Exp $ */ +/* $OpenBSD: util.c,v 1.12 2006/10/27 12:22:41 henning Exp $ */ /* * Copyright (c) 2004 Alexander Guy @@ -47,6 +47,17 @@ gettime(void) return (tv.tv_sec + JAN_1970 + 1.0e-6 * tv.tv_usec); } +time_t +getmonotime(void) +{ + struct timespec ts; + + if (clock_gettime(CLOCK_MONOTONIC, &ts) != 0) + fatal("clock_gettime"); + + return (ts.tv_sec); +} + void d_to_tv(double d, struct timeval *tv)