]> git.ipfire.org Git - thirdparty/chrony.git/commitdiff
Add makestep directive
authorMiroslav Lichvar <mlichvar@redhat.com>
Mon, 25 Jan 2010 14:33:56 +0000 (15:33 +0100)
committerMiroslav Lichvar <mlichvar@redhat.com>
Mon, 25 Jan 2010 14:51:15 +0000 (15:51 +0100)
chrony.texi
cmdmon.c
conf.c
conf.h
local.c
local.h
reference.c

index f3d0c85bff1f060d3fe1658d949443796f2d0941..b867d21865bb7c1feb42544922ff1712b5d0cf79 100644 (file)
@@ -1184,6 +1184,7 @@ directives can occur in any order in the file.
 * logchange directive::         Generate syslog messages if large offsets occur
 * logdir directive::            Specify directory for logging
 * 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.
 * maxupdateskew directive::     Stop bad estimates upsetting machine clock
 * noclientlog directive::       Prevent chronyd from gathering data about clients
@@ -2085,6 +2086,32 @@ mailonchange root@@localhost 0.5
 This would send a mail message to root if a change of more than 0.5
 seconds were applied to the system clock.
 @c }}}
+@c {{{ makestep
+@node makestep directive
+@subsection makestep
+Normally chronyd will cause the system to gradually correct any time
+offset, by slowing down or speeding up the clock as required.  In
+certain situations, the system clock may be so far adrift that this
+slewing process would take a very long time to correct the system clock.
+
+This directive forces @code{chronyd} to step system clock if the
+adjustment is larger than a threshold value, but only if there were no
+more clock updates since @code{chronyd} was started than a specified
+limit (a negative value can be used to disable the limit).
+
+This is particularly useful when using reference clocks, because the
+@code{initstepslew} directive (@pxref{initstepslew directive}) works
+only with NTP sources.
+
+An example of the use of this directive is
+
+@example
+makestep 1000 10
+@end example
+
+This would step system clock if the adjustment is larger than 1000
+seconds, but only in the first ten clock updates.
+@c }}}
 @c {{{ manual
 @node manual directive
 @subsection manual
@@ -3075,6 +3102,10 @@ clock by the equivalent amount, making it correct immediately.
 BE WARNED - certain software will be seriously affected by such jumps to
 the system time.  (That is the reason why chronyd uses slewing
 normally.)
+
+The @code{makestep} directive in the configuration file can be used
+to step the clock automatically when the adjustment is larger than a
+specified threshold, see @ref{makestep directive}.
 @c }}}
 @c {{{ manual
 @node manual command
index e1edfba16dc8a2dec400604d45857129ed81dc78..397f6a3a52bb2682ae2d799c15a1f7c67f6dcc5e 100644 (file)
--- a/cmdmon.c
+++ b/cmdmon.c
@@ -1676,13 +1676,8 @@ handle_manual_delete(CMD_Request *rx_message, CMD_Reply *tx_message)
 static void
 handle_make_step(CMD_Request *rx_message, CMD_Reply *tx_message)
 {
-  int status;
-  status = LCL_MakeStep();
-  if (status) {
-    tx_message->status = htons(STT_SUCCESS);
-  } else {
-    tx_message->status = htons(STT_NOTENABLED);
-  }
+  LCL_MakeStep(0.0);
+  tx_message->status = htons(STT_SUCCESS);
   return;
 }
 
diff --git a/conf.c b/conf.c
index 04cdab9ff68703f4831bf42644797dacf0317f73..8cbc8b13def5ae2915685c1d29d64f62e5dc55d8 100644 (file)
--- a/conf.c
+++ b/conf.c
@@ -92,6 +92,7 @@ static void parse_cmdport(const char *);
 static void parse_rtconutc(const char *);
 static void parse_noclientlog(const char *);
 static void parse_clientloglimit(const char *);
+static void parse_makestep(const char *);
 static void parse_logchange(const char *);
 static void parse_mailonchange(const char *);
 static void parse_bindaddress(const char *);
@@ -146,6 +147,10 @@ static int enable_manual=0;
    incl. daylight saving). */
 static int rtc_on_utc = 0;
 
+/* Limit and threshold for clock stepping */
+static int make_step_limit = 0;
+static double make_step_threshold = 0.0;
+
 /* Flag set if we should log to syslog when a time adjustment
    exceeding the threshold is initiated */
 static int do_log_change = 0;
@@ -220,6 +225,7 @@ static const Command commands[] = {
   {"rtconutc", 8, parse_rtconutc},
   {"noclientlog", 11, parse_noclientlog},
   {"clientloglimit", 14, parse_clientloglimit},
+  {"makestep", 8, parse_makestep},
   {"logchange", 9, parse_logchange},
   {"mailonchange", 12, parse_mailonchange},
   {"bindaddress", 11, parse_bindaddress},
@@ -788,6 +794,19 @@ parse_clientloglimit(const char *line)
 
 /* ================================================== */
 
+static void
+parse_makestep(const char *line)
+{
+  if (sscanf(line, "%lf %d", &make_step_threshold, &make_step_limit) != 2) {
+    make_step_limit = 0;
+    LOG(LOGS_WARN, LOGF_Configure,
+        "Could not read threshold or update limit for stepping clock at line %d\n",
+        line_number);
+  }
+}
+
+/* ================================================== */
+
 static void
 parse_logchange(const char *line)
 {
@@ -1319,6 +1338,15 @@ CNF_GetRTCOnUTC(void)
 
 /* ================================================== */
 
+void
+CNF_GetMakeStep(int *limit, double *threshold)
+{
+  *limit = make_step_limit;
+  *threshold = make_step_threshold;
+}
+
+/* ================================================== */
+
 void
 CNF_GetLogChange(int *enabled, double *threshold)
 {
diff --git a/conf.h b/conf.h
index 004bfcfb93327d22a9cdfbc4afa89bcff45403d8..480bfed1d1fd31dfaae8c750a6f4687fdc6fce52 100644 (file)
--- a/conf.h
+++ b/conf.h
@@ -60,6 +60,7 @@ extern int CNF_GetDumpOnExit(void);
 extern int CNF_GetManualEnabled(void);
 extern int CNF_GetCommandPort(void);
 extern int CNF_GetRTCOnUTC(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);
 extern int CNF_GetNoClientLog(void);
diff --git a/local.c b/local.c
index a1e95f568bcd5eb888b1d8ca146235144945a43c..0e69f5a1de0c40b31271bdc37a29aaf98e8aa501 100644 (file)
--- a/local.c
+++ b/local.c
@@ -555,10 +555,10 @@ lcl_RegisterSystemDrivers(lcl_ReadFrequencyDriver read_freq,
 
 /* ================================================== */
 /* Look at the current difference between the system time and the NTP
-   time, and make a step to cancel it. */
+   time, and make a step to cancel it if it's larger than the threshold. */
 
 int
-LCL_MakeStep(void)
+LCL_MakeStep(double threshold)
 {
   struct timeval raw;
   double correction;
@@ -566,6 +566,9 @@ LCL_MakeStep(void)
   LCL_ReadRawTime(&raw);
   correction = LCL_GetOffsetCorrection(&raw);
 
+  if (fabs(correction) <= threshold)
+    return 0;
+
   /* Cancel remaining slew and make the step */
   LCL_AccumulateOffset(correction);
   LCL_ApplyStepOffset(-correction);
diff --git a/local.h b/local.h
index 6f7d211c7802bce8569c4217d0a76d16497a52e4..98899a9cc388eff53a43faf7be781bfb8d931385 100644 (file)
--- a/local.h
+++ b/local.h
@@ -179,7 +179,7 @@ extern void LCL_Finalise(void);
 /* Routine to convert the outstanding system clock error to a step and
    apply it, e.g. if the system clock has ended up an hour wrong due
    to a timezone problem. */
-extern int LCL_MakeStep(void);
+extern int LCL_MakeStep(double threshold);
 
 /* Routine to schedule a leap second. Leap second will be inserted
    at the end of the day if argument is positive, deleted if negative,
index 2ac283c4ae9bb5861236548f9264e70f8a76dc6b..af8baa15b13de4e1b2dafbbeb6dd35529dbdb20a 100644 (file)
@@ -61,6 +61,10 @@ static double max_update_skew;
 /* Flag indicating that we are initialised */
 static int initialised = 0;
 
+/* Threshold and update limit for stepping clock */
+static int make_step_limit;
+static double make_step_threshold;
+
 /* Flag and threshold for logging clock changes to syslog */
 static int do_log_change;
 static double log_change_threshold;
@@ -161,6 +165,7 @@ REF_Initialise(void)
 
   enable_local_stratum = CNF_AllowLocalReference(&local_stratum);
 
+  CNF_GetMakeStep(&make_step_limit, &make_step_threshold);
   CNF_GetLogChange(&do_log_change, &log_change_threshold);
   CNF_GetMailOnChange(&do_mail_change, &mail_change_threshold, &mail_change_user);
 
@@ -318,6 +323,19 @@ maybe_log_offset(double offset)
 
 /* ================================================== */
 
+static void
+maybe_make_step()
+{
+  if (make_step_limit == 0) {
+    return;
+  } else if (make_step_limit > 0) {
+    make_step_limit--;
+  }
+  LCL_MakeStep(make_step_threshold);
+}
+
+/* ================================================== */
+
 static void
 update_leap_status(NTP_Leap leap)
 {
@@ -487,6 +505,8 @@ REF_SetReference(int stratum,
     our_residual_freq = frequency;
   }
 
+  maybe_make_step();
+
   abs_freq_ppm = LCL_ReadAbsoluteFrequency();
 
   write_log(ref_time,
@@ -530,6 +550,7 @@ REF_SetManualReference
 
   maybe_log_offset(offset);
   LCL_AccumulateFrequencyAndOffset(frequency, offset);
+  maybe_make_step();
 
   abs_freq_ppm = LCL_ReadAbsoluteFrequency();