Extend tracking, sources and activity reports

This commit is contained in:
Miroslav Lichvar 2012-02-03 14:57:25 +01:00
parent 5fb5a89f02
commit 19b3c5be26
8 changed files with 136 additions and 44 deletions

12
candm.h
View file

@ -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;

View 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

View file

@ -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;

View file

@ -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);
}

View 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;

View 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;
}
}

View file

@ -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 */

View file

@ -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);