Hi,
Paul and I have been doing some testing of OpenNTPD on various OSes,
and found some interesting deviations. Paul noted that running the
latest OpenNTPD-portable on OmniOS (Solaris derivative) that it would
cycle back and forth between 'clock is now synced' and 'clock is now
unsynced'. So, we put together a short test program to test behavior
of adjtime:
#include <sys/time.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
struct timeval a, b, c = { 0 };
a.tv_sec = 0;
a.tv_usec = 500000;
if (argc > 1)
a.tv_usec = atoi(argv[1]);
printf("setting adjtime to %lu usec\n", (long)a.tv_usec);
if (adjtime(&a, &b) == -1) {
perror("adjtime");
return 1;
}
do {
sleep(1);
// try putting &c for Solaris in the first arg
if (adjtime(NULL, &b) == -1) {
perror("adjtime");
return 1;
}
printf("%ld usec left\n", b.tv_usec);
} while (b.tv_usec != 0);
return 0;
}
OpenBSD appears to adjust by 5000 usec/sec.
Linux appears to adjust by 500 usec/sec.
Solaris adjust by...well, who knows what amount. But, it is
inconsistent in its ability to eventually hit '0', especially if the
clock frequency adjustment for 'adjfreq/ntpd_adjtime' was ever set to
anything other than '0'. It also doesn't allow specifying a NULL first
argument to adjtime, so a run looks something like this:
setting adjtime to 500000 usec
437963 usec left
375299 usec left
312634 usec left
249343 usec left
186679 usec left
124015 usec left
-339216 usec left
-272516 usec left
-205817 usec left
-139740 usec left
-73041 usec left
-6341 usec left
-3 usec left
-3 usec left
-3 usec left
In a number of machines, it never hits '0' at all, simply gets kind of
close. I was wondering if it made sense to either:
1. add some sort of fudge factor to the clock 'synced' state when
the olddelta simply stabilizes (not sure if there's a good technique
here)?
2. quiet the debug logging for synced/unsynced
3. document as a Solaris bug and move on?
I got the same behavior after running ntp.org's ntpd and openntpd (and
stopping them) and having adjfreq pre-set, so I don't think its a case
of us programming adjfreq/ntp_adjtime incorrectly. It seems this
behavior first showed up since OpenNTPD-portable now calls adjfreq. It
is also possible that if we never call adjfreq that Solaris does
eventually adjust the time all the way. We've tested on a variety of
Solaris 10 / 11 and x86 and Sparc hardware.
- Brent