]> git.pld-linux.org Git - packages/openntpd.git/blob - openntpd-3.6p1-linux-adjtimex4.patch
- up to 3.6.1p1
[packages/openntpd.git] / openntpd-3.6p1-linux-adjtimex4.patch
1 This patch adds support for the Linux adjtimex call to OpenNTPd, to adjust
2 the kernel to compensate for systematic clock skew/drift.
3
4 Apply with:
5 cd openntpd-3.6p1 && patch -p0 </tmp/openntpd-3.6p1-linux-adjtimex4.patch
6
7 then either rebuild configure with "autoconf" or define USE_ADJTIMEX with:
8 CFLAGS=-DUSE_ADJTIMEX ./configure && make
9
10 Index: client.c
11 ===================================================================
12 RCS file: /usr/local/cvs/openntpd-portable/client.c,v
13 retrieving revision 1.14
14 diff -u -p -r1.14 client.c
15 --- client.c    20 Aug 2004 11:44:24 -0000      1.14
16 +++ client.c    11 Nov 2004 23:10:24 -0000
17 @@ -270,7 +270,8 @@ client_update(struct ntp_peer *p)
18          * clock filter
19          * find the offset which arrived with the lowest delay
20          * use that as the peer update
21 -        * invalidate it and all older ones
22 +        * Afterwards, invalidate all offsets: since we're going to adjust,
23 +        * the old ones will not be valid any more anyway.
24          */
25  
26         for (i = 0; good == 0 && i < OFFSET_ARRAY_SIZE; i++)
27 @@ -293,8 +294,7 @@ client_update(struct ntp_peer *p)
28         ntp_adjtime();
29  
30         for (i = 0; i < OFFSET_ARRAY_SIZE; i++)
31 -               if (p->reply[i].rcvd <= p->reply[best].rcvd)
32 -                       p->reply[i].good = 0;
33 +               p->reply[i].good = 0;
34  
35         return (0);
36  }
37 Index: configure.ac
38 ===================================================================
39 RCS file: /usr/local/cvs/openntpd-portable/configure.ac,v
40 retrieving revision 1.31.2.3
41 diff -u -p -r1.31.2.3 configure.ac
42 --- configure.ac        15 Oct 2004 01:39:37 -0000      1.31.2.3
43 +++ configure.ac        11 Nov 2004 23:10:24 -0000
44 @@ -388,6 +388,11 @@ AC_ARG_WITH(builtin-arc4random,
45         [ builtin_arc4random=$withval ]
46  )
47  
48 +AC_ARG_WITH(adjtimex,
49 +       [  --with-adjtimex         Use adjtimex to adjust kernel skew],
50 +       [ AC_DEFINE(USE_ADJTIMEX, [], [Use adjust skew with adjtimex (experimental)]) ]
51 +)
52 +
53  # Search for OpenSSL if required.
54  if test "$ac_cv_func_arc4random" != "yes" && test "x$builtin_arc4random" != "xyes"; then
55  saved_CPPFLAGS="$CPPFLAGS"
56 Index: defines.h
57 ===================================================================
58 RCS file: /usr/local/cvs/openntpd-portable/defines.h,v
59 retrieving revision 1.13.2.1
60 diff -u -p -r1.13.2.1 defines.h
61 --- defines.h   14 Oct 2004 09:58:57 -0000      1.13.2.1
62 +++ defines.h   11 Nov 2004 23:10:24 -0000
63 @@ -20,6 +20,10 @@
64  # define setproctitle(x)
65  #endif
66  
67 +#ifdef USE_ADJTIMEX
68 +# define adjtime(a,b)  (_compat_adjtime((a),(b)))
69 +#endif
70 +
71  #if !defined(SA_LEN)
72  # if defined(HAVE_STRUCT_SOCKADDR_SA_LEN)
73  #  define SA_LEN(x)    ((x)->sa_len)
74 Index: openbsd-compat/Makefile.in
75 ===================================================================
76 RCS file: /usr/local/cvs/openntpd-portable/openbsd-compat/Makefile.in,v
77 retrieving revision 1.4.2.1
78 diff -u -p -r1.4.2.1 Makefile.in
79 --- openbsd-compat/Makefile.in  14 Oct 2004 09:59:00 -0000      1.4.2.1
80 +++ openbsd-compat/Makefile.in  11 Nov 2004 23:11:05 -0000
81 @@ -8,6 +8,7 @@ all:    libopenbsd-compat.a
82  
83  OPENBSD=       asprintf.o daemon.o inet_pton.o strlcpy.o
84  COMPAT=                bsd-arc4random.o bsd-misc.o fake-rfc2553.o uidswap.o
85 +PORT=          port-linux.o
86  
87  VPATH=@srcdir@
88  CC=@CC@
89 @@ -22,14 +23,14 @@ INSTALL=@INSTALL@
90  
91  $(COMPAT): ../config.h
92  $(OPENBSD): ../config.h
93 -
94 +$(PORT): ../config.h
95  
96  .c.o:
97         $(CC) $(CFLAGS) $(CPPFLAGS) -c $<
98  
99 -libopenbsd-compat.a:   $(COMPAT) $(OPENBSD)
100 -       $(AR) rv $@ $(COMPAT) $(OPENBSD)
101 +libopenbsd-compat.a:   $(COMPAT) $(OPENBSD) $(PORT)
102 +       $(AR) rv $@ $(COMPAT) $(OPENBSD) $(PORT)
103         $(RANLIB) $@
104  
105  clean:
106 -       rm -f $(COMPAT) $(OPENBSD) libopenbsd-compat.a
107 +       rm -f $(COMPAT) $(OPENBSD) $(PORT) libopenbsd-compat.a
108 Index: openbsd-compat/openbsd-compat.h
109 ===================================================================
110 RCS file: /usr/local/cvs/openntpd-portable/openbsd-compat/openbsd-compat.h,v
111 retrieving revision 1.4.2.3
112 diff -u -p -r1.4.2.3 openbsd-compat.h
113 --- openbsd-compat/openbsd-compat.h     14 Oct 2004 12:36:34 -0000      1.4.2.3
114 +++ openbsd-compat/openbsd-compat.h     11 Nov 2004 23:10:24 -0000
115 @@ -52,4 +52,9 @@ int seteuid(uid_t);
116  int setegid(uid_t);
117  #endif /* !defined(HAVE_SETEGID) && defined(HAVE_SETRESGID) */
118  
119 +#ifdef USE_ADJTIMEX
120 +# include <sys/time.h>
121 +int _compat_adjtime(const struct timeval *, struct timeval *);
122 +#endif
123 +
124  int permanently_set_uid(struct passwd *);
125 Index: openbsd-compat/port-linux.c
126 ===================================================================
127 RCS file: openbsd-compat/port-linux.c
128 diff -N openbsd-compat/port-linux.c
129 --- /dev/null   1 Jan 1970 00:00:00 -0000
130 +++ openbsd-compat/port-linux.c 11 Nov 2004 23:12:42 -0000
131 @@ -0,0 +1,110 @@
132 +/* $Id$ */
133 +
134 +/*
135 + * Copyright (c) 2004 Darren Tucker <dtucker at zip com au>
136 + *
137 + * Permission to use, copy, modify, and distribute this software for any
138 + * purpose with or without fee is hereby granted, provided that the above
139 + * copyright notice and this permission notice appear in all copies.
140 + *
141 + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
142 + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
143 + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
144 + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
145 + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
146 + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
147 + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
148 + */
149 +
150 +#include "includes.h"
151 +
152 +#ifdef USE_ADJTIMEX
153 +#include <sys/timex.h>
154 +#include <errno.h>
155 +#ifdef adjtime
156 +# undef adjtime
157 +#endif
158 +
159 +/* scale factor used by adjtimex freq param.  1 ppm = 65536 */
160 +#define ADJTIMEX_FREQ_SCALE 65536
161 +
162 +/* maximum change to skew per adjustment, in PPM */
163 +#define MAX_SKEW_DELTA 5.0
164 +
165 +/*
166 + * Prevent warnings.  We can't just include ntpd.h because of conflicting
167 + * definitions of ntp_adjtime()
168 + */
169 +void log_warn(const char *, ...);
170 +void log_info(const char *, ...);
171 +
172 +int
173 +_compat_adjtime(const struct timeval *delta, struct timeval *olddelta)
174 +{
175 +       static struct timeval tlast = {0,0};
176 +       static double tskew = 0;
177 +       static int synced = -1;
178 +       struct timeval tnow, tdelta;
179 +       double skew = 0, newskew, deltaskew, adjust, interval = 0;
180 +       struct timex tmx;
181 +       int result, saved_errno;
182 +
183 +       gettimeofday(&tnow, NULL);
184 +       adjust = (double)delta->tv_sec;
185 +       adjust += (double)delta->tv_usec / 1000000;
186 +
187 +       /* Even if the caller doesn't care about the olddelta, we do */
188 +       if (olddelta == NULL)
189 +               olddelta = &tdelta;
190 +
191 +       result = adjtime(delta, olddelta);
192 +       saved_errno = errno;
193 +
194 +       if (olddelta->tv_sec == 0 && olddelta->tv_usec == 0 &&
195 +           synced != INT_MAX)
196 +               synced++;
197 +        else
198 +               synced = 0;
199 +
200 +       /*
201 +        * do skew calculations if we have synced
202 +        */
203 +       if (synced == 0 ) {
204 +               tmx.modes = 0;
205 +               if (adjtimex(&tmx) == -1)
206 +                       log_warn("adjtimex get failed");
207 +               else
208 +                       tskew = (double)tmx.freq / ADJTIMEX_FREQ_SCALE;
209 +       } else if (synced >= 1) {
210 +               interval = (double)(tnow.tv_sec - tlast.tv_sec);
211 +               interval += (double)(tnow.tv_usec - tlast.tv_usec) / 1000000;
212 +
213 +               skew = (adjust * 1000000) / interval;
214 +               newskew = ((tskew * synced) + skew) / synced;
215 +               deltaskew = newskew - tskew;
216 +
217 +               if (deltaskew > MAX_SKEW_DELTA) {
218 +                       log_info("skew change %0.3lf exceeds limit", deltaskew);
219 +                       tskew += MAX_SKEW_DELTA;
220 +               } else if (deltaskew < -MAX_SKEW_DELTA) {
221 +                       log_info("skew change %0.3lf exceeds limit", deltaskew);
222 +                       tskew -= MAX_SKEW_DELTA;
223 +               } else {
224 +                       tskew = newskew;
225 +               }
226 +
227 +               /* Adjust the kernel skew.  */
228 +               tmx.freq = (long)(tskew * ADJTIMEX_FREQ_SCALE);
229 +               tmx.modes = ADJ_FREQUENCY;
230 +               if (adjtimex(&tmx) == -1)
231 +                       log_warn("adjtimex set freq failed");
232 +       }
233 +
234 +       log_info("interval %0.3lf skew %0.3lf total skew %0.3lf", interval,
235 +           skew, tskew);
236 +
237 +       tlast = tnow;
238 +       errno = saved_errno;
239 +       return result;
240 +}
241 +#endif
This page took 0.079486 seconds and 3 git commands to generate.