sources: add option to limit selection by root distance
Add maxdistance directive to set the maximum root distance the sources are allowed to have to be selected. This is useful to reject NTPv4 sources that are no longer synchronized and report large dispersion. The default value is 3 seconds.
This commit is contained in:
parent
b7a54f8cd8
commit
5039f959e0
5 changed files with 41 additions and 0 deletions
|
@ -1152,6 +1152,7 @@ the configuration file is ignored.
|
|||
* manual directive:: Allow manual entry using chronyc's settime cmd
|
||||
* maxchange directive:: Set maximum allowed offset
|
||||
* maxclockerror directive:: Set maximum frequency error of local clock
|
||||
* maxdistance directive:: Set maximum allowed distance of sources
|
||||
* maxsamples directive:: Set maximum number of samples per source
|
||||
* maxslewrate directive:: Set maximum slew rate
|
||||
* maxupdateskew directive:: Stop bad estimates upsetting machine clock
|
||||
|
@ -2441,6 +2442,23 @@ Typical values for <error-in-ppm> might be 10 for a low quality clock
|
|||
to 0.1 for a high quality clock using a temperature compensated
|
||||
crystal oscillator.
|
||||
@c }}}
|
||||
@c {{{ maxdistance
|
||||
@node maxdistance directive
|
||||
@subsection maxdistance
|
||||
The @code{maxdistance} directive sets the maximum allowed root distance of the
|
||||
sources to not be rejected by the source selection algorithm. The distance
|
||||
includes the accumulated dispersion, which may be large when the source is no
|
||||
longer synchronised, and half of the total round-trip delay to the primary
|
||||
source.
|
||||
|
||||
By default, the maximum distance is 3 seconds.
|
||||
|
||||
The syntax is
|
||||
|
||||
@example
|
||||
maxdistance <seconds>
|
||||
@end example
|
||||
@c }}}
|
||||
@c {{{ maxsamples
|
||||
@node maxsamples directive
|
||||
@subsection maxsamples
|
||||
|
|
11
conf.c
11
conf.c
|
@ -90,6 +90,7 @@ static double correction_time_ratio = 3.0;
|
|||
static double max_clock_error = 1.0; /* in ppm */
|
||||
static double max_slew_rate = 1e6 / 12.0; /* in ppm */
|
||||
|
||||
static double max_distance = 3.0;
|
||||
static double reselect_distance = 1e-4;
|
||||
static double stratum_weight = 1e-3;
|
||||
static double combine_limit = 3.0;
|
||||
|
@ -477,6 +478,8 @@ CNF_ParseLine(const char *filename, int number, char *line)
|
|||
parse_maxchange(p);
|
||||
} else if (!strcasecmp(command, "maxclockerror")) {
|
||||
parse_double(p, &max_clock_error);
|
||||
} else if (!strcasecmp(command, "maxdistance")) {
|
||||
parse_double(p, &max_distance);
|
||||
} else if (!strcasecmp(command, "maxsamples")) {
|
||||
parse_int(p, &max_samples);
|
||||
} else if (!strcasecmp(command, "maxslewrate")) {
|
||||
|
@ -1524,6 +1527,14 @@ CNF_GetMaxSlewRate(void)
|
|||
|
||||
/* ================================================== */
|
||||
|
||||
double
|
||||
CNF_GetMaxDistance(void)
|
||||
{
|
||||
return max_distance;
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
double
|
||||
CNF_GetReselectDistance(void)
|
||||
{
|
||||
|
|
1
conf.h
1
conf.h
|
@ -86,6 +86,7 @@ extern double CNF_GetMaxClockError(void);
|
|||
extern double CNF_GetCorrectionTimeRatio(void);
|
||||
extern double CNF_GetMaxSlewRate(void);
|
||||
|
||||
extern double CNF_GetMaxDistance(void);
|
||||
extern double CNF_GetReselectDistance(void);
|
||||
extern double CNF_GetStratumWeight(void);
|
||||
extern double CNF_GetCombineLimit(void);
|
||||
|
|
10
sources.c
10
sources.c
|
@ -70,6 +70,7 @@ typedef enum {
|
|||
SRC_OK, /* OK so far, not a final status! */
|
||||
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_WAITS_STATS, /* Others have bad stats, selection postponed */
|
||||
SRC_STALE, /* Has older samples than others */
|
||||
SRC_FALSETICKER, /* Doesn't agree with others */
|
||||
|
@ -155,6 +156,7 @@ static int selected_source_index; /* Which source index is currently
|
|||
/* Number of updates needed to reset the distant status */
|
||||
#define DISTANT_PENALTY 32
|
||||
|
||||
static double max_distance;
|
||||
static double reselect_distance;
|
||||
static double stratum_weight;
|
||||
static double combine_limit;
|
||||
|
@ -179,6 +181,7 @@ void SRC_Initialise(void) {
|
|||
n_sources = 0;
|
||||
max_n_sources = 0;
|
||||
selected_source_index = INVALID_SOURCE;
|
||||
max_distance = CNF_GetMaxDistance();
|
||||
reselect_distance = CNF_GetReselectDistance();
|
||||
stratum_weight = CNF_GetStratumWeight();
|
||||
combine_limit = CNF_GetCombineLimit();
|
||||
|
@ -653,6 +656,12 @@ SRC_SelectSource(SRC_Instance updated_inst)
|
|||
continue;
|
||||
}
|
||||
|
||||
/* Require the root distance to be below the allowed maximum */
|
||||
if (si->root_distance > max_distance) {
|
||||
sources[i]->status = SRC_BAD_DISTANCE;
|
||||
continue;
|
||||
}
|
||||
|
||||
sources[i]->status = SRC_OK; /* For now */
|
||||
|
||||
if (sources[i]->reachability && max_reach_sample_ago < first_sample_ago)
|
||||
|
@ -1216,6 +1225,7 @@ SRC_ReportSource(int index, RPT_SourceReport *report, struct timeval *now)
|
|||
switch (src->status) {
|
||||
case SRC_UNSELECTABLE:
|
||||
case SRC_BAD_STATS:
|
||||
case SRC_BAD_DISTANCE:
|
||||
case SRC_STALE:
|
||||
case SRC_WAITS_STATS:
|
||||
report->state = RPT_UNREACH;
|
||||
|
|
|
@ -6,6 +6,7 @@ test_start "presend option"
|
|||
min_sync_time=140
|
||||
max_sync_time=260
|
||||
client_server_options="presend 6 maxdelay 16"
|
||||
client_conf="maxdistance 10"
|
||||
|
||||
run_test || test_fail
|
||||
check_chronyd_exit || test_fail
|
||||
|
|
Loading…
Reference in a new issue