* 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
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
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;
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")) {
/* ================================================== */
+double
+CNF_GetMaxDistance(void)
+{
+ return max_distance;
+}
+
+/* ================================================== */
+
double
CNF_GetReselectDistance(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);
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 */
/* 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;
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();
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)
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;
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