]> git.ipfire.org Git - thirdparty/chrony.git/commitdiff
Add rtcsync directive
authorMiroslav Lichvar <mlichvar@redhat.com>
Fri, 14 May 2010 12:41:11 +0000 (14:41 +0200)
committerMiroslav Lichvar <mlichvar@redhat.com>
Fri, 14 May 2010 12:41:11 +0000 (14:41 +0200)
The directive enables the 11 minute kernel mode. It cannot be used
when the normal RTC tracking is enabled.

chrony.texi
chrony_timex.h
conf.c
conf.h
rtc.c
sys_linux.c
wrap_adjtimex.c
wrap_adjtimex.h

index f9980f130881369c223c001f2287af56710068e7..af8e1235e2af8a842d23508dc8e1518ea286acd4 100644 (file)
@@ -1197,6 +1197,7 @@ directives can occur in any order in the file.
 * 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
+* rtcsync directive::           Specify that RTC should be automatically synchronised by kernel
 * server directive::            Specify an NTP server
 * sched_priority directive::    Require real-time scheduling and specify a priority for it.
 * lock_all directive::          Require that chronyd be locked into RAM. 
@@ -2458,6 +2459,17 @@ If the @code{rtconutc} directive appears, it means the RTC is required
 to keep UTC.  The directive takes no arguments.  It is equivalent to
 specifying the @code{-u} switch to the Linux @file{/sbin/clock} program.
 @c }}}
+@c {{{ rtcsync
+@node rtcsync directive
+@subsection rtcsync
+
+The @code{rtcsync} directive will enable a kernel mode where the
+system time is copied to the real time clock (RTC) every 11 minutes.
+
+This directive is supported only on Linux and cannot be used when the
+normal RTC tracking is enabled, i.e. when the @code{rtcfile} directive
+is used.
+@c }}}
 @c {{{ sched_priority
 @node sched_priority directive
 @subsection sched_priority
index 38e1146138ce714b19b058f9d3928b979d39b263..6b8027b465205b778941d852cd5f0a27b1bc2306 100644 (file)
@@ -36,6 +36,7 @@ struct timex {
 };
 
 #define ADJ_FREQUENCY          0x0002  /* frequency offset */
+#define ADJ_MAXERROR           0x0004  /* maximum time error */
 #define ADJ_STATUS             0x0010  /* clock status */
 #define ADJ_TICK               0x4000  /* tick value */
 #define ADJ_OFFSET_SINGLESHOT  0x8001  /* old-fashioned adjtime */
diff --git a/conf.c b/conf.c
index 1556c2fe9ac1eeaaab3c26b8af015b5529d8bdce..d1dd2edff207ba2415b7b8a11134b464ee431983 100644 (file)
--- a/conf.c
+++ b/conf.c
@@ -90,6 +90,7 @@ static void parse_cmdallow(const char *);
 static void parse_cmddeny(const char *);
 static void parse_cmdport(const char *);
 static void parse_rtconutc(const char *);
+static void parse_rtcsync(const char *);
 static void parse_noclientlog(const char *);
 static void parse_clientloglimit(const char *);
 static void parse_fallbackdrift(const char *);
@@ -150,6 +151,9 @@ static int enable_manual=0;
    incl. daylight saving). */
 static int rtc_on_utc = 0;
 
+/* Flag set if the RTC should be automatically synchronised by kernel */
+static int rtc_sync = 0;
+
 /* Limit and threshold for clock stepping */
 static int make_step_limit = 0;
 static double make_step_threshold = 0.0;
@@ -235,6 +239,7 @@ static const Command commands[] = {
   {"cmddeny", 7, parse_cmddeny},
   {"cmdport", 7, parse_cmdport},
   {"rtconutc", 8, parse_rtconutc},
+  {"rtcsync", 7, parse_rtcsync},
   {"noclientlog", 11, parse_noclientlog},
   {"clientloglimit", 14, parse_clientloglimit},
   {"fallbackdrift", 13, parse_fallbackdrift},
@@ -784,6 +789,14 @@ parse_rtconutc(const char *line)
 
 /* ================================================== */
 
+static void
+parse_rtcsync(const char *line)
+{
+  rtc_sync = 1;
+}
+
+/* ================================================== */
+
 static void
 parse_noclientlog(const char *line)
 {
@@ -1394,6 +1407,14 @@ CNF_GetRTCOnUTC(void)
 
 /* ================================================== */
 
+int
+CNF_GetRTCSync(void)
+{
+  return rtc_sync;
+}
+
+/* ================================================== */
+
 void
 CNF_GetMakeStep(int *limit, double *threshold)
 {
diff --git a/conf.h b/conf.h
index 31f4cf065d7b62c3e923b2174c78d291d97e8855..cf8788b42d640be074af9699ca1ea0eba3c116af 100644 (file)
--- a/conf.h
+++ b/conf.h
@@ -61,6 +61,7 @@ extern int CNF_GetDumpOnExit(void);
 extern int CNF_GetManualEnabled(void);
 extern int CNF_GetCommandPort(void);
 extern int CNF_GetRTCOnUTC(void);
+extern int CNF_GetRTCSync(void);
 extern void CNF_GetMakeStep(int *limit, double *threshold);
 extern void CNF_GetLogChange(int *enabled, double *threshold);
 extern void CNF_GetMailOnChange(int *enabled, double *threshold, char **user);
diff --git a/rtc.c b/rtc.c
index d4ec01e12ae00d6e512d4bffb95a7eb193c58631..688c238023a74e5dfad3d842252fb1940624b41c 100644 (file)
--- a/rtc.c
+++ b/rtc.c
@@ -86,6 +86,10 @@ RTC_Initialise(void)
   file_name = CNF_GetRtcFile();
 
   if (file_name) {
+    if (CNF_GetRTCSync()) {
+      LOG_FATAL(LOGF_Rtc, "rtcfile directive cannot be used with rtcsync");
+    }
+
     if (driver.init) {
       if ((driver.init)()) {
         ok = 1;
index 11cf6a422009d13b04884a41db21daa4cb54196f..c40e99c3d117e4a4e4f967f5ffe263810239873a 100644 (file)
@@ -991,6 +991,8 @@ SYS_Linux_Initialise(void)
   lcl_RegisterSystemDrivers(read_frequency, set_frequency,
                             accrue_offset, apply_step_offset,
                             get_offset_correction, set_leap);
+
+  TMX_SetSync(CNF_GetRTCSync());
 }
 
 /* ================================================== */
index 13a44407332b8eff8a66e3b0cb9f5eaf4f1e37dc..f34f477fd88f1541e41a7cdec850b602fa4c3aeb 100644 (file)
@@ -39,8 +39,7 @@
 #include "chrony_timex.h"
 #include "wrap_adjtimex.h"
 
-/* Save leap status between calls */
-static int leap_status = 0;
+static int status = 0;
 
 int
 TMX_SetTick(long tick)
@@ -75,9 +74,16 @@ TMX_SetFrequency(double *freq, long tick)
   txc.freq = (long)(*freq * (double)(1 << SHIFT_USEC));
   *freq = txc.freq / (double)(1 << SHIFT_USEC);
   txc.tick = tick;
-  txc.status = STA_UNSYNC; /* Prevent any of the FLL/PLL stuff coming
-                              up */
-  txc.status |= leap_status; /* Preserve leap bits */
+
+  /* Prevent any of the FLL/PLL stuff coming up */
+  txc.status = status; 
+
+  if (!(status & STA_UNSYNC)) {
+    /* maxerror has to be reset periodically to prevent kernel
+       from enabling UNSYNC flag */
+    txc.modes |= ADJ_MAXERROR;
+    txc.maxerror = 0;
+  }
 
   return adjtimex(&txc);
 }
@@ -165,16 +171,32 @@ TMX_SetLeap(int leap)
 {
   struct timex txc;
 
+  status &= ~(STA_INS | STA_DEL);
+
   if (leap > 0) {
-    leap_status = STA_INS;
+    status |= STA_INS;
   } else if (leap < 0) {
-    leap_status = STA_DEL;
-  } else {
-    leap_status = 0;
+    status |= STA_DEL;
   }
   
   txc.modes = ADJ_STATUS;
-  txc.status = STA_UNSYNC | leap_status;
+  txc.status = status;
+
+  return adjtimex(&txc);
+}
+
+int TMX_SetSync(int sync)
+{
+  struct timex txc;
+
+  if (sync) {
+    status &= ~STA_UNSYNC;
+  } else {
+    status |= STA_UNSYNC;
+  }
+
+  txc.modes = ADJ_STATUS;
+  txc.status = status;
 
   return adjtimex(&txc);
 }
index f88188afedf4e57d6ad98cca80470ba9c2a63a77..45c79def9033c5bdbf6d934b2afebd5ff338aa30 100644 (file)
@@ -76,6 +76,7 @@ int TMX_GetOffsetLeftOld(long *offset);
 int TMX_GetOffsetLeft(long *offset);
 int TMX_ReadCurrentParams(struct tmx_params *params);
 int TMX_SetLeap(int leap);
+int TMX_SetSync(int sync);
 
 #endif  /* GOT_WRAP_ADJTIMEX_H */