* port directive:: Set port to use for NTP packets
* refclock directive:: Specify a reference clock
* reselectdist directive:: Set improvement in distance needed to reselect a source
+* rtcautotrim directive:: Specify threshold at which RTC is trimmed automatically
* rtcdevice directive:: Specify name of enhanced RTC device (if not /dev/rtc)
* rtcfile directive:: Specify the file where real-time clock data is stored
* rtconutc directive:: Specify that the real time clock keeps UTC not local time
reselectdist <dist-in-seconds>
@end example
@c }}}
+@c {{{ rtcautotrim
+@node rtcautotrim directive
+@subsection rtcautotrim
+The @code{rtcautotrim} directive is used to keep the real time clock (RTC)
+close to the system clock automatically. When the system clock is synchronized
+and the estimated error between the two clocks is larger than the specified
+threshold, @code{chronyd} will trim the RTC as if the @code{trimrtc}
+(@pxref{trimrtc command}) command was issued.
+
+This directive is effective only with the @code{rtcfile} directive.
+
+An example of the use of this directive is
+
+@example
+rtcautotrim 30
+@end example
+
+This would set the threshold error to 30 seconds.
+@c }}}
@c {{{ rtcdevice
@node rtcdevice directive
@subsection rtcdevice
static void parse_port(char *);
static void parse_refclock(char *);
static void parse_reselectdist(char *);
+static void parse_rtcautotrim(char *);
static void parse_rtcdevice(char *);
static void parse_rtcfile(char *);
static void parse_rtconutc(char *);
static int make_step_limit = 0;
static double make_step_threshold = 0.0;
+/* Threshold for automatic RTC trimming */
+static double rtc_autotrim_threshold = 0.0;
+
/* Number of updates before offset checking, number of ignored updates
before exiting and the maximum allowed offset */
static int max_offset_delay = -1;
parse_refclock(p);
} else if (!strcasecmp(command, "reselectdist")) {
parse_reselectdist(p);
+ } else if (!strcasecmp(command, "rtcautotrim")) {
+ parse_rtcautotrim(p);
} else if (!strcasecmp(command, "rtcdevice")) {
parse_rtcdevice(p);
} else if (!strcasecmp(command, "rtcfile")) {
/* ================================================== */
+static void
+parse_rtcautotrim(char *line)
+{
+ check_number_of_args(line, 1);
+ if (sscanf(line, "%lf", &rtc_autotrim_threshold) != 1) {
+ command_parse_error();
+ }
+}
+
+/* ================================================== */
+
static void
parse_rtcfile(char *line)
{
/* ================================================== */
+double
+CNF_GetRtcAutotrim(void)
+{
+ return rtc_autotrim_threshold;
+}
+
+/* ================================================== */
+
char *
CNF_GetRtcFile(void)
{
extern int CNF_GetMaxSamples(void);
extern int CNF_GetMinSamples(void);
+extern double CNF_GetRtcAutotrim(void);
+
#endif /* GOT_CONF_H */
#include "local.h"
#include "util.h"
#include "sys_linux.h"
+#include "reference.h"
#include "regress.h"
#include "rtc.h"
#include "rtc_linux.h"
RTC data file once we have reacquired its offset after the step */
static double saved_coef_gain_rate;
+/* Threshold for automatic RTC trimming in seconds, zero when disabled */
+static double autotrim_threshold;
+
/* Filename supplied by config file where RTC coefficients are
stored. */
static char *coefs_file_name;
} else {
rtc_on_utc = 0;
}
+
+ autotrim_threshold = CNF_GetRtcAutotrim();
}
/* ================================================== */
/* ================================================== */
+static void
+maybe_autotrim(void)
+{
+ /* Trim only when in normal mode, the coefficients are fresh, the current
+ offset is above the threshold and the system clock is synchronized */
+
+ if (operating_mode != OM_NORMAL || !coefs_valid || n_samples_since_regression)
+ return;
+
+ if (autotrim_threshold <= 0.0 || fabs(coef_seconds_fast) < autotrim_threshold)
+ return;
+
+ if (REF_GetOurStratum() >= 16)
+ return;
+
+ RTC_Linux_Trim();
+}
+
+/* ================================================== */
+
static void
process_reading(time_t rtc_time, struct timeval *system_time)
{
if (n_samples_since_regression >= N_SAMPLES_PER_REGRESSION) {
run_regression(1, &coefs_valid, &coef_ref_time, &coef_seconds_fast, &coef_gain_rate);
n_samples_since_regression = 0;
+ maybe_autotrim();
}
break;