* mailonchange directive:: Send email if a clock correction above a threshold occurs
* makestep directive:: Step system clock if large correction is needed
* manual directive:: Allow manual entry using chronyc's settime cmd.
+* maxclockerror directive:: Set maximum frequency error of local clock
* maxupdateskew directive:: Stop bad estimates upsetting machine clock
* noclientlog directive:: Prevent chronyd from gathering data about clients
* clientloglimit directive:: Set client log memory limit
manual clock driver's behaviour, whereas the @code{settime} command
allows samples of manually entered time to be provided).
@c }}}
+@c {{{ maxclockerror
+@node maxclockerror directive
+@subsection maxclockerror
+The @code{maxclockerror} directive sets the maximum assumed frequency
+error of the local clock. This is a frequency stability of the clock,
+not an absolute frequency error.
+
+By default, the maximum assumed error is set to 10 ppm.
+
+The syntax is
+
+@example
+maxclockerror <error-in-ppm>
+@end example
+
+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 {{{ maxupdateskew
@node maxupdateskew directive
@subsection maxupdateskew
static void parse_logbanner(const char *);
static void parse_logdir(const char *);
static void parse_maxupdateskew(const char *);
+static void parse_maxclockerror(const char *);
static void parse_peer(const char *);
static void parse_acquisitionport(const char *);
static void parse_port(const char *);
static char *rtc_file = NULL;
static unsigned long command_key_id;
static double max_update_skew = 1000.0;
+static double max_clock_error = 10; /* in ppm */
static int cmd_port = -1;
{"dumponexit", 10, parse_dumponexit},
{"dumpdir", 7, parse_dumpdir},
{"maxupdateskew", 13, parse_maxupdateskew},
+ {"maxclockerror", 13, parse_maxclockerror},
{"commandkey", 10, parse_commandkey},
{"initstepslew", 12, parse_initstepslew},
{"local", 5, parse_local},
/* ================================================== */
+static void
+parse_maxclockerror(const char *line)
+{
+ if (sscanf(line, "%lf", &max_clock_error) != 1) {
+ LOG(LOGS_WARN, LOGF_Configure, "Could not read max clock error at line %d in file", line_number);
+ }
+}
+
+/* ================================================== */
+
static void
parse_driftfile(const char *line)
{
/* ================================================== */
+double
+CNF_GetMaxClockError(void)
+{
+ return max_clock_error;
+}
+
+/* ================================================== */
+
int
CNF_GetManualEnabled(void)
{
/* Value returned in ppm, as read from file */
extern double CNF_GetMaxUpdateSkew(void);
+extern double CNF_GetMaxClockError(void);
extern int CNF_AllowLocalReference(int *stratum);
extern void CNF_SetupAccessRestrictions(void);
#include <assert.h>
#include <stddef.h>
+#include "conf.h"
#include "local.h"
#include "localp.h"
#include "memory.h"
static int precision_log;
static double precision_quantum;
+static double max_clock_error;
+
/* ================================================== */
/* Define the number of increments of the system clock that we want
temp_comp_ppm = 0.0;
calculate_sys_precision();
+
+ max_clock_error = CNF_GetMaxClockError() * 1e-6;
}
/* ================================================== */
/* ================================================== */
+double
+LCL_GetMaxClockError(void)
+{
+ return max_clock_error;
+}
+
+/* ================================================== */
+
void
LCL_AddParameterChangeHandler(LCL_ParameterChangeHandler handler, void *anything)
{
/* Routine to read the system precision in terms of the actual time step */
extern double LCL_GetSysPrecisionAsQuantum(void);
+/* Routine to read the maximum frequency error of the local clock. This
+ is a frequency stability, not an absolute error. */
+extern double LCL_GetMaxClockError(void);
+
/* Routine to initialise the module (to be called once at program
start-up) */
*stratum = our_stratum;
UTI_DiffTimevalsToDouble(&elapsed, local_time, &our_ref_time);
- extra_dispersion = (our_skew + fabs(our_residual_freq)) * elapsed;
+ extra_dispersion = (our_skew + fabs(our_residual_freq) + LCL_GetMaxClockError()) * elapsed;
*leap_status = our_leap_status;
*ref_id = our_ref_id;
if (are_we_synchronised) {
UTI_DiffTimevalsToDouble(&elapsed, &now_cooked, &our_ref_time);
- extra_dispersion = (our_skew + fabs(our_residual_freq)) * elapsed;
+ extra_dispersion = (our_skew + fabs(our_residual_freq) + LCL_GetMaxClockError()) * elapsed;
rep->ref_id = our_ref_id;
rep->ip_addr = our_ref_ip;