Make importance of stratum in source selection configurable
Instead of always selecting the source with minimum stratum, add weighted stratum to the distance when comparing selectable sources. The weight can be configured with new stratumweight directive and can be set to zero to ignore stratum completely, by default 1.0.
This commit is contained in:
parent
b712b3a979
commit
9cf08fc780
4 changed files with 58 additions and 12 deletions
21
chrony.texi
21
chrony.texi
|
@ -1206,6 +1206,7 @@ directives can occur in any order in the file.
|
|||
* rtcsync directive:: Specify that RTC should be automatically synchronised by kernel
|
||||
* server directive:: Specify an NTP server
|
||||
* sched_priority directive:: Require real-time scheduling and specify a priority for it.
|
||||
* stratumweight directive:: Specify how important is stratum when selecting source
|
||||
* lock_all directive:: Require that chronyd be locked into RAM.
|
||||
* tempcomp directive:: Specify temperature sensor and compensation coefficients
|
||||
|
||||
|
@ -2543,6 +2544,26 @@ resource requirements are modest, but it should result in lower and
|
|||
more consistent latency since Chronyd will not need to wait for the
|
||||
scheduler to get around to running it. You should not use this unless
|
||||
you really need it. The sched_setscheduler man page has more details.
|
||||
@c }}}
|
||||
@c {{{ stratumweight
|
||||
@node stratumweight directive
|
||||
@subsection stratumweight
|
||||
|
||||
The @code{stratumweight} directive sets how much distance should be added
|
||||
per stratum to the synchronisation distance when @code{chronyd} selects
|
||||
the synchronisation source from available sources.
|
||||
|
||||
The syntax is
|
||||
|
||||
@example
|
||||
stratumweight <dist-in-seconds>
|
||||
@end example
|
||||
|
||||
By default, it is 1 second. This usually means that sources with lower stratum
|
||||
will be preferred to sources with higher stratum even when their distance is
|
||||
significantly worse. Setting @code{stratumweight} to 0 makes @code{chronyd}
|
||||
ignore stratum when selecting the source.
|
||||
|
||||
@c }}}
|
||||
@c {{{ lock_all
|
||||
@node lock_all directive
|
||||
|
|
21
conf.c
21
conf.c
|
@ -79,6 +79,7 @@ static void parse_logdir(const char *);
|
|||
static void parse_maxupdateskew(const char *);
|
||||
static void parse_maxclockerror(const char *);
|
||||
static void parse_reselectdist(const char *);
|
||||
static void parse_stratumweight(const char *);
|
||||
static void parse_peer(const char *);
|
||||
static void parse_acquisitionport(const char *);
|
||||
static void parse_port(const char *);
|
||||
|
@ -125,6 +126,7 @@ static double max_update_skew = 1000.0;
|
|||
static double max_clock_error = 10; /* in ppm */
|
||||
|
||||
static double reselect_distance = 1e-4;
|
||||
static double stratum_weight = 1.0;
|
||||
|
||||
static int cmd_port = -1;
|
||||
|
||||
|
@ -262,6 +264,7 @@ static const Command commands[] = {
|
|||
{"broadcast", 9, parse_broadcast},
|
||||
{"tempcomp", 8, parse_tempcomp},
|
||||
{"reselectdist", 12, parse_reselectdist},
|
||||
{"stratumweight", 13, parse_stratumweight},
|
||||
{"linux_hz", 8, parse_linux_hz},
|
||||
{"linux_freq_scale", 16, parse_linux_freq_scale},
|
||||
{"sched_priority", 14, parse_sched_priority},
|
||||
|
@ -623,6 +626,16 @@ parse_reselectdist(const char *line)
|
|||
|
||||
/* ================================================== */
|
||||
|
||||
static void
|
||||
parse_stratumweight(const char *line)
|
||||
{
|
||||
if (sscanf(line, "%lf", &stratum_weight) != 1) {
|
||||
LOG(LOGS_WARN, LOGF_Configure, "Could not read stratum weight at line %d in file", line_number);
|
||||
}
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
static void
|
||||
parse_driftfile(const char *line)
|
||||
{
|
||||
|
@ -1453,6 +1466,14 @@ CNF_GetReselectDistance(void)
|
|||
|
||||
/* ================================================== */
|
||||
|
||||
double
|
||||
CNF_GetStratumWeight(void)
|
||||
{
|
||||
return stratum_weight;
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
int
|
||||
CNF_GetManualEnabled(void)
|
||||
{
|
||||
|
|
3
conf.h
3
conf.h
|
@ -78,7 +78,10 @@ extern void CNF_GetLinuxFreqScale(int *set, double *freq_scale);
|
|||
/* Value returned in ppm, as read from file */
|
||||
extern double CNF_GetMaxUpdateSkew(void);
|
||||
extern double CNF_GetMaxClockError(void);
|
||||
|
||||
extern double CNF_GetReselectDistance(void);
|
||||
extern double CNF_GetStratumWeight(void);
|
||||
|
||||
extern int CNF_AllowLocalReference(int *stratum);
|
||||
|
||||
extern void CNF_SetupAccessRestrictions(void);
|
||||
|
|
25
sources.c
25
sources.c
|
@ -139,6 +139,7 @@ static int selected_source_index; /* Which source index is currently
|
|||
#define SCORE_LIMIT 10.0
|
||||
|
||||
static double reselect_distance;
|
||||
static double stratum_weight;
|
||||
|
||||
/* ================================================== */
|
||||
/* Forward prototype */
|
||||
|
@ -160,6 +161,7 @@ void SRC_Initialise(void) {
|
|||
max_n_sources = 0;
|
||||
selected_source_index = INVALID_SOURCE;
|
||||
reselect_distance = CNF_GetReselectDistance();
|
||||
stratum_weight = CNF_GetStratumWeight();
|
||||
initialised = 1;
|
||||
|
||||
LCL_AddParameterChangeHandler(slew_sources, NULL);
|
||||
|
@ -428,7 +430,7 @@ SRC_SelectSource(unsigned long match_addr)
|
|||
double best_lo, best_hi;
|
||||
int depth, best_depth;
|
||||
int n_sel_sources;
|
||||
double distance;
|
||||
double distance, sel_src_distance;
|
||||
int stratum, min_stratum;
|
||||
struct SelectInfo *si;
|
||||
double total_root_dispersion;
|
||||
|
@ -755,6 +757,12 @@ SRC_SelectSource(unsigned long match_addr)
|
|||
|
||||
max_score_index = INVALID_SOURCE;
|
||||
max_score = 0.0;
|
||||
sel_src_distance = 0.0;
|
||||
|
||||
if (selected_source_index != INVALID_SOURCE) {
|
||||
sel_src_distance = sources[selected_source_index]->sel_info.root_distance +
|
||||
(sources[selected_source_index]->sel_info.stratum - min_stratum) * stratum_weight;
|
||||
}
|
||||
|
||||
for (i = 0; i < n_sources; i++) {
|
||||
|
||||
|
@ -764,13 +772,8 @@ SRC_SelectSource(unsigned long match_addr)
|
|||
continue;
|
||||
}
|
||||
|
||||
/* And for sources with stratum higher than the minimum */
|
||||
if (sources[i]->sel_info.stratum > min_stratum) {
|
||||
sources[i]->sel_score = 1.0;
|
||||
continue;
|
||||
}
|
||||
|
||||
distance = sources[i]->sel_info.root_distance + reselect_distance;
|
||||
distance = sources[i]->sel_info.root_distance + reselect_distance +
|
||||
(sources[i]->sel_info.stratum - min_stratum) * stratum_weight;
|
||||
|
||||
if (selected_source_index != INVALID_SOURCE) {
|
||||
|
||||
|
@ -779,8 +782,7 @@ SRC_SelectSource(unsigned long match_addr)
|
|||
if (sources[i]->ref_id == match_addr ||
|
||||
sources[selected_source_index]->ref_id == match_addr) {
|
||||
|
||||
sources[i]->sel_score *=
|
||||
sources[selected_source_index]->sel_info.root_distance / distance;
|
||||
sources[i]->sel_score *= sel_src_distance / distance;
|
||||
|
||||
if (sources[i]->sel_score < 1.0)
|
||||
sources[i]->sel_score = 1.0;
|
||||
|
@ -808,12 +810,11 @@ SRC_SelectSource(unsigned long match_addr)
|
|||
|
||||
assert(max_score_index != INVALID_SOURCE);
|
||||
|
||||
/* Does the current source have this stratum, is it still a survivor
|
||||
/* Is the current source still a survivor
|
||||
and no other source has reached the score limit? */
|
||||
|
||||
if ((selected_source_index == INVALID_SOURCE) ||
|
||||
(sources[selected_source_index]->status != SRC_SELECTABLE) ||
|
||||
(sources[selected_source_index]->sel_info.stratum > min_stratum) ||
|
||||
(max_score_index != selected_source_index && max_score > SCORE_LIMIT)) {
|
||||
|
||||
/* We have to elect a new synchronisation source */
|
||||
|
|
Loading…
Reference in a new issue