Add minsamples and maxsamples directives
Allow configuration of the maximum and minimum number of samples per source.
This commit is contained in:
parent
22e5ed44c2
commit
6d2fb9f782
6 changed files with 97 additions and 2 deletions
|
@ -1195,7 +1195,9 @@ directives can occur in any order in the file.
|
||||||
* maxchange directive:: Set maximum allowed offset
|
* maxchange directive:: Set maximum allowed offset
|
||||||
* manual directive:: Allow manual entry using chronyc's settime cmd.
|
* manual directive:: Allow manual entry using chronyc's settime cmd.
|
||||||
* maxclockerror directive:: Set maximum frequency error of local clock
|
* maxclockerror directive:: Set maximum frequency error of local clock
|
||||||
|
* maxsamples directive:: Set maximum number of samples per source
|
||||||
* maxupdateskew directive:: Stop bad estimates upsetting machine clock
|
* maxupdateskew directive:: Stop bad estimates upsetting machine clock
|
||||||
|
* minsamples directive:: Set minimum number of samples per source
|
||||||
* noclientlog directive:: Prevent chronyd from gathering data about clients
|
* noclientlog directive:: Prevent chronyd from gathering data about clients
|
||||||
* clientloglimit directive:: Set client log memory limit
|
* clientloglimit directive:: Set client log memory limit
|
||||||
* peer directive:: Specify an NTP peer
|
* peer directive:: Specify an NTP peer
|
||||||
|
@ -2374,6 +2376,19 @@ 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
|
to 0.1 for a high quality clock using a temperature compensated
|
||||||
crystal oscillator.
|
crystal oscillator.
|
||||||
@c }}}
|
@c }}}
|
||||||
|
@c {{{ maxsamples
|
||||||
|
@node maxsamples directive
|
||||||
|
@subsection maxsamples
|
||||||
|
The @code{maxsamples} directive sets the maximum number of samples
|
||||||
|
@code{chronyd} should keep for each source. The default is 0, which
|
||||||
|
disables the configurable limit, and the useful range is 4 to 64.
|
||||||
|
|
||||||
|
The syntax is
|
||||||
|
|
||||||
|
@example
|
||||||
|
maxsamples <samples>
|
||||||
|
@end example
|
||||||
|
@c }}}
|
||||||
@c {{{ maxupdateskew
|
@c {{{ maxupdateskew
|
||||||
@node maxupdateskew directive
|
@node maxupdateskew directive
|
||||||
@subsection maxupdateskew
|
@subsection maxupdateskew
|
||||||
|
@ -2408,6 +2423,19 @@ highly-reliable master estimate and a new estimate is generated which
|
||||||
has large error bounds, the existing master estimate will dominate in
|
has large error bounds, the existing master estimate will dominate in
|
||||||
the new master estimate.
|
the new master estimate.
|
||||||
@c }}}
|
@c }}}
|
||||||
|
@c {{{ minsamples
|
||||||
|
@node minsamples directive
|
||||||
|
@subsection minsamples
|
||||||
|
The @code{minsamples} directive sets the minimum number of samples
|
||||||
|
@code{chronyd} should try to keep for each source. The default is 0 and the
|
||||||
|
useful range is 4 to 64.
|
||||||
|
|
||||||
|
The syntax is
|
||||||
|
|
||||||
|
@example
|
||||||
|
minsamples <samples>
|
||||||
|
@end example
|
||||||
|
@c }}}
|
||||||
@c {{{ noclientlog
|
@c {{{ noclientlog
|
||||||
@node noclientlog directive
|
@node noclientlog directive
|
||||||
@subsection noclientlog
|
@subsection noclientlog
|
||||||
|
|
48
conf.c
48
conf.c
|
@ -92,7 +92,9 @@ static void parse_makestep(char *);
|
||||||
static void parse_manual(char *);
|
static void parse_manual(char *);
|
||||||
static void parse_maxchange(char *);
|
static void parse_maxchange(char *);
|
||||||
static void parse_maxclockerror(char *);
|
static void parse_maxclockerror(char *);
|
||||||
|
static void parse_maxsamples(char *line);
|
||||||
static void parse_maxupdateskew(char *);
|
static void parse_maxupdateskew(char *);
|
||||||
|
static void parse_minsamples(char *line);
|
||||||
static void parse_noclientlog(char *);
|
static void parse_noclientlog(char *);
|
||||||
static void parse_peer(char *);
|
static void parse_peer(char *);
|
||||||
static void parse_pidfile(char *);
|
static void parse_pidfile(char *);
|
||||||
|
@ -173,6 +175,10 @@ static int max_offset_delay = -1;
|
||||||
static int max_offset_ignore;
|
static int max_offset_ignore;
|
||||||
static double max_offset;
|
static double max_offset;
|
||||||
|
|
||||||
|
/* Maximum and minimum number of samples per source */
|
||||||
|
static int max_samples = 0; /* no limit */
|
||||||
|
static int min_samples = 0;
|
||||||
|
|
||||||
/* Flag set if we should log to syslog when a time adjustment
|
/* Flag set if we should log to syslog when a time adjustment
|
||||||
exceeding the threshold is initiated */
|
exceeding the threshold is initiated */
|
||||||
static int do_log_change = 0;
|
static int do_log_change = 0;
|
||||||
|
@ -428,8 +434,12 @@ CNF_ReadFile(const char *filename)
|
||||||
parse_maxchange(p);
|
parse_maxchange(p);
|
||||||
} else if (!strcasecmp(command, "maxclockerror")) {
|
} else if (!strcasecmp(command, "maxclockerror")) {
|
||||||
parse_maxclockerror(p);
|
parse_maxclockerror(p);
|
||||||
|
} else if (!strcasecmp(command, "maxsamples")) {
|
||||||
|
parse_maxsamples(p);
|
||||||
} else if (!strcasecmp(command, "maxupdateskew")) {
|
} else if (!strcasecmp(command, "maxupdateskew")) {
|
||||||
parse_maxupdateskew(p);
|
parse_maxupdateskew(p);
|
||||||
|
} else if (!strcasecmp(command, "minsamples")) {
|
||||||
|
parse_minsamples(p);
|
||||||
} else if (!strcasecmp(command, "noclientlog")) {
|
} else if (!strcasecmp(command, "noclientlog")) {
|
||||||
parse_noclientlog(p);
|
parse_noclientlog(p);
|
||||||
} else if (!strcasecmp(command, "peer")) {
|
} else if (!strcasecmp(command, "peer")) {
|
||||||
|
@ -828,6 +838,28 @@ parse_logdir(char *line)
|
||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
|
static void
|
||||||
|
parse_maxsamples(char *line)
|
||||||
|
{
|
||||||
|
check_number_of_args(line, 1);
|
||||||
|
if (sscanf(line, "%d", &max_samples) != 1) {
|
||||||
|
command_parse_error();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ================================================== */
|
||||||
|
|
||||||
|
static void
|
||||||
|
parse_minsamples(char *line)
|
||||||
|
{
|
||||||
|
check_number_of_args(line, 1);
|
||||||
|
if (sscanf(line, "%d", &min_samples) != 1) {
|
||||||
|
command_parse_error();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ================================================== */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
parse_dumpdir(char *line)
|
parse_dumpdir(char *line)
|
||||||
{
|
{
|
||||||
|
@ -1883,3 +1915,19 @@ CNF_GetUser(void)
|
||||||
{
|
{
|
||||||
return user;
|
return user;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ================================================== */
|
||||||
|
|
||||||
|
int
|
||||||
|
CNF_GetMaxSamples(void)
|
||||||
|
{
|
||||||
|
return max_samples;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ================================================== */
|
||||||
|
|
||||||
|
int
|
||||||
|
CNF_GetMinSamples(void)
|
||||||
|
{
|
||||||
|
return min_samples;
|
||||||
|
}
|
||||||
|
|
3
conf.h
3
conf.h
|
@ -96,4 +96,7 @@ extern void CNF_GetTempComp(char **file, double *interval, double *T0, double *k
|
||||||
|
|
||||||
extern char *CNF_GetUser(void);
|
extern char *CNF_GetUser(void);
|
||||||
|
|
||||||
|
extern int CNF_GetMaxSamples(void);
|
||||||
|
extern int CNF_GetMinSamples(void);
|
||||||
|
|
||||||
#endif /* GOT_CONF_H */
|
#endif /* GOT_CONF_H */
|
||||||
|
|
|
@ -226,6 +226,9 @@ RGR_FindBestRegression
|
||||||
int m, /* number of extra samples in x and y arrays
|
int m, /* number of extra samples in x and y arrays
|
||||||
(negative index) which can be used to
|
(negative index) which can be used to
|
||||||
extend runs test */
|
extend runs test */
|
||||||
|
int min_samples, /* minimum number of samples to be kept after
|
||||||
|
changing the starting index to pass the runs
|
||||||
|
test */
|
||||||
|
|
||||||
/* And now the results */
|
/* And now the results */
|
||||||
|
|
||||||
|
@ -297,7 +300,9 @@ RGR_FindBestRegression
|
||||||
/* Count number of runs */
|
/* Count number of runs */
|
||||||
nruns = n_runs_from_residuals(resid, n - resid_start);
|
nruns = n_runs_from_residuals(resid, n - resid_start);
|
||||||
|
|
||||||
if (nruns > critical_runs[n - resid_start] || n - start <= MIN_SAMPLES_FOR_REGRESS) {
|
if (nruns > critical_runs[n - resid_start] ||
|
||||||
|
n - start <= MIN_SAMPLES_FOR_REGRESS ||
|
||||||
|
n - start <= min_samples) {
|
||||||
if (start != resid_start) {
|
if (start != resid_start) {
|
||||||
/* Ignore extra samples in returned nruns */
|
/* Ignore extra samples in returned nruns */
|
||||||
nruns = n_runs_from_residuals(resid - resid_start + start, n - start);
|
nruns = n_runs_from_residuals(resid - resid_start + start, n - start);
|
||||||
|
|
|
@ -80,6 +80,9 @@ RGR_FindBestRegression
|
||||||
int m, /* number of extra samples in x and y arrays
|
int m, /* number of extra samples in x and y arrays
|
||||||
(negative index) which can be used to
|
(negative index) which can be used to
|
||||||
extend runs test */
|
extend runs test */
|
||||||
|
int min_samples, /* minimum number of samples to be kept after
|
||||||
|
changing the starting index to pass the runs
|
||||||
|
test */
|
||||||
|
|
||||||
/* And now the results */
|
/* And now the results */
|
||||||
|
|
||||||
|
|
|
@ -43,6 +43,10 @@
|
||||||
to store per source */
|
to store per source */
|
||||||
#define MAX_SAMPLES 64
|
#define MAX_SAMPLES 64
|
||||||
|
|
||||||
|
/* User defined maximum and minimum number of samples */
|
||||||
|
int max_samples;
|
||||||
|
int min_samples;
|
||||||
|
|
||||||
/* This is the assumed worst case bound on an unknown frequency,
|
/* This is the assumed worst case bound on an unknown frequency,
|
||||||
2000ppm, which would be pretty bad */
|
2000ppm, which would be pretty bad */
|
||||||
#define WORST_CASE_FREQ_BOUND (2000.0/1.0e6)
|
#define WORST_CASE_FREQ_BOUND (2000.0/1.0e6)
|
||||||
|
@ -160,6 +164,8 @@ SST_Initialise(void)
|
||||||
logfileid = CNF_GetLogStatistics() ? LOG_FileOpen("statistics",
|
logfileid = CNF_GetLogStatistics() ? LOG_FileOpen("statistics",
|
||||||
" Date (UTC) Time IP Address Std dev'n Est offset Offset sd Diff freq Est skew Stress Ns Bs Nr")
|
" Date (UTC) Time IP Address Std dev'n Est offset Offset sd Diff freq Est skew Stress Ns Bs Nr")
|
||||||
: -1;
|
: -1;
|
||||||
|
max_samples = CNF_GetMaxSamples();
|
||||||
|
min_samples = CNF_GetMinSamples();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
@ -239,7 +245,8 @@ SST_AccumulateSample(SST_Stats inst, struct timeval *sample_time,
|
||||||
int n, m;
|
int n, m;
|
||||||
|
|
||||||
/* Make room for the new sample */
|
/* Make room for the new sample */
|
||||||
if (inst->n_samples == MAX_SAMPLES) {
|
if (inst->n_samples > 0 &&
|
||||||
|
(inst->n_samples == MAX_SAMPLES || inst->n_samples == max_samples)) {
|
||||||
prune_register(inst, 1);
|
prune_register(inst, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -428,6 +435,7 @@ SST_DoNewRegression(SST_Stats inst)
|
||||||
inst->regression_ok = RGR_FindBestRegression(times_back + inst->runs_samples,
|
inst->regression_ok = RGR_FindBestRegression(times_back + inst->runs_samples,
|
||||||
offsets + inst->runs_samples, weights,
|
offsets + inst->runs_samples, weights,
|
||||||
inst->n_samples, inst->runs_samples,
|
inst->n_samples, inst->runs_samples,
|
||||||
|
min_samples,
|
||||||
&est_intercept, &est_slope, &est_var,
|
&est_intercept, &est_slope, &est_var,
|
||||||
&est_intercept_sd, &est_slope_sd,
|
&est_intercept_sd, &est_slope_sd,
|
||||||
&best_start, &nruns, °rees_of_freedom);
|
&best_start, &nruns, °rees_of_freedom);
|
||||||
|
|
Loading…
Reference in a new issue