From a12c7c422b729b9417ea027dfded199fe35ee1ca Mon Sep 17 00:00:00 2001 From: Miroslav Lichvar Date: Tue, 22 Mar 2016 17:07:46 +0100 Subject: [PATCH] local: make maximum frequency offset configurable Add maxdrift directive to set the maximum assumed drift of the clock, which sets the maximum frequency offset chronyd is allowed to use to to correct the drift. --- conf.c | 11 +++++++++++ conf.h | 1 + doc/chrony.conf.adoc | 10 ++++++++++ local.c | 16 ++++++++++------ 4 files changed, 32 insertions(+), 6 deletions(-) diff --git a/conf.c b/conf.c index 682b971..b7c3ddc 100644 --- a/conf.c +++ b/conf.c @@ -85,6 +85,7 @@ static char *rtc_file = NULL; static double max_update_skew = 1000.0; static double correction_time_ratio = 3.0; static double max_clock_error = 1.0; /* in ppm */ +static double max_drift = 500000.0; /* in ppm */ static double max_slew_rate = 1e6 / 12.0; /* in ppm */ static double max_distance = 3.0; @@ -489,6 +490,8 @@ CNF_ParseLine(const char *filename, int number, char *line) parse_double(p, &max_clock_error); } else if (!strcasecmp(command, "maxdistance")) { parse_double(p, &max_distance); + } else if (!strcasecmp(command, "maxdrift")) { + parse_double(p, &max_drift); } else if (!strcasecmp(command, "maxsamples")) { parse_int(p, &max_samples); } else if (!strcasecmp(command, "maxslewrate")) { @@ -1486,6 +1489,14 @@ CNF_GetMaxUpdateSkew(void) /* ================================================== */ +double +CNF_GetMaxDrift(void) +{ + return max_drift; +} + +/* ================================================== */ + double CNF_GetMaxClockError(void) { diff --git a/conf.h b/conf.h index b5ac5cf..34c7e41 100644 --- a/conf.h +++ b/conf.h @@ -83,6 +83,7 @@ extern char *CNF_GetLeapSecTimezone(void); /* Value returned in ppm, as read from file */ extern double CNF_GetMaxUpdateSkew(void); extern double CNF_GetMaxClockError(void); +extern double CNF_GetMaxDrift(void); extern double CNF_GetCorrectionTimeRatio(void); extern double CNF_GetMaxSlewRate(void); diff --git a/doc/chrony.conf.adoc b/doc/chrony.conf.adoc index 55d20ca..bd44b90 100644 --- a/doc/chrony.conf.adoc +++ b/doc/chrony.conf.adoc @@ -805,6 +805,16 @@ By default, the maximum error is 1 ppm. Typical values for _error-in-ppm_ might be 10 for a low quality clock and 0.1 for a high quality clock using a temperature compensated crystal oscillator. +[[maxdrift]]*maxdrift* _drift-in-ppm_:: +This directive specifies the maximum assumed drift (frequency error) of the +system clock. It limits the frequency adjustment that *chronyd* is allowed to +use to correct the measured drift. It is an additional limit to the maximum +adjustment that can be set by the system driver (100000 ppm on Linux, 500 ppm +on FreeBSD and NetBSD, 32500 ppm on Solaris). ++ +By default, the maximum assumed drift is 500000 ppm, i.e. the adjustment is +limited by the system driver rather than this directive. + [[maxupdateskew]]*maxupdateskew* _skew-in-ppm_:: One of *chronyd*'s tasks is to work out how fast or slow the computer's clock runs relative to its reference sources. In addition, it computes an estimate of diff --git a/local.c b/local.c index 848cc3e..2ec173e 100644 --- a/local.c +++ b/local.c @@ -42,13 +42,12 @@ /* ================================================== */ -/* Maximum allowed frequency offset in ppm, the time must not stop - or run backwards */ -#define MAX_FREQ 500000.0 - /* Variable to store the current frequency, in ppm */ static double current_freq_ppm; +/* Maximum allowed frequency, in ppm */ +static double max_freq_ppm; + /* Temperature compensation, in ppm */ static double temp_comp_ppm; @@ -166,6 +165,11 @@ LCL_Initialise(void) calculate_sys_precision(); + /* This is the maximum allowed frequency offset in ppm, the time must + never stop or run backwards */ + max_freq_ppm = CNF_GetMaxDrift(); + max_freq_ppm = CLAMP(0.0, max_freq_ppm, 500000.0); + max_clock_error = CNF_GetMaxClockError() * 1e-6; } @@ -406,12 +410,12 @@ LCL_ReadAbsoluteFrequency(void) static double clamp_freq(double freq) { - if (freq <= MAX_FREQ && freq >= -MAX_FREQ) + if (freq <= max_freq_ppm && freq >= -max_freq_ppm) return freq; LOG(LOGS_WARN, LOGF_Local, "Frequency %.1f ppm exceeds allowed maximum", freq); - return freq >= MAX_FREQ ? MAX_FREQ : -MAX_FREQ; + return CLAMP(-max_freq_ppm, freq, max_freq_ppm); } /* ================================================== */