]> git.ipfire.org Git - thirdparty/chrony.git/commitdiff
Extend tracking, sources and activity reports
authorMiroslav Lichvar <mlichvar@redhat.com>
Fri, 3 Feb 2012 13:57:25 +0000 (14:57 +0100)
committerMiroslav Lichvar <mlichvar@redhat.com>
Fri, 3 Feb 2012 16:22:53 +0000 (17:22 +0100)
candm.h
chrony.texi
client.c
cmdmon.c
ntp_sources.c
reference.c
reports.h
sources.c

diff --git a/candm.h b/candm.h
index fdff31d9a5f7ad12bdc6b4fd57ef040fea1462db..a6edc6ec69957c73ad7c2fa7009dedd27d202c1e 100644 (file)
--- a/candm.h
+++ b/candm.h
@@ -369,7 +369,8 @@ typedef struct {
    and used also instead of integer microseconds, new commands: modify stratum,
    modify polltarget, modify maxdelaydevratio, reselect, reselectdistance
 
-   Version 5 : auth data moved to the end of the packet to allow different hashes
+   Version 5 : auth data moved to the end of the packet to allow hashes with
+   different sizes, extended sources, tracking and activity reports
  */
 
 #define PROTO_VERSION_NUMBER 5
@@ -508,12 +509,17 @@ typedef struct {
 #define RPY_SD_ST_CANDIDATE 4
 #define RPY_SD_ST_OUTLYER 5
 
+#define RPY_SD_FLAG_NOSELECT 0x1
+#define RPY_SD_FLAG_PREFER 0x2
+
 typedef struct {
   IPAddr ip_addr;
   uint16_t poll;
   uint16_t stratum;
   uint16_t state;
   uint16_t mode;
+  uint16_t flags;
+  uint16_t reachability;
   uint32_t  since_sample;
   Float orig_latest_meas;
   Float latest_meas;
@@ -527,11 +533,14 @@ typedef struct {
   uint32_t stratum;
   Timeval ref_time;
   Float current_correction;
+  Float last_offset;
+  Float rms_offset;
   Float freq_ppm;
   Float resid_freq_ppm;
   Float skew_ppm;
   Float root_delay;
   Float root_dispersion;
+  Float last_update_interval;
   int32_t EOR;
 } RPY_Tracking;
 
@@ -619,6 +628,7 @@ typedef struct {
   int32_t offline;
   int32_t burst_online;
   int32_t burst_offline;
+  int32_t unresolved;
   int32_t EOR;
 } RPY_Activity;
 
index 5984f7bd8162a152dcb2e0e7ff2f36c2146ef048..2ef766feb869af2a2738e714ad36e728973cef20 100644 (file)
@@ -1523,6 +1523,9 @@ The syntax is
 corrtimeratio 10
 @end example
 
+The current remaining correction is shown in the @code{tracking} report
+(@pxref{tracking command}) as the @code{System time} value.
+
 @c }}}
 @c {{{ deny
 @node deny directive
@@ -3021,7 +3024,7 @@ If the auto_offline option is used in specifying some of the servers/peers, the
 @code{activity} command may be useful for detecting when all of them have
 entered the offline state after the PPP link has been disconnected.
 
-The report shows the number of servers/peers in 4 states:
+The report shows the number of servers/peers in 5 states:
 @itemize
 @item @code{online} : the server/peer is currently online (i.e. assumed by
 chronyd to be reachable)
@@ -3033,6 +3036,9 @@ server/peer will be returned to the online state.
 @item @code{burst_offline} : a burst command has been initiated for the
 server/peer and is being performed; after the burst is complete, the
 server/peer will be returned to the offline state.
+@item @code{unresolved} : the name of the server/peer wasn't resolved to an
+address yet; this server is not visible in the @code{sources} and
+@code{sourcestats} reports.
 @end itemize
 @c }}}
 @c {{{ add peer
@@ -3942,11 +3948,11 @@ columns.
 @example
 @group
 210 Number of sources = 3
-MS Name/IP address      Stratum Poll LastRx Last sample
-=======================================================================
-^+ a.b.c                    3     6    47m  -9491us[-6983us] +/-  159ms
-^+ d.e.f                    3     6    47m    +32ms[  +35ms] +/-  274ms
-^* g.h.i                    2     6    47m  +8839us[  +11ms] +/-  214ms
+MS Name/IP address         Stratum Poll Reach LastRx Last sample
+===============================================================================
+#* GPS0                          0   4   377    11   -479ns[ -621ns] +/-  134ns
+^? a.b.c                         2   6   377    23   -923us[ -924us] +/-   43ms
+^+ d.e.f                         1   6   377    21  -2629us[-2619us] +/-   86ms
 @end group
 @end example
 
@@ -3987,10 +3993,18 @@ that a measurement is being made every 64 seconds.
 @code{chronyd} automatically varies the polling rate in response to prevailing
 conditions.
 
+@item Reach
+This shows the source's reachability register printed as octal number.  The
+register has 8 bits and is updated on every received or missed packet from
+the source.  A value of 377 indicates that a valid reply was received for all
+from the last eight transmissions.
+
 @item LastRx
 This column shows how long ago the last sample was received from the
 source.  This is normally in seconds.  The letters @code{m}, @code{h},
-@code{d} or @code{y} indicate minutes, hours, days or years.
+@code{d} or @code{y} indicate minutes, hours, days or years.  A value
+of 10 years indicates there were no samples received from this source
+yet.
 
 @item Last sample
 This column shows the offset between the local clock and the source at
@@ -4091,8 +4105,10 @@ performance.  An example of the output is shown below.
 @example
 Reference ID    : 1.2.3.4 (a.b.c)
 Stratum         : 3
-Ref time (UTC)  : Sun May 17 06:13:11 1998
-System time     : 0.000000000 seconds fast of NTP time
+Ref time (UTC)  : Fri Feb  3 15:00:29 2012
+System time     : 0.000001501 seconds slow of NTP time
+Last offset     : -0.000001632 seconds
+RMS offset      : 0.000002360 seconds
 Frequency       : 331.898 ppm fast
 Residual freq   : 0.004 ppm
 Skew            : 0.154 ppm
@@ -4118,7 +4134,7 @@ computer, so the computer in the example is two hops away
 (i.e. @code{a.b.c} is a stratum-2 and is synchronised from a stratum-1).
 
 @item Ref time
-This is the time (GMT) at which the last measurement from the reference
+This is the time (UTC) at which the last measurement from the reference
 source was processed.
 
 @item System time
@@ -4139,9 +4155,13 @@ On systems such as Solaris and SunOS, @code{chronyd} has no means to
 adjust the fundamental rate of the system clock, so keeps the system
 time correct by periodically making offsets to it as though an error had
 been measured.  The build up of these offsets will be observed in this
-report.  On systems such as Linux where @code{chronyd} can adjust the
-fundamental rate of the system clock, this value will show zero unless a
-very recent measurement has shown the system to be error.
+report.
+
+@item Last offset
+This is the estimated local offset on the last clock update.
+
+@item RMS offset
+This is a long-term average of the offset value.
 
 @item Frequency
 The `frequency' is the rate by which the system's clock would be would
@@ -4195,6 +4215,9 @@ stratum-1 computer is correct) is given by
 clock_error <= root_dispersion + (0.5 * |root_delay|)
 @end example
 
+@item Update interval
+This is the interval between the last two clock updates.
+
 @end table
 @c }}}
 @c {{{ trimrtc
index 78849916db2dc4c617fe51f55a1b4b9e584f4862..c7bc4582a036addeebcc6c5779fc7a898d7fda25 100644 (file)
--- a/client.c
+++ b/client.c
@@ -1670,7 +1670,7 @@ process_cmd_sources(char *line)
   IPAddr ip_addr;
   uint32_t latest_meas_ago;
   uint16_t poll, stratum;
-  uint16_t state, mode;
+  uint16_t state, mode, flags, reachability;
   char hostname_buf[50];
 
   /* Check whether to output verbose headers */
@@ -1692,10 +1692,10 @@ process_cmd_sources(char *line)
       printf("||                                   |           |                         \n");
     }
 
-    printf("MS Name/IP address           Stratum Poll LastRx Last sample\n");
-    printf("============================================================================\n");
+    printf("MS Name/IP address         Stratum Poll Reach LastRx Last sample\n");
+    printf("===============================================================================\n");
 
-    /*     "MS NNNNNNNNNNNNNNNNNNNNNNNNN    SS   PP   RRRR  SSSSSSS[SSSSSSS] +/- SSSSSS" */
+    /*     "MS NNNNNNNNNNNNNNNNNNNNNNNNNNN  SS  PP   RRR  RRRR  SSSSSSS[SSSSSSS] +/- SSSSSS" */
 
     for (i=0; i<n_sources; i++) {
       request.command = htons(REQ_SOURCE_DATA);
@@ -1706,6 +1706,8 @@ process_cmd_sources(char *line)
           stratum = ntohs(reply.data.source_data.stratum);
           state = ntohs(reply.data.source_data.state);
           mode = ntohs(reply.data.source_data.mode);
+          flags = ntohs(reply.data.source_data.flags);
+          reachability = ntohs(reply.data.source_data.reachability);
           latest_meas_ago = ntohl(reply.data.source_data.since_sample);
           orig_latest_meas = UTI_FloatNetworkToHost(reply.data.source_data.orig_latest_meas);
           latest_meas = UTI_FloatNetworkToHost(reply.data.source_data.latest_meas);
@@ -1746,8 +1748,12 @@ process_cmd_sources(char *line)
             default:
               printf(" ");
           }
+          switch (flags) {
+            default:
+              break;
+          }
 
-          printf(" %-25s    %2d   %2d   ", hostname_buf, stratum, poll);
+          printf(" %-27s  %2d  %2d   %3o  ", hostname_buf, stratum, poll, reachability);
           print_seconds(latest_meas_ago);
           printf("  ");
           print_signed_nanoseconds(latest_meas);
@@ -1866,11 +1872,14 @@ process_cmd_tracking(char *line)
   struct tm ref_time_tm;
   unsigned long a, b, c, d;
   double correction;
+  double last_offset;
+  double rms_offset;
   double freq_ppm;
   double resid_freq_ppm;
   double skew_ppm;
   double root_delay;
   double root_dispersion;
+  double last_update_interval;
   
   request.command = htons(REQ_TRACKING);
   if (request_reply(&request, &reply, RPY_TRACKING, 0)) {
@@ -1896,18 +1905,24 @@ process_cmd_tracking(char *line)
     ref_time_tm = *gmtime((time_t *)&ref_time.tv_sec);
     printf("Ref time (UTC)  : %s", asctime(&ref_time_tm));
     correction = UTI_FloatNetworkToHost(reply.data.tracking.current_correction);
+    last_offset = UTI_FloatNetworkToHost(reply.data.tracking.last_offset);
+    rms_offset = UTI_FloatNetworkToHost(reply.data.tracking.rms_offset);
     printf("System time     : %.9f seconds %s of NTP time\n", fabs(correction),
            (correction > 0.0) ? "slow" : "fast");
+    printf("Last offset     : %.9f seconds\n", last_offset);
+    printf("RMS offset      : %.9f seconds\n", rms_offset);
     freq_ppm = UTI_FloatNetworkToHost(reply.data.tracking.freq_ppm);
     resid_freq_ppm = UTI_FloatNetworkToHost(reply.data.tracking.resid_freq_ppm);
     skew_ppm = UTI_FloatNetworkToHost(reply.data.tracking.skew_ppm);
     root_delay = UTI_FloatNetworkToHost(reply.data.tracking.root_delay);
     root_dispersion = UTI_FloatNetworkToHost(reply.data.tracking.root_dispersion);
+    last_update_interval = UTI_FloatNetworkToHost(reply.data.tracking.last_update_interval);
     printf("Frequency       : %.3f ppm %s\n", fabs(freq_ppm), (freq_ppm < 0.0) ? "slow" : "fast"); 
     printf("Residual freq   : %.3f ppm\n", resid_freq_ppm);
     printf("Skew            : %.3f ppm\n", skew_ppm);
     printf("Root delay      : %.6f seconds\n", root_delay);
     printf("Root dispersion : %.6f seconds\n", root_dispersion);
+    printf("Update interval : %.1f seconds\n", last_update_interval);
     return 1;
   }
   return 0;
@@ -2357,11 +2372,13 @@ process_cmd_activity(const char *line)
                "%ld sources online\n"
                "%ld sources offline\n"
                "%ld sources doing burst (return to online)\n"
-               "%ld sources doing burst (return to offline)\n",
+               "%ld sources doing burst (return to offline)\n"
+               "%ld sources with unknown address\n",
                 (long) ntohl(reply.data.activity.online),
                 (long) ntohl(reply.data.activity.offline),
                 (long) ntohl(reply.data.activity.burst_online),
-                (long) ntohl(reply.data.activity.burst_offline));
+                (long) ntohl(reply.data.activity.burst_offline),
+                (long) ntohl(reply.data.activity.unresolved));
         return 1;
   }
   return 0;
index 7810fefdc18e6d999cae2ea5dd2968130cf2413f..0755a47807c4ce08f62365b807ab96f15f7a392c 100644 (file)
--- a/cmdmon.c
+++ b/cmdmon.c
@@ -1062,6 +1062,18 @@ handle_source_data(CMD_Request *rx_message, CMD_Reply *tx_message)
         tx_message->data.source_data.mode    = htons(RPY_SD_MD_REF);
         break;
     }
+    switch (report.sel_option) {
+      case RPT_NORMAL:
+        tx_message->data.source_data.flags = htons(0);
+        break;
+      case RPT_PREFER:
+        tx_message->data.source_data.flags = htons(RPY_SD_FLAG_PREFER);
+        break;
+      case RPT_NOSELECT:
+        tx_message->data.source_data.flags = htons(RPY_SD_FLAG_PREFER);
+        break;
+    }
+    tx_message->data.source_data.reachability = htons(report.reachability);
     tx_message->data.source_data.since_sample = htonl(report.latest_meas_ago);
     tx_message->data.source_data.orig_latest_meas = UTI_FloatHostToNetwork(report.orig_latest_meas);
     tx_message->data.source_data.latest_meas = UTI_FloatHostToNetwork(report.latest_meas);
@@ -1373,11 +1385,14 @@ handle_tracking(CMD_Request *rx_message, CMD_Reply *tx_message)
   tx_message->data.tracking.stratum = htonl(rpt.stratum);
   UTI_TimevalHostToNetwork(&rpt.ref_time, &tx_message->data.tracking.ref_time);
   tx_message->data.tracking.current_correction = UTI_FloatHostToNetwork(rpt.current_correction);
+  tx_message->data.tracking.last_offset = UTI_FloatHostToNetwork(rpt.last_offset);
+  tx_message->data.tracking.rms_offset = UTI_FloatHostToNetwork(rpt.rms_offset);
   tx_message->data.tracking.freq_ppm = UTI_FloatHostToNetwork(rpt.freq_ppm);
   tx_message->data.tracking.resid_freq_ppm = UTI_FloatHostToNetwork(rpt.resid_freq_ppm);
   tx_message->data.tracking.skew_ppm = UTI_FloatHostToNetwork(rpt.skew_ppm);
   tx_message->data.tracking.root_delay = UTI_FloatHostToNetwork(rpt.root_delay);
   tx_message->data.tracking.root_dispersion = UTI_FloatHostToNetwork(rpt.root_dispersion);
+  tx_message->data.tracking.last_update_interval = UTI_FloatHostToNetwork(rpt.last_update_interval);
 }
 
 /* ================================================== */
@@ -1679,6 +1694,7 @@ handle_activity(CMD_Request *rx_message, CMD_Reply *tx_message)
   tx_message->data.activity.offline = htonl(report.offline);
   tx_message->data.activity.burst_online = htonl(report.burst_online);
   tx_message->data.activity.burst_offline = htonl(report.burst_offline);
+  tx_message->data.activity.unresolved = htonl(report.unresolved);
   tx_message->status = htons(STT_SUCCESS);
   tx_message->reply = htons(RPY_ACTIVITY);
 }
index ca84ff46271d3062f18a7cf6a04331c0c2b64f42..65294b620662c3be03a6326bba87aefb4f1a013f 100644 (file)
@@ -665,9 +665,10 @@ NSR_GetActivityReport(RPT_ActivityReport *report)
     }
   }
 
-  /* Add unresolved sources to offline count */
+  report->unresolved = 0;
+
   for (us = unresolved_sources; us; us = us->next) {
-    report->offline++;
+    report->unresolved++;
   }
 
   return;
index fa9be8ba63333c5cf41e2666a583403215618620..093b6be7eba2528b5b7bb650654217c09ca277ae 100644 (file)
@@ -55,6 +55,9 @@ static double our_root_dispersion;
 
 static double max_update_skew;
 
+static double last_offset;
+static double avg2_offset;
+
 static double correction_time_ratio;
 
 /* Flag indicating that we are initialised */
@@ -705,6 +708,11 @@ REF_SetReference(int stratum,
   }
 
   last_ref_update_interval = update_interval;
+  last_offset = our_offset;
+  if (avg2_offset > 0.0)
+    avg2_offset += 0.1 * (our_offset * our_offset - avg2_offset);
+  else
+    avg2_offset = our_offset * our_offset;
 
   /* And now set the freq and offset to zero */
   our_frequency = 0.0;
@@ -917,6 +925,21 @@ REF_GetTrackingReport(RPT_TrackingReport *rep)
   LCL_GetOffsetCorrection(&now_raw, &correction, NULL);
   UTI_AddDoubleToTimeval(&now_raw, correction, &now_cooked);
 
+  rep->ref_id = 0;
+  rep->ip_addr.family = IPADDR_UNSPEC;
+  rep->stratum = 0;
+  rep->ref_time.tv_sec = 0;
+  rep->ref_time.tv_usec = 0;
+  rep->current_correction = correction;
+  rep->freq_ppm = LCL_ReadAbsoluteFrequency();
+  rep->resid_freq_ppm = 0.0;
+  rep->skew_ppm = 0.0;
+  rep->root_delay = 0.0;
+  rep->root_dispersion = 0.0;
+  rep->last_update_interval = last_ref_update_interval;
+  rep->last_offset = last_offset;
+  rep->rms_offset = sqrt(avg2_offset);
+
   if (are_we_synchronised) {
     
     UTI_DiffTimevalsToDouble(&elapsed, &now_cooked, &our_ref_time);
@@ -926,8 +949,6 @@ REF_GetTrackingReport(RPT_TrackingReport *rep)
     rep->ip_addr = our_ref_ip;
     rep->stratum = our_stratum;
     rep->ref_time = our_ref_time;
-    rep->current_correction = correction;
-    rep->freq_ppm = LCL_ReadAbsoluteFrequency();
     rep->resid_freq_ppm = 1.0e6 * our_residual_freq;
     rep->skew_ppm = 1.0e6 * our_skew;
     rep->root_delay = our_root_delay;
@@ -939,26 +960,7 @@ REF_GetTrackingReport(RPT_TrackingReport *rep)
     rep->ip_addr.family = IPADDR_UNSPEC;
     rep->stratum = local_stratum;
     rep->ref_time = now_cooked;
-    rep->current_correction = correction;
-    rep->freq_ppm = LCL_ReadAbsoluteFrequency();
-    rep->resid_freq_ppm = 0.0;
-    rep->skew_ppm = 0.0;
-    rep->root_delay = 0.0;
     rep->root_dispersion = LCL_GetSysPrecisionAsQuantum();
-
-  } else {
-
-    rep->ref_id = 0;
-    rep->ip_addr.family = IPADDR_UNSPEC;
-    rep->stratum = 0;
-    rep->ref_time.tv_sec = 0;
-    rep->ref_time.tv_usec = 0;
-    rep->current_correction = correction;
-    rep->freq_ppm = LCL_ReadAbsoluteFrequency();
-    rep->resid_freq_ppm = 0.0;
-    rep->skew_ppm = 0.0;
-    rep->root_delay = 0.0;
-    rep->root_dispersion = 0.0;
   }
 
 }
index 4b4f55e75b8e20daf2df379c157c32a993f1f928..4322a9c46ce62fa745bd2fe29404ba60a9975d57 100644 (file)
--- a/reports.h
+++ b/reports.h
@@ -38,7 +38,9 @@ typedef struct {
   int poll;
   enum {RPT_NTP_CLIENT, RPT_NTP_PEER, RPT_LOCAL_REFERENCE} mode;
   enum {RPT_SYNC, RPT_UNREACH, RPT_FALSETICKER, RPT_JITTERY, RPT_CANDIDATE} state;
+  enum {RPT_NORMAL, RPT_PREFER, RPT_NOSELECT} sel_option;
 
+  int reachability;
   unsigned long latest_meas_ago; /* seconds */
   double orig_latest_meas; /* seconds */
   double latest_meas; /* seconds */
@@ -51,11 +53,14 @@ typedef struct {
   unsigned long stratum;
   struct timeval ref_time;
   double current_correction;
+  double last_offset;
+  double rms_offset;
   double freq_ppm;
   double resid_freq_ppm;
   double skew_ppm;
   double root_delay;
   double root_dispersion;
+  double last_update_interval;
 } RPT_TrackingReport;
 
 typedef struct {
@@ -113,6 +118,7 @@ typedef struct {
   int offline;
   int burst_online;
   int burst_offline;
+  int unresolved;
 } RPT_ActivityReport;
 
 #endif /* GOT_REPORTS_H */
index bfe7e3c2b72cc58e9533693164ca3c6d2c4a79bd..890d87a416226666928c827fc4e96880f172ea70 100644 (file)
--- a/sources.c
+++ b/sources.c
@@ -1110,6 +1110,23 @@ SRC_ReportSource(int index, RPT_SourceReport *report, struct timeval *now)
         assert(0);
         break;
     }
+
+    switch (src->sel_option) {
+      case SRC_SelectNormal:
+        report->sel_option = RPT_NOSELECT;
+        break;
+      case SRC_SelectPrefer:
+        report->sel_option = RPT_PREFER;
+        break;
+      case SRC_SelectNoselect:
+        report->sel_option = RPT_NOSELECT;
+        break;
+      default:
+        assert(0);
+    }
+
+    report->reachability = src->reachability;
+
     /* Call stats module to fill out estimates */
     SST_DoSourceReport(src->stats, report, now);