n_sources = ntohl(reply.data.n_sources.n_sources);
if (verbose) {
- printf( " . State: N - noselect, s - unsynchronised, M - missing samples,\n");
+ printf( " . State: N - noselect, s - unsynchronised, M - missing samples, r - stratum\n");
printf( " / d/D - large distance, ~ - jittery, w/W - waits for others,\n");
printf( "| S - stale, O - orphan, T - not trusted, P - not preferred,\n");
printf( "| U - waits for update,, x - falseticker, + - combined, * - best.\n");
static SRC_AuthSelectMode authselect_mode = SRC_AUTHSELECT_MIX;
static double max_distance = 3.0;
static double max_jitter = 1.0;
+static int max_stratum = NTP_MAX_STRATUM - 1;
+static int min_stratum = 0;
static double reselect_distance = 1e-4;
static double stratum_weight = 1e-3;
static double combine_limit = 3.0;
parse_int(p, &max_samples, 0, INT_MAX);
} else if (!strcasecmp(command, "maxslewrate")) {
parse_double(p, &max_slew_rate);
+ } else if (!strcasecmp(command, "maxstratum")) {
+ parse_int(p, &max_stratum, 0, INT_MAX);
} else if (!strcasecmp(command, "maxupdateskew")) {
parse_double(p, &max_update_skew);
} else if (!strcasecmp(command, "minsamples")) {
parse_int(p, &min_samples, 0, INT_MAX);
} else if (!strcasecmp(command, "minsources")) {
parse_int(p, &min_sources, 1, INT_MAX);
+ } else if (!strcasecmp(command, "minstratum")) {
+ parse_int(p, &min_stratum, 0, INT_MAX);
} else if (!strcasecmp(command, "nocerttimecheck")) {
parse_int(p, &no_cert_time_check, 0, INT_MAX);
} else if (!strcasecmp(command, "noclientlog")) {
/* ================================================== */
+int
+CNF_GetMaxStratum(void)
+{
+ return max_stratum;
+}
+
+/* ================================================== */
+
+int
+CNF_GetMinStratum(void)
+{
+ return min_stratum;
+}
+
+/* ================================================== */
+
double
CNF_GetReselectDistance(void)
{
extern SRC_AuthSelectMode CNF_GetAuthSelectMode(void);
extern double CNF_GetMaxDistance(void);
extern double CNF_GetMaxJitter(void);
+extern int CNF_GetMaxStratum(void);
+extern int CNF_GetMinStratum(void);
extern double CNF_GetReselectDistance(void);
extern double CNF_GetStratumWeight(void);
extern double CNF_GetCombineLimit(void);
The DNS record can change over time. The used address will be replaced with a
newly resolved address when the server becomes unreachable (i.e. no valid
response to the last 8 requests), unsynchronised, a falseticker (i.e. does not
-agree with a majority of other sources), or the root distance is too large (the
-limit can be configured by the <<maxdistance,*maxdistance*>> directive). The
+agree with a majority of other sources), the root distance is too large (the
+limit can be configured by the <<maxdistance,*maxdistance*>> directive), or
+the stratum is too small or too large (the limits can be configured by the
+<<minstratum,*minstratum*>> and <<maxstratum,*maxstratum*>> directives). The
automatic replacement happens at most once per 30 minutes and only one
server can be replaced at a time. The address is also refreshed periodically
when the server is working normally (the interval can be configured by the
increase stratum of the source to the specified minimum, so *chronyd* will
avoid selecting that source. This is useful with low-stratum sources that are
known to be unreliable or inaccurate and that should be used only when other
-sources are unreachable.
+sources are unreachable. Note that the <<minstratum,*minstratum*>> directive
+is distinct from this option.
*version* _version_:::
This option sets the NTP version of packets sent to the server. This can be
useful when the server runs an old NTP implementation that does not respond to
+
By default, the maximum jitter is 1 second.
+[[maxstratum]]*maxstratum* _stratum_::
+The *maxstratum* directive sets the maximum allowed stratum of the sources to
+be selected for synchronisation. The default value is 15. The useful range is 0
+to 15.
+
+[[minstratum]]*minstratum* _stratum_::
+The *minstratum* directive sets the minimum allowed stratum of the sources to
+be selected for synchronisation. The default value is 0. The useful range is 0
+to 15.
+
[[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
* _N_ - has the *noselect* option.
* _s_ - is not synchronised.
* _M_ - does not have enough measurements.
+* _r_ - has a stratum outside of the allowed range (configured by the
+ <<minstratum,*minstratum*>> and <<maxstratum,*maxstratum*>>
+ directives).
* _d_ - has a root distance larger than the maximum distance (configured by the
<<maxdistance,*maxdistance*>> directive).
* _~_ - has a jitter larger than the maximum jitter (configured by the
* _N_ - has the *noselect* option.
* _M_ - does not have enough measurements.
* _s_ - is not synchronised.
+* _r_ - has a stratum outside of the allowed range (configured by the
+ <<chrony.conf.adoc#minstratum,*minstratum*>> and
+ <<chrony.conf.adoc#maxstratum,*maxstratum*>> directives).
* _d_ - has a root distance larger than the maximum distance (configured by the
<<chrony.conf.adoc#maxdistance,*maxdistance*>> directive).
* _~_ - has a jitter larger than the maximum jitter (configured by the
SRC_UNSELECTABLE, /* Has noselect option set */
SRC_BAD_STATS, /* Doesn't have valid stats data */
SRC_UNSYNCHRONISED, /* Provides samples, but not synchronised */
+ SRC_BAD_STRATUM, /* Has stratum outside of allowed range */
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 */
static double max_distance;
static double max_jitter;
+static int max_stratum;
+static int min_stratum;
static double reselect_distance;
static double stratum_weight;
static double combine_limit;
selected_source_index = INVALID_SOURCE;
max_distance = CNF_GetMaxDistance();
max_jitter = CNF_GetMaxJitter();
+ max_stratum = CNF_GetMaxStratum();
+ min_stratum = CNF_GetMinStratum();
reselect_distance = CNF_GetReselectDistance();
stratum_weight = CNF_GetStratumWeight();
combine_limit = CNF_GetCombineLimit();
distance or jitter larger than the allowed maximums */
if (inst == last_updated_inst) {
if (inst->bad < INT_MAX &&
- (status == SRC_FALSETICKER || status == SRC_BAD_DISTANCE || status == SRC_JITTERY))
+ (status == SRC_FALSETICKER || status == SRC_BAD_DISTANCE ||
+ status == SRC_BAD_STRATUM || status == SRC_JITTERY))
inst->bad++;
else
inst->bad = 0;
if (!inst->reported_status[status]) {
switch (status) {
+ case SRC_BAD_STRATUM:
+ if (inst->bad < BAD_HANDLE_THRESHOLD)
+ break;
+ log_selection_source(LOGS_WARN, inst,
+ "Stratum of ## %sstratum of %d",
+ inst->stratum < min_stratum ? "below min" : "above max",
+ inst->stratum < min_stratum ? min_stratum : max_stratum);
+ break;
case SRC_BAD_DISTANCE:
if (inst->bad < BAD_HANDLE_THRESHOLD)
break;
continue;
}
+ /* Require the stratum to be in the allowed range */
+ if (sources[i]->stratum < min_stratum || sources[i]->stratum > max_stratum) {
+ mark_source(sources[i], SRC_BAD_STRATUM);
+ continue;
+ }
+
/* Include extra dispersion in the root distance of sources that don't
have new samples (the last sample is older than span of all samples) */
if (first_sample_ago < 2.0 * si->last_sample_ago) {
return 'M';
case SRC_UNSYNCHRONISED:
return 's';
+ case SRC_BAD_STRATUM:
+ return 'r';
case SRC_BAD_DISTANCE:
return 'd';
case SRC_JITTERY:
--- /dev/null
+#!/usr/bin/env bash
+
+. ./test.common
+
+test_start "minstratum and maxstratum options"
+
+client_conf="
+minstratum 3
+maxstratum 5"
+
+for s in 3 5; do
+ server_conf="local stratum $s"
+ run_test || test_fail
+ check_chronyd_exit || test_fail
+ check_source_selection || test_fail
+ check_packet_interval || test_fail
+ check_sync || test_fail
+
+ check_log_messages "Stratum of .* stratum" 0 0 || test_fail
+done
+
+for s in 2 6; do
+ server_conf="local stratum $s"
+ run_test || test_fail
+ check_chronyd_exit || test_fail
+ check_source_selection && test_fail
+ check_packet_interval || test_fail
+ check_sync && test_fail
+
+ check_log_messages "Stratum of .* stratum" 0 0 || test_fail
+ if [ $s -lt 3 ]; then
+ check_log_messages "Stratum of .* below minstratum of 3" 1 1 || test_fail
+ else
+ check_log_messages "Stratum of .* above maxstratum of 5" 1 1 || test_fail
+ fi
+done
+
+test_pass