]> git.ipfire.org Git - thirdparty/chrony.git/commitdiff
Add prefer and noselect options
authorMiroslav Lichvar <mlichvar@redhat.com>
Wed, 25 Aug 2010 16:11:52 +0000 (18:11 +0200)
committerMiroslav Lichvar <mlichvar@redhat.com>
Wed, 25 Aug 2010 16:32:40 +0000 (18:32 +0200)
chrony.texi
client.c
cmdmon.c
cmdparse.c
conf.c
ntp_core.c
refclock.c
refclock.h
sources.c
sources.h
srcparams.h

index b4681ae2ee81bb67923c7b35d2941d41c5a41d35..f20376993a37254f487ebe00b4e49a6c19139493 100644 (file)
@@ -2387,6 +2387,10 @@ nanosecond).
 @item precision
 Refclock precision (in seconds).  The default is 1e-6 (1 microsecond)
 for SHM refclock, and 1e-9 (1 nanosecond) for SOCK and PPS refclocks.
+@item prefer
+Prefer this source over sources without prefer option.
+@item noselect
+Never select this source.  This is particularly useful for monitoring.
 @end table
 
 @c }}}
@@ -2625,6 +2629,12 @@ selecting that source.  This is useful with low stratum sources that are known
 to be unrealiable or inaccurate and which should be used only when other
 sources are unreachable.
 
+@item prefer
+Prefer this source over sources without prefer option.
+
+@item noselect
+Never select this source.  This is particularly useful for monitoring.
+
 @end table
 @c }}}
 @c {{{ tempcomp
index cfe518d81dc3817f98a9887876736a6a54f197ae..1e44031431d7812b0b42c403d3b6cdae88bffb5f 100644 (file)
--- a/client.c
+++ b/client.c
@@ -934,6 +934,9 @@ process_cmd_add_server_or_peer(CMD_Request *msg, char *line)
       if (data.params.min_stratum) {
         fprintf(stderr, "Option minstratum not supported\n");
         break;
+      } else if (data.params.sel_option != SRC_SelectNormal) {
+        fprintf(stderr, "Options noselect and prefer not supported\n");
+        break;
       }
 
       msg->data.ntp_source.port = htonl((unsigned long) data.port);
index e382e10255801f5d1a526e7ee834caf828c69916..f230bbceb7f3242e1467ea1d54afa502db283847 100644 (file)
--- a/cmdmon.c
+++ b/cmdmon.c
@@ -1246,7 +1246,11 @@ handle_add_server(CMD_Request *rx_message, CMD_Reply *tx_message)
   params.iburst = ntohl(rx_message->data.ntp_source.flags) & REQ_ADDSRC_IBURST ? 1 : 0;
   params.max_delay = UTI_FloatNetworkToHost(rx_message->data.ntp_source.max_delay);
   params.max_delay_ratio = UTI_FloatNetworkToHost(rx_message->data.ntp_source.max_delay_ratio);
-  params.min_stratum = 0;       /* not transmitted in cmdmon protocol yet */
+
+ /* not transmitted in cmdmon protocol yet */
+  params.min_stratum = 0;       
+  params.sel_option = SRC_SelectNormal;
+
   status = NSR_AddSource(&rem_addr, NTP_SERVER, &params);
   switch (status) {
     case NSR_Success:
@@ -1288,7 +1292,11 @@ handle_add_peer(CMD_Request *rx_message, CMD_Reply *tx_message)
   params.iburst = ntohl(rx_message->data.ntp_source.flags) & REQ_ADDSRC_IBURST ? 1 : 0;
   params.max_delay = UTI_FloatNetworkToHost(rx_message->data.ntp_source.max_delay);
   params.max_delay_ratio = UTI_FloatNetworkToHost(rx_message->data.ntp_source.max_delay_ratio);
-  params.min_stratum = 0;       /* not transmitted in cmdmon protocol yet */
+
+ /* not transmitted in cmdmon protocol yet */
+  params.min_stratum = 0;       
+  params.sel_option = SRC_SelectNormal;
+
   status = NSR_AddSource(&rem_addr, NTP_PEER, &params);
   switch (status) {
     case NSR_Success:
index 9f514c1cb742f19bab42b34b614b2b431b6b1b2b..2d7c5437d044c7610822d121b7e4d6ab6f13e6f7 100644 (file)
@@ -60,6 +60,7 @@ CPS_ParseNTPSourceAdd(const char *line, CPS_NTP_Source *src)
   src->params.auto_offline = 0;
   src->params.iburst = 0;
   src->params.min_stratum = 0;
+  src->params.sel_option = SRC_SelectNormal;
 
   result = CPS_Success;
   
@@ -163,6 +164,12 @@ CPS_ParseNTPSourceAdd(const char *line, CPS_NTP_Source *src)
           } else {
             line += n;
           }
+
+        } else if (!strncasecmp(cmd, "noselect", 8)) {
+          src->params.sel_option = SRC_SelectNoselect;
+        
+        } else if (!strncasecmp(cmd, "prefer", 6)) {
+          src->params.sel_option = SRC_SelectPrefer;
         
         } else {
           result = CPS_BadOption;
diff --git a/conf.c b/conf.c
index f1c4914e404f0c18b2f8ebe0704206a750c95c4c..552a5fd049bb4313fa5da34371c6c619c27e43ce 100644 (file)
--- a/conf.c
+++ b/conf.c
@@ -448,6 +448,7 @@ parse_refclock(const char *line)
   const char *tmp;
   char name[5], cmd[10 + 1], *param;
   unsigned char ref[5];
+  SRC_SelectOption sel_option;
 
   i = n_refclock_sources;
   if (i >= MAX_RCL_SOURCES)
@@ -462,6 +463,7 @@ parse_refclock(const char *line)
   precision = 0.0;
   ref_id = 0;
   lock_ref_id = 0;
+  sel_option = SRC_SelectNormal;
 
   if (sscanf(line, "%4s%n", name, &n) != 1) {
     LOG(LOGS_WARN, LOGF_Configure, "Could not read refclock driver name at line %d", line_number);
@@ -518,6 +520,12 @@ parse_refclock(const char *line)
     } else if (!strncasecmp(cmd, "precision", 9)) {
       if (sscanf(line, "%lf%n", &precision, &n) != 1)
         break;
+    } else if (!strncasecmp(cmd, "noselect", 8)) {
+      n = 0;
+      sel_option = SRC_SelectNoselect;
+    } else if (!strncasecmp(cmd, "prefer", 6)) {
+      n = 0;
+      sel_option = SRC_SelectPrefer;
     } else {
       LOG(LOGS_WARN, LOGF_Configure, "Unknown refclock parameter %s at line %d", cmd, line_number);
       break;
@@ -534,6 +542,7 @@ parse_refclock(const char *line)
   refclock_sources[i].offset = offset;
   refclock_sources[i].delay = delay;
   refclock_sources[i].precision = precision;
+  refclock_sources[i].sel_option = sel_option;
   refclock_sources[i].ref_id = ref_id;
   refclock_sources[i].lock_ref_id = lock_ref_id;
 
index c00c462fa0386822a2c456d67876e7738c2fe775..7f8d3ca0b24f7a13a57abc2d0a3aa1821b9219b8 100644 (file)
@@ -312,7 +312,7 @@ NCR_GetInstance(NTP_Remote_Address *remote_addr, NTP_Source_Type type, SourcePar
   result->local_poll = params->minpoll;
 
   /* Create a source instance for this NTP source */
-  result->source = SRC_CreateNewInstance(UTI_IPToRefid(&remote_addr->ip_addr), SRC_NTP, &result->remote_addr.ip_addr);
+  result->source = SRC_CreateNewInstance(UTI_IPToRefid(&remote_addr->ip_addr), SRC_NTP, params->sel_option, &result->remote_addr.ip_addr);
 
   result->local_rx.tv_sec = 0;
   result->local_rx.tv_usec = 0;
index 635faabe97b6df8f5c69c4888faed1da9bbc2f10..8aed917704a1ac4631ec7d03300dfe1a46ee2913 100644 (file)
@@ -236,7 +236,7 @@ RCL_AddRefclock(RefclockParameters *params)
 
   filter_init(&inst->filter, params->filter_length);
 
-  inst->source = SRC_CreateNewInstance(inst->ref_id, SRC_REFCLOCK, NULL);
+  inst->source = SRC_CreateNewInstance(inst->ref_id, SRC_REFCLOCK, params->sel_option, NULL);
 
 #if 0
   LOG(LOGS_INFO, LOGF_Refclock, "refclock added poll=%d dpoll=%d filter=%d",
index 1e08a68affc8ea87b3813f787ef7bbd0620f90c3..438f1dd7d30685af2e66999f21f1d1eb1e52c9be 100644 (file)
@@ -43,6 +43,7 @@ typedef struct {
   double offset;
   double delay;
   double precision;
+  SRC_SelectOption sel_option;
 } RefclockParameters;
 
 typedef struct RCL_Instance_Record *RCL_Instance;
index 98e4dc75e1f0914c8482f1b64257a75b725d5729..a019890176eea4759b03b78206f89e1527d3e6b9 100644 (file)
--- a/sources.c
+++ b/sources.c
@@ -100,6 +100,9 @@ struct SRC_Instance_Record {
   /* Type of the source */
   SRC_Type type;
 
+  /* Options used when selecting sources */ 
+  SRC_SelectOption sel_option;
+
   struct SelectInfo sel_info;
 };
 
@@ -165,7 +168,7 @@ void SRC_Finalise(void)
 /* Function to create a new instance.  This would be called by one of
    the individual source-type instance creation routines. */
 
-SRC_Instance SRC_CreateNewInstance(unsigned long ref_id, SRC_Type type, IPAddr *addr)
+SRC_Instance SRC_CreateNewInstance(unsigned long ref_id, SRC_Type type, SRC_SelectOption sel_option, IPAddr *addr)
 {
   SRC_Instance result;
 
@@ -196,6 +199,7 @@ SRC_Instance SRC_CreateNewInstance(unsigned long ref_id, SRC_Type type, IPAddr *
   result->reachable = 0;
   result->status = SRC_BAD_STATS;
   result->type = type;
+  result->sel_option = sel_option;
 
   n_sources++;
 
@@ -414,7 +418,7 @@ SRC_SelectSource(unsigned long match_addr)
   n_reachable_sources = 0;
   for (i=0; i<n_sources; i++) {
 
-    if (sources[i]->reachable) {
+    if (sources[i]->reachable && sources[i]->sel_option != SRC_SelectNoselect) {
 
       ++n_reachable_sources;
 
@@ -638,11 +642,39 @@ SRC_SelectSource(unsigned long match_addr)
       }
       n_sel_sources = j;
 
-      /* Now find minimum stratum.  If none are left now,
-         tough. RFC1305 is not so harsh on pruning sources due to
-         excess variance, which prevents this from happening */
-
       if (n_sel_sources > 0) {
+        /* Accept leap second status if more than half of selectable sources agree */
+
+        for (i=j1=j2=0; i<n_sel_sources; i++) {
+          index = sel_sources[i];
+          if (sources[index]->leap_status == LEAP_InsertSecond) {
+            j1++;
+          } else if (sources[index]->leap_status == LEAP_DeleteSecond) {
+            j2++;
+          }
+        }
+
+        if (j1 > n_sel_sources / 2) {
+          leap_status = LEAP_InsertSecond;
+        } else if (j2 > n_sel_sources / 2) {
+          leap_status = LEAP_DeleteSecond;
+        }
+
+        /* If there are any sources with prefer option, reduce the list again
+           only to the prefer sources */
+        for (i=j=0; i<n_sel_sources; i++) {
+          if (sources[sel_sources[i]]->sel_option == SRC_SelectPrefer) {
+            sel_sources[j++] = sel_sources[i];
+          }
+        }
+        if (j > 0) {
+          n_sel_sources = j;
+        }
+
+        /* Now find minimum stratum.  If none are left now,
+           tough. RFC1305 is not so harsh on pruning sources due to
+           excess variance, which prevents this from happening */
+
         index = sel_sources[0];
         min_stratum = sources[index]->sel_info.stratum;
         for (i=1; i<n_sel_sources; i++) {
@@ -709,23 +741,6 @@ SRC_SelectSource(unsigned long match_addr)
         total_root_dispersion = (src_accrued_dispersion +
                                  sources[selected_source_index]->sel_info.root_dispersion);
 
-        /* Accept leap second status if more than half of selectable sources agree */
-
-        for (i=j1=j2=0; i<n_sel_sources; i++) {
-          index = sel_sources[i];
-          if (sources[index]->leap_status == LEAP_InsertSecond) {
-            j1++;
-          } else if (sources[index]->leap_status == LEAP_DeleteSecond) {
-            j2++;
-          }
-        }
-
-        if (j1 > n_sel_sources / 2) {
-          leap_status = LEAP_InsertSecond;
-        } else if (j2 > n_sel_sources / 2) {
-          leap_status = LEAP_DeleteSecond;
-        }
-
         if ((match_addr == 0) ||
             (match_addr == sources[selected_source_index]->ref_id)) {
 
index c1cfffca7fa23145429c086fe769f3cfeb1c53e7..aff800a97c59c6411e76d0ebf9fd9664ac5a1775 100644 (file)
--- a/sources.h
+++ b/sources.h
@@ -55,10 +55,17 @@ typedef enum {
   SRC_REFCLOCK                  /* Rerefence clock */
 } SRC_Type;
 
+/* Options used when selecting sources */ 
+typedef enum {
+  SRC_SelectNormal,
+  SRC_SelectNoselect,
+  SRC_SelectPrefer
+} SRC_SelectOption;
+
 /* Function to create a new instance.  This would be called by one of
    the individual source-type instance creation routines. */
 
-extern SRC_Instance SRC_CreateNewInstance(unsigned long ref_id, SRC_Type type, IPAddr *addr);
+extern SRC_Instance SRC_CreateNewInstance(unsigned long ref_id, SRC_Type type, SRC_SelectOption sel_option, IPAddr *addr);
 
 /* Function to get rid of a source when it is being unconfigured.
    This may cause the current reference source to be reselected, if this
index 1fb93e7297d77e021f76b0ed68e7b2530c9e6207..1b52369a5acea9fc655012075520ce75794c77a6 100644 (file)
@@ -31,6 +31,8 @@
 #ifndef GOT_SRCPARAMS_H
 #define GOT_SRCPARAMS_H
 
+#include "sources.h"
+
 typedef struct {
   int minpoll;
   int maxpoll;
@@ -42,6 +44,7 @@ typedef struct {
   unsigned long authkey;
   double max_delay;
   double max_delay_ratio;
+  SRC_SelectOption sel_option;
 } SourceParameters;
 
 #define INACTIVE_AUTHKEY 0UL