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)