From 8bbb8fa062fe7b2457ba91f39eb497db5a297f16 Mon Sep 17 00:00:00 2001 From: Miroslav Lichvar Date: Wed, 7 Dec 2016 09:40:43 +0100 Subject: [PATCH] sources: add configurable limit for jitter The maxjitter directive sets the maximum allowed jitter of the sources to not be rejected by the source selection algorithm. This prevents synchronisation with sources that have a small root distance, but their time is too variable. By default, the maximum jitter is 1 second. --- conf.c | 11 +++++++++++ conf.h | 1 + doc/chrony.conf.adoc | 7 +++++++ sources.c | 10 +++++++++- 4 files changed, 28 insertions(+), 1 deletion(-) diff --git a/conf.c b/conf.c index 384fc56..be3a189 100644 --- a/conf.c +++ b/conf.c @@ -90,6 +90,7 @@ static double max_drift = 500000.0; /* in ppm */ static double max_slew_rate = 1e6 / 12.0; /* in ppm */ static double max_distance = 3.0; +static double max_jitter = 1.0; static double reselect_distance = 1e-4; static double stratum_weight = 1e-3; static double combine_limit = 3.0; @@ -510,6 +511,8 @@ CNF_ParseLine(const char *filename, int number, char *line) parse_double(p, &max_distance); } else if (!strcasecmp(command, "maxdrift")) { parse_double(p, &max_drift); + } else if (!strcasecmp(command, "maxjitter")) { + parse_double(p, &max_jitter); } else if (!strcasecmp(command, "maxsamples")) { parse_int(p, &max_samples); } else if (!strcasecmp(command, "maxslewrate")) { @@ -1551,6 +1554,14 @@ CNF_GetMaxDistance(void) /* ================================================== */ +double +CNF_GetMaxJitter(void) +{ + return max_jitter; +} + +/* ================================================== */ + double CNF_GetReselectDistance(void) { diff --git a/conf.h b/conf.h index 13e58b5..d241665 100644 --- a/conf.h +++ b/conf.h @@ -90,6 +90,7 @@ extern double CNF_GetCorrectionTimeRatio(void); extern double CNF_GetMaxSlewRate(void); extern double CNF_GetMaxDistance(void); +extern double CNF_GetMaxJitter(void); extern double CNF_GetReselectDistance(void); extern double CNF_GetStratumWeight(void); extern double CNF_GetCombineLimit(void); diff --git a/doc/chrony.conf.adoc b/doc/chrony.conf.adoc index 30c77c9..123666a 100644 --- a/doc/chrony.conf.adoc +++ b/doc/chrony.conf.adoc @@ -600,6 +600,13 @@ Setting *maxdistance* to a larger value can be useful to allow synchronisation with a server that only has a very infrequent connection to its sources and can accumulate a large dispersion between updates of its clock. +[[maxjitter]]*maxjitter* _jitter_:: +The *maxjitter* directive sets the maximum allowed jitter of the sources to not +be rejected by the source selection algorithm. This prevents synchronisation +with sources that have a small root distance, but their time is too variable. ++ +By default, the maximum jitter is 1 second. + [[minsources]]*minsources* _sources_:: The *minsources* directive sets the minimum number of sources that need to be considered as selectable in the source selection algorithm before the local diff --git a/sources.c b/sources.c index 55e6a82..5c9bbe3 100644 --- a/sources.c +++ b/sources.c @@ -71,12 +71,12 @@ typedef enum { SRC_UNSELECTABLE, /* Has noselect option set */ SRC_BAD_STATS, /* Doesn't have valid stats data */ SRC_BAD_DISTANCE, /* Has root distance longer than allowed maximum */ + SRC_JITTERY, /* Had std dev larger than allowed maximum */ SRC_WAITS_STATS, /* Others have bad stats, selection postponed */ SRC_STALE, /* Has older samples than others */ SRC_ORPHAN, /* Has stratum equal or larger than orphan stratum */ SRC_UNTRUSTED, /* Overlaps trusted sources */ SRC_FALSETICKER, /* Doesn't agree with others */ - SRC_JITTERY, /* Scatter worse than other's dispersion (not used) */ SRC_WAITS_SOURCES, /* Not enough sources, selection postponed */ SRC_NONPREFERRED, /* Others have prefer option */ SRC_WAITS_UPDATE, /* No updates, selection postponed */ @@ -159,6 +159,7 @@ static int selected_source_index; /* Which source index is currently #define DISTANT_PENALTY 32 static double max_distance; +static double max_jitter; static double reselect_distance; static double stratum_weight; static double combine_limit; @@ -184,6 +185,7 @@ void SRC_Initialise(void) { max_n_sources = 0; selected_source_index = INVALID_SOURCE; max_distance = CNF_GetMaxDistance(); + max_jitter = CNF_GetMaxJitter(); reselect_distance = CNF_GetReselectDistance(); stratum_weight = CNF_GetStratumWeight(); combine_limit = CNF_GetCombineLimit(); @@ -665,6 +667,12 @@ SRC_SelectSource(SRC_Instance updated_inst) continue; } + /* And the same applies for the estimated standard deviation */ + if (si->std_dev > max_jitter) { + sources[i]->status = SRC_JITTERY; + continue; + } + sources[i]->status = SRC_OK; /* For now */ if (sources[i]->reachability && max_reach_sample_ago < first_sample_ago)