]> git.ipfire.org Git - thirdparty/chrony.git/commitdiff
sources: add minsources option
authorMiroslav Lichvar <mlichvar@redhat.com>
Mon, 20 Oct 2014 15:46:33 +0000 (17:46 +0200)
committerMiroslav Lichvar <mlichvar@redhat.com>
Mon, 20 Oct 2014 16:04:37 +0000 (18:04 +0200)
This sets the minimum number of selectable sources needed to update the
local clock.

chrony.texi.in
conf.c
conf.h
sources.c

index 6a36b857ad2df0e991ebc63e92a9a1c3746354bc..fbdff387ddcacf8ae28bd04395a68db418ff2c54 100644 (file)
@@ -1160,6 +1160,7 @@ the configuration file is ignored.
 * maxslewrate directive::       Set maximum slew rate
 * maxupdateskew directive::     Stop bad estimates upsetting machine clock
 * minsamples directive::        Set minimum number of samples per source
+* minsources directive::        Set minimum number of selectable sources to update clock
 * noclientlog directive::       Prevent chronyd from gathering data about clients
 * peer directive::              Specify an NTP peer
 * pidfile directive::           Specify the file where chronyd's pid is written
@@ -2447,6 +2448,23 @@ The syntax is
 minsamples <samples>
 @end example
 @c }}}
+@c {{{ minsources
+@node minsources directive
+@subsection minsources
+The @code{minsources} directive sets the minimum number of sources that need
+to be considered as selectable in the source selection algorithm before the
+local clock is updated.  The default value is 1.
+
+Setting this option to a larger number can be used to improve the reliability.
+More sources will have to agree with each other and the clock will not be
+updated when only one source (which could be serving wrong time) is reachable.
+
+The syntax is
+
+@example
+minsources <sources>
+@end example
+@c }}}
 @c {{{ noclientlog
 @node noclientlog directive
 @subsection noclientlog
diff --git a/conf.c b/conf.c
index 26a15beb405339895740313d17fd950807342405..d14c53e738613443ef75110ebf274a76bcb52a9c 100644 (file)
--- a/conf.c
+++ b/conf.c
@@ -135,6 +135,9 @@ static double make_step_threshold = 0.0;
 /* Threshold for automatic RTC trimming */
 static double rtc_autotrim_threshold = 0.0;
 
+/* Minimum number of selectables sources required to update the clock */
+static int min_sources = 1;
+
 /* Number of updates before offset checking, number of ignored updates
    before exiting and the maximum allowed offset */
 static int max_offset_delay = -1;
@@ -456,6 +459,8 @@ CNF_ParseLine(const char *filename, int number, char *line)
     parse_double(p, &max_update_skew);
   } else if (!strcasecmp(command, "minsamples")) {
     parse_int(p, &min_samples);
+  } else if (!strcasecmp(command, "minsources")) {
+    parse_int(p, &min_sources);
   } else if (!strcasecmp(command, "noclientlog")) {
     no_client_log = parse_null(p);
   } else if (!strcasecmp(command, "peer")) {
@@ -1700,6 +1705,14 @@ CNF_GetMinSamples(void)
 
 /* ================================================== */
 
+int
+CNF_GetMinSources(void)
+{
+  return min_sources;
+}
+
+/* ================================================== */
+
 char *
 CNF_GetHwclockFile(void)
 {
diff --git a/conf.h b/conf.h
index 7bc7ec23c15ce611c8f7877bfbeb8b84d2cbcb62..70db557030f0dac0262dd1ffd2d92ebae823e0b5 100644 (file)
--- a/conf.h
+++ b/conf.h
@@ -101,6 +101,8 @@ extern char *CNF_GetUser(void);
 extern int CNF_GetMaxSamples(void);
 extern int CNF_GetMinSamples(void);
 
+extern int CNF_GetMinSources(void);
+
 extern double CNF_GetRtcAutotrim(void);
 extern char *CNF_GetHwclockFile(void);
 
index bac56cf4d28d1ae335192e4370ad9951662ba0ed..01ebdcd4546b96b591cc664a6817d504d1d78deb 100644 (file)
--- a/sources.c
+++ b/sources.c
@@ -74,6 +74,7 @@ typedef enum {
   SRC_STALE,            /* Has older samples than others */
   SRC_FALSETICKER,      /* Doesn't agree with others */
   SRC_JITTERY,          /* Scatter worse than other's dispersion (not used) */
+  SRC_WAITS_SOURCES,    /* Not enough sources, selection postponed */
   SRC_NONPREFERRED,     /* Others have prefer option */
   SRC_WAITS_UPDATE,     /* No updates, selection postponed */
   SRC_DISTANT,          /* Others have shorter root distance */
@@ -807,11 +808,13 @@ SRC_SelectSource(SRC_Instance updated_inst)
   n_sel_sources = j;
 #endif
 
-  if (n_sel_sources == 0) {
+  if (n_sel_sources == 0 || n_sel_sources < CNF_GetMinSources()) {
     if (selected_source_index != INVALID_SOURCE) {
-      log_selection_message("Can't synchronise: no selectable sources", NULL);
+      log_selection_message("Can't synchronise: %s selectable sources",
+                            n_sel_sources ? "not enough" : "no");
       selected_source_index = INVALID_SOURCE;
     }
+    mark_ok_sources(SRC_WAITS_SOURCES);
     return;
   }
 
@@ -1225,6 +1228,7 @@ SRC_ReportSource(int index, RPT_SourceReport *report, struct timeval *now)
       case SRC_JITTERY:
         report->state = RPT_JITTERY;
         break;
+      case SRC_WAITS_SOURCES:
       case SRC_NONPREFERRED:
       case SRC_WAITS_UPDATE:
       case SRC_DISTANT: