]> git.ipfire.org Git - thirdparty/chrony.git/commitdiff
Add option to trim RTC automatically
authorMiroslav Lichvar <mlichvar@redhat.com>
Wed, 27 Nov 2013 16:33:03 +0000 (17:33 +0100)
committerMiroslav Lichvar <mlichvar@redhat.com>
Wed, 27 Nov 2013 16:35:00 +0000 (17:35 +0100)
chrony.texi.in
conf.c
conf.h
rtc_linux.c

index 8cf6e9343a6f5f3b5ca549b78fda4cc06a1ad676..7714d9d91ea4bfcbd56b83dd3fa898593037711b 100644 (file)
@@ -1157,6 +1157,7 @@ directives can occur in any order in the file.
 * 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
@@ -2603,6 +2604,25 @@ The syntax is
 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
diff --git a/conf.c b/conf.c
index 265cdb4414bd4c76250a25a0cddb7701be1dd3f3..82eecd4c3dd9bb4401d2936b205cc131fbaf1ba0 100644 (file)
--- a/conf.c
+++ b/conf.c
@@ -90,6 +90,7 @@ static void parse_pidfile(char *);
 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 *);
@@ -158,6 +159,9 @@ static int rtc_sync = 0;
 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;
@@ -441,6 +445,8 @@ CNF_ReadFile(const char *filename)
         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")) {
@@ -789,6 +795,17 @@ parse_keyfile(char *line)
 
 /* ================================================== */
 
+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)
 {
@@ -1586,6 +1603,14 @@ CNF_GetKeysFile(void)
 
 /* ================================================== */
 
+double
+CNF_GetRtcAutotrim(void)
+{
+  return rtc_autotrim_threshold;
+}
+
+/* ================================================== */
+
 char *
 CNF_GetRtcFile(void)
 {
diff --git a/conf.h b/conf.h
index d03406be36a2945096e15d3bc62de55afb97f09f..52491f9950105d0292f650230e94ba0d4dcae65d 100644 (file)
--- a/conf.h
+++ b/conf.h
@@ -99,4 +99,6 @@ extern char *CNF_GetUser(void);
 extern int CNF_GetMaxSamples(void);
 extern int CNF_GetMinSamples(void);
 
+extern double CNF_GetRtcAutotrim(void);
+
 #endif /* GOT_CONF_H */
index 85418a07e8e73e9c18279ebcc57bc0e9d5f497bd..4d2ffb371d77fb2b5f929ad66e08495f106c4439 100644 (file)
@@ -38,6 +38,7 @@
 #include "local.h"
 #include "util.h"
 #include "sys_linux.h"
+#include "reference.h"
 #include "regress.h"
 #include "rtc.h"
 #include "rtc_linux.h"
@@ -123,6 +124,9 @@ static double coef_gain_rate;
    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;
@@ -375,6 +379,8 @@ setup_config(void)
   } else {
     rtc_on_utc = 0;
   }
+
+  autotrim_threshold = CNF_GetRtcAutotrim();
 }
 
 /* ================================================== */
@@ -686,6 +692,26 @@ handle_relock_after_trim(void)
 
 /* ================================================== */
 
+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)
 {
@@ -699,6 +725,7 @@ 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;