Add minsamples and maxsamples directives

Allow configuration of the maximum and minimum number of samples per
source.
This commit is contained in:
Miroslav Lichvar 2013-06-13 16:23:32 +02:00
parent 22e5ed44c2
commit 6d2fb9f782
6 changed files with 97 additions and 2 deletions

View file

@ -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
View file

@ -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
View file

@ -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 */

View file

@ -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);

View file

@ -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 */

View file

@ -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, &degrees_of_freedom); &best_start, &nruns, &degrees_of_freedom);