summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHenning Brauer <henning@cvs.openbsd.org>2006-10-24 12:23:40 +0000
committerHenning Brauer <henning@cvs.openbsd.org>2006-10-24 12:23:40 +0000
commitbc4f25d927077f33e59b81c2332c27a200642e4f (patch)
treedb86c073366342d297f559f77dc0ab7dae4fab17
parent20fceac37c1a322e86f956c818ec6c7d27718ef7 (diff)
timedelta sensors are usually updated very often, but we used to query
them only every 30 seconds. now query them every 5,and take the median value from 7 queries as sensor value. this takes outliers out of the equation and makes the overall result much better, especially for sensors with heavy jitter (like nmea for now)
-rw-r--r--usr.sbin/ntpd/ntp.c3
-rw-r--r--usr.sbin/ntpd/ntpd.h8
-rw-r--r--usr.sbin/ntpd/sensors.c58
3 files changed, 53 insertions, 16 deletions
diff --git a/usr.sbin/ntpd/ntp.c b/usr.sbin/ntpd/ntp.c
index aafba9aaacd..0c3f8d011e0 100644
--- a/usr.sbin/ntpd/ntp.c
+++ b/usr.sbin/ntpd/ntp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ntp.c,v 1.92 2006/10/21 07:30:58 henning Exp $ */
+/* $OpenBSD: ntp.c,v 1.93 2006/10/24 12:23:39 henning Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -46,7 +46,6 @@ void ntp_sighdlr(int);
int ntp_dispatch_imsg(void);
void peer_add(struct ntp_peer *);
void peer_remove(struct ntp_peer *);
-int offset_compare(const void *, const void *);
void
ntp_sighdlr(int sig)
diff --git a/usr.sbin/ntpd/ntpd.h b/usr.sbin/ntpd/ntpd.h
index 2349203e483..69c5477ab6c 100644
--- a/usr.sbin/ntpd/ntpd.h
+++ b/usr.sbin/ntpd/ntpd.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ntpd.h,v 1.76 2006/06/30 16:52:13 deraadt Exp $ */
+/* $OpenBSD: ntpd.h,v 1.77 2006/10/24 12:23:39 henning Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -55,6 +55,7 @@
#define QUERYTIME_MAX 15 /* single query might take n secs max */
#define OFFSET_ARRAY_SIZE 8
+#define SENSOR_OFFSETS 7
#define SETTIME_MIN_OFFSET 180 /* min offset for settime at start */
#define SETTIME_TIMEOUT 15 /* max seconds to wait with -s */
#define LOG_NEGLIGEE 32 /* negligible drift to not log (ms) */
@@ -63,7 +64,7 @@
#define SENSOR_DATA_MAXAGE (15*60)
-#define SENSOR_QUERY_INTERVAL 30
+#define SENSOR_QUERY_INTERVAL 5
#define SENSOR_SCAN_INTERVAL (5*60)
enum client_state {
@@ -134,11 +135,13 @@ struct ntp_peer {
struct ntp_sensor {
TAILQ_ENTRY(ntp_sensor) entry;
+ struct ntp_offset offsets[SENSOR_OFFSETS];
struct ntp_offset update;
time_t next;
char *device;
int sensorid;
u_int8_t weight;
+ u_int8_t shift;
};
struct ntp_conf_sensor {
@@ -258,6 +261,7 @@ pid_t ntp_main(int[2], struct ntpd_conf *);
int priv_adjtime(void);
void priv_settime(double);
void priv_host_dns(char *, u_int32_t);
+int offset_compare(const void *, const void *);
/* parse.y */
int parse_config(const char *, struct ntpd_conf *);
diff --git a/usr.sbin/ntpd/sensors.c b/usr.sbin/ntpd/sensors.c
index 484f44e1350..309e006669f 100644
--- a/usr.sbin/ntpd/sensors.c
+++ b/usr.sbin/ntpd/sensors.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sensors.c,v 1.23 2006/10/12 10:41:51 henning Exp $ */
+/* $OpenBSD: sensors.c,v 1.24 2006/10/24 12:23:39 henning Exp $ */
/*
* Copyright (c) 2006 Henning Brauer <henning@openbsd.org>
@@ -37,6 +37,7 @@
void sensor_probe(int);
void sensor_add(struct sensor *);
void sensor_remove(struct ntp_sensor *);
+void sensor_update(struct ntp_sensor *);
struct ntpd_conf *conf;
@@ -157,21 +158,54 @@ sensor_query(struct ntp_sensor *s)
return;
memcpy(&refid, "HARD", sizeof(refid));
- s->update.offset = (0 - (float)sensor.value / 1000000000.0) -
+ s->offsets[s->shift].offset = (0 - (float)sensor.value / 1000000000.0) -
getoffset();
- s->update.rcvd = sensor.tv.tv_sec;
- s->update.good = 1;
+ s->offsets[s->shift].rcvd = sensor.tv.tv_sec;
+ s->offsets[s->shift].good = 1;
+
+ s->offsets[s->shift].status.refid = htonl(refid);
+ s->offsets[s->shift].status.stratum = 0; /* increased when sent out */
+ s->offsets[s->shift].status.rootdelay = 0;
+ s->offsets[s->shift].status.rootdispersion = 0;
+ s->offsets[s->shift].status.reftime = sensor.tv.tv_sec;
+ s->offsets[s->shift].status.synced = 1;
+
+ log_debug("sensor %s: offset %f", s->device,
+ s->offsets[s->shift].offset);
+
+ if (++s->shift >= SENSOR_OFFSETS) {
+ s->shift = 0;
+ sensor_update(s);
+ }
- s->update.status.refid = htonl(refid);
- s->update.status.stratum = 0; /* increased when sent out */
- s->update.status.rootdelay = 0;
- s->update.status.rootdispersion = 0;
- s->update.status.reftime = sensor.tv.tv_sec;
- s->update.status.synced = 1;
+}
- priv_adjtime();
+void
+sensor_update(struct ntp_sensor *s)
+{
+ struct ntp_offset **offsets;
+ int i;
+
+ if ((offsets = calloc(SENSOR_OFFSETS, sizeof(struct ntp_offset *))) ==
+ NULL)
+ fatal("calloc sensor_update");
- log_debug("sensor %s: offset %f", s->device, s->update.offset);
+ for (i = 0; i < SENSOR_OFFSETS; i++)
+ offsets[i] = &s->offsets[i];
+
+ qsort(offsets, SENSOR_OFFSETS, sizeof(struct ntp_offset *),
+ offset_compare);
+
+ i = SENSOR_OFFSETS / 2;
+ memcpy(&s->update, offsets[i], sizeof(s->update));
+ if (SENSOR_OFFSETS % 2 == 0) {
+ s->update.offset =
+ (offsets[i - 1]->offset + offsets[i]->offset) / 2;
+ }
+ free(offsets);
+
+ log_debug("sensor update %s: offset %f", s->device, s->update.offset);
+ priv_adjtime();
}
int