summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVincent Blut <vincent.debian@free.fr>2019-05-03 23:09:08 +0200
committerVincent Blut <vincent.debian@free.fr>2019-05-03 23:09:08 +0200
commit2aeb886c840372ecf7daf6f1461c0aa6c3fc62bc (patch)
tree85bbaf7ab088272e34297039c63fe8ed8302eb80
parent6e35115cec449f05061b37a848fca709125a2ce4 (diff)
parentaff496ced38fb2ac20b6b4607c29a9b25042d28f (diff)
Update upstream source from tag 'upstream/3.5-pre1'
Update to upstream version '3.5-pre1' with Debian dir 82dd6af14ed17f2d5308de50d11b159b7e5c84b3
-rw-r--r--FAQ8
-rw-r--r--INSTALL23
-rw-r--r--Makefile.in2
-rw-r--r--NEWS17
-rw-r--r--README109
-rwxr-xr-xconfigure43
-rw-r--r--doc/chrony.conf.adoc58
-rw-r--r--doc/chrony.conf.man.in62
-rw-r--r--doc/chronyc.man.in4
-rw-r--r--doc/chronyd.man.in4
-rw-r--r--doc/faq.adoc6
-rw-r--r--doc/installation.adoc13
-rw-r--r--hash_intmd5.c1
-rw-r--r--nameserv.c3
-rw-r--r--ntp_io.c14
-rw-r--r--ntp_io_linux.c6
-rw-r--r--refclock.c64
-rw-r--r--refclock.h1
-rw-r--r--refclock_phc.c3
-rw-r--r--refclock_pps.c3
-rw-r--r--refclock_shm.c3
-rw-r--r--refclock_sock.c2
-rw-r--r--sys.c13
-rw-r--r--sys_linux.c206
-rw-r--r--sys_linux.h4
-rw-r--r--sys_macosx.c42
-rw-r--r--sys_posix.c109
-rw-r--r--sys_posix.h36
-rw-r--r--sysincl.h2
-rwxr-xr-xtest/simulation/008-ntpera2
-rwxr-xr-xtest/simulation/105-ntpauth2
-rwxr-xr-xtest/simulation/106-refclock4
-rwxr-xr-xtest/simulation/107-allowdeny2
-rwxr-xr-xtest/simulation/110-chronyc3
-rwxr-xr-xtest/simulation/112-port2
-rwxr-xr-xtest/simulation/113-leapsecond3
-rwxr-xr-xtest/simulation/115-cmdmontime3
-rwxr-xr-xtest/simulation/119-smoothtime3
-rwxr-xr-xtest/simulation/121-orphan2
-rwxr-xr-xtest/simulation/124-tai3
-rwxr-xr-xtest/simulation/128-nocontrol2
-rwxr-xr-xtest/simulation/133-hwtimestamp4
-rwxr-xr-xtest/simulation/134-log3
-rw-r--r--test/simulation/test.common8
-rwxr-xr-xtest/system/001-minimal13
-rwxr-xr-xtest/system/002-extended13
-rwxr-xr-xtest/system/003-memlock15
-rwxr-xr-xtest/system/004-priority15
-rwxr-xr-xtest/system/005-scfilter17
-rwxr-xr-xtest/system/006-privdrop17
-rwxr-xr-xtest/system/007-cmdmon69
-rwxr-xr-xtest/system/100-clockupdate30
-rwxr-xr-xtest/system/101-rtc19
-rwxr-xr-xtest/system/102-hwtimestamp28
-rwxr-xr-xtest/system/103-refclock19
-rwxr-xr-xtest/system/104-systemdirs19
-rwxr-xr-xtest/system/run64
-rw-r--r--test/system/test.common339
-rw-r--r--test/unit/ntp_core.c16
-rw-r--r--test/unit/ntp_sources.c14
-rw-r--r--test/unit/test.c8
-rw-r--r--test/unit/test.h9
-rw-r--r--version.txt2
63 files changed, 1279 insertions, 354 deletions
diff --git a/FAQ b/FAQ
index 089b3b8..f4b38fe 100644
--- a/FAQ
+++ b/FAQ
@@ -227,6 +227,12 @@ tens of nanoseconds may be possible. For example:
server ntp.local minpoll 0 maxpoll 0 xleave
hwtimestamp eth0
+For best stability, the CPU should be running at a constant frequency (i.e.
+disabled power saving and performance boosting). Energy-Efficient Ethernet
+(EEE) should be disabled in the network. The switches should be configured to
+prioritize NTP packets, especially if the network is expected to be heavily
+loaded.
+
If it is acceptable for NTP clients in the network to send requests at an
excessive rate, a sub-second polling interval may be specified. A median filter
can be enabled in order to update the clock at a reduced rate with more stable
@@ -538,4 +544,4 @@ needs to be made to work as a service.
We have no plans to do this. Anyone is welcome to pick this work up and
contribute it back to the project.
-Last updated 2018-09-19 16:38:15 CEST
+Last updated 2019-05-02 11:50:41 CEST
diff --git a/INSTALL b/INSTALL
index b4ad72f..a77cfa7 100644
--- a/INSTALL
+++ b/INSTALL
@@ -4,6 +4,27 @@ The software is distributed as source code which has to be compiled. The source
code is supplied in the form of a gzipped tar file, which unpacks to a
subdirectory identifying the name and version of the program.
+The following programs and libraries with their development files are needed to
+build chrony:
+
+ o C compiler (gcc or clang recommended)
+
+ o GNU Make
+
+ o Nettle, NSS, or LibTomCrypt (optional)
+
+ o Editline (optional)
+
+ o libcap (Linux only, optional)
+
+ o libseccomp (Linux only, optional)
+
+ o timepps.h header (optional)
+
+ o Asciidoctor (for HTML documentation)
+
+ o Bash (for testing)
+
After unpacking the source code, change directory into it, and type
./configure
@@ -171,4 +192,4 @@ tar cvf - . | gzip -9 > chrony.tar.gz
to build a package. When untarred within the root directory, this will install
the files to the intended final locations.
-Last updated 2018-09-19 16:38:15 CEST
+Last updated 2019-05-02 11:50:41 CEST
diff --git a/Makefile.in b/Makefile.in
index 2d3e67d..8e68ef4 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -113,10 +113,12 @@ install-docs :
quickcheck : chronyd chronyc
$(MAKE) -C test/unit check
cd test/simulation && ./run
+ cd test/system && ./run
check : chronyd chronyc
$(MAKE) -C test/unit check
cd test/simulation && ./run -i 20 -m 2
+ cd test/system && ./run
print-chronyd-objects :
@echo $(OBJS) $(EXTRA_OBJS)
diff --git a/NEWS b/NEWS
index 51a0c22..b0baf06 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,20 @@
+New in version 3.5
+==================
+
+Enhancements
+------------
+* Add support for more accurate reading of PHC on Linux 5.0
+* Add support for memory locking and real-time priority on FreeBSD,
+ NetBSD, Solaris
+* Update seccomp filter to work on more architectures
+* Validate refclock driver options
+
+Bug fixes
+---------
+* Fix bindaddress directive on FreeBSD
+* Fix transposition of hardware RX timestamp on Linux 4.13 and later
+* Fix building on non-glibc systems
+
New in version 3.4
==================
diff --git a/README b/README
index aad727e..a492446 100644
--- a/README
+++ b/README
@@ -108,132 +108,57 @@ The following people have provided patches and other major contributions
to the program :
Lonnie Abelbeck <lonnie@abelbeck.com>
- Patch to add tab-completion to chronyc
-
Benny Lyne Amorsen <benny@amorsen.dk>
- Patch to add minstratum option
-
Andrew Bishop <amb@gedanken.demon.co.uk>
- Fixes for bugs in logging when in daemon mode
- Fixes for compiler warnings
- Robustness improvements for drift file
- Improve installation (directory checking etc)
- Entries in contrib directory
- Improvements to 'sources' and 'sourcestats' output from chronyc
- Improvements to documentation
- Investigation of required dosynctodr behaviour for various Solaris
- versions
-
+Vincent Blut <vincent.debian@free.fr>
Stephan I. Boettcher <stephan@nevis1.columbia.edu>
- Entries in contrib directory
-
+Goswin Brederlow <brederlo@informatik.uni-tuebingen.de>
+Leigh Brown <leigh@solinno.co.uk>
Erik Bryer <ebryer@spots.ab.ca>
- Entries in contrib directory
-
+Jonathan Cameron <jic23@cam.ac.uk>
Bryan Christianson <bryan@whatroute.net>
- Support for macOS
- Support for privilege separation
- Entries in contrib directory
-
Juliusz Chroboczek <jch@pps.jussieu.fr>
- Patch to fix install rule in Makefile if chronyd file is in use
-
Christian Ehrhardt <christian.ehrhardt@canonical.com>
- Patch to generate a warning message when CAP_SYS_TIME is missing
-
Paul Elliott <pelliott@io.com>
- Entries in contrib directory
-
+Stefan R. Filipek <srfilipek@gmail.com>
Mike Fleetwood <mike@rockover.demon.co.uk>
- Fixes for compiler warnings
-
Alexander Gretencord <arutha@gmx.de>
- Changes to installation directory system to make it easier for
- package builders
-
Andrew Griffiths <agriffit@redhat.com>
- Patch to add support for seccomp filter
-
Walter Haidinger <walter.haidinger@gmx.at>
- Access to a Linux installation where v1.12 wouldn't compile
- Disc space for an independent backup of the sources
-
Juergen Hannken-Illjes <hannken@eis.cs.tu-bs.de>
- Port to NetBSD
-
John Hasler <john@dhh.gt.org>
- Project and website at tuxfamily.org
- Changes to support 64 bit machines (i.e. those where
- sizeof(unsigned long) > 4)
- Bug fix to initstepslew directive
- Fix to remove potential buffer overrun errors
- Memory locking and real-time scheduler support
- Fix fault where chronyd enters an endless loop
-
Tjalling Hattink <t.hattink@fugro.nl>
- Fix scheduler to allow stepping clock from timeout handler
- Patch to take leap second in PPS refclock from locked source
- Patch to make reading of RTC for initial trim more reliable
-
Liam Hatton <me@liamhatton.com>
- Advice on configuring for Linux on PPC
-
Jachym Holecek <jakym@volny.cz>
- Patch to make Linux real time clock work with devfs
-
HÃ¥kan Johansson <f96hajo@chalmers.se>
- Patch to avoid large values in sources and sourcestats output
-
Jim Knoble <jmknoble@pobox.com>
- Fixes for compiler warnings
-
Antti Jrvinen <costello@iki.fi>
- Advice on configuring for BSD/386
-
+Eric Lammerts <eric@lammerts.org>
+Stefan Lucke <stefan@lucke.in-berlin.de>
+Victor Lum <viclum@vanu.com>
+Kevin Lyda <kevin@ie.suberic.net>
+Paul Menzel <paulepanter@users.sourceforge.net>
+Vladimir Michl <vladimir.michl@seznam.cz>
Victor Moroz <vim@prv.adlum.ru>
- Patch to support Linux with HZ!=100
-
Kalle Olavi Niemitalo <tosi@stekt.oulu.fi>
- Patch to add acquisitionport directive
-
Frank Otto <sandwichmacher@web.de>
- Handling arbitrary HZ values
-
Denny Page <dennypage@me.com>
- Advice on support for hardware timestamping
-
Chris Perl <cperl@janestreet.com>
- Patches to improve support for refclocks keeping time in TAI
-
Gautier PHILIPPON <gautier.philippon@ensimag.grenoble-inp.fr>
- Patch to add refresh command to chronyc
-
Andreas Piesk <apiesk@virbus.de>
- Patch to make chronyc use the readline library if available
-
Andreas Steinmetz <ast@domdv.de>
- Patch to make stratum of refclocks configurable
-
+NAKAMURA Takumi <takumi@ps.sakura.ne.jp>
Timo Teras <timo.teras@iki.fi>
- Patch to reply correctly on multihomed hosts
-
Bill Unruh <unruh@physics.ubc.ca>
- Advice on statistics
-
Stephen Wadeley <swadeley@redhat.com>
- Improvements to man pages
-
+Bernhard Weiss <lisnablagh@web.de>
Wolfgang Weisselberg <weissel@netcologne.de>
- Entries in contrib directory
-
+Bernhard M. Wiedemann <bwiedemann@suse.de>
+Joachim Wiedorn <ad_debian@joonet.de>
Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
- Many robustness and security improvements
-
-Ulrich Windl <ulrich.windl@rz.uni-regensburg.de> for the
- Information about the Linux 2.2 kernel functionality compared to 2.0
-
+Ulrich Windl <ulrich.windl@rz.uni-regensburg.de>
Doug Woodward <dougw@whistler.com>
- Advice on configuring for Solaris 2.8 on x86
+Thomas Zajic <zlatko@zlatko.fdns.net>
Many other people have contributed bug reports and suggestions. We are sorry
we cannot identify all of you individually.
diff --git a/configure b/configure
index 486b0bc..9e21a8b 100755
--- a/configure
+++ b/configure
@@ -227,6 +227,7 @@ feat_timestamping=1
try_timestamping=0
feat_ntp_signd=0
ntp_era_split=""
+use_pthread=0
default_user="root"
default_hwclockfile=""
default_pidfile="/var/run/chrony/chronyd.pid"
@@ -395,7 +396,7 @@ SYSTEM=${OPERATINGSYSTEM}-${MACHINE}
case $OPERATINGSYSTEM in
Linux)
- EXTRA_OBJECTS="sys_generic.o sys_linux.o sys_timex.o"
+ EXTRA_OBJECTS="sys_generic.o sys_linux.o sys_timex.o sys_posix.o"
[ $try_libcap != "0" ] && try_libcap=1
try_rtc=1
[ $try_seccomp != "0" ] && try_seccomp=1
@@ -410,7 +411,9 @@ case $OPERATINGSYSTEM in
# recvmmsg() seems to be broken on FreeBSD 11.0 and it's just
# a wrapper around recvmsg()
try_recvmmsg=0
- EXTRA_OBJECTS="sys_generic.o sys_netbsd.o sys_timex.o"
+ EXTRA_OBJECTS="sys_generic.o sys_netbsd.o sys_timex.o sys_posix.o"
+ try_setsched=1
+ try_lockmem=1
add_def FREEBSD
if [ $feat_droproot = "1" ]; then
add_def FEAT_PRIVDROP
@@ -419,8 +422,10 @@ case $OPERATINGSYSTEM in
echo "Configuring for $SYSTEM"
;;
NetBSD)
- EXTRA_OBJECTS="sys_generic.o sys_netbsd.o sys_timex.o"
+ EXTRA_OBJECTS="sys_generic.o sys_netbsd.o sys_timex.o sys_posix.o"
try_clockctl=1
+ try_setsched=1
+ try_lockmem=1
add_def NETBSD
echo "Configuring for $SYSTEM"
;;
@@ -445,9 +450,11 @@ case $OPERATINGSYSTEM in
echo "Configuring for macOS (" $SYSTEM "macOS version" $VERSION ")"
;;
SunOS)
- EXTRA_OBJECTS="sys_generic.o sys_solaris.o sys_timex.o"
+ EXTRA_OBJECTS="sys_generic.o sys_solaris.o sys_timex.o sys_posix.o"
EXTRA_LIBS="-lsocket -lnsl -lresolv"
EXTRA_CLI_LIBS="-lsocket -lnsl -lresolv"
+ try_setsched=1
+ try_lockmem=1
add_def SOLARIS
# These are needed to have msg_control in struct msghdr
add_def __EXTENSIONS__
@@ -652,7 +659,7 @@ then
add_def FEAT_ASYNCDNS
add_def USE_PTHREAD_ASYNCDNS
EXTRA_OBJECTS="$EXTRA_OBJECTS nameserv_async.o"
- MYCFLAGS="$MYCFLAGS -pthread"
+ use_pthread=1
fi
if test_code 'arc4random_buf()' 'stdlib.h' '' '' 'arc4random_buf(NULL, 0);'; then
@@ -786,25 +793,33 @@ fi
if [ $try_setsched = "1" ] && \
test_code \
- 'sched_setscheduler()' \
- 'sched.h' '' '' '
+ 'pthread_setschedparam()' \
+ 'pthread.h sched.h' '-pthread' '' '
struct sched_param sched;
sched_get_priority_max(SCHED_FIFO);
- sched_setscheduler(0, SCHED_FIFO, &sched);'
+ pthread_setschedparam(pthread_self(), SCHED_FIFO, &sched);'
then
- add_def HAVE_SCHED_SETSCHEDULER
+ add_def HAVE_PTHREAD_SETSCHEDPARAM
+ use_pthread=1
fi
if [ $try_lockmem = "1" ] && \
test_code \
'mlockall()' \
- 'sys/mman.h sys/resource.h' '' '' '
- struct rlimit rlim;
- setrlimit(RLIMIT_MEMLOCK, &rlim);
+ 'sys/mman.h' '' '' '
mlockall(MCL_CURRENT|MCL_FUTURE);'
then
add_def HAVE_MLOCKALL
fi
+if [ $try_lockmem = "1" ] && \
+ test_code \
+ 'setrlimit(RLIMIT_MEMLOCK, ...)' \
+ 'sys/resource.h' '' '' '
+ struct rlimit rlim;
+ setrlimit(RLIMIT_MEMLOCK, &rlim);'
+then
+ add_def HAVE_SETRLIMIT_MEMLOCK
+fi
if [ $feat_forcednsretry = "1" ]
then
@@ -896,6 +911,10 @@ if [ $feat_sechash = "1" ] && [ "x$HASH_LINK" = "x" ] && [ $try_tomcrypt = "1" ]
fi
fi
+if [ $use_pthread = "1" ]; then
+ MYCFLAGS="$MYCFLAGS -pthread"
+fi
+
SYSCONFDIR=/etc
if [ "x$SETSYSCONFDIR" != "x" ]; then
SYSCONFDIR=$SETSYSCONFDIR
diff --git a/doc/chrony.conf.adoc b/doc/chrony.conf.adoc
index 4b1239f..e1fbef3 100644
--- a/doc/chrony.conf.adoc
+++ b/doc/chrony.conf.adoc
@@ -374,12 +374,12 @@ for *initstepslew* to finish before exiting. This is useful to prevent programs
started in the boot sequence after *chronyd* from reading the clock before it
has been stepped.
-[[refclock]]*refclock* _driver_ _parameter_[:__option__,...] [_option_]...::
+[[refclock]]*refclock* _driver_ _parameter_[:__option__]... [_option_]...::
The *refclock* directive specifies a hardware reference clock to be used as a
time source. It has two mandatory parameters, a driver name and a
driver-specific parameter. The two parameters are followed by zero or more
refclock options. Some drivers have special options, which can be appended to
-the driver-specific parameter (separated by the *:* and *,* characters).
+the driver-specific parameter using the *:* character.
+
There are four drivers included in *chronyd*:
+
@@ -476,7 +476,7 @@ Examples:
----
refclock PHC /dev/ptp0 poll 0 dpoll -2 offset -37
refclock PHC /dev/ptp1:nocrossts poll 3 pps
-refclock PHC /dev/ptp2:extpps,pin=1 width 0.2 poll 2
+refclock PHC /dev/ptp2:extpps:pin=1 width 0.2 poll 2
----
+
::
@@ -681,6 +681,8 @@ The *combinelimit* directive limits which sources are included in the combining
algorithm. Their synchronisation distance has to be shorter than the distance
of the selected source multiplied by the value of the limit. Also, their
measured frequencies have to be close to the frequency of the selected source.
+If the selected source was specified with the *prefer* option, it can be
+combined only with other sources specified with this option.
+
By default, the limit is 3. Setting the limit to 0 effectively disables the
source combining algorithm and only the selected source will be used to control
@@ -1601,8 +1603,8 @@ If the *rtconutc* directive appears, it means the RTC is required to keep UTC.
The directive takes no arguments. It is equivalent to specifying the *-u*
switch to the Linux *hwclock* program.
+
-Note that this setting is overridden when the <<hwclockfile,*hwclockfile*>>
-directive is specified.
+Note that this setting is overridden by the <<hwclockfile,*hwclockfile*>> file
+and is not relevant for the <<rtcsync,*rtcsync*>> directive.
[[rtcsync]]*rtcsync*::
The *rtcsync* directive enables a mode where the system time is periodically
@@ -2063,11 +2065,11 @@ file when the <<chronyc.adoc#rekey,*rekey*>> command is issued by *chronyc*).
[[lock_all]]*lock_all*::
The *lock_all* directive will lock chronyd into RAM so that it will never be
-paged out. This mode is only supported on Linux. This directive uses the Linux
-*mlockall()* system call to prevent *chronyd* from ever being swapped out. This
-should result in lower and more consistent latency. It should not have
-significant impact on performance as *chronyd's* memory usage is modest. The
-*mlockall(2)* man page has more details.
+paged out. This mode is supported on Linux, FreeBSD, NetBSD, and Solaris. This
+directive uses the POSIX *mlockall()* system call to prevent *chronyd* from
+ever being swapped out. This should result in lower and more consistent
+latency. It should not have significant impact on performance as *chronyd's*
+memory usage is modest. The *mlockall(2)* man page has more details.
[[pidfile]]*pidfile* _file_::
Unless *chronyd* is started with the *-Q* option, it writes its process ID
@@ -2081,26 +2083,26 @@ pidfile /run/chronyd.pid
----
[[sched_priority]]*sched_priority* _priority_::
-On Linux, the *sched_priority* directive will select the SCHED_FIFO real-time
-scheduler at the specified priority (which must be between 0 and 100). On
-macOS, this option must have either a value of 0 (the default) to disable the
-thread time constraint policy or 1 for the policy to be enabled. Other systems
-do not support this option.
-+
-On Linux, this directive uses the *sched_setscheduler()* system call to
-instruct the kernel to use the SCHED_FIFO first-in, first-out real-time
-scheduling policy for *chronyd* with the specified priority. This means that
-whenever *chronyd* is ready to run it will run, interrupting whatever else is
-running unless it is a higher priority real-time process. This should not
-impact performance as *chronyd* resource requirements are modest, but it should
-result in lower and more consistent latency since *chronyd* will not need to
-wait for the scheduler to get around to running it. You should not use this
-unless you really need it. The *sched_setscheduler(2)* man page has more
-details.
+On Linux, FreeBSD, NetBSD, and Solaris, the *sched_priority* directive will
+select the SCHED_FIFO real-time scheduler at the specified priority (which must
+be between 0 and 100). On macOS, this option must have either a value of 0 (the
+default) to disable the thread time constraint policy or 1 for the policy to be
+enabled.
++
+On systems other than macOS, this directive uses the *pthread_setschedparam()*
+system call to instruct the kernel to use the SCHED_FIFO first-in, first-out
+real-time scheduling policy for *chronyd* with the specified priority. This
+means that whenever *chronyd* is ready to run it will run, interrupting
+whatever else is running unless it is a higher priority real-time process. This
+should not impact performance as *chronyd* resource requirements are modest,
+but it should result in lower and more consistent latency since *chronyd* will
+not need to wait for the scheduler to get around to running it. You should not
+use this unless you really need it. The *pthread_setschedparam(3)* man page has
+more details.
+
On macOS, this directive uses the *thread_policy_set()* kernel call to
-specify real-time scheduling. As noted for Linux, you should not use this
-directive unless you really need it.
+specify real-time scheduling. As noted above, you should not use this directive
+unless you really need it.
[[user]]*user* _user_::
The *user* directive sets the name of the system user to which *chronyd* will
diff --git a/doc/chrony.conf.man.in b/doc/chrony.conf.man.in
index d50e825..c058e8d 100644
--- a/doc/chrony.conf.man.in
+++ b/doc/chrony.conf.man.in
@@ -2,12 +2,12 @@
.\" Title: chrony.conf
.\" Author: [see the "AUTHORS" section]
.\" Generator: Asciidoctor 1.5.6.1
-.\" Date: 2018-09-19
+.\" Date: 2019-05-02
.\" Manual: Configuration Files
.\" Source: chrony @CHRONY_VERSION@
.\" Language: English
.\"
-.TH "CHRONY.CONF" "5" "2018-09-19" "chrony @CHRONY_VERSION@" "Configuration Files"
+.TH "CHRONY.CONF" "5" "2019-05-02" "chrony @CHRONY_VERSION@" "Configuration Files"
.ie \n(.g .ds Aq \(aq
.el .ds Aq '
.ss \n[.ss] 0
@@ -469,13 +469,13 @@ started in the boot sequence after \fBchronyd\fP from reading the clock before i
has been stepped.
.RE
.sp
-\fBrefclock\fP \fIdriver\fP \fIparameter\fP[:\fIoption\fP,...] [\fIoption\fP]...
+\fBrefclock\fP \fIdriver\fP \fIparameter\fP[:\fIoption\fP]... [\fIoption\fP]...
.RS 4
The \fBrefclock\fP directive specifies a hardware reference clock to be used as a
time source. It has two mandatory parameters, a driver name and a
driver\-specific parameter. The two parameters are followed by zero or more
refclock options. Some drivers have special options, which can be appended to
-the driver\-specific parameter (separated by the \fB:\fP and \fB,\fP characters).
+the driver\-specific parameter using the \fB:\fP character.
.sp
There are four drivers included in \fBchronyd\fP:
.sp
@@ -626,7 +626,7 @@ Examples:
.nf
refclock PHC /dev/ptp0 poll 0 dpoll \-2 offset \-37
refclock PHC /dev/ptp1:nocrossts poll 3 pps
-refclock PHC /dev/ptp2:extpps,pin=1 width 0.2 poll 2
+refclock PHC /dev/ptp2:extpps:pin=1 width 0.2 poll 2
.fi
.if n \{\
.RE
@@ -924,6 +924,8 @@ The \fBcombinelimit\fP directive limits which sources are included in the combin
algorithm. Their synchronisation distance has to be shorter than the distance
of the selected source multiplied by the value of the limit. Also, their
measured frequencies have to be close to the frequency of the selected source.
+If the selected source was specified with the \fBprefer\fP option, it can be
+combined only with other sources specified with this option.
.sp
By default, the limit is 3. Setting the limit to 0 effectively disables the
source combining algorithm and only the selected source will be used to control
@@ -2159,8 +2161,8 @@ If the \fBrtconutc\fP directive appears, it means the RTC is required to keep UT
The directive takes no arguments. It is equivalent to specifying the \fB\-u\fP
switch to the Linux \fBhwclock\fP program.
.sp
-Note that this setting is overridden when the \fBhwclockfile\fP
-directive is specified.
+Note that this setting is overridden by the \fBhwclockfile\fP file
+and is not relevant for the \fBrtcsync\fP directive.
.RE
.sp
\fBrtcsync\fP
@@ -3461,11 +3463,11 @@ file when the \fBrekey\fP command is issued by \fBchronyc\fP).
\fBlock_all\fP
.RS 4
The \fBlock_all\fP directive will lock chronyd into RAM so that it will never be
-paged out. This mode is only supported on Linux. This directive uses the Linux
-\fBmlockall()\fP system call to prevent \fBchronyd\fP from ever being swapped out. This
-should result in lower and more consistent latency. It should not have
-significant impact on performance as \fBchronyd\(cqs\fP memory usage is modest. The
-\fBmlockall(2)\fP man page has more details.
+paged out. This mode is supported on Linux, FreeBSD, NetBSD, and Solaris. This
+directive uses the POSIX \fBmlockall()\fP system call to prevent \fBchronyd\fP from
+ever being swapped out. This should result in lower and more consistent
+latency. It should not have significant impact on performance as \fBchronyd\(cqs\fP
+memory usage is modest. The \fBmlockall(2)\fP man page has more details.
.RE
.sp
\fBpidfile\fP \fIfile\fP
@@ -3489,26 +3491,26 @@ pidfile /run/chronyd.pid
.sp
\fBsched_priority\fP \fIpriority\fP
.RS 4
-On Linux, the \fBsched_priority\fP directive will select the SCHED_FIFO real\-time
-scheduler at the specified priority (which must be between 0 and 100). On
-macOS, this option must have either a value of 0 (the default) to disable the
-thread time constraint policy or 1 for the policy to be enabled. Other systems
-do not support this option.
-.sp
-On Linux, this directive uses the \fBsched_setscheduler()\fP system call to
-instruct the kernel to use the SCHED_FIFO first\-in, first\-out real\-time
-scheduling policy for \fBchronyd\fP with the specified priority. This means that
-whenever \fBchronyd\fP is ready to run it will run, interrupting whatever else is
-running unless it is a higher priority real\-time process. This should not
-impact performance as \fBchronyd\fP resource requirements are modest, but it should
-result in lower and more consistent latency since \fBchronyd\fP will not need to
-wait for the scheduler to get around to running it. You should not use this
-unless you really need it. The \fBsched_setscheduler(2)\fP man page has more
-details.
+On Linux, FreeBSD, NetBSD, and Solaris, the \fBsched_priority\fP directive will
+select the SCHED_FIFO real\-time scheduler at the specified priority (which must
+be between 0 and 100). On macOS, this option must have either a value of 0 (the
+default) to disable the thread time constraint policy or 1 for the policy to be
+enabled.
+.sp
+On systems other than macOS, this directive uses the \fBpthread_setschedparam()\fP
+system call to instruct the kernel to use the SCHED_FIFO first\-in, first\-out
+real\-time scheduling policy for \fBchronyd\fP with the specified priority. This
+means that whenever \fBchronyd\fP is ready to run it will run, interrupting
+whatever else is running unless it is a higher priority real\-time process. This
+should not impact performance as \fBchronyd\fP resource requirements are modest,
+but it should result in lower and more consistent latency since \fBchronyd\fP will
+not need to wait for the scheduler to get around to running it. You should not
+use this unless you really need it. The \fBpthread_setschedparam(3)\fP man page has
+more details.
.sp
On macOS, this directive uses the \fBthread_policy_set()\fP kernel call to
-specify real\-time scheduling. As noted for Linux, you should not use this
-directive unless you really need it.
+specify real\-time scheduling. As noted above, you should not use this directive
+unless you really need it.
.RE
.sp
\fBuser\fP \fIuser\fP
diff --git a/doc/chronyc.man.in b/doc/chronyc.man.in
index 1a6ec02..6ad8e01 100644
--- a/doc/chronyc.man.in
+++ b/doc/chronyc.man.in
@@ -2,12 +2,12 @@
.\" Title: chronyc
.\" Author: [see the "AUTHORS" section]
.\" Generator: Asciidoctor 1.5.6.1
-.\" Date: 2018-09-19
+.\" Date: 2019-05-02
.\" Manual: User manual
.\" Source: chrony @CHRONY_VERSION@
.\" Language: English
.\"
-.TH "CHRONYC" "1" "2018-09-19" "chrony @CHRONY_VERSION@" "User manual"
+.TH "CHRONYC" "1" "2019-05-02" "chrony @CHRONY_VERSION@" "User manual"
.ie \n(.g .ds Aq \(aq
.el .ds Aq '
.ss \n[.ss] 0
diff --git a/doc/chronyd.man.in b/doc/chronyd.man.in
index 6342f1b..e346d78 100644
--- a/doc/chronyd.man.in
+++ b/doc/chronyd.man.in
@@ -2,12 +2,12 @@
.\" Title: chronyd
.\" Author: [see the "AUTHORS" section]
.\" Generator: Asciidoctor 1.5.6.1
-.\" Date: 2018-09-19
+.\" Date: 2019-05-02
.\" Manual: System Administration
.\" Source: chrony @CHRONY_VERSION@
.\" Language: English
.\"
-.TH "CHRONYD" "8" "2018-09-19" "chrony @CHRONY_VERSION@" "System Administration"
+.TH "CHRONYD" "8" "2019-05-02" "chrony @CHRONY_VERSION@" "System Administration"
.ie \n(.g .ds Aq \(aq
.el .ds Aq '
.ss \n[.ss] 0
diff --git a/doc/faq.adoc b/doc/faq.adoc
index b07c550..318b418 100644
--- a/doc/faq.adoc
+++ b/doc/faq.adoc
@@ -217,6 +217,12 @@ server ntp.local minpoll 0 maxpoll 0 xleave
hwtimestamp eth0
----
+For best stability, the CPU should be running at a constant frequency (i.e.
+disabled power saving and performance boosting). Energy-Efficient Ethernet
+(EEE) should be disabled in the network. The switches should be configured to
+prioritize NTP packets, especially if the network is expected to be heavily
+loaded.
+
If it is acceptable for NTP clients in the network to send requests at an
excessive rate, a sub-second polling interval may be specified. A median filter
can be enabled in order to update the clock at a reduced rate with more stable
diff --git a/doc/installation.adoc b/doc/installation.adoc
index eea9088..3e0f3c3 100644
--- a/doc/installation.adoc
+++ b/doc/installation.adoc
@@ -22,6 +22,19 @@ The software is distributed as source code which has to be compiled. The source
code is supplied in the form of a gzipped tar file, which unpacks to a
subdirectory identifying the name and version of the program.
+The following programs and libraries with their development files are needed to
+build `chrony`:
+
+* C compiler (gcc or clang recommended)
+* GNU Make
+* Nettle, NSS, or LibTomCrypt (optional)
+* Editline (optional)
+* libcap (Linux only, optional)
+* libseccomp (Linux only, optional)
+* timepps.h header (optional)
+* Asciidoctor (for HTML documentation)
+* Bash (for testing)
+
After unpacking the source code, change directory into it, and type
----
diff --git a/hash_intmd5.c b/hash_intmd5.c
index 0b60f9b..49da1cf 100644
--- a/hash_intmd5.c
+++ b/hash_intmd5.c
@@ -29,6 +29,7 @@
#include "sysincl.h"
#include "hash.h"
#include "memory.h"
+#include "util.h"
#include "md5.c"
diff --git a/nameserv.c b/nameserv.c
index 1cb9608..90a65b1 100644
--- a/nameserv.c
+++ b/nameserv.c
@@ -30,6 +30,9 @@
#include "sysincl.h"
+#include <netdb.h>
+#include <resolv.h>
+
#include "nameserv.h"
#include "util.h"
diff --git a/ntp_io.c b/ntp_io.c
index 305ba07..ab08372 100644
--- a/ntp_io.c
+++ b/ntp_io.c
@@ -105,6 +105,9 @@ static int separate_client_sockets;
disabled */
static int permanent_server_sockets;
+/* Flag indicating the server IPv4 socket is bound to an address */
+static int bound_server_sock_fd4;
+
/* Flag indicating that we have been initialised */
static int initialised=0;
@@ -168,6 +171,9 @@ prepare_socket(int family, int port_number, int client_only)
my_addr.in4.sin_port = htons(port_number);
my_addr_len = sizeof (my_addr.in4);
+ if (!client_only)
+ bound_server_sock_fd4 = my_addr.in4.sin_addr.s_addr != htonl(INADDR_ANY);
+
break;
#ifdef FEAT_IPV6
case AF_INET6:
@@ -821,8 +827,8 @@ NIO_SendPacket(NTP_Packet *packet, NTP_Remote_Address *remote_addr,
msg.msg_flags = 0;
cmsglen = 0;
- if (local_addr->ip_addr.family == IPADDR_INET4) {
#ifdef HAVE_IN_PKTINFO
+ if (local_addr->ip_addr.family == IPADDR_INET4) {
struct in_pktinfo *ipi;
cmsg = CMSG_FIRSTHDR(&msg);
@@ -837,7 +843,11 @@ NIO_SendPacket(NTP_Packet *packet, NTP_Remote_Address *remote_addr,
ipi->ipi_spec_dst.s_addr = htonl(local_addr->ip_addr.addr.in4);
if (local_addr->if_index != INVALID_IF_INDEX)
ipi->ipi_ifindex = local_addr->if_index;
+ }
#elif defined(IP_SENDSRCADDR)
+ /* Specify the IPv4 source address only if the socket is not bound */
+ if (local_addr->ip_addr.family == IPADDR_INET4 &&
+ local_addr->sock_fd == server_sock_fd4 && !bound_server_sock_fd4) {
struct in_addr *addr;
cmsg = CMSG_FIRSTHDR(&msg);
@@ -850,8 +860,8 @@ NIO_SendPacket(NTP_Packet *packet, NTP_Remote_Address *remote_addr,
addr = (struct in_addr *)CMSG_DATA(cmsg);
addr->s_addr = htonl(local_addr->ip_addr.addr.in4);
-#endif
}
+#endif
#ifdef HAVE_IN6_PKTINFO
if (local_addr->ip_addr.family == IPADDR_INET6) {
diff --git a/ntp_io_linux.c b/ntp_io_linux.c
index 819792a..eb4a3a8 100644
--- a/ntp_io_linux.c
+++ b/ntp_io_linux.c
@@ -584,7 +584,11 @@ process_hw_timestamp(struct Interface *iface, struct timespec *hw_ts,
if (rx_ntp_length && iface->link_speed) {
if (!l2_length)
l2_length = (family == IPADDR_INET4 ? iface->l2_udp4_ntp_start :
- iface->l2_udp6_ntp_start) + rx_ntp_length + 4;
+ iface->l2_udp6_ntp_start) + rx_ntp_length;
+
+ /* Include the frame check sequence (FCS) */
+ l2_length += 4;
+
rx_correction = l2_length / (1.0e6 / 8 * iface->link_speed);
UTI_AddDoubleToTimespec(hw_ts, rx_correction, hw_ts);
diff --git a/refclock.c b/refclock.c
index 8f234f6..42fee4c 100644
--- a/refclock.c
+++ b/refclock.c
@@ -325,25 +325,57 @@ RCL_GetDriverParameter(RCL_Instance instance)
return instance->driver_parameter;
}
-char *
-RCL_GetDriverOption(RCL_Instance instance, char *name)
+static char *
+get_next_driver_option(RCL_Instance instance, char *option)
{
- char *s, *e;
- int n;
+ if (option == NULL)
+ option = instance->driver_parameter;
- s = instance->driver_parameter;
- e = s + instance->driver_parameter_length;
- n = strlen(name);
+ option += strlen(option) + 1;
- while (1) {
- s += strlen(s) + 1;
- if (s >= e)
- break;
- if (!strncmp(name, s, n)) {
- if (s[n] == '=')
- return s + n + 1;
- if (s[n] == '\0')
- return s + n;
+ if (option >= instance->driver_parameter + instance->driver_parameter_length)
+ return NULL;
+
+ return option;
+}
+
+void
+RCL_CheckDriverOptions(RCL_Instance instance, const char **options)
+{
+ char *option;
+ int i, len;
+
+ for (option = get_next_driver_option(instance, NULL);
+ option;
+ option = get_next_driver_option(instance, option)) {
+ for (i = 0; options && options[i]; i++) {
+ len = strlen(options[i]);
+ if (!strncmp(options[i], option, strlen(options[i])) &&
+ (option[len] == '=' || option[len] == '\0'))
+ break;
+ }
+
+ if (!options || !options[i])
+ LOG_FATAL("Invalid refclock driver option %s", option);
+ }
+}
+
+char *
+RCL_GetDriverOption(RCL_Instance instance, char *name)
+{
+ char *option;
+ int len;
+
+ len = strlen(name);
+
+ for (option = get_next_driver_option(instance, NULL);
+ option;
+ option = get_next_driver_option(instance, option)) {
+ if (!strncmp(name, option, len)) {
+ if (option[len] == '=')
+ return option + len + 1;
+ if (option[len] == '\0')
+ return option + len;
}
}
diff --git a/refclock.h b/refclock.h
index 724f620..69a0152 100644
--- a/refclock.h
+++ b/refclock.h
@@ -72,6 +72,7 @@ extern void RCL_ReportSource(RPT_SourceReport *report, struct timespec *now);
extern void RCL_SetDriverData(RCL_Instance instance, void *data);
extern void *RCL_GetDriverData(RCL_Instance instance);
extern char *RCL_GetDriverParameter(RCL_Instance instance);
+extern void RCL_CheckDriverOptions(RCL_Instance instance, const char **options);
extern char *RCL_GetDriverOption(RCL_Instance instance, char *name);
extern int RCL_AddSample(RCL_Instance instance, struct timespec *sample_time, double offset, int leap);
extern int RCL_AddPulse(RCL_Instance instance, struct timespec *pulse_time, double second);
diff --git a/refclock_phc.c b/refclock_phc.c
index 03450db..a000fe4 100644
--- a/refclock_phc.c
+++ b/refclock_phc.c
@@ -56,10 +56,13 @@ static void read_ext_pulse(int sockfd, int event, void *anything);
static int phc_initialise(RCL_Instance instance)
{
+ const char *options[] = {"nocrossts", "extpps", "pin", "channel", "clear", NULL};
struct phc_instance *phc;
int phc_fd, rising_edge;
char *path, *s;
+ RCL_CheckDriverOptions(instance, options);
+
path = RCL_GetDriverParameter(instance);
phc_fd = SYS_Linux_OpenPHC(path, 0);
diff --git a/refclock_pps.c b/refclock_pps.c
index 85ff9e9..b9e8009 100644
--- a/refclock_pps.c
+++ b/refclock_pps.c
@@ -48,12 +48,15 @@ struct pps_instance {
};
static int pps_initialise(RCL_Instance instance) {
+ const char *options[] = {"clear", NULL};
pps_handle_t handle;
pps_params_t params;
struct pps_instance *pps;
int fd, edge_clear, mode;
char *path;
+ RCL_CheckDriverOptions(instance, options);
+
path = RCL_GetDriverParameter(instance);
edge_clear = RCL_GetDriverOption(instance, "clear") ? 1 : 0;
diff --git a/refclock_shm.c b/refclock_shm.c
index e8f6256..ed68095 100644
--- a/refclock_shm.c
+++ b/refclock_shm.c
@@ -59,10 +59,13 @@ struct shmTime {
};
static int shm_initialise(RCL_Instance instance) {
+ const char *options[] = {"perm", NULL};
int id, param, perm;
char *s;
struct shmTime *shm;
+ RCL_CheckDriverOptions(instance, options);
+
param = atoi(RCL_GetDriverParameter(instance));
s = RCL_GetDriverOption(instance, "perm");
perm = s ? strtol(s, NULL, 8) & 0777 : 0600;
diff --git a/refclock_sock.c b/refclock_sock.c
index 176310c..492ee32 100644
--- a/refclock_sock.c
+++ b/refclock_sock.c
@@ -101,6 +101,8 @@ static int sock_initialise(RCL_Instance instance)
int sockfd;
char *path;
+ RCL_CheckDriverOptions(instance, NULL);
+
path = RCL_GetDriverParameter(instance);
s.sun_family = AF_UNIX;
diff --git a/sys.c b/sys.c
index 4d68b37..f3797c4 100644
--- a/sys.c
+++ b/sys.c
@@ -35,10 +35,13 @@
#if defined(LINUX)
#include "sys_linux.h"
+#include "sys_posix.h"
#elif defined(SOLARIS)
#include "sys_solaris.h"
+#include "sys_posix.h"
#elif defined(NETBSD) || defined(FREEBSD)
#include "sys_netbsd.h"
+#include "sys_posix.h"
#elif defined(MACOSX)
#include "sys_macosx.h"
#endif
@@ -124,10 +127,10 @@ void SYS_EnableSystemCallFilter(int level)
void SYS_SetScheduler(int SchedPriority)
{
-#if defined(LINUX) && defined(HAVE_SCHED_SETSCHEDULER)
- SYS_Linux_SetScheduler(SchedPriority);
-#elif defined(MACOSX)
+#if defined(MACOSX)
SYS_MacOSX_SetScheduler(SchedPriority);
+#elif defined(HAVE_PTHREAD_SETSCHEDPARAM)
+ SYS_Posix_SetScheduler(SchedPriority);
#else
LOG_FATAL("scheduler priority setting not supported");
#endif
@@ -137,8 +140,8 @@ void SYS_SetScheduler(int SchedPriority)
void SYS_LockMemory(void)
{
-#if defined(LINUX) && defined(HAVE_MLOCKALL)
- SYS_Linux_MemLockAll(1);
+#if defined(HAVE_MLOCKALL)
+ SYS_Posix_MemLockAll();
#else
LOG_FATAL("memory locking not supported");
#endif
diff --git a/sys_linux.c b/sys_linux.c
index 00bc239..898dc7a 100644
--- a/sys_linux.c
+++ b/sys_linux.c
@@ -33,15 +33,6 @@
#include <sys/utsname.h>
-#if defined(HAVE_SCHED_SETSCHEDULER)
-# include <sched.h>
-#endif
-
-#if defined(HAVE_MLOCKALL)
-# include <sys/mman.h>
-#include <sys/resource.h>
-#endif
-
#if defined(FEAT_PHC) || defined(HAVE_LINUX_TIMESTAMPING)
#include <linux/ptp_clock.h>
#endif
@@ -493,25 +484,27 @@ SYS_Linux_EnableSystemCallFilter(int level)
SCMP_SYS(clone), SCMP_SYS(exit), SCMP_SYS(exit_group), SCMP_SYS(getpid),
SCMP_SYS(getrlimit), SCMP_SYS(rt_sigaction), SCMP_SYS(rt_sigreturn),
SCMP_SYS(rt_sigprocmask), SCMP_SYS(set_tid_address), SCMP_SYS(sigreturn),
- SCMP_SYS(wait4),
+ SCMP_SYS(wait4), SCMP_SYS(waitpid),
/* Memory */
SCMP_SYS(brk), SCMP_SYS(madvise), SCMP_SYS(mmap), SCMP_SYS(mmap2),
SCMP_SYS(mprotect), SCMP_SYS(mremap), SCMP_SYS(munmap), SCMP_SYS(shmdt),
/* Filesystem */
- SCMP_SYS(access), SCMP_SYS(chmod), SCMP_SYS(chown), SCMP_SYS(chown32),
+ SCMP_SYS(_llseek), SCMP_SYS(access), SCMP_SYS(chmod), SCMP_SYS(chown),
+ SCMP_SYS(chown32), SCMP_SYS(faccessat), SCMP_SYS(fchmodat), SCMP_SYS(fchownat),
SCMP_SYS(fstat), SCMP_SYS(fstat64), SCMP_SYS(getdents), SCMP_SYS(getdents64),
- SCMP_SYS(lseek), SCMP_SYS(rename), SCMP_SYS(stat), SCMP_SYS(stat64),
- SCMP_SYS(statfs), SCMP_SYS(statfs64), SCMP_SYS(unlink),
+ SCMP_SYS(lseek), SCMP_SYS(newfstatat), SCMP_SYS(rename), SCMP_SYS(renameat),
+ SCMP_SYS(stat), SCMP_SYS(stat64), SCMP_SYS(statfs), SCMP_SYS(statfs64),
+ SCMP_SYS(unlink), SCMP_SYS(unlinkat),
/* Socket */
SCMP_SYS(bind), SCMP_SYS(connect), SCMP_SYS(getsockname), SCMP_SYS(getsockopt),
- SCMP_SYS(recvfrom), SCMP_SYS(recvmmsg), SCMP_SYS(recvmsg),
- SCMP_SYS(sendmmsg), SCMP_SYS(sendmsg), SCMP_SYS(sendto),
+ SCMP_SYS(recv), SCMP_SYS(recvfrom), SCMP_SYS(recvmmsg), SCMP_SYS(recvmsg),
+ SCMP_SYS(send), SCMP_SYS(sendmmsg), SCMP_SYS(sendmsg), SCMP_SYS(sendto),
/* TODO: check socketcall arguments */
SCMP_SYS(socketcall),
/* General I/O */
SCMP_SYS(_newselect), SCMP_SYS(close), SCMP_SYS(open), SCMP_SYS(openat), SCMP_SYS(pipe),
- SCMP_SYS(poll), SCMP_SYS(read), SCMP_SYS(futex), SCMP_SYS(select),
- SCMP_SYS(set_robust_list), SCMP_SYS(write),
+ SCMP_SYS(pipe2), SCMP_SYS(poll), SCMP_SYS(ppoll), SCMP_SYS(pselect6), SCMP_SYS(read),
+ SCMP_SYS(futex), SCMP_SYS(select), SCMP_SYS(set_robust_list), SCMP_SYS(write),
/* Miscellaneous */
SCMP_SYS(getrandom), SCMP_SYS(sysinfo), SCMP_SYS(uname),
};
@@ -544,6 +537,9 @@ SYS_Linux_EnableSystemCallFilter(int level)
#ifdef PTP_PIN_SETFUNC
PTP_PIN_SETFUNC,
#endif
+#ifdef PTP_SYS_OFFSET_EXTENDED
+ PTP_SYS_OFFSET_EXTENDED,
+#endif
#ifdef PTP_SYS_OFFSET_PRECISE
PTP_SYS_OFFSET_PRECISE,
#endif
@@ -627,63 +623,6 @@ add_failed:
/* ================================================== */
-#if defined(HAVE_SCHED_SETSCHEDULER)
- /* Install SCHED_FIFO real-time scheduler with specified priority */
-void SYS_Linux_SetScheduler(int SchedPriority)
-{
- int pmax, pmin;
- struct sched_param sched;
-
- if (SchedPriority < 1 || SchedPriority > 99) {
- LOG_FATAL("Bad scheduler priority: %d", SchedPriority);
- } else {
- sched.sched_priority = SchedPriority;
- pmax = sched_get_priority_max(SCHED_FIFO);
- pmin = sched_get_priority_min(SCHED_FIFO);
- if ( SchedPriority > pmax ) {
- sched.sched_priority = pmax;
- }
- else if ( SchedPriority < pmin ) {
- sched.sched_priority = pmin;
- }
- if ( sched_setscheduler(0, SCHED_FIFO, &sched) == -1 ) {
- LOG(LOGS_ERR, "sched_setscheduler() failed");
- }
- else {
- DEBUG_LOG("Enabled SCHED_FIFO with priority %d",
- sched.sched_priority);
- }
- }
-}
-#endif /* HAVE_SCHED_SETSCHEDULER */
-
-#if defined(HAVE_MLOCKALL)
-/* Lock the process into RAM so that it will never be swapped out */
-void SYS_Linux_MemLockAll(int LockAll)
-{
- struct rlimit rlim;
- if (LockAll == 1 ) {
- /* Make sure that we will be able to lock all the memory we need */
- /* even after dropping privileges. This does not actually reaerve any memory */
- rlim.rlim_max = RLIM_INFINITY;
- rlim.rlim_cur = RLIM_INFINITY;
- if (setrlimit(RLIMIT_MEMLOCK, &rlim) < 0) {
- LOG(LOGS_ERR, "setrlimit() failed: not locking into RAM");
- }
- else {
- if (mlockall(MCL_CURRENT|MCL_FUTURE) < 0) {
- LOG(LOGS_ERR, "mlockall() failed");
- }
- else {
- DEBUG_LOG("Successfully locked into RAM");
- }
- }
- }
-}
-#endif /* HAVE_MLOCKALL */
-
-/* ================================================== */
-
int
SYS_Linux_CheckKernelVersion(int req_major, int req_minor)
{
@@ -701,35 +640,17 @@ SYS_Linux_CheckKernelVersion(int req_major, int req_minor)
#define PHC_READINGS 10
static int
-get_phc_sample(int phc_fd, double precision, struct timespec *phc_ts,
- struct timespec *sys_ts, double *err)
+process_phc_readings(struct timespec ts[][3], int n, double precision,
+ struct timespec *phc_ts, struct timespec *sys_ts, double *err)
{
- struct ptp_sys_offset sys_off;
- struct timespec ts1, ts2, ts3, phc_tss[PHC_READINGS], sys_tss[PHC_READINGS];
- double min_delay = 0.0, delays[PHC_READINGS], phc_sum, sys_sum, sys_prec;
- int i, n;
+ double min_delay = 0.0, delays[PTP_MAX_SAMPLES], phc_sum, sys_sum, sys_prec;
+ int i, combined;
- /* Silence valgrind */
- memset(&sys_off, 0, sizeof (sys_off));
-
- sys_off.n_samples = PHC_READINGS;
-
- if (ioctl(phc_fd, PTP_SYS_OFFSET, &sys_off)) {
- DEBUG_LOG("ioctl(%s) failed : %s", "PTP_SYS_OFFSET", strerror(errno));
+ if (n > PTP_MAX_SAMPLES)
return 0;
- }
- for (i = 0; i < PHC_READINGS; i++) {
- ts1.tv_sec = sys_off.ts[i * 2].sec;
- ts1.tv_nsec = sys_off.ts[i * 2].nsec;
- ts2.tv_sec = sys_off.ts[i * 2 + 1].sec;
- ts2.tv_nsec = sys_off.ts[i * 2 + 1].nsec;
- ts3.tv_sec = sys_off.ts[i * 2 + 2].sec;
- ts3.tv_nsec = sys_off.ts[i * 2 + 2].nsec;
-
- sys_tss[i] = ts1;
- phc_tss[i] = ts2;
- delays[i] = UTI_DiffTimespecsToDouble(&ts3, &ts1);
+ for (i = 0; i < n; i++) {
+ delays[i] = UTI_DiffTimespecsToDouble(&ts[i][2], &ts[i][0]);
if (delays[i] < 0.0) {
/* Step in the middle of a PHC reading? */
@@ -744,23 +665,92 @@ get_phc_sample(int phc_fd, double precision, struct timespec *phc_ts,
sys_prec = LCL_GetSysPrecisionAsQuantum();
/* Combine best readings */
- for (i = n = 0, phc_sum = sys_sum = 0.0; i < PHC_READINGS; i++) {
+ for (i = combined = 0, phc_sum = sys_sum = 0.0; i < n; i++) {
if (delays[i] > min_delay + MAX(sys_prec, precision))
continue;
- phc_sum += UTI_DiffTimespecsToDouble(&phc_tss[i], &phc_tss[0]);
- sys_sum += UTI_DiffTimespecsToDouble(&sys_tss[i], &sys_tss[0]) + delays[i] / 2.0;
- n++;
+ phc_sum += UTI_DiffTimespecsToDouble(&ts[i][1], &ts[0][1]);
+ sys_sum += UTI_DiffTimespecsToDouble(&ts[i][0], &ts[0][0]) + delays[i] / 2.0;
+ combined++;
}
- assert(n);
+ assert(combined);
- UTI_AddDoubleToTimespec(&phc_tss[0], phc_sum / n, phc_ts);
- UTI_AddDoubleToTimespec(&sys_tss[0], sys_sum / n, sys_ts);
+ UTI_AddDoubleToTimespec(&ts[0][1], phc_sum / combined, phc_ts);
+ UTI_AddDoubleToTimespec(&ts[0][0], sys_sum / combined, sys_ts);
*err = MAX(min_delay / 2.0, precision);
return 1;
}
+
+/* ================================================== */
+
+static int
+get_phc_sample(int phc_fd, double precision, struct timespec *phc_ts,
+ struct timespec *sys_ts, double *err)
+{
+ struct timespec ts[PHC_READINGS][3];
+ struct ptp_sys_offset sys_off;
+ int i;
+
+ /* Silence valgrind */
+ memset(&sys_off, 0, sizeof (sys_off));
+
+ sys_off.n_samples = PHC_READINGS;
+
+ if (ioctl(phc_fd, PTP_SYS_OFFSET, &sys_off)) {
+ DEBUG_LOG("ioctl(%s) failed : %s", "PTP_SYS_OFFSET", strerror(errno));
+ return 0;
+ }
+
+ for (i = 0; i < PHC_READINGS; i++) {
+ ts[i][0].tv_sec = sys_off.ts[i * 2].sec;
+ ts[i][0].tv_nsec = sys_off.ts[i * 2].nsec;
+ ts[i][1].tv_sec = sys_off.ts[i * 2 + 1].sec;
+ ts[i][1].tv_nsec = sys_off.ts[i * 2 + 1].nsec;
+ ts[i][2].tv_sec = sys_off.ts[i * 2 + 2].sec;
+ ts[i][2].tv_nsec = sys_off.ts[i * 2 + 2].nsec;
+ }
+
+ return process_phc_readings(ts, PHC_READINGS, precision, phc_ts, sys_ts, err);
+}
+
+/* ================================================== */
+
+static int
+get_extended_phc_sample(int phc_fd, double precision, struct timespec *phc_ts,
+ struct timespec *sys_ts, double *err)
+{
+#ifdef PTP_SYS_OFFSET_EXTENDED
+ struct timespec ts[PHC_READINGS][3];
+ struct ptp_sys_offset_extended sys_off;
+ int i;
+
+ /* Silence valgrind */
+ memset(&sys_off, 0, sizeof (sys_off));
+
+ sys_off.n_samples = PHC_READINGS;
+
+ if (ioctl(phc_fd, PTP_SYS_OFFSET_EXTENDED, &sys_off)) {
+ DEBUG_LOG("ioctl(%s) failed : %s", "PTP_SYS_OFFSET_EXTENDED", strerror(errno));
+ return 0;
+ }
+
+ for (i = 0; i < PHC_READINGS; i++) {
+ ts[i][0].tv_sec = sys_off.ts[i][0].sec;
+ ts[i][0].tv_nsec = sys_off.ts[i][0].nsec;
+ ts[i][1].tv_sec = sys_off.ts[i][1].sec;
+ ts[i][1].tv_nsec = sys_off.ts[i][1].nsec;
+ ts[i][2].tv_sec = sys_off.ts[i][2].sec;
+ ts[i][2].tv_nsec = sys_off.ts[i][2].nsec;
+ }
+
+ return process_phc_readings(ts, PHC_READINGS, precision, phc_ts, sys_ts, err);
+#else
+ return 0;
+#endif
+}
+
/* ================================================== */
static int
@@ -834,6 +824,10 @@ SYS_Linux_GetPHCSample(int fd, int nocrossts, double precision, int *reading_mod
get_precise_phc_sample(fd, precision, phc_ts, sys_ts, err)) {
*reading_mode = 2;
return 1;
+ } else if ((*reading_mode == 3 || !*reading_mode) &&
+ get_extended_phc_sample(fd, precision, phc_ts, sys_ts, err)) {
+ *reading_mode = 3;
+ return 1;
} else if ((*reading_mode == 1 || !*reading_mode) &&
get_phc_sample(fd, precision, phc_ts, sys_ts, err)) {
*reading_mode = 1;
diff --git a/sys_linux.h b/sys_linux.h
index 799ae9a..551a186 100644
--- a/sys_linux.h
+++ b/sys_linux.h
@@ -35,10 +35,6 @@ extern void SYS_Linux_DropRoot(uid_t uid, gid_t gid, int clock_control);
extern void SYS_Linux_EnableSystemCallFilter(int level);
-extern void SYS_Linux_MemLockAll(int LockAll);
-
-extern void SYS_Linux_SetScheduler(int SchedPriority);
-
extern int SYS_Linux_CheckKernelVersion(int req_major, int req_minor);
extern int SYS_Linux_OpenPHC(const char *path, int phc_index);
diff --git a/sys_macosx.c b/sys_macosx.c
index 00ce302..807d62e 100644
--- a/sys_macosx.c
+++ b/sys_macosx.c
@@ -49,10 +49,8 @@
#ifdef HAVE_MACOS_SYS_TIMEX
#include <dlfcn.h>
#include "sys_netbsd.h"
-#include "sys_timex.h"
static int have_ntp_adjtime = 0;
-static int have_bad_adjtime = 0;
#endif
/* ================================================== */
@@ -453,45 +451,13 @@ legacy_MacOSX_Finalise(void)
/* ================================================== */
-#ifdef HAVE_MACOS_SYS_TIMEX
-/*
- Test adjtime() to see if Apple have fixed the signed/unsigned bug
-*/
-static int
-test_adjtime()
-{
- struct timeval tv1 = {-1, 0};
- struct timeval tv2 = {0, 0};
- struct timeval tv;
-
- if (PRV_AdjustTime(&tv1, &tv) != 0) {
- return 0;
- }
- if (PRV_AdjustTime(&tv2, &tv) != 0) {
- return 0;
- }
- if (tv.tv_sec < -1 || tv.tv_sec > 1) {
- return 0;
- }
- return 1;
-}
-#endif
-
-/* ================================================== */
-
void
SYS_MacOSX_Initialise(void)
{
#ifdef HAVE_MACOS_SYS_TIMEX
have_ntp_adjtime = (dlsym(RTLD_NEXT, "ntp_adjtime") != NULL);
if (have_ntp_adjtime) {
- have_bad_adjtime = !test_adjtime();
- if (have_bad_adjtime) {
- LOG(LOGS_WARN, "adjtime() is buggy - using timex driver");
- SYS_Timex_Initialise();
- } else {
- SYS_NetBSD_Initialise();
- }
+ SYS_NetBSD_Initialise();
return;
}
#endif
@@ -505,11 +471,7 @@ SYS_MacOSX_Finalise(void)
{
#ifdef HAVE_MACOS_SYS_TIMEX
if (have_ntp_adjtime) {
- if (have_bad_adjtime) {
- SYS_Timex_Finalise();
- } else {
- SYS_NetBSD_Finalise();
- }
+ SYS_NetBSD_Finalise();
return;
}
#endif
diff --git a/sys_posix.c b/sys_posix.c
new file mode 100644
index 0000000..356e86a
--- /dev/null
+++ b/sys_posix.c
@@ -0,0 +1,109 @@
+/*
+ chronyd/chronyc - Programs for keeping computer clocks accurate.
+
+ **********************************************************************
+ * Copyright (C) Richard P. Curnow 1997-2003
+ * Copyright (C) John G. Hasler 2009
+ * Copyright (C) Miroslav Lichvar 2009-2012, 2014-2018
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ **********************************************************************
+
+ =======================================================================
+
+ This module is for POSIX compliant operating systems.
+
+ */
+
+#include "config.h"
+
+#include "sysincl.h"
+
+#include <sys/utsname.h>
+
+#if defined(HAVE_PTHREAD_SETSCHEDPARAM)
+#include <pthread.h>
+#include <sched.h>
+#endif
+
+#if defined(HAVE_MLOCKALL)
+#include <sys/mman.h>
+#endif
+#if defined(HAVE_SETRLIMIT_MEMLOCK)
+#include <sys/resource.h>
+#endif
+
+#include "sys_posix.h"
+#include "conf.h"
+#include "local.h"
+#include "logging.h"
+#include "util.h"
+
+/* ================================================== */
+
+#if defined(HAVE_PTHREAD_SETSCHEDPARAM)
+/* Install SCHED_FIFO real-time scheduler with specified priority */
+void
+SYS_Posix_SetScheduler(int priority)
+{
+ struct sched_param sched;
+ int pmax, pmin;
+
+ if (priority < 1 || priority > 99)
+ LOG_FATAL("Bad scheduler priority: %d", priority);
+
+ sched.sched_priority = priority;
+ pmax = sched_get_priority_max(SCHED_FIFO);
+ pmin = sched_get_priority_min(SCHED_FIFO);
+ if (priority > pmax) {
+ sched.sched_priority = pmax;
+ } else if (priority < pmin) {
+ sched.sched_priority = pmin;
+ }
+
+ if (pthread_setschedparam(pthread_self(), SCHED_FIFO, &sched) < 0) {
+ LOG(LOGS_ERR, "pthread_setschedparam() failed");
+ } else {
+ DEBUG_LOG("Enabled SCHED_FIFO with priority %d", sched.sched_priority);
+ }
+}
+#endif /* HAVE_PTHREAD_SETSCHEDPARAM */
+
+/* ================================================== */
+
+#if defined(HAVE_MLOCKALL)
+/* Lock the process into RAM so that it will never be swapped out */
+void
+SYS_Posix_MemLockAll(void)
+{
+#if defined(HAVE_SETRLIMIT_MEMLOCK)
+ struct rlimit rlim;
+
+ /* Ensure we can reserve as much as we need */
+ rlim.rlim_max = RLIM_INFINITY;
+ rlim.rlim_cur = RLIM_INFINITY;
+ if (setrlimit(RLIMIT_MEMLOCK, &rlim) < 0) {
+ LOG(LOGS_ERR, "setrlimit() failed");
+ return;
+ }
+#endif
+
+ if (mlockall(MCL_CURRENT|MCL_FUTURE) < 0) {
+ LOG(LOGS_ERR, "mlockall() failed");
+ } else {
+ DEBUG_LOG("Successfully locked into RAM");
+ }
+}
+#endif /* HAVE_MLOCKALL */
diff --git a/sys_posix.h b/sys_posix.h
new file mode 100644
index 0000000..bb34b80
--- /dev/null
+++ b/sys_posix.h
@@ -0,0 +1,36 @@
+/*
+ chronyd/chronyc - Programs for keeping computer clocks accurate.
+
+ **********************************************************************
+ * Copyright (C) Richard P. Curnow 1997-2003
+ * Copyright (C) John G. Hasler 2009
+ * Copyright (C) Miroslav Lichvar 2009-2012, 2014-2018
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ **********************************************************************
+
+ =======================================================================
+
+ The header file for shared Posix functionality
+ */
+
+#ifndef GOT_SYS_POSIX_H
+#define GOT_SYS_POSIX_H
+
+extern void SYS_Posix_MemLockAll(void);
+
+extern void SYS_Posix_SetScheduler(int priority);
+
+#endif /* GOT_SYS_POSIX_H */
diff --git a/sysincl.h b/sysincl.h
index 54431de..296c5e6 100644
--- a/sysincl.h
+++ b/sysincl.h
@@ -38,10 +38,8 @@
#include <grp.h>
#include <inttypes.h>
#include <math.h>
-#include <netdb.h>
#include <netinet/in.h>
#include <pwd.h>
-#include <resolv.h>
#include <signal.h>
#include <stdarg.h>
#include <stddef.h>
diff --git a/test/simulation/008-ntpera b/test/simulation/008-ntpera
index 3c63419..360a97d 100755
--- a/test/simulation/008-ntpera
+++ b/test/simulation/008-ntpera
@@ -16,7 +16,7 @@ check_packet_interval || test_fail
check_sync || test_fail
# The following tests need 64-bit time_t
-grep -q 'HAVE_LONG_TIME_T 1' ../../config.h || test_skip
+check_config_h 'HAVE_LONG_TIME_T 1' || test_skip
for year in 1990 2090; do
export CLKNETSIM_START_DATE=$(date -d "Jan 1 00:00:00 UTC $year" +'%s')
diff --git a/test/simulation/105-ntpauth b/test/simulation/105-ntpauth
index 4c77f10..9ec4fba 100755
--- a/test/simulation/105-ntpauth
+++ b/test/simulation/105-ntpauth
@@ -23,7 +23,7 @@ EOF
keys=4
-if grep -q 'FEAT_SECHASH 1' ../../config.h; then
+if check_config_h 'FEAT_SECHASH 1'; then
hashes="MD5 SHA1 SHA256 SHA384 SHA512"
else
hashes="MD5"
diff --git a/test/simulation/106-refclock b/test/simulation/106-refclock
index 5c5794c..c4cec20 100755
--- a/test/simulation/106-refclock
+++ b/test/simulation/106-refclock
@@ -3,6 +3,10 @@
. ./test.common
test_start "SHM refclock"
+check_config_h 'FEAT_REFCLOCK 1' || test_skip
+check_config_h 'FEAT_PHC 1' || test_skip
+check_config_h 'FEAT_CMDMON 1' || test_skip
+
servers=0
limit=1000
refclock_jitter=$jitter
diff --git a/test/simulation/107-allowdeny b/test/simulation/107-allowdeny
index b11db32..3ab83ff 100755
--- a/test/simulation/107-allowdeny
+++ b/test/simulation/107-allowdeny
@@ -4,6 +4,8 @@
test_start "allow/deny directives"
+check_config_h 'FEAT_CMDMON 1' || test_skip
+
limit=500
# Note that start_client in clknetsim.bash always adds allow to the config
diff --git a/test/simulation/110-chronyc b/test/simulation/110-chronyc
index 7fe5dcf..5736ae4 100755
--- a/test/simulation/110-chronyc
+++ b/test/simulation/110-chronyc
@@ -4,6 +4,9 @@
test_start "chronyc"
+check_config_h 'FEAT_REFCLOCK 1' || test_skip
+check_config_h 'FEAT_CMDMON 1' || test_skip
+
refclock_jitter=$jitter
client_conf="
refclock SHM 0 noselect
diff --git a/test/simulation/112-port b/test/simulation/112-port
index e983757..a8efabd 100755
--- a/test/simulation/112-port
+++ b/test/simulation/112-port
@@ -4,6 +4,8 @@
test_start "port and acquisitionport directives"
+check_config_h 'FEAT_CMDMON 1' || test_skip
+
run_test || test_fail
check_chronyd_exit || test_fail
check_source_selection || test_fail
diff --git a/test/simulation/113-leapsecond b/test/simulation/113-leapsecond
index 5b9758f..2fb81b8 100755
--- a/test/simulation/113-leapsecond
+++ b/test/simulation/113-leapsecond
@@ -1,8 +1,11 @@
#!/bin/bash
. ./test.common
+
test_start "leap second"
+check_config_h 'FEAT_REFCLOCK 1' || test_skip
+
export CLKNETSIM_START_DATE=$(TZ=UTC date -d 'Dec 30 2008 0:00:00' +'%s')
leap=$[2 * 24 * 3600]
diff --git a/test/simulation/115-cmdmontime b/test/simulation/115-cmdmontime
index 2806a1f..732decd 100755
--- a/test/simulation/115-cmdmontime
+++ b/test/simulation/115-cmdmontime
@@ -5,7 +5,8 @@
test_start "cmdmon timestamps"
# The following tests need 64-bit time_t
-grep -q 'HAVE_LONG_TIME_T 1' ../../config.h || test_skip
+check_config_h 'HAVE_LONG_TIME_T 1' || test_skip
+check_config_h 'FEAT_CMDMON 1' || test_skip
limit=2
client_server_options="noselect"
diff --git a/test/simulation/119-smoothtime b/test/simulation/119-smoothtime
index 6b4ae39..3f90715 100755
--- a/test/simulation/119-smoothtime
+++ b/test/simulation/119-smoothtime
@@ -1,8 +1,11 @@
#!/bin/bash
. ./test.common
+
test_start "smoothtime option"
+check_config_h 'FEAT_REFCLOCK 1' || test_skip
+
server_strata=2
server_conf="smoothtime 400 0.001"
server_server_options="minpoll 8"
diff --git a/test/simulation/121-orphan b/test/simulation/121-orphan
index 1b47f76..bbebc9d 100755
--- a/test/simulation/121-orphan
+++ b/test/simulation/121-orphan
@@ -4,6 +4,8 @@
test_start "orphan option"
+check_config_h 'FEAT_CMDMON 1' || test_skip
+
server_strata=3
server_conf="local stratum 5 orphan
server 192.168.123.1
diff --git a/test/simulation/124-tai b/test/simulation/124-tai
index b5be030..d41d29d 100755
--- a/test/simulation/124-tai
+++ b/test/simulation/124-tai
@@ -1,8 +1,11 @@
#!/bin/bash
. ./test.common
+
test_start "tai option"
+check_config_h 'FEAT_REFCLOCK 1' || test_skip
+
export CLKNETSIM_START_DATE=$(TZ=UTC date -d 'Dec 31 2008 23:50:00' +'%s')
leap=$[10 * 60]
diff --git a/test/simulation/128-nocontrol b/test/simulation/128-nocontrol
index 0a98cd7..cca82f4 100755
--- a/test/simulation/128-nocontrol
+++ b/test/simulation/128-nocontrol
@@ -4,6 +4,8 @@
test_start "-x option"
+check_config_h 'FEAT_CMDMON 1' || test_skip
+
wander=0.0
time_offset=0.0
freq_offset=0.0
diff --git a/test/simulation/133-hwtimestamp b/test/simulation/133-hwtimestamp
index 1448c21..113ea69 100755
--- a/test/simulation/133-hwtimestamp
+++ b/test/simulation/133-hwtimestamp
@@ -4,6 +4,8 @@
test_start "hwtimestamp directive"
+check_config_h 'HAVE_LINUX_TIMESTAMPING 1' || test_skip
+
export CLKNETSIM_TIMESTAMPING=2
refclock_jitter=1e-8
@@ -20,7 +22,7 @@ check_chronyd_exit || test_fail
check_source_selection || test_fail
check_sync || test_fail
-if grep -q 'FEAT_DEBUG 1' ../../config.h; then
+if check_config_h 'FEAT_DEBUG 1'; then
check_log_messages "HW clock samples" 190 200 || test_fail
check_log_messages "HW clock reset" 0 0 || test_fail
check_log_messages "Received.*tss=1" 1 1 || test_fail
diff --git a/test/simulation/134-log b/test/simulation/134-log
index f5293c4..0a6ef76 100755
--- a/test/simulation/134-log
+++ b/test/simulation/134-log
@@ -1,8 +1,11 @@
#!/bin/bash
. ./test.common
+
test_start "log directive"
+check_config_h 'FEAT_PHC 1' || test_skip
+
refclock_jitter=$jitter
client_server_options="maxpoll 6"
client_conf="refclock PHC /dev/ptp0 dpoll 4 poll 6 noselect
diff --git a/test/simulation/test.common b/test/simulation/test.common
index 18dd9e1..951a794 100644
--- a/test/simulation/test.common
+++ b/test/simulation/test.common
@@ -84,6 +84,8 @@ done
test_start() {
rm -f tmp/*
echo "Testing $@:"
+
+ check_config_h 'FEAT_NTP 1' || test_skip
}
test_pass() {
@@ -211,6 +213,12 @@ get_chronyd_conf() {
fi
}
+# Check if chrony was built with specified option in config.h
+check_config_h() {
+ local pattern=$1
+ grep -q "^#define $pattern" ../../config.h
+}
+
# Check if the clock was well synchronized
check_sync() {
local i sync_time max_time_error max_freq_error ret=0
diff --git a/test/system/001-minimal b/test/system/001-minimal
new file mode 100755
index 0000000..107fa3f
--- /dev/null
+++ b/test/system/001-minimal
@@ -0,0 +1,13 @@
+#!/usr/bin/env bash
+
+. ./test.common
+
+test_start "minimal configuration"
+
+minimal_config=1
+
+start_chronyd || test_fail
+stop_chronyd || test_fail
+check_chronyd_messages || test_fail
+
+test_pass
diff --git a/test/system/002-extended b/test/system/002-extended
new file mode 100755
index 0000000..7a6734f
--- /dev/null
+++ b/test/system/002-extended
@@ -0,0 +1,13 @@
+#!/usr/bin/env bash
+
+. ./test.common
+
+test_start "extended configuration"
+
+start_chronyd || test_fail
+wait_for_sync || test_fail
+stop_chronyd || test_fail
+check_chronyd_messages || test_fail
+check_chronyd_files || test_fail
+
+test_pass
diff --git a/test/system/003-memlock b/test/system/003-memlock
new file mode 100755
index 0000000..e4ab1bf
--- /dev/null
+++ b/test/system/003-memlock
@@ -0,0 +1,15 @@
+#!/usr/bin/env bash
+
+. ./test.common
+
+test_start "memory locking"
+
+extra_chronyd_options="-m"
+
+start_chronyd || test_fail
+wait_for_sync || test_fail
+stop_chronyd || test_fail
+check_chronyd_messages || test_fail
+check_chronyd_files || test_fail
+
+test_pass
diff --git a/test/system/004-priority b/test/system/004-priority
new file mode 100755
index 0000000..bf8a04b
--- /dev/null
+++ b/test/system/004-priority
@@ -0,0 +1,15 @@
+#!/usr/bin/env bash
+
+. ./test.common
+
+test_start "process priority"
+
+extra_chronyd_options="-P 1"
+
+start_chronyd || test_fail
+wait_for_sync || test_fail
+stop_chronyd || test_fail
+check_chronyd_messages || test_fail
+check_chronyd_files || test_fail
+
+test_pass
diff --git a/test/system/005-scfilter b/test/system/005-scfilter
new file mode 100755
index 0000000..778a688
--- /dev/null
+++ b/test/system/005-scfilter
@@ -0,0 +1,17 @@
+#!/usr/bin/env bash
+
+. ./test.common
+
+check_chronyd_features SCFILTER || test_skip "SCFILTER support disabled"
+
+test_start "system call filter"
+
+for extra_chronyd_options in "-F -1" "-F 1"; do
+ start_chronyd || test_fail
+ wait_for_sync || test_fail
+ stop_chronyd || test_fail
+ check_chronyd_messages || test_fail
+ check_chronyd_files || test_fail
+done
+
+test_pass
diff --git a/test/system/006-privdrop b/test/system/006-privdrop
new file mode 100755
index 0000000..6d7b0c9
--- /dev/null
+++ b/test/system/006-privdrop
@@ -0,0 +1,17 @@
+#!/usr/bin/env bash
+
+. ./test.common
+
+check_chronyd_features PRIVDROP || test_skip "PRIVDROP support disabled"
+
+user="nobody"
+
+test_start "dropping of root privileges"
+
+minimal_config=1
+
+start_chronyd || test_fail
+stop_chronyd || test_fail
+check_chronyd_messages || test_fail
+
+test_pass
diff --git a/test/system/007-cmdmon b/test/system/007-cmdmon
new file mode 100755
index 0000000..f705fb0
--- /dev/null
+++ b/test/system/007-cmdmon
@@ -0,0 +1,69 @@
+#!/usr/bin/env bash
+
+. ./test.common
+
+test_start "chronyc commands"
+
+start_chronyd || test_fail
+
+for command in \
+ "accheck 1.2.3.4" \
+ "delete $server" \
+ "add server $server" \
+ "deny" \
+ "allow" \
+ "burst 1/1" \
+ "clients" \
+ "cmdallow 1.2.3.4" \
+ "cmdaccheck 1.2.3.4" \
+ "cmddeny 1.2.3.4" \
+ "cyclelogs" \
+ "dfreq 1.0e-3" \
+ "doffset -0.1" \
+ "dump" \
+ "local off" \
+ "local" \
+ "manual on" \
+ "settime now" \
+ "manual delete 0" \
+ "settime now" \
+ "manual reset" \
+ "manual off" \
+ "maxdelay $server 1e-2" \
+ "maxdelaydevratio $server 5.0" \
+ "maxdelayratio $server 3.0" \
+ "maxpoll $server 5" \
+ "maxupdateskew $server 10.0" \
+ "minpoll $server 3" \
+ "minstratum $server 1" \
+ "ntpdata $server" \
+ "offline" \
+ "online" \
+ "onoffline" \
+ "polltarget $server 10" \
+ "refresh" \
+ "rekey" \
+ "reselect" \
+ "reselectdist 1e-3" \
+ "serverstats" \
+ "smoothtime reset" \
+ "smoothtime activate" \
+ "shutdown" \
+; do
+ run_chronyc "$command" || test_fail
+done
+
+stop_chronyd || test_fail
+check_chronyd_messages || test_fail
+start_chronyd || test_fail
+
+run_chronyc "makestep" && test_fail
+check_chronyc_output "500 Failure" || test_fail
+run_chronyc "trimrtc" && test_fail
+check_chronyc_output "513 RTC driver not running" || test_fail
+run_chronyc "writertc" && test_fail
+check_chronyc_output "513 RTC driver not running" || test_fail
+
+stop_chronyd || test_fail
+
+test_pass
diff --git a/test/system/100-clockupdate b/test/system/100-clockupdate
new file mode 100755
index 0000000..191e461
--- /dev/null
+++ b/test/system/100-clockupdate
@@ -0,0 +1,30 @@
+#!/usr/bin/env bash
+
+. ./test.common
+
+test_start "update of system clock"
+
+clock_control=1
+minimal_config=1
+
+start_chronyd || test_fail
+run_chronyc "dfreq 1e-3" || test_fail
+check_chronyc_output "200 OK" || test_fail
+
+before=$(date '+%s')
+run_chronyc "doffset -1.0" || test_fail
+check_chronyc_output "200 OK" || test_fail
+run_chronyc "makestep" || test_fail
+check_chronyc_output "200 OK" || test_fail
+after=$(date '+%s')
+
+test_message 1 0 "checking system clock"
+[ "$before" -lt "$after" ] && test_ok || test_bad || test_fail
+
+run_chronyc "doffset 1.0" || test_fail
+run_chronyc "makestep" || test_fail
+stop_chronyd || test_fail
+check_chronyd_messages || test_fail
+check_chronyd_message_count "System clock was stepped by" 2 2 || test_fail
+
+test_pass
diff --git a/test/system/101-rtc b/test/system/101-rtc
new file mode 100755
index 0000000..fa9a70d
--- /dev/null
+++ b/test/system/101-rtc
@@ -0,0 +1,19 @@
+#!/usr/bin/env bash
+
+. ./test.common
+
+check_chronyd_features RTC || test_skip "RTC support disabled"
+[ -c "/dev/rtc" ] || test_skip "missing /dev/rtc"
+
+test_start "real-time clock"
+
+minimal_config=1
+extra_chronyd_options="-s"
+extra_chronyd_directives="rtcfile $TEST_DIR/rtcfile"
+echo "1 $(date +%s) 0.0 0.0" > "$TEST_DIR/rtcfile"
+
+start_chronyd || test_fail
+stop_chronyd || test_fail
+check_chronyd_message_count "\(clock off from RTC\|RTC time before last\)" 1 1 || test_fail
+
+test_pass
diff --git a/test/system/102-hwtimestamp b/test/system/102-hwtimestamp
new file mode 100755
index 0000000..86f2287
--- /dev/null
+++ b/test/system/102-hwtimestamp
@@ -0,0 +1,28 @@
+#!/usr/bin/env bash
+
+. ./test.common
+
+[ "$(uname -s)" = "Linux" ] || test_skip "non-Linux system"
+
+hwts_iface=""
+for iface_path in /sys/class/net/*; do
+ iface=$(basename "$iface_path")
+ if ethtool -T "$iface" 2> /dev/null | grep -q HWTSTAMP_FILTER_ALL; then
+ hwts_iface="$iface"
+ break
+ fi
+done
+
+[ -n "$hwts_iface" ] || test_skip "no HW timestamping interface found"
+
+test_start "hardware timestamping"
+
+minimal_config=1
+extra_chronyd_directives="hwtimestamp $hwts_iface"
+
+start_chronyd || test_fail
+stop_chronyd || test_fail
+check_chronyd_messages || test_fail
+check_chronyd_message_count "Enabled HW timestamping on $hwts_iface" 1 1 || test_fail
+
+test_pass
diff --git a/test/system/103-refclock b/test/system/103-refclock
new file mode 100755
index 0000000..e5b74e0
--- /dev/null
+++ b/test/system/103-refclock
@@ -0,0 +1,19 @@
+#!/usr/bin/env bash
+
+. ./test.common
+
+check_chronyd_features REFCLOCK || test_skip "refclock support disabled"
+
+test_start "reference clocks"
+
+extra_chronyd_directives="
+refclock SOCK $TEST_DIR/refclock.sock
+refclock SHM 100"
+
+start_chronyd || test_fail
+wait_for_sync || test_fail
+stop_chronyd || test_fail
+check_chronyd_messages || test_fail
+check_chronyd_files || test_fail
+
+test_pass
diff --git a/test/system/104-systemdirs b/test/system/104-systemdirs
new file mode 100755
index 0000000..15508dc
--- /dev/null
+++ b/test/system/104-systemdirs
@@ -0,0 +1,19 @@
+#!/usr/bin/env bash
+
+TEST_LIBDIR=${CHRONY_LIBDIR:-/var/lib/chrony}
+TEST_LOGDIR=${CHRONY_LOGDIR:-/var/log/chrony}
+TEST_RUNDIR=${CHRONY_RUNDIR:-/var/run/chrony}
+
+. ./test.common
+
+user=$(ls -ld "$TEST_RUNDIR" 2> /dev/null | awk '{print $3}')
+
+test_start "system directories"
+
+start_chronyd || test_fail
+wait_for_sync || test_fail
+stop_chronyd || test_fail
+check_chronyd_messages || test_fail
+check_chronyd_files || test_fail
+
+test_pass
diff --git a/test/system/run b/test/system/run
new file mode 100755
index 0000000..5516ed4
--- /dev/null
+++ b/test/system/run
@@ -0,0 +1,64 @@
+#!/usr/bin/env bash
+
+print_help() {
+ echo "$1 [-a] [-d] [TEST]..."
+}
+
+run_test() {
+ local result name=$1
+
+ if [ $destructive -ne 1 ] && [[ "$name" == 1[0-9][0-9]-* ]]; then
+ echo "SKIP (destructive test)"
+ return 9
+ fi
+
+ ./$name
+ result=$?
+
+ if [ $result -ne 0 -a $result -ne 9 ]; then
+ if [ $abort_on_fail -ne 0 ]; then
+ exit 1
+ fi
+ fi
+
+ return $result
+}
+
+passed=() failed=() skipped=()
+
+abort_on_fail=0
+destructive=0
+
+while getopts ":ad" opt; do
+ case $opt in
+ a) abort_on_fail=1;;
+ d) destructive=1;;
+ *) print_help "$0"; exit 3;;
+ esac
+done
+
+shift $[$OPTIND - 1]
+
+[ $# -gt 0 ] && tests=($@) || tests=([0-9]*-*[^_])
+
+for test in "${tests[@]}"; do
+ printf "%s " "$test"
+ run_test $test
+ result=$?
+ echo
+
+ case $result in
+ 0) passed=(${passed[@]} $test);;
+ 9) skipped=(${skipped[@]} $test);;
+ *) failed=(${failed[@]} $test);;
+ esac
+done
+
+echo
+echo "SUMMARY:"
+echo " TOTAL $[${#passed[@]} + ${#failed[@]} + ${#skipped[@]}]"
+echo " PASSED ${#passed[@]}"
+echo " FAILED ${#failed[@]} (${failed[@]})"
+echo " SKIPPED ${#skipped[@]} (${skipped[@]})"
+
+[ ${#failed[@]} -eq 0 ]
diff --git a/test/system/test.common b/test/system/test.common
new file mode 100644
index 0000000..28c4805
--- /dev/null
+++ b/test/system/test.common
@@ -0,0 +1,339 @@
+# Copyright (C) Miroslav Lichvar 2009
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of version 2 of the GNU General Public License as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+export LC_ALL=C
+export PATH=${CHRONY_PATH:-../..}:$PATH
+
+TEST_DIR=${TEST_DIR:-$(pwd)/tmp}
+TEST_LIBDIR=${TEST_LIBDIR:-$TEST_DIR}
+TEST_LOGDIR=${TEST_LOGDIR:-$TEST_DIR}
+TEST_RUNDIR=${TEST_RUNDIR:-$TEST_DIR}
+
+test_start() {
+ check_chronyd_features NTP CMDMON || test_skip "NTP/CMDMON support disabled"
+
+ [ "${#TEST_DIR}" -ge 5 ] || test_skip "invalid TEST_DIR"
+
+ rm -rf "$TEST_DIR"
+ mkdir -p "$TEST_DIR" && chmod 700 "$TEST_DIR" || test_skip "could not create $TEST_DIR"
+
+ [ -d "$TEST_LIBDIR" ] || test_skip "missing $TEST_LIBDIR"
+ [ -d "$TEST_LOGDIR" ] || test_skip "missing $TEST_LOGDIR"
+ [ -d "$TEST_RUNDIR" ] || test_skip "missing $TEST_RUNDIR"
+
+ rm -f "$TEST_LIBDIR"/* "$TEST_LOGDIR"/* "$TEST_RUNDIR"/*
+
+ if [ "$user" != "root" ]; then
+ id -u "$user" > /dev/null 2> /dev/null || test_skip "missing user $user"
+ chown "$user:$(id -g "$user")" "$TEST_DIR" || test_skip "could not chown $TEST_DIR"
+ su "$user" -s /bin/sh -c "touch $TEST_DIR/test" 2> /dev/null || \
+ test_skip "$user cannot access $TEST_DIR"
+ rm "$TEST_DIR/test"
+ fi
+
+ echo "Testing $*:"
+}
+
+test_pass() {
+ echo "PASS"
+ exit 0
+}
+
+test_fail() {
+ echo "FAIL"
+ exit 1
+}
+
+test_skip() {
+ local msg=$1
+
+ [ -n "$msg" ] && echo "SKIP ($msg)" || echo "SKIP"
+ exit 9
+}
+
+test_ok() {
+ pad_line
+ echo -e "\tOK"
+ return 0
+}
+
+test_bad() {
+ pad_line
+ echo -e "\tBAD"
+ return 1
+}
+
+test_error() {
+ pad_line
+ echo -e "\tERROR"
+ return 1
+}
+
+chronyd=$(command -v chronyd)
+chronyc=$(command -v chronyc)
+
+[ $EUID -eq 0 ] || test_skip "not root"
+
+[ -x "$chronyd" ] || test_skip "chronyd not found"
+[ -x "$chronyc" ] || test_skip "chronyc not found"
+
+netstat -aln > /dev/null 2> /dev/null || test_skip "missing netstat"
+
+# Default test testings
+default_minimal_config=0
+default_extra_chronyd_directives=""
+default_extra_chronyd_options=""
+default_clock_control=0
+default_server=127.0.0.1
+default_user=root
+
+# Initialize test settings from their defaults
+for defoptname in ${!default_*}; do
+ optname=${defoptname#default_}
+ [ -z "${!optname}" ] && declare "$optname"="${!defoptname}"
+done
+
+msg_length=0
+pad_line() {
+ local line_length=56
+ [ $msg_length -lt $line_length ] && \
+ printf "%$((line_length - msg_length))s" ""
+ msg_length=0
+}
+
+# Print aligned message
+test_message() {
+ local level=$1 eol=$2
+ shift 2
+ local msg="$*"
+
+ while [ "$level" -gt 0 ]; do
+ echo -n " "
+ level=$((level - 1))
+ msg_length=$((msg_length + 2))
+ done
+ echo -n "$msg"
+
+ msg_length=$((msg_length + ${#msg}))
+ if [ "$eol" -ne 0 ]; then
+ echo
+ msg_length=0
+ fi
+}
+
+# Check if chronyd has specified features
+check_chronyd_features() {
+ local feature features
+
+ features=$($chronyd -v | sed 's/.*(\(.*\)).*/\1/')
+
+ for feature; do
+ echo "$features" | grep -q "+$feature" || return 1
+ done
+}
+
+# Print test settings which differ from default value
+print_nondefaults() {
+ local defoptname optname
+
+ test_message 1 1 "non-default settings:"
+ for defoptname in ${!default_*}; do
+ optname=${defoptname#default_}
+ [ "${!defoptname}" = "${!optname}" ] || \
+ test_message 2 1 "$optname"=${!optname}
+ done
+}
+
+get_conffile() {
+ echo "$TEST_DIR/chronyd.conf"
+}
+
+get_pidfile() {
+ echo "$TEST_RUNDIR/chronyd.pid"
+}
+
+get_logfile() {
+ echo "$TEST_LOGDIR/chronyd.log"
+}
+
+get_cmdsocket() {
+ echo "$TEST_RUNDIR/chronyd.sock"
+}
+
+# Find a free port in the 10000-20000 range (their use is racy)
+get_free_port() {
+ local port
+
+ while true; do
+ port=$((RANDOM % 10000 + 10000))
+ netstat -aln | grep '^udp.*:'$port && continue
+ break
+ done
+
+ echo $port
+}
+
+generate_chrony_conf() {
+ local ntpport cmdport
+
+ ntpport=$(get_free_port)
+ cmdport=$(get_free_port)
+
+ echo "0.0 10000" > "$TEST_LIBDIR/driftfile"
+ echo "1 MD5 abcdefghijklmnopq" > "$TEST_DIR/keys"
+ chown "$user:$(id -g "$user")" "$TEST_LIBDIR/driftfile" "$TEST_DIR/keys"
+ echo "0.0" > "$TEST_DIR/tempcomp"
+
+ (
+ echo "pidfile $(get_pidfile)"
+ echo "bindcmdaddress $(get_cmdsocket)"
+ echo "port $ntpport"
+ echo "cmdport $cmdport"
+
+ echo "$extra_chronyd_directives"
+
+ [ "$minimal_config" -ne 0 ] && exit 0
+
+ echo "allow"
+ echo "cmdallow"
+ echo "local"
+
+ echo "server $server port $ntpport minpoll -6 maxpoll -6"
+
+ [ "$server" = "127.0.0.1" ] && echo "bindacqaddress $server"
+ echo "bindaddress 127.0.0.1"
+ echo "bindcmdaddress 127.0.0.1"
+ echo "dumpdir $TEST_RUNDIR"
+ echo "logdir $TEST_LOGDIR"
+ echo "log tempcomp rawmeasurements refclocks statistics tracking rtc"
+ echo "logbanner 0"
+ echo "smoothtime 100.0 0.001"
+
+ echo "include /dev/null"
+ echo "keyfile $TEST_DIR/keys"
+ echo "driftfile $TEST_LIBDIR/driftfile"
+ echo "tempcomp $TEST_DIR/tempcomp 0.1 0 0 0 0"
+
+ ) > "$(get_conffile)"
+}
+
+get_chronyd_options() {
+ [ "$clock_control" -eq 0 ] && echo "-x"
+ echo "-l $(get_logfile)"
+ echo "-f $(get_conffile)"
+ echo "-u $user"
+ echo "$extra_chronyd_options"
+}
+
+# Start a chronyd instance
+start_chronyd() {
+ local pid pidfile=$(get_pidfile)
+
+ print_nondefaults
+ test_message 1 0 "starting chronyd"
+
+ generate_chrony_conf
+
+ trap stop_chronyd EXIT
+
+ $CHRONYD_WRAPPER "$chronyd" $(get_chronyd_options) > "$TEST_DIR/chronyd.out" 2>&1
+
+ [ $? -eq 0 ] && [ -f "$pidfile" ] && ps -p "$(cat "$pidfile")" > /dev/null && test_ok || test_error
+}
+
+wait_for_sync() {
+ test_message 1 0 "waiting for synchronization"
+ sleep 1 && test_ok || test_error
+}
+
+# Stop the chronyd instance
+stop_chronyd() {
+ local pid pidfile
+
+ pidfile=$(get_pidfile)
+ [ -f "$pidfile" ] || return 0
+
+ pid=$(cat "$pidfile")
+
+ test_message 1 0 "stopping chronyd"
+
+ if ! kill "$pid" 2> /dev/null; then
+ test_error
+ return
+ fi
+
+ # Wait for the process to terminate (we cannot use "wait")
+ while ps -p "$pid" > /dev/null; do
+ sleep 0.1
+ done
+
+ test_ok
+}
+
+# Check chronyd log for expected and unexpected messages
+check_chronyd_messages() {
+ local logfile=$(get_logfile)
+
+ test_message 1 0 "checking chronyd messages"
+
+ grep -q 'chronyd exiting' "$logfile" && \
+ ([ "$clock_control" -eq 0 ] || ! grep -q 'Disabled control of system clock' "$logfile") && \
+ ([ "$clock_control" -ne 0 ] || grep -q 'Disabled control of system clock' "$logfile") && \
+ ([ "$minimal_config" -ne 0 ] || grep -q 'Frequency .* read from' "$logfile") && \
+ grep -q 'chronyd exiting' "$logfile" && \
+ ! grep -q 'Could not' "$logfile" && \
+ ! grep -q 'Disabled command socket' "$logfile" && \
+ test_ok || test_bad
+}
+
+# Check the number of messages matching a pattern in a specified file
+check_chronyd_message_count() {
+ local count pattern=$1 min=$2 max=$3 logfile=$(get_logfile)
+
+ test_message 1 0 "checking message \"$pattern\""
+
+ count=$(grep "$pattern" "$(get_logfile)" | wc -l)
+
+ [ "$min" -le "$count" ] && [ "$count" -le "$max" ] && test_ok || test_bad
+}
+
+# Check the logs and dump file for measurements and a clock update
+check_chronyd_files() {
+ test_message 1 0 "checking chronyd files"
+
+ grep -q " $server .* 111 111 1111 " "$TEST_LOGDIR/measurements.log" && \
+ grep -q " $server " "$TEST_LOGDIR/statistics.log" && \
+ grep -q " $server " "$TEST_LOGDIR/tracking.log" && \
+ [ -f "$TEST_LOGDIR/tempcomp.log" ] && [ "$(wc -l < "$TEST_LOGDIR/tempcomp.log")" -ge 2 ] && \
+ [ -f "$TEST_RUNDIR/$server.dat" ] && [ "$(wc -l < "$TEST_RUNDIR/$server.dat")" -ge 5 ] && \
+ test_ok || test_bad
+}
+
+# Run a chronyc command
+run_chronyc() {
+ test_message 1 0 "running chronyc $*"
+
+ $CHRONYC_WRAPPER "$chronyc" -h "$(get_cmdsocket)" -n -m "$@" > "$TEST_DIR/chronyc.out" && \
+ test_ok || test_error
+}
+
+# Compare chronyc output with specified pattern
+check_chronyc_output() {
+ local pattern=$1
+
+ test_message 1 0 "checking chronyc output"
+
+ [[ "$(cat "$TEST_DIR/chronyc.out")" =~ $pattern ]] && test_ok || test_bad
+}
diff --git a/test/unit/ntp_core.c b/test/unit/ntp_core.c
index 5e519e5..ac01205 100644
--- a/test/unit/ntp_core.c
+++ b/test/unit/ntp_core.c
@@ -28,6 +28,8 @@
#include <local.h>
#include "test.h"
+#ifdef FEAT_NTP
+
static struct timespec current_time;
static NTP_Receive_Buffer req_buffer, res_buffer;
static int req_length, res_length;
@@ -332,10 +334,8 @@ test_unit(void)
CPS_ParseNTPSourceAdd(source_line, &source);
for (i = 0; i < 1000; i++) {
- if (random() % 2)
- source.params.interleaved = 1;
- if (random() % 2)
- source.params.authkey = get_random_key_id();
+ source.params.interleaved = random() % 2;
+ source.params.authkey = random() % 2 ? get_random_key_id() : INACTIVE_AUTHKEY;
source.params.version = random() % 4 + 1;
UTI_ZeroTimespec(&current_time);
@@ -475,3 +475,11 @@ test_unit(void)
CNF_Finalise();
HSH_Finalise();
}
+
+#else
+void
+test_unit(void)
+{
+ TEST_REQUIRE(0);
+}
+#endif
diff --git a/test/unit/ntp_sources.c b/test/unit/ntp_sources.c
index ea8f19c..f13852e 100644
--- a/test/unit/ntp_sources.c
+++ b/test/unit/ntp_sources.c
@@ -18,10 +18,14 @@
**********************************************************************
*/
+#include <config.h>
+#include "test.h"
+
+#ifdef FEAT_NTP
+
#include <ntp_sources.c>
#include <conf.h>
#include <ntp_io.h>
-#include "test.h"
void
test_unit(void)
@@ -98,3 +102,11 @@ test_unit(void)
CNF_Finalise();
HSH_Finalise();
}
+
+#else
+void
+test_unit(void)
+{
+ TEST_REQUIRE(0);
+}
+#endif
diff --git a/test/unit/test.c b/test/unit/test.c
index 3a9ec74..fbfeb4b 100644
--- a/test/unit/test.c
+++ b/test/unit/test.c
@@ -22,6 +22,7 @@
#include <sysincl.h>
#include <logging.h>
#include <localp.h>
+#include <util.h>
#include "test.h"
@@ -32,6 +33,13 @@ TST_Fail(int line)
exit(1);
}
+void
+TST_Skip(int line)
+{
+ printf("SKIP (on line %d)\n", line);
+ exit(0);
+}
+
int
main(int argc, char **argv)
{
diff --git a/test/unit/test.h b/test/unit/test.h
index f409252..2d3637b 100644
--- a/test/unit/test.h
+++ b/test/unit/test.h
@@ -33,7 +33,16 @@ extern void test_unit(void);
} \
} while (0)
+#define TEST_REQUIRE(expr) \
+ do { \
+ if (!(expr)) { \
+ TST_Skip(__LINE__); \
+ exit(0); \
+ } \
+ } while (0)
+
extern void TST_Fail(int line);
+extern void TST_Skip(int line);
extern void TST_SuspendLogging(void);
extern void TST_ResumeLogging(void);
diff --git a/version.txt b/version.txt
index 2f4b607..c50661d 100644
--- a/version.txt
+++ b/version.txt
@@ -1 +1 @@
-3.4
+3.5-pre1