* 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
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
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
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 *);
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;
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")) {
/* ================================================== */
+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)
{
{
return user;
}
+
+/* ================================================== */
+
+int
+CNF_GetMaxSamples(void)
+{
+ return max_samples;
+}
+
+/* ================================================== */
+
+int
+CNF_GetMinSamples(void)
+{
+ return min_samples;
+}
extern char *CNF_GetUser(void);
+extern int CNF_GetMaxSamples(void);
+extern int CNF_GetMinSamples(void);
+
#endif /* GOT_CONF_H */
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 */
/* 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);
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 */
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)
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();
}
/* ================================================== */
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);
}
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, °rees_of_freedom);