2 * systime -- routines to fiddle a UNIX clock.
4 * ATTENTION: Get approval from Dave Mills on all changes to this file!
10 #include "ntp_syslog.h"
11 #include "ntp_stdlib.h"
12 #include "timespecops.h"
13 #include "ntp_calendar.h"
15 #ifndef USE_COMPILETIME_PIVOT
16 # define USE_COMPILETIME_PIVOT 1
20 * These routines (get_systime, step_systime, adj_systime) implement an
21 * interface between the system independent NTP clock and the Unix
22 * system clock in various architectures and operating systems. Time is
23 * a precious quantity in these routines and every effort is made to
24 * minimize errors by unbiased rounding and amortizing adjustment
27 * In order to improve the apparent resolution, provide unbiased
28 * rounding and most importantly ensure that the readings cannot be
29 * predicted, the low-order unused portion of the time below the minimum
30 * time to read the clock is filled with an unbiased random fuzz.
32 * The sys_tick variable specifies the system clock tick interval in
33 * seconds, for stepping clocks, defined as those which return times
34 * less than MINSTEP greater than the previous reading. For systems that
35 * use a high-resolution counter such that each clock reading is always
36 * at least MINSTEP greater than the prior, sys_tick is the time to read
39 * The sys_fuzz variable measures the minimum time to read the system
40 * clock, regardless of its precision. When reading the system clock
41 * using get_systime() after sys_tick and sys_fuzz have been determined,
42 * ntpd ensures each unprocessed clock reading is no less than sys_fuzz
43 * later than the prior unprocessed reading, and then fuzzes the bits
44 * below sys_fuzz in the timestamp returned, ensuring each of its
45 * resulting readings is strictly later than the previous.
47 * When slewing the system clock using adj_systime() (with the kernel
48 * loop discipline unavailable or disabled), adjtime() offsets are
49 * quantized to sys_tick, if sys_tick is greater than sys_fuzz, which
50 * is to say if the OS presents a stepping clock. Otherwise, offsets
51 * are quantized to the microsecond resolution of adjtime()'s timeval
52 * input. The remaining correction sys_residual is carried into the
53 * next adjtime() and meanwhile is also factored into get_systime()
56 * adj_systime() and step_systime() will behave sanely with these
57 * variables not set, but the adjustments may be in larger steps.
59 time_stepped_callback step_callback
;
61 static doubletime_t sys_residual
= 0; /* adjustment residue (s) */
63 static void get_ostime (struct timespec
*tsp
);
73 rc
= clock_gettime(CLOCK_REALTIME
, tsp
);
76 msyslog(LOG_ERR
, "TIME: read system clock failed: %s (%d)",
77 strerror(errno
), errno
);
78 #endif /* __COVERITY__ */
86 * get_systime - return system time in NTP timestamp format.
90 l_fp
*now
/* system time */
93 struct timespec ts
; /* seconds and nanoseconds */
95 *now
= tspec_stamp_to_lfp(ts
);
100 * adj_systime - adjust system time by the argument.
102 bool /* true on okay, false on error */
104 double now
, /* adjustment (s) */
105 int (*ladjtime
)(const struct timeval
*, struct timeval
*)
108 struct timeval adjtv
; /* new adjustment */
109 struct timeval oadjtv
; /* residual adjustment */
110 double quant
; /* quantize to multiples of */
116 * FIXME: With the legacy Windows port gone, this might be removable.
117 * See also the related FIXME comment in ntpd/ntp_loopfilter.c.
119 * The Windows port adj_systime() depended on being called each
120 * second even when there's no additional correction, to allow
121 * emulation of adjtime() behavior on top of an API that simply
122 * sets the current rate. This POSIX implementation needs to
123 * ignore invocations with zero correction, otherwise ongoing
124 * EVNT_NSET adjtime() can be aborted by a tiny adjtime()
125 * triggered by sys_residual.
127 if ( D_ISZERO_NS(now
))
131 * Most Unix adjtime() implementations adjust the system clock
132 * in microsecond quanta, but some adjust in 10-ms quanta. We
133 * carefully round the adjustment to the nearest quantum, then
134 * adjust in quanta and keep the residue for later.
136 dtemp
= now
+ sys_residual
;
141 adjtv
.tv_sec
= (long)dtemp
;
142 dtemp
-= adjtv
.tv_sec
;
144 ticks
= (long)(dtemp
/ quant
+ .5);
145 adjtv
.tv_usec
= (long)(ticks
* quant
* US_PER_S
+ .5);
146 /* The rounding in the conversions could push us over the
147 * limits: make sure the result is properly normalised!
148 * note: sign comes later, all numbers non-negative here.
150 if (adjtv
.tv_usec
>= US_PER_S
) {
152 adjtv
.tv_usec
-= US_PER_S
;
155 /* set the new residual with leftover from correction */
156 sys_residual
= dtemp
- adjtv
.tv_usec
* S_PER_US
;
159 * Convert to signed seconds and microseconds for the Unix
160 * adjtime() system call. Note we purposely lose the adjtime()
164 adjtv
.tv_sec
= -adjtv
.tv_sec
;
165 adjtv
.tv_usec
= -adjtv
.tv_usec
;
166 sys_residual
= -sys_residual
;
168 if (adjtv
.tv_sec
!= 0 || adjtv
.tv_usec
!= 0) {
169 if (ladjtime(&adjtv
, &oadjtv
) < 0) {
170 msyslog(LOG_ERR
, "CLOCK: adj_systime: %s", strerror(errno
));
179 * step_systime - step the system clock.
181 * if your timespec has a 64 bit time_t then you are 2038 ready.
182 * if your timespec has a 32 bit time_t, be sure to duck in 2038
190 time_t pivot
; /* for ntp era unfolding */
191 struct timespec timets
;
192 struct timespec old
, new;
194 l_fp fp_ofs
, fp_sys
; /* offset and target system time in FP */
197 * Get pivot time for NTP era unfolding. Since we don't step
198 * very often, we can afford to do the whole calculation from
199 * scratch. And we're not in the time-critical path yet.
201 #if NTP_SIZEOF_TIME_T > 4
203 * This code makes sure the resulting time stamp for the new
204 * system time is in the 2^32 seconds starting at 1970-01-01,
208 #if USE_COMPILETIME_PIVOT
210 * Add the compile time minus 10 years to get a possible target
211 * area of (compile time - 10 years) to (compile time + 126
212 * years). This should be sufficient for a given binary of
215 if (ntpcal_get_build_date(&jd
)) {
217 pivot
+= ntpcal_date_to_time(&jd
);
220 "CLOCK: step_systime: assume 1970-01-01 as build date");
224 #endif /* USE_COMPILETIME_PIVOT */
227 /* This makes sure the resulting time stamp is on or after
228 * 1969-12-31/23:59:59 UTC and gives us additional two years,
229 * from the change of NTP era in 2036 to the UNIX rollover in
230 * 2038. (Minus one second, but that won't hurt.) We *really*
231 * need a longer 'time_t' after that! Or a different baseline,
232 * but that would cause other serious trouble, too.
237 /* get the complete jump distance as l_fp */
238 fp_sys
= dtolfp(sys_residual
);
239 fp_ofs
= dtolfp(step
);
242 /* ---> time-critical path starts ---> */
244 /* get the current time as l_fp (without fuzz) and as struct timespec */
247 fp_sys
= tspec_stamp_to_lfp(timets
);
249 /* get the target time as l_fp */
252 /* unfold the new system time */
253 timets
= lfp_stamp_to_tspec(fp_sys
, pivot
);
256 /* now set new system time */
257 if (ntp_set_tod(&timets
) != 0) {
258 msyslog(LOG_ERR
, "CLOCK: step_systime: %s", strerror(errno
));
262 /* <--- time-critical path ended with call to the settime hook <--- */
264 msyslog(LOG_WARNING
, "CLOCK: time stepped by %Lf", step
);
265 if (fabsl(step
) > 86400) {
266 /* Get the full year (both old and new) into the log file.
268 struct tm oldtm
, newtm
;
269 char oldbuf
[100], newbuf
[100];
270 if (!localtime_r(&old
.tv_sec
, &oldtm
)) {
271 oldtm
.tm_year
= 9999-1900;
275 snprintf(oldbuf
, sizeof(oldbuf
), "%04d-%02d-%02d",
276 oldtm
.tm_year
+1900, oldtm
.tm_mon
+1, oldtm
.tm_mday
);
277 if (!localtime_r(&new.tv_sec
, &newtm
)) {
278 newtm
.tm_year
= 9999-1900;
282 snprintf(newbuf
, sizeof(newbuf
), "%04d-%02d-%02d",
283 newtm
.tm_year
+1900, newtm
.tm_mon
+1, newtm
.tm_mday
);
284 msyslog(LOG_WARNING
, "CLOCK: time changed from %s to %s",