Commit a0060fee authored by Eric S. Raymond's avatar Eric S. Raymond

Implement and document JSON reporting in ntpfrob.

parent 1d0e1c66
......@@ -27,16 +27,34 @@ Portions of it formerly traveled as `tickadj` and `ntptime`.
Measure clock precision.
`-s`::
Check for stepback bug.
`-j`::
Report in self-describing JSON.
== Modes of operation ==
Documentation for some of these functions is scanty. If you suspect
you may need to use them, reading the source code may be wise.
Documentation for some of these functions is scanty; this is a problem
inherited from ancient days along with their code. If you suspect
you may need to use them, reading the source code may be wise. If
you believe you understand the code in more detail than any of
these descriptions, please explain it to the {project-shortname}
maintainers.
Normally this tool reports in an eyeball-friendly unstructured text
format. With the -j option (where applicable) it reports JSON records.
Note that the -j option should be given before any mode option.
The reporting formats of this tool should be considered unstable;
they may change as diagnostics are added or improved. JSON
reports will be kept forward-compatible through changes.
=== Clock tick adjustment ===
The -A function reads your clock's tick rate in microseconds. The -a
function sets it. Both rely on the adjtimex(2) system call.
function sets it. Both rely on the adjtimex(2) system call. This
mode finishes by tereporting the tick value and (if available) the
tick adjustment value.
The -j option is applicable to this mode.
Tweaking your tick rate is almost never necessary on hardware new
enough to have a fully POSIX.1-2001-conformant Unix.
......@@ -50,6 +68,8 @@ hardware interrupt, usually in the range 10 us-1 ms. For those systems
with microsecond counters the jitter is dominated only by the
operating system.
The -j option is applicable to this mode.
=== Pulse-per-second check ==
The -p option shows whether the PPS-API (RFC 2783 kernel
......@@ -60,6 +80,8 @@ PPS interface) finds PPS on a specified device.
The -e option measure the resolution of the system clock, watching how
the current time changes as we read it repeatedly.
The -j option is applicable to this mode.
=== Stepback bug check ===
The -s option checks for a bug originally seen on IBM RS/6000 AIX
......
......@@ -15,10 +15,13 @@
#include <stdio.h>
#include <sys/time.h>
#include <stdlib.h>
#include <stdbool.h>
#include "ntp_fp.h"
#define NBUF 800002
#define JAN_1970 2208988800UL /* Unix base epoch */
#define NSAMPLES 10
char progname[10];
double sys_residual;
......@@ -58,7 +61,7 @@ get_clocktime(
now->l_uf = (uint32_t)dtemp;
}
void jitter(void)
void jitter(const bool json)
{
l_fp tr;
int i, j;
......@@ -101,13 +104,33 @@ void jitter(void)
}
}
average = average / (NBUF - 2);
fprintf(stderr, "Average %13.9f\n", average);
fprintf(stderr, "First rank\n");
for (i = 0; i < 10; i++)
fprintf(stderr, "%2d %13.9f\n", i, gtod[i]);
fprintf(stderr, "Last rank\n");
for (i = NBUF - 12; i < NBUF - 2; i++)
fprintf(stderr, "%2d %13.9f\n", i, gtod[i]);
if (json) {
fprintf(stdout, "{\"Average\":%13.9f,", average);
fprintf(stdout, "\"First rank\":[");
for (i = 0; i < NSAMPLES; i++) {
fprintf(stdout, "%13.9f", gtod[i]);
if (i < NSAMPLES - 1)
fputc(',', stdout);
fputs("],", stdout);
}
fprintf(stdout, "\"Last rank\":");
for (i = NBUF - 12; i < NBUF - 2; i++) {
fprintf(stdout, "%13.9f\n", gtod[i]);
if (i < NSAMPLES - 1)
fputc(',', stdout);
fputs("]}\n", stdout);
}
}
else
{
fprintf(stdout, "Average %13.9f\n", average);
fprintf(stdout, "First rank\n");
for (i = 0; i < NSAMPLES; i++)
fprintf(stdout, "%2d %13.9f\n", i, gtod[i]);
fprintf(stdout, "Last rank\n");
for (i = NBUF - 12; i < NBUF - 2; i++)
fprintf(stdout, "%2d %13.9f\n", i, gtod[i]);
}
}
/* end */
......@@ -5,6 +5,7 @@
#include <stdlib.h>
#include <stdio.h>
#include <getopt.h>
#include <stdbool.h>
#include "config.h"
......@@ -12,20 +13,21 @@
* Our methods, one per linked module
*/
extern void ppscheck(char *device);
extern void tickadj(const int tick);
extern void jitter(void);
extern void tickadj(const bool json, const int tick);
extern void jitter(const bool json);
extern void stepback(void);
extern void precision(void);
extern void precision(const bool json);
int
main(int argc, char **argv)
{
int ch;
while ((ch = getopt(argc, argv, "aA:cp:")) != EOF) {
bool json = false;
while ((ch = getopt(argc, argv, "a:Acejp:")) != EOF) {
switch (ch) {
case 'A':
#ifdef HAVE_ADJTIMEX
tickadj(0);
tickadj(json, 0);
#else
fputs("ntpfrob: no adjtimex(2) call.\n", stderr);
exit(0);
......@@ -33,16 +35,23 @@ main(int argc, char **argv)
break;
case 'a':
#ifdef HAVE_ADJTIMEX
tickadj(atoi(optarg));
tickadj(json, atoi(optarg));
#else
fputs("ntpfrob: no adjtimex(2) call.\n", stderr);
exit(0);
#endif
break;
case 'c':
jitter();
jitter(json);
exit(0);
break;
case 'e':
precision(json);
exit(0);
break;
case 'j':
json = true;
break;
case 'p':
#ifdef HAVE_SYS_TIMEPPS_H
ppscheck(optarg);
......@@ -51,6 +60,10 @@ main(int argc, char **argv)
exit(0);
#endif
break;
default:
fputs("ntpfrob: no mode option specified.\n", stderr);
exit(1);
break;
}
}
......
......@@ -6,17 +6,23 @@
#include "ntp_unixtime.h"
#include <stdio.h>
#include <stdbool.h>
#define DEFAULT_SYS_PRECISION -99
int default_get_resolution();
int default_get_precision();
int default_get_resolution(void);
int default_get_precision(void);
void precision(void)
void precision(const bool json)
{
printf("log2(resolution) = %d, log2(precision) = %d\n",
default_get_resolution(),
default_get_precision());
if (json)
printf("{\"log2 of resolution\":%d, \"log2 of precision\":%d}\n",
default_get_resolution(),
default_get_precision());
else
printf("log2(resolution) = %d, log2(precision) = %d\n",
default_get_resolution(),
default_get_precision());
}
/* Find the resolution of the system clock by watching how the current time
......@@ -80,23 +86,24 @@ default_get_resolution(void)
last = tp.tv_usec;
}
printf("resolution = %ld usec after %d loop%s\n",
fprintf(stderr, "resolution = %ld usec after %d loop%s\n",
diff, i, (i==1) ? "" : "s");
diff = (diff *3)/2;
if (i >= MAXLOOPS) {
printf(
fprintf(stderr,
" (Boy this machine is fast ! %d loops without a step)\n",
MAXLOOPS);
diff = 1; /* No STEP, so FAST machine */
}
if (i == 0) {
printf(
fprintf(stderr,
" (The resolution is less than the time to read the clock -- Assume 1us)\n");
diff = 1; /* time to read clock >= resolution */
}
for (i=0, val=HUSECS; val>0; i--, val >>= 1) if (diff >= val) return i;
printf(" (Oh dear -- that wasn't expected ! I'll guess !)\n");
fprintf(stderr,
" (Oh dear -- that wasn't expected ! I'll guess !)\n");
return DEFAULT_SYS_PRECISION /* Something's BUST, so lie ! */;
}
......@@ -157,10 +164,10 @@ default_get_precision(void)
val = diff;
}
}
printf("precision = %ld usec after %d loop%s\n",
fprintf(stderr, "precision = %ld usec after %d loop%s\n",
val, i, (i == 1) ? "" : "s");
if (usec >= HUSECS) {
printf(" (Boy this machine is fast ! usec was %ld)\n",
fprintf(stderr, " (Boy this machine is fast ! usec was %ld)\n",
usec);
val = MINSTEP; /* val <= MINSTEP; fast machine */
}
......
......@@ -25,7 +25,7 @@
static struct timex txc;
void tickadj(const int newtick)
void tickadj(const bool json, const int newtick)
{
if (newtick != 0)
{
......@@ -68,9 +68,17 @@ void tickadj(const int newtick)
else
{
#ifdef STRUCT_TIMEX_HAS_TIME_TICK
printf("tick = %ld\ntick_adj = %ld\n", txc.time_tick, txc.tickadj);
if (json)
printf("{\"tick\":%ld,\"tick_adj\":%ld}\n",
txc.time_tick, txc.tickadj);
else
printf("tick = %ld\ntick_adj = %ld\n",
txc.time_tick, txc.tickadj);
#else
printf("tick = %ld\n", txc.tick);
if (json)
printf("{\"tick\":%ld}\n", txc.tick);
else
printf("tick = %ld\n", txc.tick);
#endif
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment