Compare commits

...

68 Commits

Author SHA1 Message Date
Miroslav Lichvar
4fac84098e Update NEWS 2011-07-13 14:55:28 +02:00
Miroslav Lichvar
21b2063a6f Retry on permanent DNS error by default 2011-07-13 14:49:22 +02:00
Miroslav Lichvar
917c191650 Update NEWS 2011-06-24 13:45:16 +02:00
Miroslav Lichvar
2bfce03d29 Add configure option for sendmail path 2011-06-24 13:27:30 +02:00
Miroslav Lichvar
1cb8167be0 Generate version and date in man pages 2011-06-24 12:30:48 +02:00
Miroslav Lichvar
40d33cc64d Convert make_release to shell script 2011-06-24 12:27:54 +02:00
Miroslav Lichvar
95433e9639 Remove chrony.lsm 2011-06-23 17:49:18 +02:00
Miroslav Lichvar
bbe1a09e7e Step also cooked select timestamp in scheduler slew handler 2011-06-23 15:23:16 +02:00
Miroslav Lichvar
dce2366b3a Detect infinite loop in scheduler
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.
2011-06-23 15:14:08 +02:00
Miroslav Lichvar
bab7ba22cf Add asserts for timeout delays 2011-06-23 13:42:04 +02:00
Miroslav Lichvar
d6a91057ae Add waitsync command 2011-06-23 12:13:51 +02:00
Miroslav Lichvar
c6e9065498 Fix current_total_tick calculation 2011-06-15 15:35:15 +02:00
Miroslav Lichvar
22fda21eae Don't call driver read_freq in LCL_ReadAbsoluteFrequency 2011-06-15 15:35:14 +02:00
Miroslav Lichvar
103a520aa6 Create logdir before making first tracking write 2011-06-15 15:35:14 +02:00
Miroslav Lichvar
86531a51a7 Don't update drift file on first reference update 2011-06-15 15:35:14 +02:00
Miroslav Lichvar
2b7e4d645f Don't reset kernel frequency on start without drift file 2011-06-15 15:35:00 +02:00
Miroslav Lichvar
a5f63180fc Don't use uninitialized values 2011-06-13 18:17:33 +02:00
Miroslav Lichvar
934d4e04b5 Validate leap status in refclock samples 2011-06-13 17:03:30 +02:00
Miroslav Lichvar
1b8547059a Set leap status by enum 2011-06-13 17:02:42 +02:00
Miroslav Lichvar
91279a0f28 Store reference IDs in uint32_t 2011-06-13 15:34:16 +02:00
Miroslav Lichvar
31ba3144c8 Don't limit refclock driver name to 4 chars 2011-06-13 13:49:46 +02:00
Miroslav Lichvar
0bf34725e3 Don't try to recover from our own time steps 2011-06-10 18:57:04 +02:00
Miroslav Lichvar
91749ebb2b Try to handle unexpected backward time jumps 2011-06-10 18:29:41 +02:00
Miroslav Lichvar
4ba3dd66ad Set version string in config.h 2011-06-09 14:32:22 +02:00
Miroslav Lichvar
d40696f7f3 Add .deps to .gitignore 2011-06-09 14:31:04 +02:00
Miroslav Lichvar
4a401a9e83 Make .deps order-only prerequisite 2011-06-09 13:56:45 +02:00
Miroslav Lichvar
6a2a837ede Remove kernel version check from rtc code
It should work with all currently supported kernels (>= 2.2.0).
2011-06-06 21:33:59 +02:00
Miroslav Lichvar
eca08a281c Determine hz and shift from sysconf(_SC_CLK_TCK) when available 2011-06-06 17:41:14 +02:00
Miroslav Lichvar
9fd8f76fa0 Log final version specific details 2011-06-06 17:12:31 +02:00
Miroslav Lichvar
50de930730 Drop support for old readonly adjtime 2011-06-06 17:12:31 +02:00
Miroslav Lichvar
da1097095c Drop support for pre 2.2 Linux kernels 2011-06-06 17:12:31 +02:00
Miroslav Lichvar
ec7d302a6c Support Linux 3.0 and later 2011-06-06 13:56:27 +02:00
Miroslav Lichvar
8cc7ebffa9 Accept packets with compatible NTP versions
All incoming NTP packets are now required to have version 2, 3 or 4.
2011-05-25 16:59:40 +02:00
Miroslav Lichvar
de4d14843f Set source IPv6 address on NTP reply
This is needed on systems with multiple IPv6 addresses to reply with
the same source address as the destination address of the NTP request.
2011-05-24 18:07:06 +02:00
Miroslav Lichvar
18605795a7 Merge CCWARNFLAGS with CFLAGS 2011-05-24 18:07:06 +02:00
Miroslav Lichvar
da2c8d9076 Use config.h 2011-05-24 18:07:06 +02:00
Miroslav Lichvar
3120f8adb6 Use object dependencies in Makefile 2011-05-24 18:06:49 +02:00
Miroslav Lichvar
2dcc16169b Update NEWS 2011-05-04 12:29:40 +02:00
Miroslav Lichvar
a8efd8c398 Update versions in man pages 2011-05-02 13:21:50 +02:00
Miroslav Lichvar
bb40f4aff4 Modify weight calculation again
Dividing the weights by variance or unweighted variance seems to have a
significant negative impact on response with normally distributed
network delays.

Divide by the difference between the mean and minimum distance instead.
It should be stable as there is no loop and the response seems to be a
good compromise between the original minimum distance weighting which
works well with normally distributed delays and the variance weighting
which works well with exponentially distributed delays.
2011-04-29 13:29:56 +02:00
Miroslav Lichvar
66c7ac4d24 Revert using unweighted variance in weight calculation
This reverts commit 165e6805ab.
2011-04-29 13:29:24 +02:00
Miroslav Lichvar
7f12919fea Increase smoothing factor in refclock variance 2011-04-20 12:41:05 +02:00
Miroslav Lichvar
55e0c6a0a1 Update NEWS 2011-04-18 12:59:06 +02:00
Miroslav Lichvar
20f306602b Add another chrony.conf example 2011-04-18 12:57:01 +02:00
Miroslav Lichvar
70735d8d79 Ignore extra samples in reported nruns 2011-04-18 12:36:02 +02:00
Miroslav Lichvar
165e6805ab In weight calculation use unweighted variance from last regression
This fixes a positive feedback where weights could reach inf.
Also change the SD_TO_DIST_RATIO constant to get close to the original
response.
2011-04-13 18:43:25 +02:00
Miroslav Lichvar
2a0c35646c Allow changing tick up to max_tick_bias 2011-04-12 16:40:22 +02:00
Miroslav Lichvar
28710e0449 Change default maxclockerror to 1 ppm 2011-04-11 17:54:01 +02:00
Miroslav Lichvar
c5587b60b2 Set reference time to last sample instead of time on update
This is done mainly to fix reported root dispersion to include max clock
error after selecting another source without new sample.
2011-04-11 17:52:04 +02:00
Miroslav Lichvar
bb95c39356 Update refclock documentation 2011-04-08 16:53:11 +02:00
Miroslav Lichvar
20a43409c6 Add new commands to protocol comment in candm.h 2011-04-07 18:35:02 +02:00
Miroslav Lichvar
4699f7ca0b Update client copyright message 2011-04-07 18:35:02 +02:00
Miroslav Lichvar
bc7586b3f4 Assert there are no unhandled commands in cmdmon 2011-04-07 18:34:47 +02:00
Miroslav Lichvar
8d3d45ea1a Add reselectdist command 2011-04-07 18:16:39 +02:00
Miroslav Lichvar
21ba1d3761 Don't add \n to chronyc command line arguments
This fixes parsing of some commands.
2011-04-07 16:17:58 +02:00
Miroslav Lichvar
e79584bb9e Revert marking offline sources as unreachable 2011-04-07 14:44:56 +02:00
Miroslav Lichvar
bca7819247 Don't crash when sources report is requested soon after start 2011-04-06 16:59:40 +02:00
Miroslav Lichvar
0ecabae2c3 Add include directive 2011-04-06 16:58:12 +02:00
Miroslav Lichvar
598c04eea2 Add configure option to force retry on DNS failure
This is apparently needed on system which keep nameservers specified
in /etc/resolv.conf even when there is no network connection. Should be
used with care as invalid names will be retried forever.
2011-04-05 18:14:05 +02:00
Miroslav Lichvar
faec23f6bd Don't update empty sourcestats on clock update 2011-04-05 16:32:50 +02:00
Miroslav Lichvar
896dad9224 Fix warnings produced by latest gcc 2011-02-15 18:55:34 +01:00
Miroslav Lichvar
680612cf09 Reduce Linux driver verbosity 2011-02-15 17:22:40 +01:00
Miroslav Lichvar
3fbd4bb15f Don't log error on opening driftfile
Log frequency and skew values read from the driftfile instead.
2011-02-15 16:56:30 +01:00
Miroslav Lichvar
cb9055072d Make starting log even in debug mode 2011-02-14 18:21:38 +01:00
Miroslav Lichvar
0fc9b555f1 Don't log in signal handler 2011-02-14 18:19:58 +01:00
Miroslav Lichvar
6ed58628f5 Don't use uninitialized memory when setting RTC time 2011-02-11 17:56:05 +01:00
Miroslav Lichvar
efff149988 Use system headers for Linux RTC support 2011-02-11 17:56:05 +01:00
Miroslav Lichvar
b02d4092f1 Fix compiler warnings in PPS configure test 2011-02-11 17:31:38 +01:00
65 changed files with 999 additions and 685 deletions

1
.gitignore vendored
View File

@@ -1,3 +1,4 @@
.deps
*.swp
*.o
Makefile

View File

@@ -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
View File

@@ -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

View File

@@ -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;
}

View File

@@ -28,6 +28,8 @@
*/
#include "config.h"
#include "sysincl.h"
#include "addrfilt.h"

View File

@@ -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
View File

@@ -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;

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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.

View File

@@ -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
View File

@@ -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);

View File

@@ -31,6 +31,8 @@
*/
#include "config.h"
#include "sysincl.h"
#include "clientlog.h"
#include "conf.h"

View File

@@ -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 {

View File

@@ -26,6 +26,8 @@
*/
#include "config.h"
#include "sysincl.h"
#include "cmdparse.h"

42
conf.c
View File

@@ -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
View File

@@ -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}%;\

View 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

View File

@@ -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
View File

@@ -25,6 +25,8 @@
*/
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

25
local.c
View File

@@ -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)
{

View File

@@ -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);

View File

@@ -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
View File

@@ -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;

View File

@@ -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

View File

@@ -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
View File

@@ -37,6 +37,8 @@
***********************************************************************
*/
#include "config.h"
#include "md5.h"
/*

View File

@@ -26,6 +26,8 @@
*/
#include "config.h"
#include "sysincl.h"
#include "mkdirpp.h"

View File

@@ -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

View File

@@ -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
}
/* ================================================== */

View File

@@ -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
}

View File

@@ -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));

View File

@@ -27,6 +27,8 @@
*/
#include "config.h"
#include "sysincl.h"
#include "ntp_sources.h"

View File

@@ -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:

View File

@@ -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
}
}

View File

@@ -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

View File

@@ -25,6 +25,8 @@
*/
#include "config.h"
#include "refclock.h"
#if HAVE_PPSAPI

View File

@@ -25,6 +25,8 @@
*/
#include "config.h"
#include "refclock.h"
#include "logging.h"
#include "util.h"

View File

@@ -25,6 +25,8 @@
*/
#include "config.h"
#include "refclock.h"
#include "logging.h"
#include "util.h"

View File

@@ -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;

View File

@@ -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,

View File

@@ -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. */

View File

@@ -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;

2
rtc.c
View File

@@ -23,6 +23,8 @@
*/
#include "config.h"
#include "sysincl.h"
#include "rtc.h"

View File

@@ -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
View File

@@ -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 {

View File

@@ -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;

View File

@@ -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. */

View File

@@ -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;

View File

@@ -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

View File

@@ -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
View File

@@ -25,6 +25,8 @@
in the various operating-system specific modules
*/
#include "config.h"
#include "sys.h"
#include "logging.h"

View File

@@ -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, &current_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
}
}
}

View File

@@ -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);

View File

@@ -25,6 +25,8 @@
Driver file for the NetBSD operating system.
*/
#include "config.h"
#ifdef __NetBSD__
#include <kvm.h>

View File

@@ -24,6 +24,8 @@
Driver file for Solaris operating system
*/
#include "config.h"
#ifdef SOLARIS
#include <kvm.h>

View File

@@ -24,6 +24,8 @@
Driver file for the SunOS 4.1.x operating system.
*/
#include "config.h"
#ifdef SUNOS
#include <kvm.h>

View File

@@ -25,6 +25,8 @@
*/
#include "config.h"
#include "conf.h"
#include "local.h"
#include "memory.h"

6
util.c
View File

@@ -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
View File

@@ -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);

View File

@@ -1 +0,0 @@
DEVELOPMENT

View File

@@ -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;
}

View File

@@ -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);