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
* manual directive:: Allow manual entry using chronyc's settime cmd.
* 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
* minsamples directive:: Set minimum number of samples per source
* noclientlog directive:: Prevent chronyd from gathering data about clients
* clientloglimit directive:: Set client log memory limit
* 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
crystal oscillator.
@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
@node maxupdateskew directive
@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
the new master estimate.
@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
@node noclientlog directive
@subsection noclientlog

48
conf.c
View file

@ -92,7 +92,9 @@ static void parse_makestep(char *);
static void parse_manual(char *);
static void parse_maxchange(char *);
static void parse_maxclockerror(char *);
static void parse_maxsamples(char *line);
static void parse_maxupdateskew(char *);
static void parse_minsamples(char *line);
static void parse_noclientlog(char *);
static void parse_peer(char *);
static void parse_pidfile(char *);
@ -173,6 +175,10 @@ static int max_offset_delay = -1;
static int max_offset_ignore;
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
exceeding the threshold is initiated */
static int do_log_change = 0;
@ -428,8 +434,12 @@ CNF_ReadFile(const char *filename)
parse_maxchange(p);
} else if (!strcasecmp(command, "maxclockerror")) {
parse_maxclockerror(p);
} else if (!strcasecmp(command, "maxsamples")) {
parse_maxsamples(p);
} else if (!strcasecmp(command, "maxupdateskew")) {
parse_maxupdateskew(p);
} else if (!strcasecmp(command, "minsamples")) {
parse_minsamples(p);
} else if (!strcasecmp(command, "noclientlog")) {
parse_noclientlog(p);
} 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
parse_dumpdir(char *line)
{
@ -1883,3 +1915,19 @@ CNF_GetUser(void)
{
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 int CNF_GetMaxSamples(void);
extern int CNF_GetMinSamples(void);
#endif /* GOT_CONF_H */

View file

@ -226,6 +226,9 @@ RGR_FindBestRegression
int m, /* number of extra samples in x and y arrays
(negative index) which can be used to
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 */
@ -297,7 +300,9 @@ RGR_FindBestRegression
/* Count number of runs */
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) {
/* Ignore extra samples in returned nruns */
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
(negative index) which can be used to
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 */

View file

@ -43,6 +43,10 @@
to store per source */
#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,
2000ppm, which would be pretty bad */
#define WORST_CASE_FREQ_BOUND (2000.0/1.0e6)
@ -160,6 +164,8 @@ SST_Initialise(void)
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")
: -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;
/* 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);
}
@ -428,6 +435,7 @@ SST_DoNewRegression(SST_Stats inst)
inst->regression_ok = RGR_FindBestRegression(times_back + inst->runs_samples,
offsets + inst->runs_samples, weights,
inst->n_samples, inst->runs_samples,
min_samples,
&est_intercept, &est_slope, &est_var,
&est_intercept_sd, &est_slope_sd,
&best_start, &nruns, &degrees_of_freedom);