]> git.ipfire.org Git - thirdparty/chrony.git/commitdiff
cmdmon: add smoothing command
authorMiroslav Lichvar <mlichvar@redhat.com>
Tue, 9 Jun 2015 09:32:37 +0000 (11:32 +0200)
committerMiroslav Lichvar <mlichvar@redhat.com>
Tue, 9 Jun 2015 14:15:30 +0000 (16:15 +0200)
This adds a new request to get a current report on time smoothing.

candm.h
cmdmon.c
pktlength.c
reports.h
smooth.c
smooth.h

diff --git a/candm.h b/candm.h
index b1a191d93b0c0bd30a9a51c97747b2b40042e20c..956db9e0023a0a1994965bce5eab99aba8c55361 100644 (file)
--- a/candm.h
+++ b/candm.h
@@ -89,7 +89,8 @@
 #define REQ_RESELECT 48
 #define REQ_RESELECTDISTANCE 49
 #define REQ_MODIFY_MAKESTEP 50
-#define N_REQUEST_TYPES 51
+#define REQ_SMOOTHING 51
+#define N_REQUEST_TYPES 52
 
 /* Special utoken value used to log on with first exchange being the
    password.  (This time value has long since gone by) */
@@ -422,7 +423,8 @@ typedef struct {
 #define RPY_CLIENT_ACCESSES_BY_INDEX 10
 #define RPY_MANUAL_LIST 11
 #define RPY_ACTIVITY 12
-#define N_REPLY_TYPES 13
+#define RPY_SMOOTHING 13
+#define N_REPLY_TYPES 14
 
 /* Status codes */
 #define STT_SUCCESS 0
@@ -577,6 +579,19 @@ typedef struct {
   int32_t EOR;
 } RPY_Activity;
 
+#define RPY_SMT_FLAG_ACTIVE 0x1
+#define RPY_SMT_FLAG_LEAPONLY 0x2
+
+typedef struct {
+  uint32_t flags;
+  Float offset;
+  Float freq_ppm;
+  Float wander_ppm;
+  Float last_update_ago;
+  Float remaining_time;
+  int32_t EOR;
+} RPY_Smoothing;
+
 typedef struct {
   uint8_t version;
   uint8_t pkt_type;
@@ -603,6 +618,7 @@ typedef struct {
     RPY_ClientAccessesByIndex client_accesses_by_index;
     RPY_ManualList manual_list;
     RPY_Activity activity;
+    RPY_Smoothing smoothing;
   } data; /* Reply specific parameters */
 
   /* authentication of the packet, there is no hole after the actual data
index c569a805dbd5c4ba22103dfd16d36a1d01bfa914..2d71b8d31ff4d417e534d6db752f9f0d428e6aae 100644 (file)
--- a/cmdmon.c
+++ b/cmdmon.c
@@ -37,6 +37,7 @@
 #include "keys.h"
 #include "ntp_sources.h"
 #include "ntp_core.h"
+#include "smooth.h"
 #include "sources.h"
 #include "sourcestats.h"
 #include "reference.h"
@@ -162,6 +163,7 @@ static const char permissions[] = {
   PERMIT_AUTH, /* RESELECT */
   PERMIT_AUTH, /* RESELECTDISTANCE */
   PERMIT_AUTH, /* MODIFY_MAKESTEP */
+  PERMIT_OPEN, /* SMOOTHING */
 };
 
 /* ================================================== */
@@ -1223,6 +1225,31 @@ handle_tracking(CMD_Request *rx_message, CMD_Reply *tx_message)
 
 /* ================================================== */
 
+static void
+handle_smoothing(CMD_Request *rx_message, CMD_Reply *tx_message)
+{
+  RPT_SmoothingReport report;
+  struct timeval now;
+
+  SCH_GetLastEventTime(&now, NULL, NULL);
+
+  if (!SMT_GetSmoothingReport(&report, &now)) {
+    tx_message->status = htons(STT_NOTENABLED);
+    return;
+  }
+
+  tx_message->reply  = htons(RPY_SMOOTHING);
+  tx_message->data.smoothing.flags = htonl((report.active ? RPY_SMT_FLAG_ACTIVE : 0) |
+                                           (report.leap_only ? RPY_SMT_FLAG_LEAPONLY : 0));
+  tx_message->data.smoothing.offset = UTI_FloatHostToNetwork(report.offset);
+  tx_message->data.smoothing.freq_ppm = UTI_FloatHostToNetwork(report.freq_ppm);
+  tx_message->data.smoothing.wander_ppm = UTI_FloatHostToNetwork(report.wander_ppm);
+  tx_message->data.smoothing.last_update_ago = UTI_FloatHostToNetwork(report.last_update_ago);
+  tx_message->data.smoothing.remaining_time = UTI_FloatHostToNetwork(report.remaining_time);
+}
+
+/* ================================================== */
+
 static void
 handle_sourcestats(CMD_Request *rx_message, CMD_Reply *tx_message)
 {
@@ -1889,6 +1916,10 @@ read_from_cmd_socket(void *anything)
           handle_tracking(&rx_message, &tx_message);
           break;
 
+        case REQ_SMOOTHING:
+          handle_smoothing(&rx_message, &tx_message);
+          break;
+
         case REQ_SOURCESTATS:
           handle_sourcestats(&rx_message, &tx_message);
           break;
index 3b125178bf5db28c9c8fec0441f4f493f99e34d2..72c31714fcc339a21c42c3e0a6a4116f0cb5c0d4 100644 (file)
@@ -146,6 +146,8 @@ command_unpadded_length(CMD_Request *r)
         return offsetof(CMD_Request, data.modify_minstratum.EOR);
       case REQ_MODIFY_POLLTARGET:
         return offsetof(CMD_Request, data.modify_polltarget.EOR);
+      case REQ_SMOOTHING:
+        return offsetof(CMD_Request, data.null.EOR);
       default:
         /* If we fall through the switch, it most likely means we've forgotten to implement a new case */
         assert(0);
@@ -296,6 +298,8 @@ PKL_CommandPaddingLength(CMD_Request *r)
       return PADDING_LENGTH(data.modify_minstratum.EOR, data.null.EOR);
     case REQ_MODIFY_POLLTARGET:
       return PADDING_LENGTH(data.modify_polltarget.EOR, data.null.EOR);
+    case REQ_SMOOTHING:
+      return PADDING_LENGTH(data.null.EOR, data.smoothing.EOR);
     default:
       /* If we fall through the switch, it most likely means we've forgotten to implement a new case */
       assert(0);
@@ -359,7 +363,8 @@ PKL_ReplyLength(CMD_Reply *r)
         }
       case RPY_ACTIVITY:
         return offsetof(CMD_Reply, data.activity.EOR);
-        
+      case RPY_SMOOTHING:
+        return offsetof(CMD_Reply, data.smoothing.EOR);
       default:
         assert(0);
     }
index 776276a881e5cfb12d6c93cb8a6b2731966d3d92..1860e784e1c2d557fb5cc781339766067b64be1f 100644 (file)
--- a/reports.h
+++ b/reports.h
@@ -112,4 +112,14 @@ typedef struct {
   int unresolved;
 } RPT_ActivityReport;
 
+typedef struct {
+  int active;
+  int leap_only;
+  double offset;
+  double freq_ppm;
+  double wander_ppm;
+  double last_update_ago;
+  double remaining_time;
+} RPT_SmoothingReport;
+
 #endif /* GOT_REPORTS_H */
index 519b2ba217b16d540d5a7ebcaad8a59fd3e33d0b..bfd7529fc6762d71a6bc0ca6d15eda2b4437cf7a 100644 (file)
--- a/smooth.c
+++ b/smooth.c
@@ -97,15 +97,17 @@ static struct timeval last_update;
 
 
 static void
-get_offset_freq(struct timeval *now, double *offset, double *freq)
+get_smoothing(struct timeval *now, double *poffset, double *pfreq,
+              double *pwander)
 {
-  double elapsed, length;
+  double elapsed, length, offset, freq, wander;
   int i;
 
   UTI_DiffTimevalsToDouble(&elapsed, now, &last_update);
 
-  *offset = smooth_offset;
-  *freq = smooth_freq;
+  offset = smooth_offset;
+  freq = smooth_freq;
+  wander = 0.0;
 
   for (i = 0; i < NUM_STAGES; i++) {
     if (elapsed <= 0.0)
@@ -115,13 +117,21 @@ get_offset_freq(struct timeval *now, double *offset, double *freq)
     if (length >= elapsed)
       length = elapsed;
 
-    *offset -= length * (2.0 * *freq + stages[i].wander * length) / 2.0;
-    *freq += stages[i].wander * length;
+    wander = stages[i].wander;
+    offset -= length * (2.0 * freq + wander * length) / 2.0;
+    freq += wander * length;
     elapsed -= length;
   }
 
-  if (elapsed > 0.0)
-    *offset -= elapsed * *freq;
+  if (elapsed > 0.0) {
+    wander = 0.0;
+    offset -= elapsed * freq;
+  }
+
+  *poffset = offset;
+  *pfreq = freq;
+  if (pwander)
+    *pwander = wander;
 }
 
 static void
@@ -193,11 +203,12 @@ update_smoothing(struct timeval *now, double offset, double freq)
       LOG(LOGS_INFO, LOGF_Smooth, "Time smoothing activated%s", leap_only_mode ?
           " (leap seconds only)" : "");
       locked = 0;
+      last_update = *now;
     }
     return;
   }
 
-  get_offset_freq(now, &smooth_offset, &smooth_freq);
+  get_smoothing(now, &smooth_offset, &smooth_freq, NULL);
   smooth_offset += offset;
   smooth_freq = (smooth_freq - freq) / (1.0 - freq);
   last_update = *now;
@@ -258,7 +269,7 @@ SMT_GetOffset(struct timeval *now)
   if (!enabled)
     return 0.0;
   
-  get_offset_freq(now, &offset, &freq);
+  get_smoothing(now, &offset, &freq, NULL);
 
   return offset;
 }
@@ -289,3 +300,35 @@ SMT_Leap(struct timeval *now, int leap)
 
   update_smoothing(now, leap, 0.0);
 }
+
+int
+SMT_GetSmoothingReport(RPT_SmoothingReport *report, struct timeval *now)
+{
+  double length, elapsed;
+  int i;
+
+  if (!enabled)
+    return 0;
+
+  report->active = !locked;
+  report->leap_only = leap_only_mode;
+
+  get_smoothing(now, &report->offset, &report->freq_ppm, &report->wander_ppm);
+
+  /* Convert to ppm and negate (positive values mean faster/speeding up) */
+  report->freq_ppm *= -1.0e6;
+  report->wander_ppm *= -1.0e6;
+
+  UTI_DiffTimevalsToDouble(&elapsed, now, &last_update);
+  if (!locked && elapsed >= 0.0) {
+    for (i = 0, length = 0.0; i < NUM_STAGES; i++)
+      length += stages[i].length;
+    report->last_update_ago = elapsed;
+    report->remaining_time = elapsed < length ? length - elapsed : 0.0;
+  } else {
+    report->last_update_ago = 0.0;
+    report->remaining_time = 0.0;
+  }
+
+  return 1;
+}
index 4cb72d7b506626bb886df0c9adf32b1c5800aa08..1cf6814bc7b7a7fdb021d559b9a8b17a0d6a489c 100644 (file)
--- a/smooth.h
+++ b/smooth.h
@@ -27,6 +27,8 @@
 #ifndef GOT_SMOOTH_H
 #define GOT_SMOOTH_H
 
+#include "reports.h"
+
 extern void SMT_Initialise(void);
 
 extern void SMT_Finalise(void);
@@ -39,4 +41,6 @@ extern void SMT_Reset(struct timeval *now);
 
 extern void SMT_Leap(struct timeval *now, int leap);
 
+extern int SMT_GetSmoothingReport(RPT_SmoothingReport *report, struct timeval *now);
+
 #endif