mirror of
https://gitlab.com/chrony/chrony.git
synced 2025-12-03 18:35:06 -05:00
Compare commits
68 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4fac84098e | ||
|
|
21b2063a6f | ||
|
|
917c191650 | ||
|
|
2bfce03d29 | ||
|
|
1cb8167be0 | ||
|
|
40d33cc64d | ||
|
|
95433e9639 | ||
|
|
bbe1a09e7e | ||
|
|
dce2366b3a | ||
|
|
bab7ba22cf | ||
|
|
d6a91057ae | ||
|
|
c6e9065498 | ||
|
|
22fda21eae | ||
|
|
103a520aa6 | ||
|
|
86531a51a7 | ||
|
|
2b7e4d645f | ||
|
|
a5f63180fc | ||
|
|
934d4e04b5 | ||
|
|
1b8547059a | ||
|
|
91279a0f28 | ||
|
|
31ba3144c8 | ||
|
|
0bf34725e3 | ||
|
|
91749ebb2b | ||
|
|
4ba3dd66ad | ||
|
|
d40696f7f3 | ||
|
|
4a401a9e83 | ||
|
|
6a2a837ede | ||
|
|
eca08a281c | ||
|
|
9fd8f76fa0 | ||
|
|
50de930730 | ||
|
|
da1097095c | ||
|
|
ec7d302a6c | ||
|
|
8cc7ebffa9 | ||
|
|
de4d14843f | ||
|
|
18605795a7 | ||
|
|
da2c8d9076 | ||
|
|
3120f8adb6 | ||
|
|
2dcc16169b | ||
|
|
a8efd8c398 | ||
|
|
bb40f4aff4 | ||
|
|
66c7ac4d24 | ||
|
|
7f12919fea | ||
|
|
55e0c6a0a1 | ||
|
|
20f306602b | ||
|
|
70735d8d79 | ||
|
|
165e6805ab | ||
|
|
2a0c35646c | ||
|
|
28710e0449 | ||
|
|
c5587b60b2 | ||
|
|
bb95c39356 | ||
|
|
20a43409c6 | ||
|
|
4699f7ca0b | ||
|
|
bc7586b3f4 | ||
|
|
8d3d45ea1a | ||
|
|
21ba1d3761 | ||
|
|
e79584bb9e | ||
|
|
bca7819247 | ||
|
|
0ecabae2c3 | ||
|
|
598c04eea2 | ||
|
|
faec23f6bd | ||
|
|
896dad9224 | ||
|
|
680612cf09 | ||
|
|
3fbd4bb15f | ||
|
|
cb9055072d | ||
|
|
0fc9b555f1 | ||
|
|
6ed58628f5 | ||
|
|
efff149988 | ||
|
|
b02d4092f1 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,3 +1,4 @@
|
||||
.deps
|
||||
*.swp
|
||||
*.o
|
||||
Makefile
|
||||
|
||||
36
Makefile.in
36
Makefile.in
@@ -29,9 +29,8 @@ INFODIR=@INFODIR@
|
||||
DOCDIR=@DOCDIR@
|
||||
|
||||
CC = @CC@
|
||||
CCWARNFLAGS = @CCWARNFLAGS@
|
||||
OPTFLAGS = @CFLAGS@
|
||||
CPPFLAGS = @CPPFLAGS@ @SYSDEFS@ @EXTRA_DEFS@
|
||||
CFLAGS = @CFLAGS@
|
||||
CPPFLAGS = @CPPFLAGS@
|
||||
|
||||
DESTDIR=
|
||||
|
||||
@@ -49,6 +48,8 @@ EXTRA_OBJS=@EXTRA_OBJECTS@
|
||||
CLI_OBJS = client.o md5.o nameserv.o getdate.o cmdparse.o \
|
||||
pktlength.o util.o
|
||||
|
||||
ALL_OBJS = $(OBJS) $(EXTRA_OBJS) $(CLI_OBJS)
|
||||
|
||||
SRCS = $(patsubst %.o,%.c,$(OBJS))
|
||||
EXTRA_SRCS = $(patsubst %.o,%.c,$(EXTRA_OBJS))
|
||||
|
||||
@@ -60,36 +61,26 @@ LIBS = @LIBS@
|
||||
EXTRA_LIBS=@EXTRA_LIBS@
|
||||
EXTRA_CLI_LIBS=@EXTRA_CLI_LIBS@
|
||||
|
||||
CFLAGS = $(CCWARNFLAGS) $(OPTFLAGS)
|
||||
|
||||
# Until we have a main procedure we can link, just build object files
|
||||
# to test compilation
|
||||
|
||||
all : chronyd chronyc
|
||||
|
||||
chronyd : $(OBJS) $(EXTRA_OBJS)
|
||||
$(CC) $(OPTFLAGS) -o chronyd $(OBJS) $(EXTRA_OBJS) $(LDFLAGS) $(LIBS) $(EXTRA_LIBS)
|
||||
$(CC) $(CFLAGS) -o chronyd $(OBJS) $(EXTRA_OBJS) $(LDFLAGS) $(LIBS) $(EXTRA_LIBS)
|
||||
|
||||
chronyc : $(CLI_OBJS)
|
||||
$(CC) $(OPTFLAGS) -o chronyc $(CLI_OBJS) $(LDFLAGS) @READLINE_LINK@ $(LIBS) $(EXTRA_CLI_LIBS)
|
||||
|
||||
conf.o : conf.c
|
||||
$(CC) $(CFLAGS) $(CPPFLAGS) -DDEFAULT_CONF_DIR=\"$(SYSCONFDIR)\" -c $<
|
||||
$(CC) $(CFLAGS) -o chronyc $(CLI_OBJS) $(LDFLAGS) @READLINE_LINK@ $(LIBS) $(EXTRA_CLI_LIBS)
|
||||
|
||||
client.o : client.c
|
||||
$(CC) $(CFLAGS) $(CPPFLAGS) @READLINE_COMPILE@ -c $<
|
||||
|
||||
.depend :
|
||||
gcc -MM $(SRCS) $(EXTRA_SRCS) > .depend
|
||||
|
||||
distclean :
|
||||
-rm -f *.o *.s chronyc chronyd core options.h Makefile *~
|
||||
distclean : clean
|
||||
-rm -f Makefile
|
||||
|
||||
clean :
|
||||
-rm -f *.o *.s chronyc chronyd core *~
|
||||
|
||||
version.h : version.txt
|
||||
./mkversion
|
||||
-rm -rf .deps
|
||||
|
||||
getdate.c : ;
|
||||
getdate :
|
||||
@@ -133,8 +124,6 @@ install: chronyd chronyc
|
||||
%.s : %.c
|
||||
$(CC) $(CFLAGS) $(CPPFLAGS) -S $<
|
||||
|
||||
main.o logging.o client.o : version.h
|
||||
|
||||
# makeinfo v4 required to generate plain text and html
|
||||
MAKEINFO:=makeinfo
|
||||
|
||||
@@ -163,3 +152,10 @@ chrony.info : chrony.texi
|
||||
faq.php : faq.txt faqgen.pl
|
||||
perl faqgen.pl < faq.txt > faq.php
|
||||
|
||||
.deps:
|
||||
@mkdir .deps
|
||||
|
||||
.deps/%.d: %.c | .deps
|
||||
@$(CC) -MM $(CPPFLAGS) -MT '$(<:%.c=%.o) $@' $< -o $@
|
||||
|
||||
-include $(ALL_OBJS:%.o=.deps/%.d)
|
||||
|
||||
17
NEWS
17
NEWS
@@ -1,3 +1,14 @@
|
||||
New in version 1.26
|
||||
===================
|
||||
|
||||
* Add compatibility with Linux 3.0 and later
|
||||
* Use proper source address in NTP replies on multihomed IPv6 hosts
|
||||
* Accept NTP packets with versions 4, 3 and 2
|
||||
* Cope with unexpected backward time jumps
|
||||
* Don't reset kernel frequency on start without drift file
|
||||
* Retry on permanent DNS error by default
|
||||
* Add waitsync command
|
||||
|
||||
New in version 1.25
|
||||
===================
|
||||
|
||||
@@ -6,6 +17,7 @@ New in version 1.25
|
||||
* Improve polling interval adjustment
|
||||
* Improve stability with temporary asymmetric delays
|
||||
* Improve source selection
|
||||
* Improve initial synchronisation
|
||||
* Add delayed server name resolving
|
||||
* Add temperature compensation
|
||||
* Add nanosecond slewing to Linux driver
|
||||
@@ -13,7 +25,8 @@ New in version 1.25
|
||||
* Add iburst, minstratum, maxdelaydevratio, polltarget,
|
||||
prefer, noselect options
|
||||
* Add rtcsync directive to enable Linux 11-minute mode
|
||||
* Add reselectdist, stratumweight, logbanner, maxclockerror directives
|
||||
* Add reselectdist, stratumweight, logbanner, maxclockerror,
|
||||
include directives
|
||||
* Add -n option to not detach daemon from terminal
|
||||
* Fix pidfile directive
|
||||
* Fix name resolving with disabled IPv6 support
|
||||
@@ -23,9 +36,9 @@ New in version 1.25
|
||||
* Fix file descriptor leaks
|
||||
* Increase burst polling interval and stop on KoD RATE
|
||||
* Set maxupdateskew to 1000 ppm by default
|
||||
* Consider offline sources unreachable
|
||||
* Require password for clients command
|
||||
* Update drift file at most once per hour
|
||||
* Use system headers for Linux RTC support
|
||||
* Reduce default chronyc timeout and make it configurable
|
||||
* Avoid large values in chronyc sources and sourcestats output
|
||||
* Add reselect command to force reselecting best source
|
||||
|
||||
12
acquire.c
12
acquire.c
@@ -37,6 +37,8 @@
|
||||
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "sysincl.h"
|
||||
|
||||
#include "acquire.h"
|
||||
@@ -61,6 +63,10 @@
|
||||
|
||||
#define RETRANSMISSION_TIMEOUT (1.0)
|
||||
|
||||
#define NTP_VERSION 3
|
||||
#define NTP_MAX_COMPAT_VERSION 4
|
||||
#define NTP_MIN_COMPAT_VERSION 2
|
||||
|
||||
typedef struct {
|
||||
IPAddr ip_addr; /* Address of the server */
|
||||
int sanity; /* Flag indicating whether source
|
||||
@@ -244,7 +250,7 @@ static void
|
||||
probe_source(SourceRecord *src)
|
||||
{
|
||||
NTP_Packet pkt;
|
||||
int version = 3;
|
||||
int version = NTP_VERSION;
|
||||
NTP_Mode my_mode = MODE_CLIENT;
|
||||
struct timeval cooked;
|
||||
union sockaddr_in46 his_addr;
|
||||
@@ -264,7 +270,7 @@ probe_source(SourceRecord *src)
|
||||
pkt.precision = -6; /* as ntpdate */
|
||||
pkt.root_delay = double_to_int32(1.0); /* 1 second */
|
||||
pkt.root_dispersion = double_to_int32(1.0); /* likewise */
|
||||
pkt.reference_id = 0UL;
|
||||
pkt.reference_id = 0;
|
||||
pkt.reference_ts.hi = 0; /* Set to 0 */
|
||||
pkt.reference_ts.lo = 0; /* Set to 0 */
|
||||
pkt.originate_ts.hi = 0; /* Set to 0 */
|
||||
@@ -370,7 +376,7 @@ process_receive(NTP_Packet *msg, SourceRecord *src, struct timeval *now)
|
||||
mode = lvm & 0x7;
|
||||
|
||||
if ((leap == LEAP_Unsynchronised) ||
|
||||
(version != 3) ||
|
||||
(version < NTP_MIN_COMPAT_VERSION || version > NTP_MAX_COMPAT_VERSION) ||
|
||||
(mode != MODE_SERVER && mode != MODE_PASSIVE)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -28,6 +28,8 @@
|
||||
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "sysincl.h"
|
||||
|
||||
#include "addrfilt.h"
|
||||
|
||||
@@ -24,6 +24,8 @@
|
||||
Deal with broadcast server functions.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "sysincl.h"
|
||||
#include "memory.h"
|
||||
|
||||
@@ -71,7 +73,7 @@ timeout_handler(void *arbitrary)
|
||||
int leap;
|
||||
int are_we_synchronised, our_stratum;
|
||||
NTP_Leap leap_status;
|
||||
unsigned long our_ref_id;
|
||||
uint32_t our_ref_id;
|
||||
struct timeval our_ref_time;
|
||||
double our_root_delay, our_root_dispersion;
|
||||
struct timeval local_transmit;
|
||||
@@ -89,7 +91,7 @@ timeout_handler(void *arbitrary)
|
||||
if (are_we_synchronised) {
|
||||
leap = (int) leap_status;
|
||||
} else {
|
||||
leap = 3;
|
||||
leap = LEAP_Unsynchronised;
|
||||
}
|
||||
|
||||
message.lvm = ((leap << 6) &0xc0) | ((version << 3) & 0x38) | (MODE_BROADCAST & 0x07);
|
||||
|
||||
12
candm.h
12
candm.h
@@ -86,7 +86,8 @@
|
||||
#define REQ_MODIFY_POLLTARGET 46
|
||||
#define REQ_MODIFY_MAXDELAYDEVRATIO 47
|
||||
#define REQ_RESELECT 48
|
||||
#define N_REQUEST_TYPES 49
|
||||
#define REQ_RESELECTDISTANCE 49
|
||||
#define N_REQUEST_TYPES 50
|
||||
|
||||
/* Special utoken value used to log on with first exchange being the
|
||||
password. (This time value has long since gone by) */
|
||||
@@ -339,6 +340,11 @@ typedef struct {
|
||||
int32_t EOR;
|
||||
} REQ_Reselect;
|
||||
|
||||
typedef struct {
|
||||
Float distance;
|
||||
int32_t EOR;
|
||||
} REQ_ReselectDistance;
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
#define PKT_TYPE_CMD_REQUEST 1
|
||||
@@ -359,7 +365,8 @@ typedef struct {
|
||||
Version 4 : IPv6 addressing added, 64-bit time values, sourcestats
|
||||
and tracking reports extended, added flags to NTP source request,
|
||||
trimmed source report, replaced fixed-point format with floating-point
|
||||
and used also instead of integer microseconds
|
||||
and used also instead of integer microseconds, new commands: modify stratum,
|
||||
modify polltarget, modify maxdelaydevratio, reselect, reselectdistance
|
||||
|
||||
*/
|
||||
|
||||
@@ -425,6 +432,7 @@ typedef struct {
|
||||
REQ_MakeStep make_step;
|
||||
REQ_Activity activity;
|
||||
REQ_Reselect reselect;
|
||||
REQ_ReselectDistance reselect_distance;
|
||||
} data; /* Command specific parameters */
|
||||
|
||||
} CMD_Request;
|
||||
|
||||
2
chrony.1
2
chrony.1
@@ -1,4 +1,4 @@
|
||||
.TH CHRONY 1 "December 04, 2009" chrony "User's Manual"
|
||||
.TH CHRONY 1 "@MAN_DATE@" "chrony @VERSION@" "User's Manual"
|
||||
.SH NAME
|
||||
chrony \- programs for keeping computer clocks accurate
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.TH chrony.conf 5 "December 04, 2009" chrony "Configuration Files"
|
||||
.TH chrony.conf 5 "@MAN_DATE@" "chrony @VERSION@" "Configuration Files"
|
||||
.SH NAME
|
||||
chrony.conf \- chronyd configuration file
|
||||
|
||||
|
||||
29
chrony.lsm
29
chrony.lsm
@@ -1,29 +0,0 @@
|
||||
Begin3
|
||||
Title: chrony
|
||||
Version: 1.18
|
||||
Entered-date: 01APR02
|
||||
Description: A pair of programs for keeping computer clocks accurate.
|
||||
chronyd is a background (daemon) program and chronyc is a
|
||||
command-line interface to it. Time reference sources for
|
||||
chronyd can be RFC1305 NTP servers, human (via keyboard and
|
||||
chronyc), and the computer's real-time clock at boot time
|
||||
(Linux only). chronyd can determine the rate at which the
|
||||
computer gains or loses time and compensate for it whilst no
|
||||
external reference is present. chronyd's use of NTP servers
|
||||
can be switched on and off (through chronyc) to support
|
||||
computers with dial-up/intermittent access to the
|
||||
Internet. chronyd can also act as an RFC1305-compatible NTP
|
||||
server.
|
||||
Keywords: time NTP RFC1305 RTC adjtime
|
||||
Author: rc@rc0.org.uk (Richard Curnow)
|
||||
Maintained-by: rc@rc0.org.uk (Richard Curnow)
|
||||
Primary-site: chrony.tuxfamily.org
|
||||
295k chrony-1.18.tar.gz
|
||||
2k chrony.lsm
|
||||
Platforms: Linux 2.0/2.1/2.2/2.3/2.4 (x86, powerpc)
|
||||
Solaris 2.5/6/7/8, SunOS 4.1.4. (Sparc)
|
||||
BSDI/386.
|
||||
NetBSD
|
||||
Solaris 2.8 (x86)
|
||||
Copying-policy: GPL
|
||||
End
|
||||
114
chrony.texi
114
chrony.texi
@@ -1179,6 +1179,7 @@ directives can occur in any order in the file.
|
||||
* dumpdir directive:: Specify directory for dumping measurements
|
||||
* dumponexit directive:: Dump measurements when daemon exits
|
||||
* fallbackdrift directive:: Specify fallback drift intervals
|
||||
* include directive:: Include a configuration file
|
||||
* initstepslew directive:: Trim the system clock on boot-up.
|
||||
* keyfile directive:: Specify location of file containing keys
|
||||
* linux_hz directive:: Define a non-standard value of the kernel HZ constant
|
||||
@@ -1601,6 +1602,17 @@ By default (or if the specified maximum or minimum is 0), no fallbacks
|
||||
will be used and the clock frequency will stay at the last value
|
||||
calculated before synchronisation was lost.
|
||||
@c }}}
|
||||
@c {{{ include
|
||||
@node include directive
|
||||
@subsection include
|
||||
The @code{include} directive includes a specified configuration file.
|
||||
This is useful when maintaining configuration on multiple hosts to
|
||||
keep the differences in a separate file.
|
||||
|
||||
@example
|
||||
include /etc/chrony/local.conf
|
||||
@end example
|
||||
@c }}}
|
||||
@c {{{ initstepslew
|
||||
@node initstepslew directive
|
||||
@subsection initstepslew
|
||||
@@ -2219,7 +2231,7 @@ The @code{maxclockerror} directive sets the maximum assumed frequency
|
||||
error of the local clock. This is a frequency stability of the clock,
|
||||
not an absolute frequency error.
|
||||
|
||||
By default, the maximum assumed error is set to 10 ppm.
|
||||
By default, the maximum assumed error is set to 1 ppm.
|
||||
|
||||
The syntax is
|
||||
|
||||
@@ -2326,30 +2338,33 @@ udp/11123.
|
||||
@c {{{ refclock
|
||||
@node refclock directive
|
||||
@subsection refclock
|
||||
The @code{refclock} directive allows reference clocks to be specified.
|
||||
The directive is immediately followed by a refclock driver name and
|
||||
its parameter.
|
||||
Reference clocks allows very accurate synchronisation and @code{chronyd}
|
||||
can function as a stratum 1 server. They are specified by the
|
||||
@code{refclock} directive. It has two mandatory parameters, a refclock driver
|
||||
name and a driver specific parameter.
|
||||
|
||||
There are currently three drivers implemented:
|
||||
There are currently three drivers included:
|
||||
|
||||
@table @code
|
||||
@item PPS
|
||||
Pulse per second (PPS) API driver. The parameter is a path to the PPS
|
||||
device. Assert events are used by default. Driver option
|
||||
@code{:clear} can be appended to the path to use clear events instead.
|
||||
PPSAPI (pulse per second) driver. The parameter is the path to a PPS
|
||||
device. Assert events are used by default. Driver option @code{:clear}
|
||||
can be appended to the path if clear events should be used instead.
|
||||
|
||||
PPS refclock needs another source (NTP or non-PPS refclock) or local
|
||||
directive (@pxref{local directive}) enabled to function. For example:
|
||||
As PPS refclock gets only sub-second time information, it needs another
|
||||
source (NTP or non-PPS refclock) or local directive (@pxref{local
|
||||
directive}) enabled to work. For example:
|
||||
|
||||
@example
|
||||
refclock SHM 0 offset 0.5 delay 0.1
|
||||
refclock PPS /dev/pps0
|
||||
refclock PPS /dev/pps0 lock NMEA
|
||||
refclock SHM 0 offset 0.5 delay 0.1 refid NMEA noselect
|
||||
@end example
|
||||
|
||||
@item SHM
|
||||
NTP shared memory driver. The parameter is the number of the
|
||||
shared memory segment that should be used for receiving timestamps, usually
|
||||
0, 1, 2 or 3. For example:
|
||||
NTP shared memory driver. This driver uses a shared memory segment to
|
||||
receive data from another daemon which communicates with an actual
|
||||
reference clock. The parameter is the number of a shared memory segment,
|
||||
usually 0, 1, 2 or 3. For example:
|
||||
|
||||
@example
|
||||
refclock SHM 1 poll 3 refid GPS1
|
||||
@@ -2359,15 +2374,25 @@ A driver option in form @code{:perm=NNN} can be appended to the
|
||||
segment number to create the segment with permissions other than the
|
||||
default @code{0600}.
|
||||
|
||||
Software that can be used as a source of reference time includes
|
||||
@code{gpsd} and @code{shmpps}.
|
||||
Some examples of applications that can be used as SHM sources are @code{gpsd},
|
||||
@code{shmpps} and @code{radioclk}.
|
||||
@item SOCK
|
||||
Unix domain socket driver. The parameter is a path to the socket
|
||||
which is used as the source of timestamps. This is as a better
|
||||
alternative to SHM, it does not require polling, the offset
|
||||
resolution is not limited to microsecond and it supports PPS.
|
||||
The format for messages sent over the socket is declared in file
|
||||
@code{refclock_sock.c}.
|
||||
Unix domain socket driver. It is similar to the SHM driver, but uses a
|
||||
different format and uses a socket instead of shared memory. It does not
|
||||
require polling, the offset resolution is not limited to microseconds and it
|
||||
supports transmitting of PPS data. The parameter is a path to the socket which
|
||||
will be created by @code{chronyd} and used to receive the messages. The format
|
||||
of messages sent over the socket is described in the
|
||||
@code{refclock_sock.c} file.
|
||||
|
||||
Recent versions of the @code{gpsd} daemon include support for the SOCK
|
||||
protocol. The path where the socket should be created is described in the
|
||||
@code{gpsd(8)} man page. For example:
|
||||
|
||||
@example
|
||||
refclock SOCK /tmp/chrony.tty0.sock
|
||||
@end example
|
||||
|
||||
@end table
|
||||
|
||||
The @code{refclock} command also supports a number of subfields (which
|
||||
@@ -2379,7 +2404,8 @@ Timestamps produced by refclock drivers are not used immediately, but
|
||||
they are stored and processed by a median filter in intervals
|
||||
specified by this option. This is defined as a power of 2. The
|
||||
default is 4 (16 seconds). A shorter interval allows @code{chronyd}
|
||||
to react faster to frequency changes, but it may increase noise.
|
||||
to react faster to changes in clock frequency, but it may decrease
|
||||
the accuracy if the source is too noisy.
|
||||
@item dpoll
|
||||
Some drivers are not controlled by external events and thus require
|
||||
polling. Again this is defined as a power of 2 and can be negative
|
||||
@@ -2388,7 +2414,7 @@ for sub-second intervals. The default is 0 (1 second).
|
||||
This option is used to specify a reference id of the refclock, as up
|
||||
to four ASCII characters. By default, first three characters from
|
||||
driver name and the number of the refclock are used as refid. Each
|
||||
refclock has to use an unique refid.
|
||||
refclock must have an unique refid.
|
||||
@item filter
|
||||
This option sets the length of the median filter which is used to
|
||||
reduce noise. With each poll about 40 percent of the stored samples is
|
||||
@@ -2423,7 +2449,8 @@ for SHM refclock, and 1e-9 (1 nanosecond) for SOCK and PPS refclocks.
|
||||
@item prefer
|
||||
Prefer this source over sources without prefer option.
|
||||
@item noselect
|
||||
Never select this source. This is particularly useful for monitoring.
|
||||
Never select this source. This is useful for monitoring or with sources
|
||||
which are not very accurate, but are locked with a PPS refclock.
|
||||
@end table
|
||||
|
||||
@c }}}
|
||||
@@ -2871,6 +2898,7 @@ password:
|
||||
@item @code{sources}
|
||||
@item @code{sourcestats}
|
||||
@item @code{tracking}
|
||||
@item @code{waitsync}
|
||||
@end itemize
|
||||
|
||||
All other commands require a password to have been specified previously,
|
||||
@@ -2922,6 +2950,7 @@ interface.
|
||||
* polltarget command:: Set poll target for a source
|
||||
* quit command:: Exit from chronyc
|
||||
* reselect command:: Reselect synchronisation source
|
||||
* reselectdist command:: Set improvement in distance needed to reselect a source
|
||||
* retries command:: Set maximum number of retries
|
||||
* rtcdata command:: Display RTC parameters
|
||||
* settime command:: Provide a manual input of the current time
|
||||
@@ -2930,6 +2959,7 @@ interface.
|
||||
* timeout command:: Set initial response timeout
|
||||
* tracking command:: Display system clock performance
|
||||
* trimrtc command:: Correct the RTC time to the current system time
|
||||
* waitsync command:: Wait until synchronised
|
||||
* writertc command:: Write the RTC parameters to file.
|
||||
@end menu
|
||||
@c }}}
|
||||
@@ -3744,6 +3774,13 @@ available sources.
|
||||
The @code{reselect} command can be used to force @code{chronyd} to
|
||||
reselect the best synchronisation source.
|
||||
@c }}}
|
||||
@c {{{ reselectdist command
|
||||
@node reselectdist command
|
||||
@subsubsection reselectdist
|
||||
The @code{reselectdist} command sets the reselect distance. It is equivalent
|
||||
to the @code{reselectdist} directive in the configuration file
|
||||
(@pxref{reselectdist directive}).
|
||||
@c }}}
|
||||
@c {{{ retries
|
||||
@node retries command
|
||||
@subsubsection retries
|
||||
@@ -4153,6 +4190,31 @@ across machine reboots even if the @code{trimrtc} command is never used
|
||||
corrected, in a manner compatible with @code{chronyd} using it to
|
||||
maintain accurate time across machine reboots.
|
||||
@c }}}
|
||||
@c {{{ waitsync
|
||||
@node waitsync command
|
||||
@subsubsection waitsync
|
||||
The @code{waitsync} command waits for @code{chronyd} to synchronise.
|
||||
|
||||
Up to three optional arguments can be specified, the first is the maximum
|
||||
number of tries in 10 second intervals before giving up and returning a
|
||||
non-zero error code. When 0 is specified, or there are no arguments, the
|
||||
number of tries will not be limited.
|
||||
|
||||
The second and third arguments are the maximum allowed remaining correction of
|
||||
the system clock and the maximum allowed skew (in ppm) as reported by the
|
||||
@code{tracking} command (@pxref{tracking command}) in the @code{System time}
|
||||
and @code{Skew} fields. If not specified or zero, the value will not be
|
||||
checked.
|
||||
|
||||
An example is
|
||||
|
||||
@example
|
||||
waitsync 60 0.01
|
||||
@end example
|
||||
|
||||
which will wait up to about 10 minutes for @code{chronyd} to synchronise to a
|
||||
source and the remaining correction to be less than 10 milliseconds.
|
||||
@c }}}
|
||||
@c {{{ writertc
|
||||
@node writertc command
|
||||
@subsubsection writertc
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.TH CHRONYC 1 "December 04, 2009" chrony "User's Manual"
|
||||
.TH CHRONYC 1 "@MAN_DATE@" "chrony @VERSION@" "User's Manual"
|
||||
.SH NAME
|
||||
chronyc \- command-line interface for chronyd
|
||||
|
||||
@@ -46,10 +46,6 @@ will be interpreted as a whole command.
|
||||
specify command. If no command is given, chronyc will read commands
|
||||
interactively.
|
||||
|
||||
|
||||
.SH VERSION
|
||||
1.24
|
||||
|
||||
.SH BUGS
|
||||
To report bugs, please visit \fIhttp://chrony.tuxfamily.org\fR
|
||||
|
||||
@@ -67,4 +63,3 @@ Man Pages Project". Please see \fIhttp://www.netmeister.org/misc/m2p2/index.htm
|
||||
for details.
|
||||
|
||||
The complete chrony documentation is supplied in texinfo format.
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.TH CHRONYD 8 "December 04, 2009" chrony "System Administration"
|
||||
.TH CHRONYD 8 "@MAN_DATE@" "chrony @VERSION@" "System Administration"
|
||||
.SH NAME
|
||||
chronyd \- chrony background daemon
|
||||
|
||||
@@ -108,9 +108,6 @@ Resolve hostnames only to IPv6 addresses.
|
||||
.SH FILES
|
||||
\fI/etc/chrony.conf\fR
|
||||
|
||||
.SH VERSION
|
||||
Version 1.24
|
||||
|
||||
.SH BUGS
|
||||
To report bugs, please visit \fIhttp://chrony.tuxfamily.org/\fR
|
||||
|
||||
|
||||
103
client.c
103
client.c
@@ -26,12 +26,13 @@
|
||||
from it whilst running.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "sysincl.h"
|
||||
|
||||
#include "candm.h"
|
||||
#include "nameserv.h"
|
||||
#include "md5.h"
|
||||
#include "version.h"
|
||||
#include "getdate.h"
|
||||
#include "cmdparse.h"
|
||||
#include "pktlength.h"
|
||||
@@ -1081,12 +1082,11 @@ process_cmd_delete(CMD_Request *msg, char *line)
|
||||
fprintf(stderr, "Could not get address for hostname\n");
|
||||
ok = 0;
|
||||
} else {
|
||||
UTI_IPHostToNetwork(&address, &msg->data.del_source.ip_addr);
|
||||
ok = 1;
|
||||
}
|
||||
}
|
||||
|
||||
UTI_IPHostToNetwork(&address, &msg->data.del_source.ip_addr);
|
||||
|
||||
return ok;
|
||||
|
||||
}
|
||||
@@ -1234,6 +1234,7 @@ give_help(void)
|
||||
printf("sourcestats [-v] : Display estimation information about current sources\n");
|
||||
printf("tracking : Display system time information\n");
|
||||
printf("trimrtc : Correct RTC relative to system clock\n");
|
||||
printf("waitsync [max-tries [max-correction [max-skew]]] : Wait until synchronised\n");
|
||||
printf("writertc : Save RTC parameters to file\n");
|
||||
printf("\n");
|
||||
printf("dns -n|+n : Disable/enable resolving IP addresses to hostnames\n");
|
||||
@@ -1787,8 +1788,8 @@ process_cmd_sourcestats(char *line)
|
||||
|
||||
char hostname_buf[50];
|
||||
unsigned long n_samples, n_runs, span_seconds;
|
||||
double resid_freq_ppm, skew_ppm, sd, est_offset, est_offset_err;
|
||||
unsigned long ref_id;
|
||||
double resid_freq_ppm, skew_ppm, sd, est_offset;
|
||||
uint32_t ref_id;
|
||||
IPAddr ip_addr;
|
||||
|
||||
verbose = check_for_verbose_flag(line);
|
||||
@@ -1827,7 +1828,7 @@ process_cmd_sourcestats(char *line)
|
||||
skew_ppm = UTI_FloatNetworkToHost(reply.data.sourcestats.skew_ppm);
|
||||
sd = UTI_FloatNetworkToHost(reply.data.sourcestats.sd);
|
||||
est_offset = UTI_FloatNetworkToHost(reply.data.sourcestats.est_offset);
|
||||
est_offset_err = UTI_FloatNetworkToHost(reply.data.sourcestats.est_offset_err);
|
||||
/* est_offset_err = UTI_FloatNetworkToHost(reply.data.sourcestats.est_offset_err); */
|
||||
|
||||
if (ip_addr.family == IPADDR_UNSPEC)
|
||||
snprintf(hostname_buf, sizeof(hostname_buf), "%s", UTI_RefidToString(ref_id));
|
||||
@@ -1867,7 +1868,7 @@ process_cmd_tracking(char *line)
|
||||
CMD_Request request;
|
||||
CMD_Reply reply;
|
||||
IPAddr ip_addr;
|
||||
unsigned long ref_id;
|
||||
uint32_t ref_id;
|
||||
char host[50];
|
||||
char *ref_ip;
|
||||
struct timeval ref_time;
|
||||
@@ -2377,6 +2378,23 @@ process_cmd_activity(const char *line)
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
static int
|
||||
process_cmd_reselectdist(CMD_Request *msg, char *line)
|
||||
{
|
||||
double dist;
|
||||
int ok;
|
||||
msg->command = htons(REQ_RESELECTDISTANCE);
|
||||
if (sscanf(line, "%lf", &dist) == 1) {
|
||||
msg->data.reselect_distance.distance = UTI_FloatHostToNetwork(dist);
|
||||
ok = 1;
|
||||
} else {
|
||||
ok = 0;
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
static void
|
||||
process_cmd_reselect(CMD_Request *msg, char *line)
|
||||
{
|
||||
@@ -2385,6 +2403,56 @@ process_cmd_reselect(CMD_Request *msg, char *line)
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
static int
|
||||
process_cmd_waitsync(char *line)
|
||||
{
|
||||
CMD_Request request;
|
||||
CMD_Reply reply;
|
||||
uint32_t ref_id, a, b, c, d;
|
||||
double correction, skew_ppm, max_correction, max_skew_ppm;
|
||||
int ret = 0, max_tries, i;
|
||||
|
||||
max_tries = 0;
|
||||
max_correction = 0.0;
|
||||
max_skew_ppm = 0.0;
|
||||
|
||||
sscanf(line, "%d %lf %lf", &max_tries, &max_correction, &max_skew_ppm);
|
||||
|
||||
request.command = htons(REQ_TRACKING);
|
||||
|
||||
for (i = 1; ; i++) {
|
||||
if (request_reply(&request, &reply, RPY_TRACKING, 0)) {
|
||||
ref_id = ntohl(reply.data.tracking.ref_id);
|
||||
a = (ref_id >> 24);
|
||||
b = (ref_id >> 16) & 0xff;
|
||||
c = (ref_id >> 8) & 0xff;
|
||||
d = (ref_id) & 0xff;
|
||||
|
||||
correction = UTI_FloatNetworkToHost(reply.data.tracking.current_correction);
|
||||
correction = fabs(correction);
|
||||
skew_ppm = UTI_FloatNetworkToHost(reply.data.tracking.skew_ppm);
|
||||
|
||||
printf("try: %d, refid: %d.%d.%d.%d, correction: %.9f, skew: %.3f\n",
|
||||
i, a, b, c, d, correction, skew_ppm);
|
||||
|
||||
if (ref_id != 0 && ref_id != 0x7f7f0101L /* LOCAL refid */ &&
|
||||
(max_correction == 0.0 || correction <= max_correction) &&
|
||||
(max_skew_ppm == 0.0 || skew_ppm <= max_skew_ppm)) {
|
||||
ret = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (!ret && (!max_tries || i < max_tries)) {
|
||||
sleep(10);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
static int
|
||||
process_cmd_dns(const char *line)
|
||||
{
|
||||
@@ -2558,8 +2626,13 @@ process_line(char *line, int *quit)
|
||||
} else if (!strncmp(p, "activity", 8)) {
|
||||
ret = process_cmd_activity(p+8);
|
||||
do_normal_submit = 0;
|
||||
} else if (!strncmp(p, "reselectdist", 12)) {
|
||||
do_normal_submit = process_cmd_reselectdist(&tx_message, p+12);
|
||||
} else if (!strncmp(p, "reselect", 8)) {
|
||||
process_cmd_reselect(&tx_message, p+8);
|
||||
} else if (!strncmp(p, "waitsync", 8)) {
|
||||
ret = process_cmd_waitsync(p+8);
|
||||
do_normal_submit = 0;
|
||||
} else if (!strncmp(p, "dns ", 4)) {
|
||||
ret = process_cmd_dns(p+4);
|
||||
do_normal_submit = 0;
|
||||
@@ -2621,8 +2694,6 @@ process_args(int argc, char **argv, int multi)
|
||||
}
|
||||
}
|
||||
|
||||
strcat(line, "\n");
|
||||
|
||||
ret = process_line(line, &quit);
|
||||
if (!ret)
|
||||
break;
|
||||
@@ -2638,12 +2709,12 @@ process_args(int argc, char **argv, int multi)
|
||||
static void
|
||||
display_gpl(void)
|
||||
{
|
||||
printf("chrony version %s, copyright (C) 1997-2002 Richard P. Curnow\n"
|
||||
"chrony comes with ABSOLUTELY NO WARRANTY.\n"
|
||||
"This is free software, and you are welcome to redistribute it\n"
|
||||
"under certain conditions.\n"
|
||||
"See the GNU General Public License version 2 for details.\n\n",
|
||||
PROGRAM_VERSION_STRING);
|
||||
printf("chrony version %s\n"
|
||||
"Copyright (C) 1997-2003, 2007, 2009-2011 Richard P. Curnow and others\n"
|
||||
"chrony comes with ABSOLUTELY NO WARRANTY. This is free software, and\n"
|
||||
"you are welcome to redistribute it under certain conditions. See the\n"
|
||||
"GNU General Public License version 2 for details.\n\n",
|
||||
CHRONY_VERSION);
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
@@ -2680,7 +2751,7 @@ main(int argc, char **argv)
|
||||
DNS_SetAddressFamily(IPADDR_INET6);
|
||||
hostname = "::1";
|
||||
} else if (!strcmp("-v", *argv) || !strcmp("--version",*argv)) {
|
||||
printf("chronyc (chrony) version %s\n", PROGRAM_VERSION_STRING);
|
||||
printf("chronyc (chrony) version %s\n", CHRONY_VERSION);
|
||||
exit(0);
|
||||
} else if (!strncmp(*argv, "-", 1)) {
|
||||
fprintf(stderr, "Usage : %s [-h <hostname>] [-p <port-number>] [-n] [-4|-6] [-m] [command]\n", progname);
|
||||
|
||||
@@ -31,6 +31,8 @@
|
||||
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "sysincl.h"
|
||||
#include "clientlog.h"
|
||||
#include "conf.h"
|
||||
|
||||
23
cmdmon.c
23
cmdmon.c
@@ -25,6 +25,8 @@
|
||||
Command and monitoring module in the main program
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "sysincl.h"
|
||||
|
||||
#include "cmdmon.h"
|
||||
@@ -158,7 +160,8 @@ static int permissions[] = {
|
||||
PERMIT_AUTH, /* MODIFY_MINSTRATUM */
|
||||
PERMIT_AUTH, /* MODIFY_POLLTARGET */
|
||||
PERMIT_AUTH, /* MODIFY_MAXDELAYDEVRATIO */
|
||||
PERMIT_AUTH /* RESELECT */
|
||||
PERMIT_AUTH, /* RESELECT */
|
||||
PERMIT_AUTH /* RESELECTDISTANCE */
|
||||
};
|
||||
|
||||
/* ================================================== */
|
||||
@@ -1711,6 +1714,18 @@ handle_activity(CMD_Request *rx_message, CMD_Reply *tx_message)
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
static void
|
||||
handle_reselect_distance(CMD_Request *rx_message, CMD_Reply *tx_message)
|
||||
{
|
||||
double dist;
|
||||
dist = UTI_FloatNetworkToHost(rx_message->data.reselect_distance.distance);
|
||||
SRC_SetReselectDistance(dist);
|
||||
tx_message->status = htons(STT_SUCCESS);
|
||||
return;
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
static void
|
||||
handle_reselect(CMD_Request *rx_message, CMD_Reply *tx_message)
|
||||
{
|
||||
@@ -2258,6 +2273,10 @@ read_from_cmd_socket(void *anything)
|
||||
handle_activity(&rx_message, &tx_message);
|
||||
break;
|
||||
|
||||
case REQ_RESELECTDISTANCE:
|
||||
handle_reselect_distance(&rx_message, &tx_message);
|
||||
break;
|
||||
|
||||
case REQ_RESELECT:
|
||||
handle_reselect(&rx_message, &tx_message);
|
||||
break;
|
||||
@@ -2271,7 +2290,7 @@ read_from_cmd_socket(void *anything)
|
||||
break;
|
||||
|
||||
default:
|
||||
/* Ignore message */
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -26,6 +26,8 @@
|
||||
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "sysincl.h"
|
||||
|
||||
#include "cmdparse.h"
|
||||
|
||||
42
conf.c
42
conf.c
@@ -36,6 +36,8 @@
|
||||
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "sysincl.h"
|
||||
|
||||
#include "conf.h"
|
||||
@@ -107,6 +109,7 @@ static void parse_linux_freq_scale(const char *);
|
||||
static void parse_sched_priority(const char *);
|
||||
static void parse_lockall(const char *);
|
||||
static void parse_tempcomp(const char *);
|
||||
static void parse_include(const char *);
|
||||
|
||||
/* ================================================== */
|
||||
/* Configuration variables */
|
||||
@@ -119,7 +122,7 @@ static char *drift_file = NULL;
|
||||
static char *rtc_file = NULL;
|
||||
static unsigned long command_key_id;
|
||||
static double max_update_skew = 1000.0;
|
||||
static double max_clock_error = 10; /* in ppm */
|
||||
static double max_clock_error = 1.0; /* in ppm */
|
||||
|
||||
static double reselect_distance = 1e-4;
|
||||
static double stratum_weight = 1.0;
|
||||
@@ -261,6 +264,7 @@ static const Command commands[] = {
|
||||
{"tempcomp", 8, parse_tempcomp},
|
||||
{"reselectdist", 12, parse_reselectdist},
|
||||
{"stratumweight", 13, parse_stratumweight},
|
||||
{"include", 7, parse_include},
|
||||
{"linux_hz", 8, parse_linux_hz},
|
||||
{"linux_freq_scale", 16, parse_linux_freq_scale},
|
||||
{"sched_priority", 14, parse_sched_priority},
|
||||
@@ -313,6 +317,7 @@ CNF_ReadFile(const char *filename)
|
||||
char line[2048];
|
||||
char *p;
|
||||
int i, ok;
|
||||
int prev_line_number;
|
||||
|
||||
if (filename == NULL) {
|
||||
filename = DEFAULT_CONF_FILE;
|
||||
@@ -323,6 +328,9 @@ CNF_ReadFile(const char *filename)
|
||||
LOG(LOGS_ERR, LOGF_Configure, "Could not open configuration file [%s]", filename);
|
||||
} else {
|
||||
|
||||
/* Save current line number in case this is an included file */
|
||||
prev_line_number = line_number;
|
||||
|
||||
line_number = 0;
|
||||
|
||||
/* Success */
|
||||
@@ -357,6 +365,8 @@ CNF_ReadFile(const char *filename)
|
||||
|
||||
}
|
||||
|
||||
line_number = prev_line_number;
|
||||
|
||||
fclose(in);
|
||||
}
|
||||
|
||||
@@ -458,10 +468,10 @@ static void
|
||||
parse_refclock(const char *line)
|
||||
{
|
||||
int i, n, poll, dpoll, filter_length, pps_rate;
|
||||
unsigned long ref_id, lock_ref_id;
|
||||
uint32_t ref_id, lock_ref_id;
|
||||
double offset, delay, precision;
|
||||
const char *tmp;
|
||||
char name[5], cmd[10 + 1], *param;
|
||||
char cmd[10 + 1], *name, *param;
|
||||
unsigned char ref[5];
|
||||
SRC_SelectOption sel_option;
|
||||
|
||||
@@ -480,11 +490,20 @@ parse_refclock(const char *line)
|
||||
lock_ref_id = 0;
|
||||
sel_option = SRC_SelectNormal;
|
||||
|
||||
if (sscanf(line, "%4s%n", name, &n) != 1) {
|
||||
while (isspace(line[0]))
|
||||
line++;
|
||||
tmp = line;
|
||||
while (line[0] != '\0' && !isspace(line[0]))
|
||||
line++;
|
||||
|
||||
if (line == tmp) {
|
||||
LOG(LOGS_WARN, LOGF_Configure, "Could not read refclock driver name at line %d", line_number);
|
||||
return;
|
||||
}
|
||||
line += n;
|
||||
|
||||
name = MallocArray(char, 1 + line - tmp);
|
||||
strncpy(name, tmp, line - tmp);
|
||||
name[line - tmp] = '\0';
|
||||
|
||||
while (isspace(line[0]))
|
||||
line++;
|
||||
@@ -494,6 +513,7 @@ parse_refclock(const char *line)
|
||||
|
||||
if (line == tmp) {
|
||||
LOG(LOGS_WARN, LOGF_Configure, "Could not read refclock parameter at line %d", line_number);
|
||||
Free(name);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -548,7 +568,7 @@ parse_refclock(const char *line)
|
||||
line += n;
|
||||
}
|
||||
|
||||
strncpy(refclock_sources[i].driver_name, name, 4);
|
||||
refclock_sources[i].driver_name = name;
|
||||
refclock_sources[i].driver_parameter = param;
|
||||
refclock_sources[i].driver_poll = dpoll;
|
||||
refclock_sources[i].poll = poll;
|
||||
@@ -1218,6 +1238,16 @@ parse_tempcomp(const char *line)
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
static void
|
||||
parse_include(const char *line)
|
||||
{
|
||||
while (isspace(line[0]))
|
||||
line++;
|
||||
CNF_ReadFile(line);
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
static void
|
||||
parse_linux_hz(const char *line)
|
||||
{
|
||||
|
||||
111
configure
vendored
111
configure
vendored
@@ -4,9 +4,12 @@
|
||||
# chronyd/chronyc - Programs for keeping computer clocks accurate.
|
||||
#
|
||||
# Copyright (C) Richard P. Curnow 1997-2003
|
||||
# Copyright (C) Miroslav Lichvar 2009
|
||||
#
|
||||
# =======================================================================
|
||||
|
||||
rm -f config.h
|
||||
|
||||
# This configure script determines the operating system type and version
|
||||
|
||||
if [ "x${CC}" = "x" ]; then
|
||||
@@ -24,9 +27,7 @@ fi
|
||||
MYCPPFLAGS="${CPPFLAGS}"
|
||||
|
||||
if [ "x${MYCC}" = "xgcc" ]; then
|
||||
CCWARNFLAGS="-Wmissing-prototypes -Wall"
|
||||
else
|
||||
CCWARNFLAGS=""
|
||||
MYCFLAGS="${MYCFLAGS} -Wmissing-prototypes -Wall"
|
||||
fi
|
||||
|
||||
MYLDFLAGS="${LDFLAGS}"
|
||||
@@ -68,7 +69,7 @@ test_code () {
|
||||
#}}}
|
||||
#{{{ usage
|
||||
usage () {
|
||||
cat <<EOF;
|
||||
cat <<EOF
|
||||
\`configure' configures tdl to adapt to many kinds of systems.
|
||||
|
||||
Usage: ./configure [OPTION]...
|
||||
@@ -101,6 +102,8 @@ For better control, use the options below.
|
||||
--disable-pps Disable PPS API support
|
||||
--disable-rtc Don't include RTC even on Linux
|
||||
--disable-linuxcaps Disable Linux capabilities support
|
||||
--disable-forcednsretry Don't retry on permanent DNS error
|
||||
--with-sendmail=PATH Path to sendmail binary [/usr/lib/sendmail]
|
||||
|
||||
Fine tuning of the installation directories:
|
||||
--sysconfdir=DIR chrony.conf location [/etc]
|
||||
@@ -131,6 +134,15 @@ EOF
|
||||
|
||||
}
|
||||
#}}}
|
||||
#{{{
|
||||
add_def () {
|
||||
if [ "x$2" = "x" ]; then
|
||||
echo "#define $1 1" >> config.h
|
||||
else
|
||||
echo "#define $1 $2" >> config.h
|
||||
fi
|
||||
}
|
||||
#}}}
|
||||
|
||||
# ======================================================================
|
||||
|
||||
@@ -151,6 +163,7 @@ feat_readline=1
|
||||
try_readline=1
|
||||
try_editline=1
|
||||
feat_rtc=1
|
||||
try_rtc=0
|
||||
feat_linuxcaps=1
|
||||
try_linuxcaps=0
|
||||
readline_lib=""
|
||||
@@ -160,12 +173,14 @@ feat_ipv6=1
|
||||
feat_pps=1
|
||||
try_setsched=0
|
||||
try_lockmem=0
|
||||
feat_forcednsretry=1
|
||||
mail_program="/usr/lib/sendmail"
|
||||
|
||||
for option
|
||||
do
|
||||
case "$option" in
|
||||
--trace )
|
||||
EXTRA_DEFS="-DTRACEON"
|
||||
add_def TRACEON
|
||||
;;
|
||||
--disable-readline )
|
||||
feat_readline=0
|
||||
@@ -224,6 +239,12 @@ do
|
||||
--disable-linuxcaps)
|
||||
feat_linuxcaps=0
|
||||
;;
|
||||
--disable-forcednsretry)
|
||||
feat_forcednsretry=0
|
||||
;;
|
||||
--with-sendmail=* )
|
||||
mail_program=`echo $option | sed -e 's/^.*=//;'`
|
||||
;;
|
||||
--host-system=* )
|
||||
OPERATINGSYSTEM=`echo $option | sed -e 's/^.*=//;'`
|
||||
;;
|
||||
@@ -250,17 +271,17 @@ case $SYSTEM in
|
||||
4.* )
|
||||
EXTRA_OBJECTS="sys_sunos.o strerror.o"
|
||||
EXTRA_LIBS="-lkvm"
|
||||
SYSDEFS="-DSUNOS"
|
||||
add_def SUNOS
|
||||
echo "Configuring for SunOS (" $SYSTEM "version" $VERSION ")"
|
||||
;;
|
||||
5.* )
|
||||
EXTRA_OBJECTS="sys_solaris.o"
|
||||
EXTRA_LIBS="-lsocket -lnsl -lkvm -lelf"
|
||||
EXTRA_CLI_LIBS="-lsocket -lnsl"
|
||||
SYSDEFS="-DSOLARIS"
|
||||
add_def SOLARIS
|
||||
echo "Configuring for Solaris (" $SYSTEM "SunOS version" $VERSION ")"
|
||||
if [ $VERSION = "5.3" ]; then
|
||||
SYSDEFS="$SYSDEFS -DHAS_NO_BZERO"
|
||||
add_def HAS_NO_BZERO
|
||||
echo "Using memset() instead of bzero()"
|
||||
fi
|
||||
;;
|
||||
@@ -268,19 +289,16 @@ case $SYSTEM in
|
||||
;;
|
||||
Linux* )
|
||||
EXTRA_OBJECTS="sys_linux.o wrap_adjtimex.o"
|
||||
if [ $feat_rtc -eq 1 ] ; then
|
||||
EXTRA_OBJECTS="$EXTRA_OBJECTS rtc_linux.o"
|
||||
EXTRA_DEFS="$EXTRA_DEFS -DFEAT_RTC=1"
|
||||
fi
|
||||
try_linuxcaps=1
|
||||
try_rtc=1
|
||||
try_setsched=1
|
||||
try_lockmem=1
|
||||
SYSDEFS="-DLINUX"
|
||||
add_def LINUX
|
||||
echo "Configuring for " $SYSTEM
|
||||
if [ "${MACHINE}" = "alpha" ]; then
|
||||
echo "Enabling -mieee"
|
||||
# FIXME: Should really test for GCC
|
||||
SYSDEFS="$SYSDEFS -mieee -DALPHA"
|
||||
MYCFLAGS="$MYCFLAGS -mieee"
|
||||
fi
|
||||
;;
|
||||
|
||||
@@ -289,7 +307,7 @@ case $SYSTEM in
|
||||
# be supported with the SunOS 4.x driver files.
|
||||
EXTRA_OBJECTS="sys_sunos.o strerror.o"
|
||||
EXTRA_LIBS="-lkvm"
|
||||
SYSDEFS="-DSUNOS"
|
||||
add_def SUNOS
|
||||
echo "Configuring for $SYSTEM (using SunOS driver)"
|
||||
;;
|
||||
NetBSD-* )
|
||||
@@ -304,13 +322,13 @@ case $SYSTEM in
|
||||
EXTRA_OBJECTS="sys_solaris.o"
|
||||
EXTRA_LIBS="-lsocket -lnsl -lkvm -lelf"
|
||||
EXTRA_CLI_LIBS="-lsocket -lnsl"
|
||||
SYSDEFS="-DSOLARIS"
|
||||
add_def SOLARIS
|
||||
echo "Configuring for Solaris (" $SYSTEM "SunOS version" $VERSION ")"
|
||||
;;
|
||||
CYGWIN32_NT-i[3456]86 )
|
||||
EXTRA_OBJECTS="sys_winnt.o"
|
||||
EXTRA_LIBS=""
|
||||
SYSDEFS="-DWINNT"
|
||||
add_def WINNT
|
||||
echo "Configuring for Windows NT (Cygwin32)"
|
||||
;;
|
||||
* )
|
||||
@@ -332,11 +350,11 @@ else
|
||||
fi
|
||||
|
||||
if test_code '<stdint.h>' 'stdint.h' '' '' ''; then
|
||||
SYSDEFS="${SYSDEFS} -DHAS_STDINT_H"
|
||||
add_def HAS_STDINT_H
|
||||
fi
|
||||
|
||||
if test_code '<inttypes.h>' 'inttypes.h' '' '' ''; then
|
||||
SYSDEFS="${SYSDEFS} -DHAS_INTTYPES_H"
|
||||
add_def HAS_INTTYPES_H
|
||||
fi
|
||||
|
||||
if [ $feat_ipv6 = "1" ] && \
|
||||
@@ -346,17 +364,26 @@ if [ $feat_ipv6 = "1" ] && \
|
||||
n.sin6_addr = in6addr_any;
|
||||
return !inet_ntop(AF_INET6, &n.sin6_addr.s6_addr, p, sizeof(p));'
|
||||
then
|
||||
SYSDEFS="${SYSDEFS} -DHAVE_IPV6"
|
||||
add_def HAVE_IPV6
|
||||
if ! test_code 'in6_pktinfo' 'sys/socket.h netinet/in.h' '' '' '
|
||||
return sizeof(struct in6_pktinfo);'
|
||||
then
|
||||
if test_code 'in6_pktinfo with _GNU_SOURCE' 'sys/socket.h netinet/in.h' \
|
||||
'-D_GNU_SOURCE' '' 'return sizeof(struct in6_pktinfo);'
|
||||
then
|
||||
add_def _GNU_SOURCE
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ $feat_pps = "1" ] && \
|
||||
test_code 'PPS API' 'timepps.h' '' '' '
|
||||
test_code 'PPS API' 'string.h timepps.h' '' '' '
|
||||
pps_handle_t h;
|
||||
pps_info_t i;
|
||||
struct timespec ts;
|
||||
return time_pps_fetch(&h, PPS_TSFMT_TSPEC, &i, &ts);'
|
||||
return time_pps_fetch(h, PPS_TSFMT_TSPEC, &i, &ts);'
|
||||
then
|
||||
SYSDEFS="${SYSDEFS} -DHAVE_PPSAPI"
|
||||
add_def HAVE_PPSAPI
|
||||
fi
|
||||
|
||||
if [ $feat_linuxcaps = "1" ] && [ $try_linuxcaps = "1" ] && \
|
||||
@@ -366,10 +393,18 @@ if [ $feat_linuxcaps = "1" ] && [ $try_linuxcaps = "1" ] && \
|
||||
'' '-lcap' \
|
||||
'prctl(PR_SET_KEEPCAPS, 1);cap_set_proc(cap_from_text("cap_sys_time=ep"));'
|
||||
then
|
||||
EXTRA_DEFS="${EXTRA_DEFS} -DFEAT_LINUXCAPS=1"
|
||||
add_def FEAT_LINUXCAPS
|
||||
EXTRA_LIBS="-lcap"
|
||||
fi
|
||||
|
||||
if [ $feat_rtc = "1" ] && [ $try_rtc = "1" ] && \
|
||||
test_code '<linux/rtc.h>' 'sys/ioctl.h linux/rtc.h' '' '' \
|
||||
'ioctl(1, RTC_UIE_ON&RTC_UIE_OFF&RTC_RD_TIME&RTC_SET_TIME, 0&RTC_UF);'
|
||||
then
|
||||
EXTRA_OBJECTS="$EXTRA_OBJECTS rtc_linux.o"
|
||||
add_def FEAT_RTC
|
||||
fi
|
||||
|
||||
if [ $try_setsched = "1" ] && \
|
||||
test_code \
|
||||
'sched_setscheduler()' \
|
||||
@@ -378,7 +413,7 @@ if [ $try_setsched = "1" ] && \
|
||||
sched_get_priority_max(SCHED_FIFO);
|
||||
sched_setscheduler(0, SCHED_FIFO, &sched);'
|
||||
then
|
||||
SYSDEFS="${SYSDEFS} -DHAVE_SCHED_SETSCHEDULER"
|
||||
add_def HAVE_SCHED_SETSCHEDULER
|
||||
fi
|
||||
|
||||
if [ $try_lockmem = "1" ] && \
|
||||
@@ -389,7 +424,12 @@ if [ $try_lockmem = "1" ] && \
|
||||
setrlimit(RLIMIT_MEMLOCK, &rlim);
|
||||
mlockall(MCL_CURRENT|MCL_FUTURE);'
|
||||
then
|
||||
SYSDEFS="${SYSDEFS} -DHAVE_MLOCKALL"
|
||||
add_def HAVE_MLOCKALL
|
||||
fi
|
||||
|
||||
if [ $feat_forcednsretry = "1" ]
|
||||
then
|
||||
add_def FORCE_DNSRETRY
|
||||
fi
|
||||
|
||||
READLINE_COMPILE=""
|
||||
@@ -400,7 +440,9 @@ if [ $feat_readline = "1" ]; then
|
||||
"$readline_inc" "$readline_lib -ledit" \
|
||||
'add_history(readline("prompt"));'
|
||||
then
|
||||
READLINE_COMPILE="-DFEAT_READLINE=1 -DUSE_EDITLINE=1 $readline_inc"
|
||||
add_def FEAT_READLINE
|
||||
add_def USE_EDITLINE
|
||||
READLINE_COMPILE="$readline_inc"
|
||||
READLINE_LINK="$readline_lib -ledit"
|
||||
fi
|
||||
fi
|
||||
@@ -410,7 +452,8 @@ if [ $feat_readline = "1" ]; then
|
||||
"$readline_inc" "$readline_lib $ncurses_lib -lreadline -lncurses" \
|
||||
'add_history(readline("prompt"));'
|
||||
then
|
||||
READLINE_COMPILE="-DFEAT_READLINE=1 $readline_inc"
|
||||
add_def FEAT_READLINE
|
||||
READLINE_COMPILE="$readline_inc"
|
||||
READLINE_LINK="$readline_lib $ncurses_lib -lreadline -lncurses"
|
||||
fi
|
||||
fi
|
||||
@@ -461,16 +504,22 @@ if [ "x$SETDOCDIR" != "x" ]; then
|
||||
DOCDIR=$SETDOCDIR
|
||||
fi
|
||||
|
||||
add_def DEFAULT_CONF_DIR "\"$SYSCONFDIR\""
|
||||
add_def MAIL_PROGRAM "\"$mail_program\""
|
||||
|
||||
if [ -f version.txt ]; then
|
||||
add_def CHRONY_VERSION "\"`cat version.txt`\""
|
||||
else
|
||||
add_def CHRONY_VERSION "\"DEVELOPMENT\""
|
||||
fi
|
||||
|
||||
sed -e "s%@EXTRA_OBJECTS@%${EXTRA_OBJECTS}%;\
|
||||
s%@CC@%${MYCC}%;\
|
||||
s%@CFLAGS@%${MYCFLAGS}%;\
|
||||
s%@CCWARNFLAGS@%${CCWARNFLAGS}%;\
|
||||
s%@CPPFLAGS@%${CPPFLAGS}%;\
|
||||
s%@LIBS@%${LIBS}%;\
|
||||
s%@LDFLAGS@%${MYLDFLAGS}%;\
|
||||
s%@EXTRA_LIBS@%${EXTRA_LIBS}%;\
|
||||
s%@SYSDEFS@%${SYSDEFS}%;\
|
||||
s%@EXTRA_DEFS@%${EXTRA_DEFS}%;\
|
||||
s%@EXTRA_CLI_LIBS@%${EXTRA_CLI_LIBS}%;\
|
||||
s%@READLINE_COMPILE@%${READLINE_COMPILE}%;\
|
||||
s%@READLINE_LINK@%${READLINE_LINK}%;\
|
||||
|
||||
39
examples/chrony.conf.example2
Normal file
39
examples/chrony.conf.example2
Normal file
@@ -0,0 +1,39 @@
|
||||
# Use public servers from the pool.ntp.org project.
|
||||
# Please consider joining the pool (http://www.pool.ntp.org/join.html).
|
||||
server 0.pool.ntp.org iburst
|
||||
server 1.pool.ntp.org iburst
|
||||
server 2.pool.ntp.org iburst
|
||||
server 3.pool.ntp.org iburst
|
||||
|
||||
# Ignore stratum in source selection.
|
||||
stratumweight 0
|
||||
|
||||
# Record the rate at which the system clock gains/losses time.
|
||||
driftfile /var/lib/chrony/drift
|
||||
|
||||
# Enable kernel RTC synchronization.
|
||||
rtcsync
|
||||
|
||||
# In first three updates step the system clock instead of slew
|
||||
# if the adjustment is larger than 100 seconds.
|
||||
makestep 100 3
|
||||
|
||||
# Allow client access from local network.
|
||||
#allow 192.168/16
|
||||
|
||||
# Serve time even if not synchronized to any NTP server.
|
||||
#local stratum 10
|
||||
|
||||
keyfile /etc/chrony.keys
|
||||
|
||||
# Specify the key used as password for chronyc.
|
||||
commandkey 1
|
||||
|
||||
# Disable logging of client accesses.
|
||||
noclientlog
|
||||
|
||||
# Send a message to syslog if a clock adjustment is larger than 0.5 seconds.
|
||||
logchange 0.5
|
||||
|
||||
logdir /var/log/chrony
|
||||
#log measurements statistics tracking
|
||||
75
io_linux.h
75
io_linux.h
@@ -1,75 +0,0 @@
|
||||
/* Taken from <asm-$foo/ioctl.h> in the Linux kernel sources.
|
||||
* The ioctl.h file is pretty similar from one architecture to another.
|
||||
* */
|
||||
#ifndef IO_LINUX_H
|
||||
#define IO_LINUX_H
|
||||
|
||||
/* Hmm. These constants vary a bit between systems. */
|
||||
/* (__sh__ includes both sh and sh64) */
|
||||
/* (__s390__ includes both s390 and s390x) */
|
||||
#if defined(__i386__) || defined(__sh__) || defined(__arm__) || defined(__x86_64__) || defined(__s390__)
|
||||
#define CHRONY_IOC_NRBITS 8
|
||||
#define CHRONY_IOC_TYPEBITS 8
|
||||
#define CHRONY_IOC_SIZEBITS 14
|
||||
#define CHRONY_IOC_DIRBITS 2
|
||||
|
||||
#define CHRONY_IOC_NONE 0U
|
||||
#define CHRONY_IOC_WRITE 1U
|
||||
#define CHRONY_IOC_READ 2U
|
||||
|
||||
#elif defined(__alpha__) || defined(__sparc__) || defined(__ppc__) || defined(__ppc64__) || defined(__sparc64__)
|
||||
#define CHRONY_IOC_NRBITS 8
|
||||
#define CHRONY_IOC_TYPEBITS 8
|
||||
#define CHRONY_IOC_SIZEBITS 13
|
||||
#define CHRONY_IOC_DIRBITS 2
|
||||
|
||||
#define CHRONY_IOC_NONE 1U
|
||||
#define CHRONY_IOC_READ 2U
|
||||
#define CHRONY_IOC_WRITE 4U
|
||||
|
||||
#elif defined(__mips__) || defined(__mips32__) || defined(__powerpc__)
|
||||
#define CHRONY_IOC_NRBITS 8
|
||||
#define CHRONY_IOC_TYPEBITS 8
|
||||
#define CHRONY_IOC_SIZEBITS 13
|
||||
#define CHRONY_IOC_DIRBITS 3
|
||||
#define CHRONY_IOC_NONE 1U
|
||||
#define CHRONY_IOC_READ 2U
|
||||
#define CHRONY_IOC_WRITE 4U
|
||||
|
||||
#else
|
||||
#error "I don't know the values of the _IOC_* constants for your architecture"
|
||||
#endif
|
||||
|
||||
#define CHRONY_IOC_NRMASK ((1 << CHRONY_IOC_NRBITS)-1)
|
||||
#define CHRONY_IOC_TYPEMASK ((1 << CHRONY_IOC_TYPEBITS)-1)
|
||||
#define CHRONY_IOC_SIZEMASK ((1 << CHRONY_IOC_SIZEBITS)-1)
|
||||
#define CHRONY_IOC_DIRMASK ((1 << CHRONY_IOC_DIRBITS)-1)
|
||||
|
||||
#define CHRONY_IOC_NRSHIFT 0
|
||||
#define CHRONY_IOC_TYPESHIFT (CHRONY_IOC_NRSHIFT+CHRONY_IOC_NRBITS)
|
||||
#define CHRONY_IOC_SIZESHIFT (CHRONY_IOC_TYPESHIFT+CHRONY_IOC_TYPEBITS)
|
||||
#define CHRONY_IOC_DIRSHIFT (CHRONY_IOC_SIZESHIFT+CHRONY_IOC_SIZEBITS)
|
||||
|
||||
#define CHRONY_IOC(dir,type,nr,size) \
|
||||
(((dir) << CHRONY_IOC_DIRSHIFT) | \
|
||||
((type) << CHRONY_IOC_TYPESHIFT) | \
|
||||
((nr) << CHRONY_IOC_NRSHIFT) | \
|
||||
((size) << CHRONY_IOC_SIZESHIFT))
|
||||
|
||||
/* used to create numbers */
|
||||
#define CHRONY_IO(type,nr) CHRONY_IOC(CHRONY_IOC_NONE,(type),(nr),0)
|
||||
#define CHRONY_IOR(type,nr,size) CHRONY_IOC(CHRONY_IOC_READ,(type),(nr),sizeof(size))
|
||||
#define CHRONY_IOW(type,nr,size) CHRONY_IOC(CHRONY_IOC_WRITE,(type),(nr),sizeof(size))
|
||||
#define CHRONY_IOWR(type,nr,size) CHRONY_IOC(CHRONY_IOC_READ|CHRONY_IOC_WRITE,(type),(nr),sizeof(size))
|
||||
|
||||
#define RTC_UIE_ON CHRONY_IO('p', 0x03) /* Update int. enable on */
|
||||
#define RTC_UIE_OFF CHRONY_IO('p', 0x04) /* ... off */
|
||||
|
||||
#define RTC_RD_TIME CHRONY_IOR('p', 0x09, struct rtc_time) /* Read RTC time */
|
||||
#define RTC_SET_TIME CHRONY_IOW('p', 0x0a, struct rtc_time) /* Set RTC time */
|
||||
|
||||
/* From mc146818.h */
|
||||
#define RTC_UIE 0x10 /* update-finished interrupt enable */
|
||||
|
||||
#endif
|
||||
|
||||
2
keys.c
2
keys.c
@@ -25,6 +25,8 @@
|
||||
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
25
local.c
25
local.c
@@ -28,6 +28,8 @@
|
||||
They interface with the system specific driver files in sys_*.c
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stddef.h>
|
||||
|
||||
@@ -103,12 +105,11 @@ static double max_clock_error;
|
||||
static void
|
||||
calculate_sys_precision(void)
|
||||
{
|
||||
struct timeval tv, old_tv, first_tv;
|
||||
struct timeval tv, old_tv;
|
||||
int dusec, best_dusec;
|
||||
int iters;
|
||||
|
||||
gettimeofday(&old_tv, NULL);
|
||||
first_tv = old_tv;
|
||||
best_dusec = 1000000; /* Assume we must be better than a second */
|
||||
iters = 0;
|
||||
do {
|
||||
@@ -357,14 +358,14 @@ LCL_GetOffsetCorrection(struct timeval *raw, double *correction, double *err)
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
/* This is just a simple passthrough of the system specific routine */
|
||||
/* Return current frequency */
|
||||
|
||||
double
|
||||
LCL_ReadAbsoluteFrequency(void)
|
||||
{
|
||||
double freq;
|
||||
|
||||
freq = (*drv_read_freq)();
|
||||
freq = current_freq_ppm;
|
||||
|
||||
/* Undo temperature compensation */
|
||||
if (temp_comp_ppm != 0.0) {
|
||||
@@ -487,6 +488,22 @@ LCL_ApplyStepOffset(double offset)
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
void
|
||||
LCL_NotifyExternalTimeStep(struct timeval *raw, struct timeval *cooked,
|
||||
double offset, double dispersion)
|
||||
{
|
||||
ChangeListEntry *ptr;
|
||||
|
||||
/* Dispatch to all handlers */
|
||||
for (ptr = change_list.next; ptr != &change_list; ptr = ptr->next) {
|
||||
(ptr->handler)(raw, cooked, 0.0, offset, 1, ptr->anything);
|
||||
}
|
||||
|
||||
lcl_InvokeDispersionNotifyHandlers(dispersion);
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
void
|
||||
LCL_AccumulateFrequencyAndOffset(double dfreq, double doffset)
|
||||
{
|
||||
|
||||
5
local.h
5
local.h
@@ -151,6 +151,11 @@ extern void LCL_AccumulateOffset(double offset);
|
||||
|
||||
extern void LCL_ApplyStepOffset(double offset);
|
||||
|
||||
/* Routine to invoke notify handlers on an unexpected time jump
|
||||
in system clock */
|
||||
extern void LCL_NotifyExternalTimeStep(struct timeval *raw, struct timeval *cooked,
|
||||
double offset, double dispersion);
|
||||
|
||||
/* Perform the combination of modifying the frequency and applying
|
||||
a slew, in one easy step */
|
||||
extern void LCL_AccumulateFrequencyAndOffset(double dfreq, double doffset);
|
||||
|
||||
@@ -25,12 +25,13 @@
|
||||
Module to handle logging of diagnostic information
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "sysincl.h"
|
||||
|
||||
#include "main.h"
|
||||
#include "conf.h"
|
||||
#include "logging.h"
|
||||
#include "version.h"
|
||||
#include "mkdirpp.h"
|
||||
#include "util.h"
|
||||
|
||||
@@ -190,7 +191,6 @@ LOG_OpenSystemLog(void)
|
||||
#else
|
||||
system_log = 1;
|
||||
openlog("chronyd", LOG_PID, LOG_DAEMON);
|
||||
LOG(LOGS_INFO, LOGF_Logging, "chronyd version %s starting", PROGRAM_VERSION_STRING);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
14
main.c
14
main.c
@@ -25,6 +25,8 @@
|
||||
The main program
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "sysincl.h"
|
||||
|
||||
#include "main.h"
|
||||
@@ -43,7 +45,6 @@
|
||||
#include "keys.h"
|
||||
#include "acquire.h"
|
||||
#include "manual.h"
|
||||
#include "version.h"
|
||||
#include "rtc.h"
|
||||
#include "refclock.h"
|
||||
#include "clientlog.h"
|
||||
@@ -114,7 +115,6 @@ MAI_CleanupAndExit(void)
|
||||
static void
|
||||
signal_cleanup(int x)
|
||||
{
|
||||
LOG(LOGS_WARN, LOGF_Main, "chronyd exiting on signal");
|
||||
if (!initialised) exit(0);
|
||||
SCH_QuitProgram();
|
||||
}
|
||||
@@ -287,7 +287,7 @@ int main
|
||||
do_init_rtc = 1;
|
||||
} else if (!strcmp("-v", *argv) || !strcmp("--version",*argv)) {
|
||||
/* This write to the terminal is OK, it comes before we turn into a daemon */
|
||||
printf("chronyd (chrony) version %s\n", PROGRAM_VERSION_STRING);
|
||||
printf("chronyd (chrony) version %s\n", CHRONY_VERSION);
|
||||
exit(0);
|
||||
} else if (!strcmp("-n", *argv)) {
|
||||
nofork = 1;
|
||||
@@ -321,6 +321,8 @@ int main
|
||||
LOG_OpenSystemLog();
|
||||
}
|
||||
|
||||
LOG(LOGS_INFO, LOGF_Main, "chronyd version %s starting", CHRONY_VERSION);
|
||||
|
||||
/* Check whether another chronyd may already be running. Do this after
|
||||
* forking, so that message logging goes to the right place (i.e. syslog), in
|
||||
* case this chronyd is being run from a boot script. */
|
||||
@@ -364,6 +366,8 @@ int main
|
||||
SYS_DropRoot(user);
|
||||
}
|
||||
|
||||
LOG_CreateLogFileDir();
|
||||
|
||||
REF_Initialise();
|
||||
SST_Initialise();
|
||||
BRD_Initialise();
|
||||
@@ -375,8 +379,6 @@ int main
|
||||
MNL_Initialise();
|
||||
TMC_Initialise();
|
||||
|
||||
LOG_CreateLogFileDir();
|
||||
|
||||
/* From now on, it is safe to do finalisation on exit */
|
||||
initialised = 1;
|
||||
|
||||
@@ -397,6 +399,8 @@ int main
|
||||
the scheduler. */
|
||||
SCH_MainLoop();
|
||||
|
||||
LOG(LOGS_INFO, LOGF_Main, "chronyd exiting");
|
||||
|
||||
MAI_CleanupAndExit();
|
||||
|
||||
return 0;
|
||||
|
||||
77
make_release
77
make_release
@@ -1,52 +1,51 @@
|
||||
#!/usr/bin/env perl
|
||||
#!/bin/sh
|
||||
|
||||
$tool = "chrony";
|
||||
LANG=C
|
||||
export LANG
|
||||
|
||||
$version = shift || die "Usage : $0 <version>\n";
|
||||
$subdir = "${tool}-${version}";
|
||||
if [ $# -ne 1 ]; then
|
||||
echo "Usage : $0 <version>"
|
||||
exit 2
|
||||
fi
|
||||
|
||||
unless (-d ".git") {
|
||||
die "No .git subdirectory?"
|
||||
}
|
||||
version=$1
|
||||
subdir=chrony-${version}
|
||||
mandate=$(date +'%B %Y')
|
||||
|
||||
unless (-d "RELEASES") {
|
||||
mkdir "RELEASES", 0755;
|
||||
}
|
||||
umask 022
|
||||
|
||||
system ("git tag -s $version");
|
||||
die "git-tag failed" if ($? != 0);
|
||||
if (-d "RELEASES/$subdir") {
|
||||
system ("rm -rf RELEASES/$subdir");
|
||||
}
|
||||
if [ ! -d .git ]; then
|
||||
echo "No .git subdirectory?"
|
||||
exit 3
|
||||
fi
|
||||
|
||||
system ("git archive --format=tar --prefix=RELEASES/${subdir}/ $version | tar xf -");
|
||||
die "git-tar-tree failed" if ($? != 0);
|
||||
[ -d RELEASES ] || mkdir RELEASES
|
||||
|
||||
chdir "RELEASES";
|
||||
$here = qx/pwd/;
|
||||
chomp $here;
|
||||
chdir $subdir;
|
||||
git tag -s $version || exit 1
|
||||
|
||||
open (OUT, ">version.txt");
|
||||
print OUT $version."\n";
|
||||
close OUT;
|
||||
rm -rf RELEASES/$subdir
|
||||
|
||||
open (IN, "<${tool}.spec.sample");
|
||||
open (OUT, ">${tool}.spec");
|
||||
while (<IN>) {
|
||||
s/\@\@VERSION\@\@/$version/;
|
||||
print OUT;
|
||||
}
|
||||
close (IN);
|
||||
close (OUT);
|
||||
git archive --format=tar --prefix=RELEASES/${subdir}/ $version | \
|
||||
tar xf - || exit 1
|
||||
|
||||
system("makeinfo --no-headers --number-sections -o chrony.txt chrony.texi");
|
||||
unlink "make_release";
|
||||
unlink "${tool}.spec.sample";
|
||||
unlink ".gitignore";
|
||||
cd RELEASES/$subdir || exit 1
|
||||
|
||||
chdir $here;
|
||||
system ("tar cvf - $subdir | gzip -9 > ${subdir}.tar.gz");
|
||||
system ("gpg -b -a -o ${subdir}-tar-gz-asc.txt ${subdir}.tar.gz");
|
||||
echo $version > version.txt
|
||||
|
||||
sed -e "s%@@VERSION@@%${version}%" < chrony.spec.sample > chrony.spec
|
||||
|
||||
for m in chrony.1 chronyc.1 chrony.conf.5 chronyd.8; do
|
||||
sed -e "s%@VERSION@%${version}%;s%@MAN_DATE@%${mandate}%" \
|
||||
< $m > ${m}_
|
||||
mv -f ${m}_ $m
|
||||
done
|
||||
|
||||
makeinfo --no-headers --number-sections -o chrony.txt chrony.texi
|
||||
|
||||
rm -f make_release chrony.spec.sample .gitignore
|
||||
|
||||
cd ..
|
||||
tar cvf - $subdir | gzip -9 > ${subdir}.tar.gz
|
||||
gpg -b -a -o ${subdir}-tar-gz-asc.txt ${subdir}.tar.gz
|
||||
|
||||
|
||||
|
||||
4
manual.c
4
manual.c
@@ -30,6 +30,8 @@
|
||||
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "manual.h"
|
||||
@@ -143,6 +145,8 @@ estimate_and_set_system(struct timeval *now, int offset_provided, double offset,
|
||||
}
|
||||
b1 = freq = 0.0;
|
||||
found_freq = 0;
|
||||
agos[0] = 0.0;
|
||||
offsets[0] = b0;
|
||||
}
|
||||
|
||||
if (offset_provided) {
|
||||
|
||||
2
md5.c
2
md5.c
@@ -37,6 +37,8 @@
|
||||
***********************************************************************
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "md5.h"
|
||||
|
||||
/*
|
||||
|
||||
@@ -26,6 +26,8 @@
|
||||
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "sysincl.h"
|
||||
|
||||
#include "mkdirpp.h"
|
||||
|
||||
15
mkversion
15
mkversion
@@ -1,15 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
rm -f version.h
|
||||
echo "#ifndef VERSION_H" > version.h
|
||||
echo "#define VERSION_H 1" >> version.h
|
||||
|
||||
if [ -f version.txt ]; then
|
||||
ver=`cat version.txt`
|
||||
echo "#define PROGRAM_VERSION_STRING \"$ver\"" >> version.h
|
||||
else
|
||||
echo "#define PROGRAM_VERSION_STRING \"DEVELOPMENT\"" >> version.h
|
||||
fi
|
||||
|
||||
echo "#endif /* VERSION_H */" >> version.h
|
||||
|
||||
11
nameserv.c
11
nameserv.c
@@ -26,6 +26,8 @@
|
||||
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "sysincl.h"
|
||||
|
||||
#include "nameserv.h"
|
||||
@@ -56,7 +58,11 @@ DNS_Name2IPAddress(const char *name, IPAddr *addr)
|
||||
result = getaddrinfo(name, NULL, &hints, &res);
|
||||
|
||||
if (result) {
|
||||
#ifdef FORCE_DNSRETRY
|
||||
return DNS_TryAgain;
|
||||
#else
|
||||
return result == EAI_AGAIN ? DNS_TryAgain : DNS_Failure;
|
||||
#endif
|
||||
}
|
||||
|
||||
for (ai = res; !result && ai != NULL; ai = ai->ai_next) {
|
||||
@@ -94,8 +100,13 @@ DNS_Name2IPAddress(const char *name, IPAddr *addr)
|
||||
return DNS_Success;
|
||||
}
|
||||
|
||||
#ifdef FORCE_DNSRETRY
|
||||
return DNS_TryAgain;
|
||||
#else
|
||||
return DNS_Failure;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
34
ntp_core.c
34
ntp_core.c
@@ -25,6 +25,8 @@
|
||||
Core NTP protocol engine
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "sysincl.h"
|
||||
|
||||
#include "ntp_core.h"
|
||||
@@ -190,6 +192,10 @@ struct NCR_Instance_Record {
|
||||
/* The NTP protocol version that we support */
|
||||
#define NTP_VERSION 3
|
||||
|
||||
/* Compatible NTP protocol versions */
|
||||
#define NTP_MAX_COMPAT_VERSION 4
|
||||
#define NTP_MIN_COMPAT_VERSION 2
|
||||
|
||||
/* Maximum allowed dispersion - as defined in RFC1305 (16 seconds) */
|
||||
#define NTP_MAX_DISPERSION 16.0
|
||||
|
||||
@@ -509,11 +515,11 @@ transmit_packet(NTP_Mode my_mode, /* The mode this machine wants to be */
|
||||
/* Parameters read from reference module */
|
||||
int are_we_synchronised, our_stratum;
|
||||
NTP_Leap leap_status;
|
||||
unsigned long our_ref_id;
|
||||
uint32_t our_ref_id;
|
||||
struct timeval our_ref_time;
|
||||
double our_root_delay, our_root_dispersion;
|
||||
|
||||
version = 3;
|
||||
version = NTP_VERSION;
|
||||
|
||||
LCL_ReadCookedTime(&local_transmit, NULL);
|
||||
REF_GetReferenceParams(&local_transmit,
|
||||
@@ -525,7 +531,7 @@ transmit_packet(NTP_Mode my_mode, /* The mode this machine wants to be */
|
||||
if (are_we_synchronised) {
|
||||
leap = (int) leap_status;
|
||||
} else {
|
||||
leap = 3;
|
||||
leap = LEAP_Unsynchronised;
|
||||
}
|
||||
|
||||
/* Generate transmit packet */
|
||||
@@ -1327,7 +1333,7 @@ process_known
|
||||
|
||||
/* Check version */
|
||||
version = (message->lvm >> 3) & 0x7;
|
||||
if (version != NTP_VERSION) {
|
||||
if (version < NTP_MIN_COMPAT_VERSION || version > NTP_MAX_COMPAT_VERSION) {
|
||||
/* Ignore packet, but might want to log it */
|
||||
return;
|
||||
}
|
||||
@@ -1519,7 +1525,14 @@ NCR_ProcessNoauthUnknown(NTP_Packet *message, struct timeval *now, double now_er
|
||||
|
||||
NTP_Mode his_mode;
|
||||
NTP_Mode my_mode;
|
||||
int my_poll;
|
||||
int my_poll, version;
|
||||
|
||||
/* Check version */
|
||||
version = (message->lvm >> 3) & 0x7;
|
||||
if (version < NTP_MIN_COMPAT_VERSION || version > NTP_MAX_COMPAT_VERSION) {
|
||||
/* Ignore packet, but might want to log it */
|
||||
return;
|
||||
}
|
||||
|
||||
if (ADF_IsAllowed(access_auth_table, &remote_addr->ip_addr)) {
|
||||
|
||||
@@ -1587,10 +1600,17 @@ NCR_ProcessAuthUnknown(NTP_Packet *message, struct timeval *now, double now_err,
|
||||
|
||||
NTP_Mode his_mode;
|
||||
NTP_Mode my_mode;
|
||||
int my_poll;
|
||||
int my_poll, version;
|
||||
int valid_key, valid_auth;
|
||||
unsigned long key_id;
|
||||
|
||||
/* Check version */
|
||||
version = (message->lvm >> 3) & 0x7;
|
||||
if (version < NTP_MIN_COMPAT_VERSION || version > NTP_MAX_COMPAT_VERSION) {
|
||||
/* Ignore packet, but might want to log it */
|
||||
return;
|
||||
}
|
||||
|
||||
if (ADF_IsAllowed(access_auth_table, &remote_addr->ip_addr)) {
|
||||
|
||||
his_mode = message->lvm & 0x07;
|
||||
@@ -1661,6 +1681,8 @@ NCR_SlewTimes(NCR_Instance inst, struct timeval *when, double dfreq, double doff
|
||||
#ifdef TRACEON
|
||||
LOG(LOGS_INFO, LOGF_NtpCore, "tx prev=[%s] new=[%s]",
|
||||
UTI_TimevalToString(&prev), UTI_TimevalToString(&inst->local_tx));
|
||||
#else
|
||||
(void)prev;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
42
ntp_io.c
42
ntp_io.c
@@ -26,6 +26,8 @@
|
||||
This file deals with the IO aspects of reading and writing NTP packets
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "sysincl.h"
|
||||
|
||||
#include "ntp_io.h"
|
||||
@@ -157,6 +159,16 @@ prepare_socket(int family)
|
||||
LOG(LOGS_ERR, LOGF_NtpIO, "Could not request IPV6_V6ONLY socket option");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef IPV6_RECVPKTINFO
|
||||
if (setsockopt(sock_fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, (char *)&on_off, sizeof(on_off)) < 0) {
|
||||
LOG(LOGS_ERR, LOGF_NtpIO, "Could not request IPv6 packet info socket option");
|
||||
}
|
||||
#elif defined(IPV6_PKTINFO)
|
||||
if (setsockopt(sock_fd, IPPROTO_IPV6, IPV6_PKTINFO, (char *)&on_off, sizeof(on_off)) < 0) {
|
||||
LOG(LOGS_ERR, LOGF_NtpIO, "Could not request IPv6 packet info socket option");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -343,6 +355,17 @@ read_from_socket(void *anything)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef IPV6_PKTINFO
|
||||
if (cmsg->cmsg_level == IPPROTO_IPV6 && cmsg->cmsg_type == IPV6_PKTINFO) {
|
||||
struct in6_pktinfo ipi;
|
||||
|
||||
memcpy(&ipi, CMSG_DATA(cmsg), sizeof(ipi));
|
||||
memcpy(&remote_addr.local_ip_addr.addr.in6, &ipi.ipi6_addr.s6_addr,
|
||||
sizeof (remote_addr.local_ip_addr.addr.in6));
|
||||
remote_addr.local_ip_addr.family = IPADDR_INET6;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SO_TIMESTAMP
|
||||
if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SO_TIMESTAMP) {
|
||||
struct timeval tv;
|
||||
@@ -443,6 +466,25 @@ send_packet(void *packet, int packetlen, NTP_Remote_Address *remote_addr)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef IPV6_PKTINFO
|
||||
if (remote_addr->local_ip_addr.family == IPADDR_INET6) {
|
||||
struct cmsghdr *cmsg;
|
||||
struct in6_pktinfo *ipi;
|
||||
|
||||
cmsg = CMSG_FIRSTHDR(&msg);
|
||||
memset(cmsg, 0, CMSG_SPACE(sizeof(struct in6_pktinfo)));
|
||||
cmsglen += CMSG_SPACE(sizeof(struct in6_pktinfo));
|
||||
|
||||
cmsg->cmsg_level = IPPROTO_IPV6;
|
||||
cmsg->cmsg_type = IPV6_PKTINFO;
|
||||
cmsg->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo));
|
||||
|
||||
ipi = (struct in6_pktinfo *) CMSG_DATA(cmsg);
|
||||
memcpy(&ipi->ipi6_addr.s6_addr, &remote_addr->local_ip_addr.addr.in6,
|
||||
sizeof(ipi->ipi6_addr.s6_addr));
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
LOG(LOGS_INFO, LOGF_NtpIO, "sending to %s:%d from %s",
|
||||
UTI_IPToString(&remote_addr->ip_addr), remote_addr->port, UTI_IPToString(&remote_addr->local_ip_addr));
|
||||
|
||||
@@ -27,6 +27,8 @@
|
||||
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "sysincl.h"
|
||||
|
||||
#include "ntp_sources.h"
|
||||
|
||||
@@ -26,6 +26,8 @@
|
||||
integer endianness within the structures.
|
||||
|
||||
*/
|
||||
#include "config.h"
|
||||
|
||||
#include "sysincl.h"
|
||||
|
||||
#include "util.h"
|
||||
@@ -147,6 +149,8 @@ PKL_CommandLength(CMD_Request *r)
|
||||
return offsetof(CMD_Request, data.activity.EOR);
|
||||
case REQ_RESELECT:
|
||||
return offsetof(CMD_Request, data.reselect.EOR);
|
||||
case REQ_RESELECTDISTANCE:
|
||||
return offsetof(CMD_Request, data.reselect_distance.EOR);
|
||||
case REQ_MODIFY_MINSTRATUM:
|
||||
return offsetof(CMD_Request, data.modify_minstratum.EOR);
|
||||
case REQ_MODIFY_POLLTARGET:
|
||||
|
||||
42
refclock.c
42
refclock.c
@@ -25,6 +25,8 @@
|
||||
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "refclock.h"
|
||||
#include "reference.h"
|
||||
#include "conf.h"
|
||||
@@ -72,8 +74,8 @@ struct RCL_Instance_Record {
|
||||
int leap_status;
|
||||
int pps_rate;
|
||||
struct MedianFilter filter;
|
||||
unsigned long ref_id;
|
||||
unsigned long lock_ref;
|
||||
uint32_t ref_id;
|
||||
uint32_t lock_ref;
|
||||
double offset;
|
||||
double delay;
|
||||
double precision;
|
||||
@@ -148,14 +150,14 @@ RCL_AddRefclock(RefclockParameters *params)
|
||||
if (n_sources == MAX_RCL_SOURCES)
|
||||
return 0;
|
||||
|
||||
if (strncmp(params->driver_name, "SHM", 4) == 0) {
|
||||
if (strcmp(params->driver_name, "SHM") == 0) {
|
||||
inst->driver = &RCL_SHM_driver;
|
||||
inst->precision = 1e-6;
|
||||
} else if (strncmp(params->driver_name, "SOCK", 4) == 0) {
|
||||
} else if (strcmp(params->driver_name, "SOCK") == 0) {
|
||||
inst->driver = &RCL_SOCK_driver;
|
||||
inst->precision = 1e-9;
|
||||
pps_source = 1;
|
||||
} else if (strncmp(params->driver_name, "PPS", 4) == 0) {
|
||||
} else if (strcmp(params->driver_name, "PPS") == 0) {
|
||||
inst->driver = &RCL_PPS_driver;
|
||||
inst->precision = 1e-9;
|
||||
pps_source = 1;
|
||||
@@ -175,7 +177,7 @@ RCL_AddRefclock(RefclockParameters *params)
|
||||
inst->driver_poll = params->driver_poll;
|
||||
inst->poll = params->poll;
|
||||
inst->driver_polled = 0;
|
||||
inst->leap_status = 0;
|
||||
inst->leap_status = LEAP_Normal;
|
||||
inst->pps_rate = params->pps_rate;
|
||||
inst->lock_ref = params->lock_ref_id;
|
||||
inst->offset = params->offset;
|
||||
@@ -242,6 +244,8 @@ RCL_AddRefclock(RefclockParameters *params)
|
||||
#endif
|
||||
n_sources++;
|
||||
|
||||
Free(params->driver_name);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -275,7 +279,7 @@ void
|
||||
RCL_ReportSource(RPT_SourceReport *report, struct timeval *now)
|
||||
{
|
||||
int i;
|
||||
unsigned long ref_id;
|
||||
uint32_t ref_id;
|
||||
|
||||
assert(report->ip_addr.family == IPADDR_INET4);
|
||||
ref_id = report->ip_addr.addr.in4;
|
||||
@@ -334,7 +338,7 @@ RCL_GetDriverOption(RCL_Instance instance, char *name)
|
||||
}
|
||||
|
||||
int
|
||||
RCL_AddSample(RCL_Instance instance, struct timeval *sample_time, double offset, NTP_Leap leap_status)
|
||||
RCL_AddSample(RCL_Instance instance, struct timeval *sample_time, double offset, int leap)
|
||||
{
|
||||
double correction, dispersion;
|
||||
struct timeval cooked_time;
|
||||
@@ -347,7 +351,17 @@ RCL_AddSample(RCL_Instance instance, struct timeval *sample_time, double offset,
|
||||
return 0;
|
||||
|
||||
filter_add_sample(&instance->filter, &cooked_time, offset - correction + instance->offset, dispersion);
|
||||
instance->leap_status = leap_status;
|
||||
|
||||
switch (leap) {
|
||||
case LEAP_Normal:
|
||||
case LEAP_InsertSecond:
|
||||
case LEAP_DeleteSecond:
|
||||
instance->leap_status = leap;
|
||||
break;
|
||||
default:
|
||||
instance->leap_status = LEAP_Unsynchronised;
|
||||
break;
|
||||
}
|
||||
|
||||
log_sample(instance, &cooked_time, 0, 0, offset, offset - correction + instance->offset, dispersion);
|
||||
|
||||
@@ -416,7 +430,7 @@ RCL_AddPulse(RCL_Instance instance, struct timeval *pulse_time, double second)
|
||||
int is_synchronised, stratum;
|
||||
double root_delay, root_dispersion, distance;
|
||||
NTP_Leap leap;
|
||||
unsigned long ref_id;
|
||||
uint32_t ref_id;
|
||||
|
||||
/* Ignore the pulse if we are not well synchronized */
|
||||
|
||||
@@ -467,7 +481,7 @@ pps_stratum(RCL_Instance instance, struct timeval *tv)
|
||||
int is_synchronised, stratum, i;
|
||||
double root_delay, root_dispersion;
|
||||
NTP_Leap leap;
|
||||
unsigned long ref_id;
|
||||
uint32_t ref_id;
|
||||
|
||||
REF_GetReferenceParams(tv, &is_synchronised, &leap, &stratum,
|
||||
&ref_id, &ref_time, &root_delay, &root_dispersion);
|
||||
@@ -825,8 +839,8 @@ filter_get_sample(struct MedianFilter *filter, struct timeval *sample_time, doub
|
||||
prev_avg_var = filter->avg_var;
|
||||
|
||||
/* update exponential moving average of the variance */
|
||||
if (filter->avg_var_n > 100) {
|
||||
filter->avg_var += dof / (dof + 100.0) * (var - filter->avg_var);
|
||||
if (filter->avg_var_n > 50) {
|
||||
filter->avg_var += dof / (dof + 50.0) * (var - filter->avg_var);
|
||||
} else {
|
||||
filter->avg_var = (filter->avg_var * filter->avg_var_n + var * dof) /
|
||||
(dof + filter->avg_var_n);
|
||||
@@ -867,6 +881,8 @@ filter_slew_samples(struct MedianFilter *filter, struct timeval *when, double df
|
||||
#if 0
|
||||
LOG(LOGS_INFO, LOGF_Refclock, "i=%d old_off=%.9f new_off=%.9f",
|
||||
i, prev_offset, filter->samples[i].offset);
|
||||
#else
|
||||
(void)prev_offset;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,14 +32,14 @@
|
||||
#include "sources.h"
|
||||
|
||||
typedef struct {
|
||||
char driver_name[4];
|
||||
char *driver_name;
|
||||
char *driver_parameter;
|
||||
int driver_poll;
|
||||
int poll;
|
||||
int filter_length;
|
||||
int pps_rate;
|
||||
unsigned long ref_id;
|
||||
unsigned long lock_ref_id;
|
||||
uint32_t ref_id;
|
||||
uint32_t lock_ref_id;
|
||||
double offset;
|
||||
double delay;
|
||||
double precision;
|
||||
@@ -66,7 +66,7 @@ extern void RCL_SetDriverData(RCL_Instance instance, void *data);
|
||||
extern void *RCL_GetDriverData(RCL_Instance instance);
|
||||
extern char *RCL_GetDriverParameter(RCL_Instance instance);
|
||||
extern char *RCL_GetDriverOption(RCL_Instance instance, char *name);
|
||||
extern int RCL_AddSample(RCL_Instance instance, struct timeval *sample_time, double offset, NTP_Leap leap_status);
|
||||
extern int RCL_AddSample(RCL_Instance instance, struct timeval *sample_time, double offset, int leap);
|
||||
extern int RCL_AddPulse(RCL_Instance instance, struct timeval *pulse_time, double second);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -25,6 +25,8 @@
|
||||
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "refclock.h"
|
||||
|
||||
#if HAVE_PPSAPI
|
||||
|
||||
@@ -25,6 +25,8 @@
|
||||
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "refclock.h"
|
||||
#include "logging.h"
|
||||
#include "util.h"
|
||||
|
||||
@@ -25,6 +25,8 @@
|
||||
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "refclock.h"
|
||||
#include "logging.h"
|
||||
#include "util.h"
|
||||
|
||||
47
reference.c
47
reference.c
@@ -25,6 +25,8 @@
|
||||
This module keeps track of the source which we are claiming to be
|
||||
our reference, for the purposes of generating outgoing NTP packets */
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "sysincl.h"
|
||||
|
||||
#include "memory.h"
|
||||
@@ -43,7 +45,7 @@ static int local_stratum;
|
||||
static NTP_Leap our_leap_status;
|
||||
static int our_leap_sec;
|
||||
static int our_stratum;
|
||||
static unsigned long our_ref_id;
|
||||
static uint32_t our_ref_id;
|
||||
static IPAddr our_ref_ip;
|
||||
struct timeval our_ref_time; /* Stored relative to reference, NOT local time */
|
||||
static double our_offset;
|
||||
@@ -76,8 +78,6 @@ static double drift_file_age;
|
||||
|
||||
static void update_drift_file(double, double);
|
||||
|
||||
#define MAIL_PROGRAM "/usr/lib/sendmail"
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
static LOG_FileID logfileid;
|
||||
@@ -127,6 +127,7 @@ REF_Initialise(void)
|
||||
our_frequency_ppm = 0.0;
|
||||
our_skew = 1.0; /* i.e. rather bad */
|
||||
our_residual_freq = 0.0;
|
||||
drift_file_age = 0.0;
|
||||
|
||||
/* Now see if we can get the drift file opened */
|
||||
drift_file = CNF_GetDriftFile();
|
||||
@@ -138,6 +139,9 @@ REF_Initialise(void)
|
||||
/* We have read valid data */
|
||||
our_frequency_ppm = file_freq_ppm;
|
||||
our_skew = 1.0e-6 * file_skew_ppm;
|
||||
LOG(LOGS_INFO, LOGF_Reference, "Frequency %.3f +- %.3f ppm read from %s", file_freq_ppm, file_skew_ppm, drift_file);
|
||||
LCL_SetAbsoluteFrequency(our_frequency_ppm);
|
||||
LCL_ReadCookedTime(&last_ref_update, NULL);
|
||||
} else {
|
||||
LOG(LOGS_WARN, LOGF_Reference, "Could not parse valid frequency and skew from driftfile %s",
|
||||
drift_file);
|
||||
@@ -147,15 +151,15 @@ REF_Initialise(void)
|
||||
drift_file);
|
||||
}
|
||||
fclose(in);
|
||||
} else {
|
||||
LOG(LOGS_WARN, LOGF_Reference, "Could not open driftfile %s for reading",
|
||||
drift_file);
|
||||
}
|
||||
|
||||
drift_file_age = 0.0;
|
||||
}
|
||||
|
||||
LCL_SetAbsoluteFrequency(our_frequency_ppm);
|
||||
if (our_frequency_ppm == 0.0) {
|
||||
our_frequency_ppm = LCL_ReadAbsoluteFrequency();
|
||||
if (our_frequency_ppm != 0.0) {
|
||||
LOG(LOGS_INFO, LOGF_Reference, "Initial frequency %.3f ppm", our_frequency_ppm);
|
||||
}
|
||||
}
|
||||
|
||||
logfileid = CNF_GetLogTracking() ? LOG_FileOpen("tracking",
|
||||
" Date (UTC) Time IP Address St Freq ppm Skew ppm Offset")
|
||||
@@ -365,7 +369,7 @@ schedule_fb_drift(struct timeval *now)
|
||||
|
||||
UTI_DiffTimevalsToDouble(&unsynchronised, now, &last_ref_update);
|
||||
|
||||
for (c = 0, i = fb_drift_min; i <= fb_drift_max; i++) {
|
||||
for (c = secs = 0, i = fb_drift_min; i <= fb_drift_max; i++) {
|
||||
secs = 1 << i;
|
||||
|
||||
if (fb_drifts[i - fb_drift_min].secs < secs)
|
||||
@@ -516,7 +520,7 @@ write_log(struct timeval *ref_time, char *ref, int stratum, double freq, double
|
||||
void
|
||||
REF_SetReference(int stratum,
|
||||
NTP_Leap leap,
|
||||
unsigned long ref_id,
|
||||
uint32_t ref_id,
|
||||
IPAddr *ref_ip,
|
||||
struct timeval *ref_time,
|
||||
double offset,
|
||||
@@ -532,10 +536,10 @@ REF_SetReference(int stratum,
|
||||
double delta_freq1, delta_freq2;
|
||||
double skew1, skew2;
|
||||
double our_frequency;
|
||||
|
||||
double abs_freq_ppm;
|
||||
|
||||
double update_interval;
|
||||
double elapsed;
|
||||
struct timeval now;
|
||||
|
||||
assert(initialised);
|
||||
|
||||
@@ -572,10 +576,13 @@ REF_SetReference(int stratum,
|
||||
else
|
||||
our_ref_ip.family = IPADDR_UNSPEC;
|
||||
our_ref_time = *ref_time;
|
||||
our_offset = offset;
|
||||
our_root_delay = root_delay;
|
||||
our_root_dispersion = root_dispersion;
|
||||
|
||||
LCL_ReadCookedTime(&now, NULL);
|
||||
UTI_DiffTimevalsToDouble(&elapsed, &now, ref_time);
|
||||
our_offset = offset + elapsed * frequency;
|
||||
|
||||
update_leap_status(leap);
|
||||
|
||||
/* Eliminate updates that are based on totally unreliable frequency
|
||||
@@ -629,14 +636,14 @@ REF_SetReference(int stratum,
|
||||
|
||||
abs_freq_ppm = LCL_ReadAbsoluteFrequency();
|
||||
|
||||
write_log(ref_time,
|
||||
write_log(&now,
|
||||
our_ref_ip.family != IPADDR_UNSPEC ? UTI_IPToString(&our_ref_ip) : UTI_RefidToString(our_ref_id),
|
||||
our_stratum,
|
||||
abs_freq_ppm,
|
||||
1.0e6*our_skew,
|
||||
our_offset);
|
||||
|
||||
UTI_DiffTimevalsToDouble(&update_interval, ref_time, &last_ref_update);
|
||||
UTI_DiffTimevalsToDouble(&update_interval, &now, &last_ref_update);
|
||||
|
||||
if (drift_file) {
|
||||
/* Update drift file at most once per hour */
|
||||
@@ -652,7 +659,7 @@ REF_SetReference(int stratum,
|
||||
update_fb_drifts(abs_freq_ppm, update_interval);
|
||||
}
|
||||
|
||||
last_ref_update = *ref_time;
|
||||
last_ref_update = now;
|
||||
last_ref_update_interval = update_interval;
|
||||
|
||||
/* And now set the freq and offset to zero */
|
||||
@@ -738,7 +745,7 @@ REF_GetReferenceParams
|
||||
int *is_synchronised,
|
||||
NTP_Leap *leap_status,
|
||||
int *stratum,
|
||||
unsigned long *ref_id,
|
||||
uint32_t *ref_id,
|
||||
struct timeval *ref_time,
|
||||
double *root_delay,
|
||||
double *root_dispersion
|
||||
@@ -791,7 +798,7 @@ REF_GetReferenceParams
|
||||
|
||||
*leap_status = LEAP_Unsynchronised;
|
||||
*stratum = 0;
|
||||
*ref_id = 0UL;
|
||||
*ref_id = 0;
|
||||
ref_time->tv_sec = ref_time->tv_usec = 0;
|
||||
/* These values seem to be standard for a client, and
|
||||
any peer or client of ours will ignore them anyway because
|
||||
@@ -897,7 +904,7 @@ REF_GetTrackingReport(RPT_TrackingReport *rep)
|
||||
|
||||
} else {
|
||||
|
||||
rep->ref_id = 0UL;
|
||||
rep->ref_id = 0;
|
||||
rep->ip_addr.family = IPADDR_UNSPEC;
|
||||
rep->stratum = 0;
|
||||
rep->ref_time.tv_sec = 0;
|
||||
|
||||
@@ -71,7 +71,7 @@ extern void REF_GetReferenceParams
|
||||
int *is_synchronised,
|
||||
NTP_Leap *leap,
|
||||
int *stratum,
|
||||
unsigned long *ref_id,
|
||||
uint32_t *ref_id,
|
||||
struct timeval *ref_time,
|
||||
double *root_delay,
|
||||
double *root_dispersion
|
||||
@@ -105,7 +105,7 @@ extern void REF_SetReference
|
||||
(
|
||||
int stratum,
|
||||
NTP_Leap leap,
|
||||
unsigned long ref_id,
|
||||
uint32_t ref_id,
|
||||
IPAddr *ref_ip,
|
||||
struct timeval *ref_time,
|
||||
double offset,
|
||||
|
||||
@@ -26,6 +26,8 @@
|
||||
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
|
||||
@@ -298,6 +300,10 @@ RGR_FindBestRegression
|
||||
nruns = n_runs_from_residuals(resid, n - resid_start);
|
||||
|
||||
if (nruns > critical_runs[n - resid_start] || n - start <= MIN_SAMPLES_FOR_REGRESS) {
|
||||
if (resid_start < 0) {
|
||||
/* Ignore extra samples in returned nruns */
|
||||
nruns = n_runs_from_residuals(resid - resid_start, n);
|
||||
}
|
||||
break;
|
||||
} else {
|
||||
/* Try dropping one sample at a time until the runs test passes. */
|
||||
|
||||
@@ -46,7 +46,7 @@ typedef struct {
|
||||
} RPT_SourceReport ;
|
||||
|
||||
typedef struct {
|
||||
unsigned long ref_id;
|
||||
uint32_t ref_id;
|
||||
IPAddr ip_addr;
|
||||
unsigned long stratum;
|
||||
struct timeval ref_time;
|
||||
@@ -59,7 +59,7 @@ typedef struct {
|
||||
} RPT_TrackingReport;
|
||||
|
||||
typedef struct {
|
||||
unsigned long ref_id;
|
||||
uint32_t ref_id;
|
||||
IPAddr ip_addr;
|
||||
unsigned long n_samples;
|
||||
unsigned long n_runs;
|
||||
|
||||
83
rtc_linux.c
83
rtc_linux.c
@@ -26,6 +26,8 @@
|
||||
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#if defined LINUX
|
||||
|
||||
#ifdef sparc
|
||||
@@ -45,6 +47,7 @@
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <linux/rtc.h>
|
||||
|
||||
#include "logging.h"
|
||||
#include "sched.h"
|
||||
@@ -54,22 +57,9 @@
|
||||
#include "regress.h"
|
||||
#include "rtc.h"
|
||||
#include "rtc_linux.h"
|
||||
#include "io_linux.h"
|
||||
#include "conf.h"
|
||||
#include "memory.h"
|
||||
|
||||
struct rtc_time {
|
||||
int tm_sec;
|
||||
int tm_min;
|
||||
int tm_hour;
|
||||
int tm_mday;
|
||||
int tm_mon;
|
||||
int tm_year;
|
||||
int tm_wday;
|
||||
int tm_yday;
|
||||
int tm_isdst;
|
||||
};
|
||||
|
||||
/* ================================================== */
|
||||
/* Forward prototypes */
|
||||
|
||||
@@ -244,14 +234,12 @@ run_regression(int new_sample,
|
||||
{
|
||||
double rtc_rel[MAX_SAMPLES]; /* Relative times on RTC axis */
|
||||
double offsets[MAX_SAMPLES]; /* How much the RTC is fast of the system clock */
|
||||
int i, n;
|
||||
int i;
|
||||
double est_intercept, est_slope;
|
||||
int best_new_start;
|
||||
|
||||
if (n_samples > 0) {
|
||||
|
||||
n = n_samples - 1;
|
||||
|
||||
for (i=0; i<n_samples; i++) {
|
||||
rtc_rel[i] = rtc_trim[i] + (double)(rtc_sec[i] - rtc_ref);
|
||||
offsets[i] = ((double) (rtc_ref - system_times[i].tv_sec) -
|
||||
@@ -319,6 +307,8 @@ slew_samples
|
||||
dfreq, doffset,
|
||||
old_seconds_fast, 1.0e6 * old_gain_rate,
|
||||
coef_seconds_fast, 1.0e6 * coef_gain_rate);
|
||||
#else
|
||||
(void)old_seconds_fast; (void)old_gain_rate;
|
||||
#endif
|
||||
|
||||
}
|
||||
@@ -517,62 +507,6 @@ write_coefs_to_file(int valid,time_t ref_time,double offset,double rate)
|
||||
int
|
||||
RTC_Linux_Initialise(void)
|
||||
{
|
||||
int major, minor, patch;
|
||||
|
||||
/* Check whether we can support the real time clock.
|
||||
|
||||
Linux 1.2.x - haven't checked yet
|
||||
|
||||
Linux 1.3.x - don't know, haven't got a system to look at
|
||||
|
||||
Linux 2.0.x - For x<=31, using any variant of the adjtimex() call
|
||||
sets the kernel into a mode where the RTC was updated every 11
|
||||
minutes. The only way to escape this is to use settimeofday().
|
||||
Since we need to have sole control over the RTC to be able to
|
||||
measure its drift rate, and there is no 'notify' callback to warn
|
||||
you that the kernel is going to do this, I can't see a way to
|
||||
support this.
|
||||
|
||||
Linux 2.0.x - For x>=32 the adjtimex()/RTC behaviour was
|
||||
modified, so that as long as the STA_UNSYNC flag is set the RTC
|
||||
is left alone. This is the mode we exploit here, so that the RTC
|
||||
continues to go its own sweet way, unless we make updates to it
|
||||
from this module.
|
||||
|
||||
Linux 2.1.x - don't know, haven't got a system to look at.
|
||||
|
||||
Linux 2.2.x, 2.3.x and 2.4.x are believed to be OK for all
|
||||
patch levels
|
||||
|
||||
*/
|
||||
|
||||
SYS_Linux_GetKernelVersion(&major, &minor, &patch);
|
||||
|
||||
/* Obviously this test can get more elaborate when we know about
|
||||
more system types. */
|
||||
if (major != 2) {
|
||||
return 0;
|
||||
} else {
|
||||
switch (minor) {
|
||||
case 0:
|
||||
if (patch <= 31) {
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
return 0;
|
||||
break;
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
case 5:
|
||||
case 6:
|
||||
case 7:
|
||||
case 8:
|
||||
break; /* OK for all patch levels */
|
||||
}
|
||||
}
|
||||
|
||||
/* Setup details depending on configuration options */
|
||||
setup_config();
|
||||
|
||||
@@ -681,6 +615,9 @@ set_rtc(time_t new_rtc_time)
|
||||
rtc_raw.tm_mday = rtc_tm.tm_mday;
|
||||
rtc_raw.tm_mon = rtc_tm.tm_mon;
|
||||
rtc_raw.tm_year = rtc_tm.tm_year;
|
||||
rtc_raw.tm_wday = rtc_tm.tm_wday;
|
||||
rtc_raw.tm_yday = rtc_tm.tm_yday;
|
||||
rtc_raw.tm_isdst = rtc_tm.tm_isdst;
|
||||
|
||||
status = ioctl(fd, RTC_SET_TIME, &rtc_raw);
|
||||
if (status < 0) {
|
||||
@@ -846,7 +783,7 @@ read_from_device(void *any)
|
||||
return;
|
||||
}
|
||||
|
||||
if ((data & RTC_UIE) == RTC_UIE) {
|
||||
if ((data & RTC_UF) == RTC_UF) {
|
||||
/* Update interrupt detected */
|
||||
|
||||
/* Read RTC time, sandwiched between two polls of the system clock
|
||||
|
||||
104
sched.c
104
sched.c
@@ -26,6 +26,8 @@
|
||||
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "sysincl.h"
|
||||
|
||||
#include "sched.h"
|
||||
@@ -68,9 +70,9 @@ typedef struct {
|
||||
|
||||
static FileHandlerEntry file_handlers[FD_SET_SIZE];
|
||||
|
||||
/* Last timestamp when a file descriptor became readable */
|
||||
static struct timeval last_fdready;
|
||||
static double last_fdready_err;
|
||||
/* Timestamp when last select() returned */
|
||||
static struct timeval last_select_ts, last_select_ts_raw;
|
||||
static double last_select_ts_err;
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
@@ -227,9 +229,9 @@ SCH_RemoveInputFileHandler(int fd)
|
||||
void
|
||||
SCH_GetFileReadyTime(struct timeval *tv, double *err)
|
||||
{
|
||||
*tv = last_fdready;
|
||||
*tv = last_select_ts;
|
||||
if (err)
|
||||
*err = last_fdready_err;
|
||||
*err = last_select_ts_err;
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
@@ -316,6 +318,7 @@ SCH_AddTimeoutByDelay(double delay, SCH_TimeoutHandler handler, SCH_ArbitraryArg
|
||||
struct timeval now, then;
|
||||
|
||||
assert(initialised);
|
||||
assert(delay >= 0.0);
|
||||
|
||||
LCL_ReadRawTime(&now);
|
||||
UTI_AddDoubleToTimeval(&now, delay, &then);
|
||||
@@ -337,6 +340,7 @@ SCH_AddTimeoutInClass(double min_delay, double separation, double randomness,
|
||||
double new_min_delay;
|
||||
|
||||
assert(initialised);
|
||||
assert(min_delay >= 0.0);
|
||||
assert(class < SCH_NumberOfClasses);
|
||||
|
||||
if (randomness > 0.0) {
|
||||
@@ -426,18 +430,26 @@ SCH_RemoveTimeout(SCH_TimeoutID id)
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
/* The current time (now) has to be passed in from the
|
||||
caller to avoid race conditions */
|
||||
/* Try to dispatch any timeouts that have already gone by, and
|
||||
keep going until all are done. (The earlier ones may take so
|
||||
long to do that the later ones come around by the time they are
|
||||
completed). */
|
||||
|
||||
static int
|
||||
static void
|
||||
dispatch_timeouts(struct timeval *now) {
|
||||
TimerQueueEntry *ptr;
|
||||
SCH_TimeoutHandler handler;
|
||||
SCH_ArbitraryArgument arg;
|
||||
int n_done = 0;
|
||||
int n_done = 0, n_entries_on_start = n_timer_queue_entries;
|
||||
|
||||
while (1) {
|
||||
LCL_ReadRawTime(now);
|
||||
|
||||
if (!(n_timer_queue_entries > 0 &&
|
||||
UTI_CompareTimevals(now, &(timer_queue.next->tv)) >= 0)) {
|
||||
break;
|
||||
}
|
||||
|
||||
if ((n_timer_queue_entries > 0) &&
|
||||
(UTI_CompareTimevals(now, &(timer_queue.next->tv)) >= 0)) {
|
||||
ptr = timer_queue.next;
|
||||
|
||||
last_class_dispatch[ptr->class] = *now;
|
||||
@@ -452,10 +464,16 @@ dispatch_timeouts(struct timeval *now) {
|
||||
|
||||
/* Increment count of timeouts handled */
|
||||
++n_done;
|
||||
|
||||
/* If more timeouts were handled than there were in the timer queue on
|
||||
start, assume some code is scheduling timeouts with negative delays and
|
||||
abort. Make the actual limit higher in case the machine is temporarily
|
||||
overloaded and dispatching the handlers takes more time than was delay
|
||||
of a scheduled timeout. */
|
||||
if (n_done > n_entries_on_start * 4) {
|
||||
LOG_FATAL(LOGF_Scheduler, "Possible infinite loop in scheduling");
|
||||
}
|
||||
}
|
||||
|
||||
return n_done;
|
||||
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
@@ -507,18 +525,50 @@ handle_slew(struct timeval *raw,
|
||||
for (i = 0; i < SCH_NumberOfClasses; i++) {
|
||||
UTI_AddDoubleToTimeval(&last_class_dispatch[i], -doffset, &last_class_dispatch[i]);
|
||||
}
|
||||
|
||||
UTI_AddDoubleToTimeval(&last_select_ts_raw, -doffset, &last_select_ts_raw);
|
||||
UTI_AddDoubleToTimeval(&last_select_ts, -doffset, &last_select_ts);
|
||||
}
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
/* Try to handle unexpected backward time jump */
|
||||
|
||||
static void
|
||||
recover_backjump(struct timeval *raw, struct timeval *cooked, int timeout)
|
||||
{
|
||||
double diff, err;
|
||||
|
||||
UTI_DiffTimevalsToDouble(&diff, &last_select_ts_raw, raw);
|
||||
|
||||
if (n_timer_queue_entries > 0) {
|
||||
UTI_DiffTimevalsToDouble(&err, &(timer_queue.next->tv), &last_select_ts_raw);
|
||||
} else {
|
||||
err = 0.0;
|
||||
}
|
||||
|
||||
diff += err;
|
||||
|
||||
if (timeout) {
|
||||
err = 1.0;
|
||||
}
|
||||
|
||||
LOG(LOGS_WARN, LOGF_Scheduler, "Backward time jump detected! (correction %.1f +- %.1f seconds)", diff, err);
|
||||
|
||||
LCL_NotifyExternalTimeStep(raw, cooked, diff, err);
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
void
|
||||
SCH_MainLoop(void)
|
||||
{
|
||||
fd_set rd;
|
||||
int status;
|
||||
struct timeval tv, *ptv;
|
||||
struct timeval now;
|
||||
struct timeval now, cooked;
|
||||
double err;
|
||||
|
||||
assert(initialised);
|
||||
|
||||
@@ -527,20 +577,15 @@ SCH_MainLoop(void)
|
||||
/* Copy current set of read file descriptors */
|
||||
memcpy((void *) &rd, (void *) &read_fds, sizeof(fd_set));
|
||||
|
||||
/* Try to dispatch any timeouts that have already gone by, and
|
||||
keep going until all are done. (The earlier ones may take so
|
||||
long to do that the later ones come around by the time they are
|
||||
completed). */
|
||||
|
||||
do {
|
||||
LCL_ReadRawTime(&now);
|
||||
} while (dispatch_timeouts(&now) > 0);
|
||||
/* Dispatch timeouts and fill now with current raw time */
|
||||
dispatch_timeouts(&now);
|
||||
|
||||
/* Check whether there is a timeout and set it up */
|
||||
if (n_timer_queue_entries > 0) {
|
||||
|
||||
UTI_DiffTimevals(&tv, &(timer_queue.next->tv), &now);
|
||||
ptv = &tv;
|
||||
assert(tv.tv_sec > 0 || tv.tv_usec > 0);
|
||||
|
||||
} else {
|
||||
ptv = NULL;
|
||||
@@ -555,12 +600,23 @@ SCH_MainLoop(void)
|
||||
|
||||
status = select(one_highest_fd, &rd, NULL, NULL, ptv);
|
||||
|
||||
LCL_ReadRawTime(&now);
|
||||
LCL_CookTime(&now, &cooked, &err);
|
||||
|
||||
/* Check if time didn't jump backwards */
|
||||
if (last_select_ts_raw.tv_sec > now.tv_sec + 1) {
|
||||
recover_backjump(&now, &cooked, status == 0);
|
||||
}
|
||||
|
||||
last_select_ts_raw = now;
|
||||
last_select_ts = cooked;
|
||||
last_select_ts_err = err;
|
||||
|
||||
if (status < 0) {
|
||||
assert(need_to_exit);
|
||||
} else if (status > 0) {
|
||||
/* A file descriptor is ready to read */
|
||||
|
||||
LCL_ReadCookedTime(&last_fdready, &last_fdready_err);
|
||||
dispatch_filehandlers(status, &rd);
|
||||
|
||||
} else {
|
||||
|
||||
60
sources.c
60
sources.c
@@ -28,6 +28,8 @@
|
||||
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "sysincl.h"
|
||||
|
||||
#include "sources.h"
|
||||
@@ -82,8 +84,8 @@ struct SRC_Instance_Record {
|
||||
SST_Stats stats;
|
||||
NTP_Leap leap_status; /* Leap status */
|
||||
int index; /* Index back into the array of source */
|
||||
unsigned long ref_id; /* The reference ID of this source
|
||||
(i.e. its IP address, NOT the
|
||||
uint32_t ref_id; /* The reference ID of this source
|
||||
(i.e. from its IP address, NOT the
|
||||
reference _it_ is sync'd to) */
|
||||
IPAddr *ip_addr; /* Its IP address if NTP source */
|
||||
|
||||
@@ -181,7 +183,7 @@ void SRC_Finalise(void)
|
||||
/* Function to create a new instance. This would be called by one of
|
||||
the individual source-type instance creation routines. */
|
||||
|
||||
SRC_Instance SRC_CreateNewInstance(unsigned long ref_id, SRC_Type type, SRC_SelectOption sel_option, IPAddr *addr)
|
||||
SRC_Instance SRC_CreateNewInstance(uint32_t ref_id, SRC_Type type, SRC_SelectOption sel_option, IPAddr *addr)
|
||||
{
|
||||
SRC_Instance result;
|
||||
|
||||
@@ -368,8 +370,12 @@ SRC_UpdateReachability(SRC_Instance inst, int reachable)
|
||||
void
|
||||
SRC_ResetReachability(SRC_Instance inst)
|
||||
{
|
||||
/* This should be disabled until source selection is modified to keep
|
||||
a peer selected even when not reachable */
|
||||
#if 0
|
||||
inst->reachability = 0;
|
||||
SRC_UpdateReachability(inst, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
@@ -414,15 +420,15 @@ source_to_string(SRC_Instance inst)
|
||||
of sources we are holding.
|
||||
|
||||
Updates are only made to the local reference if a new source is selected
|
||||
or match_addr is equal to the selected reference source address */
|
||||
or match_refid is equal to the selected reference source refid */
|
||||
|
||||
void
|
||||
SRC_SelectSource(unsigned long match_addr)
|
||||
SRC_SelectSource(uint32_t match_refid)
|
||||
{
|
||||
int i, j, index, old_selected_index;
|
||||
struct timeval now;
|
||||
struct timeval now, ref_time;
|
||||
double src_offset, src_offset_sd, src_frequency, src_skew;
|
||||
double src_accrued_dispersion;
|
||||
double src_root_delay, src_root_dispersion;
|
||||
int n_endpoints, j1, j2;
|
||||
double best_lo, best_hi;
|
||||
int depth, best_depth;
|
||||
@@ -430,7 +436,6 @@ SRC_SelectSource(unsigned long match_addr)
|
||||
double distance, sel_src_distance;
|
||||
int stratum, min_stratum;
|
||||
struct SelectInfo *si;
|
||||
double total_root_dispersion;
|
||||
int n_badstats_sources;
|
||||
int max_sel_reach, max_badstat_reach;
|
||||
int max_score_index;
|
||||
@@ -778,8 +783,8 @@ SRC_SelectSource(unsigned long match_addr)
|
||||
|
||||
/* Update score, but only for source pairs where one source
|
||||
has a new sample */
|
||||
if (sources[i]->ref_id == match_addr ||
|
||||
sources[selected_source_index]->ref_id == match_addr) {
|
||||
if (sources[i]->ref_id == match_refid ||
|
||||
sources[selected_source_index]->ref_id == match_refid) {
|
||||
|
||||
sources[i]->sel_score *= sel_src_distance / distance;
|
||||
|
||||
@@ -798,7 +803,7 @@ SRC_SelectSource(unsigned long match_addr)
|
||||
|
||||
#if 0
|
||||
LOG(LOGS_INFO, LOGF_Sources, "select score=%f refid=%lx match_refid=%lx status=%d dist=%f",
|
||||
sources[i]->sel_score, sources[i]->ref_id, match_addr, sources[i]->status, distance);
|
||||
sources[i]->sel_score, sources[i]->ref_id, match_refid, sources[i]->status, distance);
|
||||
#endif
|
||||
|
||||
if (max_score < sources[i]->sel_score) {
|
||||
@@ -835,32 +840,27 @@ SRC_SelectSource(unsigned long match_addr)
|
||||
sources[selected_source_index]->status = SRC_SYNC;
|
||||
|
||||
/* Update local reference only when a new source was selected or a new
|
||||
sample was received (i.e. match_addr is equal to selected ref_id) */
|
||||
sample was received (i.e. match_refid is equal to selected refid) */
|
||||
if (selected_source_index != old_selected_index ||
|
||||
match_addr == sources[selected_source_index]->ref_id) {
|
||||
match_refid == sources[selected_source_index]->ref_id) {
|
||||
|
||||
/* Now just use the statistics of the selected source for
|
||||
trimming the local clock */
|
||||
|
||||
LCL_ReadCookedTime(&now, NULL);
|
||||
|
||||
SST_GetTrackingData(sources[selected_source_index]->stats, &now,
|
||||
SST_GetTrackingData(sources[selected_source_index]->stats, &ref_time,
|
||||
&src_offset, &src_offset_sd,
|
||||
&src_accrued_dispersion,
|
||||
&src_frequency, &src_skew);
|
||||
|
||||
total_root_dispersion = (src_accrued_dispersion +
|
||||
sources[selected_source_index]->sel_info.root_dispersion);
|
||||
&src_frequency, &src_skew,
|
||||
&src_root_delay, &src_root_dispersion);
|
||||
|
||||
REF_SetReference(min_stratum, leap_status,
|
||||
sources[selected_source_index]->ref_id,
|
||||
sources[selected_source_index]->ip_addr,
|
||||
&now,
|
||||
&ref_time,
|
||||
src_offset,
|
||||
src_frequency,
|
||||
src_skew,
|
||||
sources[selected_source_index]->sel_info.root_delay,
|
||||
total_root_dispersion);
|
||||
src_root_delay,
|
||||
src_root_dispersion);
|
||||
}
|
||||
|
||||
} else {
|
||||
@@ -897,6 +897,17 @@ SRC_ReselectSource(void)
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
void
|
||||
SRC_SetReselectDistance(double distance)
|
||||
{
|
||||
if (reselect_distance != distance) {
|
||||
reselect_distance = distance;
|
||||
LOG(LOGS_INFO, LOGF_Sources, "New reselect distance %f", distance);
|
||||
}
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
double
|
||||
SRC_PredictOffset(SRC_Instance inst, struct timeval *when)
|
||||
{
|
||||
@@ -1083,6 +1094,7 @@ SRC_ReportSource(int index, RPT_SourceReport *report, struct timeval *now)
|
||||
case SRC_JITTERY:
|
||||
report->state = RPT_JITTERY;
|
||||
break;
|
||||
case SRC_OK:
|
||||
case SRC_BAD_STATS:
|
||||
case SRC_UNREACHABLE:
|
||||
report->state = RPT_UNREACH;
|
||||
|
||||
@@ -61,7 +61,7 @@ typedef enum {
|
||||
/* Function to create a new instance. This would be called by one of
|
||||
the individual source-type instance creation routines. */
|
||||
|
||||
extern SRC_Instance SRC_CreateNewInstance(unsigned long ref_id, SRC_Type type, SRC_SelectOption sel_option, IPAddr *addr);
|
||||
extern SRC_Instance SRC_CreateNewInstance(uint32_t ref_id, SRC_Type type, SRC_SelectOption sel_option, IPAddr *addr);
|
||||
|
||||
/* Function to get rid of a source when it is being unconfigured.
|
||||
This may cause the current reference source to be reselected, if this
|
||||
@@ -135,11 +135,14 @@ extern void SRC_ResetReachability(SRC_Instance inst);
|
||||
reference source address. (This avoids updating the frequency
|
||||
tracking for every sample from other sources - only the ones from
|
||||
the selected reference make a difference) */
|
||||
extern void SRC_SelectSource(unsigned long match_addr);
|
||||
extern void SRC_SelectSource(uint32_t match_refid);
|
||||
|
||||
/* Force reselecting the best source */
|
||||
extern void SRC_ReselectSource(void);
|
||||
|
||||
/* Set reselect distance */
|
||||
extern void SRC_SetReselectDistance(double distance);
|
||||
|
||||
/* Predict the offset of the local clock relative to a given source at
|
||||
a given local cooked time. Positive indicates local clock is FAST
|
||||
relative to reference. */
|
||||
|
||||
@@ -26,6 +26,8 @@
|
||||
analysis on the samples obtained from the sources,
|
||||
to determined frequencies and error bounds. */
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "sysincl.h"
|
||||
|
||||
#include "sourcestats.h"
|
||||
@@ -56,7 +58,7 @@ static LOG_FileID logfileid;
|
||||
struct SST_Stats_Record {
|
||||
|
||||
/* Reference ID and IP address of source, used for logging to statistics log */
|
||||
unsigned long refid;
|
||||
uint32_t refid;
|
||||
IPAddr *ip_addr;
|
||||
|
||||
/* Number of samples currently stored. The samples are stored in circular
|
||||
@@ -171,7 +173,7 @@ SST_Finalise(void)
|
||||
/* This function creates a new instance of the statistics handler */
|
||||
|
||||
SST_Stats
|
||||
SST_CreateInstance(unsigned long refid, IPAddr *addr)
|
||||
SST_CreateInstance(uint32_t refid, IPAddr *addr)
|
||||
{
|
||||
SST_Stats inst;
|
||||
inst = MallocNew(struct SST_Stats_Record);
|
||||
@@ -384,7 +386,7 @@ SST_DoNewRegression(SST_Stats inst)
|
||||
int best_start, times_back_start;
|
||||
double est_intercept, est_slope, est_var, est_intercept_sd, est_slope_sd;
|
||||
int i, j, nruns;
|
||||
double min_distance;
|
||||
double min_distance, mean_distance;
|
||||
double sd_weight, sd;
|
||||
double old_skew, old_freq, stress;
|
||||
|
||||
@@ -395,17 +397,19 @@ SST_DoNewRegression(SST_Stats inst)
|
||||
offsets[i + inst->runs_samples] = inst->offsets[get_runsbuf_index(inst, i)];
|
||||
}
|
||||
|
||||
for (i = 0, min_distance = DBL_MAX; i < inst->n_samples; i++) {
|
||||
for (i = 0, mean_distance = 0.0, min_distance = DBL_MAX; i < inst->n_samples; i++) {
|
||||
j = get_buf_index(inst, i);
|
||||
peer_distances[i] = 0.5 * inst->peer_delays[j] + inst->peer_dispersions[j];
|
||||
mean_distance += peer_distances[i];
|
||||
if (peer_distances[i] < min_distance) {
|
||||
min_distance = peer_distances[i];
|
||||
}
|
||||
}
|
||||
mean_distance /= inst->n_samples;
|
||||
|
||||
/* And now, work out the weight vector */
|
||||
|
||||
sd = sqrt(inst->variance);
|
||||
sd = mean_distance - min_distance;
|
||||
if (sd > min_distance || sd <= 0.0)
|
||||
sd = min_distance;
|
||||
|
||||
@@ -572,6 +576,8 @@ SST_GetSelectionData(SST_Stats inst, struct timeval *now,
|
||||
LOG(LOGS_INFO, LOGF_SourceStats, "n=%d off=%f del=%f dis=%f var=%f pdist=%f avoff=%f avok=%d selok=%d",
|
||||
inst->n_samples, *best_offset, *best_root_delay, *best_root_dispersion, *variance,
|
||||
peer_distance, average_offset, average_ok, *select_ok);
|
||||
#else
|
||||
(void)average_ok;
|
||||
#endif
|
||||
|
||||
return;
|
||||
@@ -580,32 +586,30 @@ SST_GetSelectionData(SST_Stats inst, struct timeval *now,
|
||||
/* ================================================== */
|
||||
|
||||
void
|
||||
SST_GetTrackingData(SST_Stats inst, struct timeval *now,
|
||||
SST_GetTrackingData(SST_Stats inst, struct timeval *ref_time,
|
||||
double *average_offset, double *offset_sd,
|
||||
double *accrued_dispersion,
|
||||
double *frequency, double *skew)
|
||||
double *frequency, double *skew,
|
||||
double *root_delay, double *root_dispersion)
|
||||
{
|
||||
int i, j;
|
||||
double peer_distance;
|
||||
double elapsed_offset, elapsed_sample;
|
||||
double elapsed_sample;
|
||||
|
||||
i = get_runsbuf_index(inst, inst->best_single_sample);
|
||||
j = get_buf_index(inst, inst->best_single_sample);
|
||||
|
||||
*ref_time = inst->offset_time;
|
||||
*average_offset = inst->estimated_offset;
|
||||
*offset_sd = inst->estimated_offset_sd;
|
||||
*frequency = inst->estimated_frequency;
|
||||
*skew = inst->skew;
|
||||
*root_delay = inst->root_delays[j];
|
||||
|
||||
peer_distance = inst->peer_dispersions[j] + 0.5 * inst->peer_delays[j];
|
||||
UTI_DiffTimevalsToDouble(&elapsed_offset, now, &(inst->offset_time));
|
||||
*average_offset = inst->estimated_offset + inst->estimated_frequency * elapsed_offset;
|
||||
*offset_sd = inst->estimated_offset_sd + elapsed_offset * inst->skew;
|
||||
|
||||
UTI_DiffTimevalsToDouble(&elapsed_sample, now, &inst->sample_times[i]);
|
||||
*accrued_dispersion = inst->skew * elapsed_sample;
|
||||
UTI_DiffTimevalsToDouble(&elapsed_sample, &inst->offset_time, &inst->sample_times[i]);
|
||||
*root_dispersion = inst->root_dispersions[j] + inst->skew * elapsed_sample;
|
||||
|
||||
#ifdef TRACEON
|
||||
LOG(LOGS_INFO, LOGF_SourceStats, "n=%d freq=%f (%.3fppm) skew=%f (%.3fppm) pdist=%f avoff=%f offsd=%f accrdis=%f",
|
||||
inst->n_samples, *frequency, 1.0e6* *frequency, *skew, 1.0e6* *skew, peer_distance, *average_offset, *offset_sd, *accrued_dispersion);
|
||||
LOG(LOGS_INFO, LOGF_SourceStats, "n=%d freq=%f (%.3fppm) skew=%f (%.3fppm) avoff=%f offsd=%f disp=%f",
|
||||
inst->n_samples, *frequency, 1.0e6* *frequency, *skew, 1.0e6* *skew, *average_offset, *offset_sd, *root_dispersion);
|
||||
#endif
|
||||
|
||||
}
|
||||
@@ -620,6 +624,9 @@ SST_SlewSamples(SST_Stats inst, struct timeval *when, double dfreq, double doffs
|
||||
struct timeval *sample, prev;
|
||||
double prev_offset, prev_freq;
|
||||
|
||||
if (!inst->n_samples)
|
||||
return;
|
||||
|
||||
for (m = -inst->runs_samples; m < inst->n_samples; m++) {
|
||||
i = get_runsbuf_index(inst, m);
|
||||
sample = &(inst->sample_times[i]);
|
||||
@@ -631,6 +638,8 @@ SST_SlewSamples(SST_Stats inst, struct timeval *when, double dfreq, double doffs
|
||||
LOG(LOGS_INFO, LOGF_SourceStats, "i=%d old_st=[%s] new_st=[%s] old_off=%f new_off=%f",
|
||||
i, UTI_TimevalToString(&prev), UTI_TimevalToString(sample),
|
||||
prev_offset, inst->offsets[i]);
|
||||
#else
|
||||
(void)prev_offset;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -648,6 +657,8 @@ SST_SlewSamples(SST_Stats inst, struct timeval *when, double dfreq, double doffs
|
||||
UTI_TimevalToString(&prev), UTI_TimevalToString(&(inst->offset_time)),
|
||||
prev_offset, inst->estimated_offset,
|
||||
1.0e6*prev_freq, 1.0e6*inst->estimated_frequency);
|
||||
#else
|
||||
(void)prev; (void)prev_freq;
|
||||
#endif
|
||||
|
||||
return;
|
||||
|
||||
@@ -38,7 +38,7 @@ extern void SST_Initialise(void);
|
||||
extern void SST_Finalise(void);
|
||||
|
||||
/* This function creates a new instance of the statistics handler */
|
||||
extern SST_Stats SST_CreateInstance(unsigned long refid, IPAddr *addr);
|
||||
extern SST_Stats SST_CreateInstance(uint32_t refid, IPAddr *addr);
|
||||
|
||||
/* This function deletes an instance of the statistics handler. */
|
||||
extern void SST_DeleteInstance(SST_Stats inst);
|
||||
@@ -89,10 +89,10 @@ SST_GetSelectionData(SST_Stats inst, struct timeval *now,
|
||||
|
||||
/* Get data needed when setting up tracking on this source */
|
||||
extern void
|
||||
SST_GetTrackingData(SST_Stats inst, struct timeval *now,
|
||||
SST_GetTrackingData(SST_Stats inst, struct timeval *ref_time,
|
||||
double *average_offset, double *offset_sd,
|
||||
double *accrued_dispersion,
|
||||
double *frequency, double *skew);
|
||||
double *frequency, double *skew,
|
||||
double *root_delay, double *root_dispersion);
|
||||
|
||||
/* Get parameters for using this source as the reference */
|
||||
extern void
|
||||
|
||||
@@ -24,6 +24,8 @@
|
||||
Replacement strerror function for systems that don't have it
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#ifdef SUNOS
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
2
sys.c
2
sys.c
@@ -25,6 +25,8 @@
|
||||
in the various operating-system specific modules
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "sys.h"
|
||||
#include "logging.h"
|
||||
|
||||
|
||||
325
sys_linux.c
325
sys_linux.c
@@ -27,6 +27,8 @@
|
||||
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#ifdef LINUX
|
||||
|
||||
#include <sys/time.h>
|
||||
@@ -104,8 +106,7 @@ static int version_patchlevel;
|
||||
/* Flag indicating whether adjtimex() returns the remaining time adjustment
|
||||
or not. If not we have to read the outstanding adjustment by setting it to
|
||||
zero, examining the return value and setting the outstanding adjustment back
|
||||
again. If 1, txc.modes equal to zero is used to read the time. If 2,
|
||||
txc.modes is set to ADJ_OFFSET_SS_READ. */
|
||||
again. */
|
||||
|
||||
static int have_readonly_adjtime;
|
||||
|
||||
@@ -493,14 +494,22 @@ initiate_slew(void)
|
||||
max_allowed_tick = nominal_tick + max_tick_bias;
|
||||
|
||||
if (offset_register > 0) {
|
||||
if (current_tick <= min_allowed_tick) {
|
||||
return;
|
||||
}
|
||||
|
||||
slewing_tick = current_tick - slew_delta_tick;
|
||||
if (slewing_tick <= min_allowed_tick) {
|
||||
slewing_tick = min_allowed_tick + 1;
|
||||
if (slewing_tick < min_allowed_tick) {
|
||||
slewing_tick = min_allowed_tick;
|
||||
}
|
||||
} else {
|
||||
if (current_tick >= max_allowed_tick) {
|
||||
return;
|
||||
}
|
||||
|
||||
slewing_tick = current_tick + slew_delta_tick;
|
||||
if (slewing_tick >= max_allowed_tick) {
|
||||
slewing_tick = max_allowed_tick - 1;
|
||||
if (slewing_tick > max_allowed_tick) {
|
||||
slewing_tick = max_allowed_tick;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -509,6 +518,8 @@ initiate_slew(void)
|
||||
delta_total_tick = (double) tick_adjust / 1.0e6;
|
||||
dseconds = - offset_register * (current_total_tick + delta_total_tick) / delta_total_tick;
|
||||
|
||||
assert(dseconds > 0.0);
|
||||
|
||||
/* Now set the thing off */
|
||||
if (gettimeofday(&T0, NULL) < 0) {
|
||||
LOG_FATAL(LOGF_SysLinux, "gettimeofday() failed");
|
||||
@@ -638,32 +649,14 @@ set_frequency(double freq_ppm)
|
||||
double scaled_freq; /* what adjtimex & the kernel use */
|
||||
double old_total_tick;
|
||||
int required_delta_tick;
|
||||
int neg; /* True if estimate is that local clock runs slow,
|
||||
i.e. positive frequency correction required */
|
||||
|
||||
|
||||
if (freq_ppm < 0.0) {
|
||||
neg = 1;
|
||||
freq_ppm = -freq_ppm;
|
||||
} else {
|
||||
neg = 0;
|
||||
}
|
||||
|
||||
required_delta_tick = our_round(freq_ppm / dhz);
|
||||
required_freq = freq_ppm - dhz * (double) required_delta_tick;
|
||||
required_freq = -(freq_ppm - dhz * required_delta_tick);
|
||||
required_tick = nominal_tick - required_delta_tick;
|
||||
scaled_freq = freq_scale * required_freq;
|
||||
|
||||
if (neg) {
|
||||
/* Uncompensated local clock runs slow */
|
||||
required_tick = nominal_tick + required_delta_tick;
|
||||
scaled_freq = freq_scale * required_freq;
|
||||
} else {
|
||||
/* Uncompensated local clock runs fast */
|
||||
required_tick = nominal_tick - required_delta_tick;
|
||||
scaled_freq = -freq_scale * required_freq;
|
||||
}
|
||||
|
||||
min_allowed_tick = nominal_tick - max_tick_bias + 5;
|
||||
max_allowed_tick = nominal_tick + max_tick_bias - 5;
|
||||
min_allowed_tick = nominal_tick - max_tick_bias;
|
||||
max_allowed_tick = nominal_tick + max_tick_bias;
|
||||
|
||||
if (required_tick < min_allowed_tick || required_tick > max_allowed_tick) {
|
||||
LOG(LOGS_WARN, LOGF_SysLinux, "Required tick %ld outside allowed range (%ld .. %ld)", required_tick, min_allowed_tick, max_allowed_tick);
|
||||
@@ -709,15 +702,17 @@ read_frequency(void)
|
||||
double tick_term;
|
||||
double unscaled_freq;
|
||||
double freq_term;
|
||||
long tick;
|
||||
|
||||
if (TMX_GetFrequency(&unscaled_freq) < 0) {
|
||||
if (TMX_GetFrequency(&unscaled_freq, &tick) < 0) {
|
||||
LOG_FATAL(LOGF_SysLinux, "adjtimex() failed");
|
||||
}
|
||||
|
||||
/* Use current_tick here rather than txc.tick, otherwise we're
|
||||
thrown off course when doing a fast slew (in which case, txc.tick
|
||||
is nowhere near the nominal value) */
|
||||
tick_term = dhz * (double)(nominal_tick - current_tick);
|
||||
if (fast_slewing) {
|
||||
tick -= slewing_tick - current_tick;
|
||||
}
|
||||
|
||||
tick_term = dhz * (double)(nominal_tick - tick);
|
||||
freq_term = unscaled_freq / freq_scale;
|
||||
|
||||
#if 0
|
||||
@@ -754,29 +749,19 @@ get_offset_correction(struct timeval *raw,
|
||||
if (!slow_slewing) {
|
||||
offset = 0;
|
||||
} else {
|
||||
switch (have_readonly_adjtime) {
|
||||
case 2:
|
||||
if (TMX_GetOffsetLeft(&offset) < 0) {
|
||||
LOG_FATAL(LOGF_SysLinux, "adjtimex() failed");
|
||||
}
|
||||
break;
|
||||
case 0:
|
||||
toffset = 0;
|
||||
if (TMX_ApplyOffset(&toffset) < 0) {
|
||||
LOG_FATAL(LOGF_SysLinux, "adjtimex() failed");
|
||||
}
|
||||
offset = toffset;
|
||||
if (TMX_ApplyOffset(&toffset) < 0) {
|
||||
LOG_FATAL(LOGF_SysLinux, "adjtimex() failed");
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
if (TMX_GetOffsetLeftOld(&offset) < 0) {
|
||||
LOG_FATAL(LOGF_SysLinux, "adjtimex() failed");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
if (have_readonly_adjtime) {
|
||||
if (TMX_GetOffsetLeft(&offset) < 0) {
|
||||
LOG_FATAL(LOGF_SysLinux, "adjtimex() failed");
|
||||
}
|
||||
} else {
|
||||
toffset = 0;
|
||||
if (TMX_ApplyOffset(&toffset) < 0) {
|
||||
LOG_FATAL(LOGF_SysLinux, "adjtimex() failed");
|
||||
}
|
||||
offset = toffset;
|
||||
if (TMX_ApplyOffset(&toffset) < 0) {
|
||||
LOG_FATAL(LOGF_SysLinux, "adjtimex() failed");
|
||||
}
|
||||
}
|
||||
|
||||
if (offset == 0) {
|
||||
@@ -869,6 +854,43 @@ guess_hz_and_shift_hz(int tick, int *hz, int *shift_hz)
|
||||
return;
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
static int
|
||||
get_hz_and_shift_hz(int *hz, int *shift_hz)
|
||||
{
|
||||
#ifdef _SC_CLK_TCK
|
||||
if ((*hz = sysconf(_SC_CLK_TCK)) < 1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (*hz == 100) {
|
||||
*shift_hz = 7;
|
||||
return 1;
|
||||
}
|
||||
|
||||
for (*shift_hz = 1; (*hz >> *shift_hz) > 1; (*shift_hz)++)
|
||||
;
|
||||
|
||||
return 1;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
static int
|
||||
kernelvercmp(int major1, int minor1, int patch1,
|
||||
int major2, int minor2, int patch2)
|
||||
{
|
||||
if (major1 != major2)
|
||||
return major1 - major2;
|
||||
if (minor1 != minor2)
|
||||
return minor1 - minor2;
|
||||
return patch1 - patch2;
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
/* Compute the scaling to use on any frequency we set, according to
|
||||
the vintage of the Linux kernel being used. */
|
||||
@@ -883,20 +905,23 @@ get_version_specific_details(void)
|
||||
int config_hz, set_config_hz; /* values of HZ from conf file */
|
||||
int set_config_freq_scale;
|
||||
double config_freq_scale;
|
||||
double calculated_freq_scale;
|
||||
struct tmx_params tmx_params;
|
||||
struct utsname uts;
|
||||
|
||||
TMX_ReadCurrentParams(&tmx_params);
|
||||
|
||||
guess_hz_and_shift_hz(tmx_params.tick, &hz, &shift_hz);
|
||||
if (!get_hz_and_shift_hz(&hz, &shift_hz)) {
|
||||
TMX_ReadCurrentParams(&tmx_params);
|
||||
|
||||
if (!shift_hz) {
|
||||
LOG_FATAL(LOGF_SysLinux, "Can't determine hz (txc.tick=%ld txc.freq=%ld (%.8f) txc.offset=%ld)",
|
||||
tmx_params.tick, tmx_params.freq, tmx_params.dfreq, tmx_params.offset);
|
||||
} else {
|
||||
LOG(LOGS_INFO, LOGF_SysLinux, "Initial txc.tick=%ld txc.freq=%ld (%.8f) txc.offset=%ld => hz=%d shift_hz=%d",
|
||||
tmx_params.tick, tmx_params.freq, tmx_params.dfreq, tmx_params.offset, hz, shift_hz);
|
||||
guess_hz_and_shift_hz(tmx_params.tick, &hz, &shift_hz);
|
||||
|
||||
if (!shift_hz) {
|
||||
LOG_FATAL(LOGF_SysLinux, "Can't determine hz (txc.tick=%ld txc.freq=%ld (%.8f) txc.offset=%ld)",
|
||||
tmx_params.tick, tmx_params.freq, tmx_params.dfreq, tmx_params.offset);
|
||||
} else {
|
||||
#if 0
|
||||
LOG(LOGS_INFO, LOGF_SysLinux, "Initial txc.tick=%ld txc.freq=%ld (%.8f) txc.offset=%ld => hz=%d shift_hz=%d",
|
||||
tmx_params.tick, tmx_params.freq, tmx_params.dfreq, tmx_params.offset, hz, shift_hz);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
CNF_GetLinuxHz(&set_config_hz, &config_hz);
|
||||
@@ -912,10 +937,6 @@ get_version_specific_details(void)
|
||||
max_tick_bias = nominal_tick / 10;
|
||||
tick_update_hz = hz;
|
||||
|
||||
LOG(LOGS_INFO, LOGF_SysLinux, "set_config_hz=%d hz=%d shift_hz=%d basic_freq_scale=%.8f nominal_tick=%d slew_delta_tick=%d max_tick_bias=%d",
|
||||
set_config_hz, hz, shift_hz, basic_freq_scale, nominal_tick, slew_delta_tick, max_tick_bias);
|
||||
|
||||
|
||||
/* The basic_freq_scale comes from:
|
||||
* the kernel increments the usec counter HZ times per second (if the timer
|
||||
interrupt period were perfect)
|
||||
@@ -946,7 +967,9 @@ get_version_specific_details(void)
|
||||
if (uname(&uts) < 0) {
|
||||
LOG_FATAL(LOGF_SysLinux, "Cannot uname(2) to get kernel version, sorry.");
|
||||
}
|
||||
if (sscanf(uts.release, "%d.%d.%d", &major, &minor, &patch) != 3) {
|
||||
|
||||
patch = 0;
|
||||
if (sscanf(uts.release, "%d.%d.%d", &major, &minor, &patch) < 2) {
|
||||
LOG_FATAL(LOGF_SysLinux, "Cannot read information from uname, sorry");
|
||||
}
|
||||
|
||||
@@ -956,101 +979,45 @@ get_version_specific_details(void)
|
||||
version_minor = minor;
|
||||
version_patchlevel = patch;
|
||||
|
||||
have_nanopll = 0;
|
||||
|
||||
switch (major) {
|
||||
case 1:
|
||||
/* Does Linux v1.x even support HZ!=100? */
|
||||
switch (minor) {
|
||||
case 2:
|
||||
if (patch == 13) {
|
||||
freq_scale = (hz==100) ? (128.0 / 100.0) : basic_freq_scale ; /* I _think_! */
|
||||
have_readonly_adjtime = 1;
|
||||
} else {
|
||||
LOG_FATAL(LOGF_SysLinux, "Kernel version not supported yet, sorry.");
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
/* I guess the change from the 1.2.x scaling to the 2.0.x
|
||||
scaling must have happened during 1.3 development. I
|
||||
haven't a clue where though, until someone looks it
|
||||
up. */
|
||||
LOG_FATAL(LOGF_SysLinux, "Kernel version not supported yet, sorry.");
|
||||
break;
|
||||
default:
|
||||
LOG_FATAL(LOGF_SysLinux, "Kernel version not supported yet, sorry.");
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
switch (minor) {
|
||||
case 0:
|
||||
if (patch < 32) {
|
||||
freq_scale = (hz==100) ? (128.0 / 125.0) : basic_freq_scale;
|
||||
have_readonly_adjtime = 1;
|
||||
} else if (patch >= 32) {
|
||||
freq_scale = (hz==100) ? (128.0 / 128.125) : basic_freq_scale;
|
||||
|
||||
/* The functionality in kernel/time.c in the kernel source
|
||||
was modified with regard to what comes back in the
|
||||
txc.offset field on return from adjtimex. If txc.modes
|
||||
was ADJ_OFFSET_SINGLESHOT on entry, the outstanding
|
||||
adjustment is returned, however the running offset will
|
||||
be modified to the passed value. */
|
||||
have_readonly_adjtime = 0;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
/* I know that earlier 2.1 kernels were like 2.0.31, hence
|
||||
the settings below. However, the 2.0.32 behaviour may
|
||||
have been added late in the 2.1 series, however I have no
|
||||
idea at which patch level. Leave it like this until
|
||||
someone supplies some info. */
|
||||
freq_scale = (hz==100) ? (128.0 / 125.0) : basic_freq_scale;
|
||||
have_readonly_adjtime = 0; /* For safety ! */
|
||||
break;
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
case 5:
|
||||
case 6:
|
||||
if (minor < 6 || patch < 27) {
|
||||
/* These seem to be like 2.0.32 */
|
||||
freq_scale = (hz==100) ? (128.0 / 128.125) : basic_freq_scale;
|
||||
have_readonly_adjtime = 0;
|
||||
break;
|
||||
}
|
||||
if (patch < 33) {
|
||||
/* Tickless kernels before 2.6.33 accumulated ticks only in
|
||||
half-second intervals. */
|
||||
tick_update_hz = 2;
|
||||
}
|
||||
/* Let's be optimistic that these will be the same until proven
|
||||
otherwise :-) */
|
||||
case 7:
|
||||
case 8:
|
||||
/* These don't seem to need scaling */
|
||||
freq_scale = 1.0;
|
||||
have_readonly_adjtime = 2;
|
||||
have_nanopll = 1;
|
||||
break;
|
||||
default:
|
||||
LOG_FATAL(LOGF_SysLinux, "Kernel version not supported yet, sorry.");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
LOG_FATAL(LOGF_SysLinux, "Kernel's major version not supported yet, sorry");
|
||||
break;
|
||||
if (kernelvercmp(major, minor, patch, 2, 2, 0) < 0) {
|
||||
LOG_FATAL(LOGF_SysLinux, "Kernel version not supported, sorry.");
|
||||
}
|
||||
|
||||
if (kernelvercmp(major, minor, patch, 2, 6, 27) < 0) {
|
||||
freq_scale = (hz == 100) ? (128.0 / 128.125) : basic_freq_scale;
|
||||
} else {
|
||||
/* These don't seem to need scaling */
|
||||
freq_scale = 1.0;
|
||||
|
||||
if (kernelvercmp(major, minor, patch, 2, 6, 33) < 0) {
|
||||
/* Tickless kernels before 2.6.33 accumulated ticks only in
|
||||
half-second intervals */
|
||||
tick_update_hz = 2;
|
||||
}
|
||||
}
|
||||
|
||||
/* ADJ_OFFSET_SS_READ support */
|
||||
if (kernelvercmp(major, minor, patch, 2, 6, 27) < 0) {
|
||||
have_readonly_adjtime = 0;
|
||||
} else {
|
||||
have_readonly_adjtime = 1;
|
||||
}
|
||||
|
||||
/* ADJ_NANO support */
|
||||
if (kernelvercmp(major, minor, patch, 2, 6, 27) < 0) {
|
||||
have_nanopll = 0;
|
||||
} else {
|
||||
have_nanopll = 1;
|
||||
}
|
||||
|
||||
/* Override freq_scale if it appears in conf file */
|
||||
CNF_GetLinuxFreqScale(&set_config_freq_scale, &config_freq_scale);
|
||||
calculated_freq_scale = freq_scale;
|
||||
if (set_config_freq_scale) freq_scale = config_freq_scale;
|
||||
|
||||
LOG(LOGS_INFO, LOGF_SysLinux, "calculated_freq_scale=%.8f freq_scale=%.8f",
|
||||
calculated_freq_scale, freq_scale);
|
||||
if (set_config_freq_scale) {
|
||||
freq_scale = config_freq_scale;
|
||||
}
|
||||
|
||||
LOG(LOGS_INFO, LOGF_SysLinux, "hz=%d shift_hz=%d freq_scale=%.8f nominal_tick=%d slew_delta_tick=%d max_tick_bias=%d",
|
||||
hz, shift_hz, freq_scale, nominal_tick, slew_delta_tick, max_tick_bias);
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
@@ -1060,25 +1027,19 @@ void
|
||||
SYS_Linux_Initialise(void)
|
||||
{
|
||||
long offset;
|
||||
double freq;
|
||||
|
||||
offset_register = 0.0;
|
||||
fast_slewing = 0;
|
||||
|
||||
get_version_specific_details();
|
||||
|
||||
current_tick = nominal_tick;
|
||||
current_total_tick = 1.0 / dhz;
|
||||
|
||||
lcl_RegisterSystemDrivers(read_frequency, set_frequency,
|
||||
accrue_offset, apply_step_offset,
|
||||
get_offset_correction, set_leap);
|
||||
|
||||
offset = 0;
|
||||
if (TMX_ApplyOffset(&offset) < 0) {
|
||||
LOG_FATAL(LOGF_SysLinux, "adjtimex() failed");
|
||||
}
|
||||
|
||||
if (have_readonly_adjtime == 2 && (TMX_GetOffsetLeft(&offset) < 0 || offset)) {
|
||||
if (have_readonly_adjtime && (TMX_GetOffsetLeft(&offset) < 0 || offset)) {
|
||||
LOG(LOGS_INFO, LOGF_SysLinux, "adjtimex() doesn't support ADJ_OFFSET_SS_READ");
|
||||
have_readonly_adjtime = 0;
|
||||
}
|
||||
@@ -1089,6 +1050,14 @@ SYS_Linux_Initialise(void)
|
||||
}
|
||||
|
||||
TMX_SetSync(CNF_GetRTCSync());
|
||||
|
||||
/* Read current kernel frequency */
|
||||
TMX_GetFrequency(&freq, ¤t_tick);
|
||||
current_total_tick = (current_tick + freq / freq_scale / dhz) / 1.0e6;
|
||||
|
||||
lcl_RegisterSystemDrivers(read_frequency, set_frequency,
|
||||
accrue_offset, apply_step_offset,
|
||||
get_offset_correction, set_leap);
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
@@ -1104,16 +1073,6 @@ SYS_Linux_Finalise(void)
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
void
|
||||
SYS_Linux_GetKernelVersion(int *major, int *minor, int *patchlevel)
|
||||
{
|
||||
*major = version_major;
|
||||
*minor = version_minor;
|
||||
*patchlevel = version_patchlevel;
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
#ifdef FEAT_LINUXCAPS
|
||||
void
|
||||
SYS_Linux_DropRoot(char *user)
|
||||
@@ -1154,7 +1113,9 @@ SYS_Linux_DropRoot(char *user)
|
||||
|
||||
cap_free(cap);
|
||||
|
||||
#if 0
|
||||
LOG(LOGS_INFO, LOGF_SysLinux, "Privileges dropped to user %s", user);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1183,7 +1144,9 @@ void SYS_Linux_SetScheduler(int SchedPriority)
|
||||
LOG(LOGS_ERR, LOGF_SysLinux, "sched_setscheduler() failed");
|
||||
}
|
||||
else {
|
||||
#if 0
|
||||
LOG(LOGS_INFO, LOGF_SysLinux, "Enabled SCHED_FIFO with priority %d", sched.sched_priority);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1207,7 +1170,9 @@ void SYS_Linux_MemLockAll(int LockAll)
|
||||
LOG(LOGS_ERR, LOGF_SysLinux, "mlockall() failed");
|
||||
}
|
||||
else {
|
||||
#if 0
|
||||
LOG(LOGS_INFO, LOGF_SysLinux, "Successfully locked into RAM");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,8 +31,6 @@ extern void SYS_Linux_Initialise(void);
|
||||
|
||||
extern void SYS_Linux_Finalise(void);
|
||||
|
||||
extern void SYS_Linux_GetKernelVersion(int *major, int *minor, int *patchlevel);
|
||||
|
||||
extern void SYS_Linux_DropRoot(char *user);
|
||||
|
||||
extern void SYS_Linux_MemLockAll(int LockAll);
|
||||
|
||||
@@ -25,6 +25,8 @@
|
||||
Driver file for the NetBSD operating system.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#ifdef __NetBSD__
|
||||
|
||||
#include <kvm.h>
|
||||
|
||||
@@ -24,6 +24,8 @@
|
||||
Driver file for Solaris operating system
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#ifdef SOLARIS
|
||||
|
||||
#include <kvm.h>
|
||||
|
||||
@@ -24,6 +24,8 @@
|
||||
Driver file for the SunOS 4.1.x operating system.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#ifdef SUNOS
|
||||
|
||||
#include <kvm.h>
|
||||
|
||||
@@ -25,6 +25,8 @@
|
||||
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "conf.h"
|
||||
#include "local.h"
|
||||
#include "memory.h"
|
||||
|
||||
6
util.c
6
util.c
@@ -25,6 +25,8 @@
|
||||
Various utility functions
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "sysincl.h"
|
||||
|
||||
#include "util.h"
|
||||
@@ -238,7 +240,7 @@ UTI_TimestampToString(NTP_int64 *ts)
|
||||
/* ================================================== */
|
||||
|
||||
char *
|
||||
UTI_RefidToString(unsigned long ref_id)
|
||||
UTI_RefidToString(uint32_t ref_id)
|
||||
{
|
||||
unsigned int i, j, c;
|
||||
char buf[5], *result;
|
||||
@@ -331,7 +333,7 @@ UTI_StringToIP(const char *addr, IPAddr *ip)
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
unsigned long
|
||||
uint32_t
|
||||
UTI_IPToRefid(IPAddr *ip)
|
||||
{
|
||||
MD5_CTX ctx;
|
||||
|
||||
4
util.h
4
util.h
@@ -71,13 +71,13 @@ extern char *UTI_TimevalToString(struct timeval *tv);
|
||||
extern char *UTI_TimestampToString(NTP_int64 *ts);
|
||||
|
||||
/* Convert ref_id into a temporary string, for diagnostics */
|
||||
extern char *UTI_RefidToString(unsigned long ref_id);
|
||||
extern char *UTI_RefidToString(uint32_t ref_id);
|
||||
|
||||
/* Convert an IP address to string, for diagnostics */
|
||||
extern char *UTI_IPToString(IPAddr *ip);
|
||||
|
||||
extern int UTI_StringToIP(const char *addr, IPAddr *ip);
|
||||
extern unsigned long UTI_IPToRefid(IPAddr *ip);
|
||||
extern uint32_t UTI_IPToRefid(IPAddr *ip);
|
||||
extern void UTI_IPHostToNetwork(IPAddr *src, IPAddr *dest);
|
||||
extern void UTI_IPNetworkToHost(IPAddr *src, IPAddr *dest);
|
||||
extern int UTI_CompareIPs(IPAddr *a, IPAddr *b, IPAddr *mask);
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
DEVELOPMENT
|
||||
@@ -29,6 +29,8 @@
|
||||
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#ifdef LINUX
|
||||
|
||||
#define _LOOSE_KERNEL_NAMES
|
||||
@@ -84,24 +86,14 @@ TMX_SetFrequency(double *freq, long tick)
|
||||
}
|
||||
|
||||
int
|
||||
TMX_GetFrequency(double *freq)
|
||||
TMX_GetFrequency(double *freq, long *tick)
|
||||
{
|
||||
struct timex txc;
|
||||
int result;
|
||||
txc.modes = 0; /* pure read */
|
||||
result = adjtimex(&txc);
|
||||
*freq = txc.freq / (double)(1 << SHIFT_USEC);
|
||||
return result;
|
||||
}
|
||||
|
||||
int
|
||||
TMX_GetOffsetLeftOld(long *offset)
|
||||
{
|
||||
struct timex txc;
|
||||
int result;
|
||||
txc.modes = 0; /* pure read */
|
||||
result = adjtimex(&txc);
|
||||
*offset = txc.offset;
|
||||
*tick = txc.tick;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -67,8 +67,7 @@ struct tmx_params {
|
||||
int TMX_SetTick(long tick);
|
||||
int TMX_ApplyOffset(long *offset);
|
||||
int TMX_SetFrequency(double *freq, long tick);
|
||||
int TMX_GetFrequency(double *freq);
|
||||
int TMX_GetOffsetLeftOld(long *offset);
|
||||
int TMX_GetFrequency(double *freq, long *tick);
|
||||
int TMX_GetOffsetLeft(long *offset);
|
||||
int TMX_ReadCurrentParams(struct tmx_params *params);
|
||||
int TMX_SetLeap(int leap);
|
||||
|
||||
Reference in New Issue
Block a user