Extend tracking, sources and activity reports
This commit is contained in:
parent
5fb5a89f02
commit
19b3c5be26
8 changed files with 136 additions and 44 deletions
12
candm.h
12
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;
|
||||
|
||||
|
|
49
chrony.texi
49
chrony.texi
|
@ -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
|
||||
|
|
31
client.c
31
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;
|
||||
|
|
16
cmdmon.c
16
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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
44
reference.c
44
reference.c
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
17
sources.c
17
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);
|
||||
|
||||
|
|
Loading…
Reference in a new issue