sources: handle unsynchronized sources in selection

Allow sources to accumulate samples with the leap status set to not
synchronized. Define a new state for them to be ignored in the
selection. This is intended for sources that are never synchronized and
will be used only for stabilization.
This commit is contained in:
Miroslav Lichvar 2022-02-14 10:55:22 +01:00
parent d06ae4a60e
commit 4c29f8888c
4 changed files with 18 additions and 6 deletions

View file

@ -2399,12 +2399,12 @@ process_cmd_selectdata(char *line)
n_sources = ntohl(reply.data.n_sources.n_sources); n_sources = ntohl(reply.data.n_sources.n_sources);
if (verbose) { if (verbose) {
printf( " .-- State: N - noselect, M - missing samples, d/D - large distance,\n"); printf( " . State: N - noselect, s - unsynchronised, M - missing samples,\n");
printf( " / ~ - jittery, w/W - waits for others, T - not trusted,\n"); printf( " / d/D - large distance, ~ - jittery, w/W - waits for others,\n");
printf( "| x - falseticker, P - not preferred, U - waits for update,\n"); printf( "| S - stale, O - orphan, T - not trusted, P - not preferred,\n");
printf( "| S - stale, O - orphan, + - combined, * - best.\n"); printf( "| U - waits for update,, x - falseticker, + - combined, * - best.\n");
printf( "| Effective options ------. (N - noselect, P - prefer\n"); printf( "| Effective options ---------. (N - noselect, P - prefer\n");
printf( "| Configured options -. \\ T - trust, R - require)\n"); printf( "| Configured options ----. \\ T - trust, R - require)\n");
printf( "| Auth. enabled (Y/N) -. \\ \\ Offset interval --.\n"); printf( "| Auth. enabled (Y/N) -. \\ \\ Offset interval --.\n");
printf( "| | | | |\n"); printf( "| | | | |\n");
} }

View file

@ -448,6 +448,7 @@ states are reported.
The following states indicate the source is not considered selectable for The following states indicate the source is not considered selectable for
synchronisation: synchronisation:
* _N_ - has the *noselect* option. * _N_ - has the *noselect* option.
* _s_ - is not synchronised.
* _M_ - does not have enough measurements. * _M_ - does not have enough measurements.
* _d_ - has a root distance larger than the maximum distance (configured by the * _d_ - has a root distance larger than the maximum distance (configured by the
<<chrony.conf.adoc#maxdistance,*maxdistance*>> directive). <<chrony.conf.adoc#maxdistance,*maxdistance*>> directive).

View file

@ -68,6 +68,7 @@ struct SelectInfo {
typedef enum { typedef enum {
SRC_OK, /* OK so far, not a final status! */ SRC_OK, /* OK so far, not a final status! */
SRC_UNSELECTABLE, /* Has noselect option set */ SRC_UNSELECTABLE, /* Has noselect option set */
SRC_UNSYNCHRONISED, /* Provides samples but not unsynchronised */
SRC_BAD_STATS, /* Doesn't have valid stats data */ SRC_BAD_STATS, /* Doesn't have valid stats data */
SRC_BAD_DISTANCE, /* Has root distance longer than allowed maximum */ SRC_BAD_DISTANCE, /* Has root distance longer than allowed maximum */
SRC_JITTERY, /* Had std dev larger than allowed maximum */ SRC_JITTERY, /* Had std dev larger than allowed maximum */
@ -815,6 +816,12 @@ SRC_SelectSource(SRC_Instance updated_inst)
continue; continue;
} }
/* Ignore sources which are not synchronised */
if (sources[i]->leap == LEAP_Unsynchronised) {
mark_source(sources[i], SRC_UNSYNCHRONISED);
continue;
}
si = &sources[i]->sel_info; si = &sources[i]->sel_info;
SST_GetSelectionData(sources[i]->stats, &now, SST_GetSelectionData(sources[i]->stats, &now,
&si->lo_limit, &si->hi_limit, &si->root_distance, &si->lo_limit, &si->hi_limit, &si->root_distance,
@ -1642,6 +1649,8 @@ get_status_char(SRC_Status status)
switch (status) { switch (status) {
case SRC_UNSELECTABLE: case SRC_UNSELECTABLE:
return 'N'; return 'N';
case SRC_UNSYNCHRONISED:
return 's';
case SRC_BAD_STATS: case SRC_BAD_STATS:
return 'M'; return 'M';
case SRC_BAD_DISTANCE: case SRC_BAD_DISTANCE:

View file

@ -101,6 +101,8 @@ test_unit(void)
TEST_CHECK(sources[l]->status > SRC_OK && sources[l]->status <= SRC_SELECTED); TEST_CHECK(sources[l]->status > SRC_OK && sources[l]->status <= SRC_SELECTED);
if (sources[l]->sel_options & SRC_SELECT_NOSELECT) { if (sources[l]->sel_options & SRC_SELECT_NOSELECT) {
TEST_CHECK(sources[l]->status == SRC_UNSELECTABLE); TEST_CHECK(sources[l]->status == SRC_UNSELECTABLE);
} else if (sources[l]->leap == LEAP_Unsynchronised) {
TEST_CHECK(sources[l]->status == SRC_UNSYNCHRONISED);
} else if (sources[l]->status != SRC_BAD_DISTANCE) { } else if (sources[l]->status != SRC_BAD_DISTANCE) {
if (sources[l]->status >= SRC_NONPREFERRED) { if (sources[l]->status >= SRC_NONPREFERRED) {
passed++; passed++;