mirror of
https://gitlab.com/chrony/chrony.git
synced 2025-12-05 10:15:06 -05:00
Compare commits
22 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6789b5165c | ||
|
|
d631d7e81f | ||
|
|
c6245dc616 | ||
|
|
4b36799ce1 | ||
|
|
d26bb9b4eb | ||
|
|
698404b02f | ||
|
|
d46d7ad947 | ||
|
|
7c6630905d | ||
|
|
129aa587c6 | ||
|
|
cc1c6c94e3 | ||
|
|
41266cbaa0 | ||
|
|
fbfd261da6 | ||
|
|
71602b8ee6 | ||
|
|
14cae239f6 | ||
|
|
2e9e309a0d | ||
|
|
3fba33d5f5 | ||
|
|
77a7162361 | ||
|
|
75efa5174c | ||
|
|
c62afbe77b | ||
|
|
a6f0688f46 | ||
|
|
5762d33e38 | ||
|
|
9c6d1c214f |
96
INSTALL
96
INSTALL
@@ -1,96 +0,0 @@
|
|||||||
The software is distributed as source code which has to be compiled.
|
|
||||||
|
|
||||||
PARTS OF THE SOFTWARE ARE HIGHLY SYSTEM-SPECIFIC AND NON-PORTABLE.
|
|
||||||
UNLESS YOU ARE RUNNING A SUPPORTED SYSTEM, BE PREPARED FOR SOME
|
|
||||||
PROGRAMMING!
|
|
||||||
|
|
||||||
After unpacking the source code, change directory into it, and type
|
|
||||||
|
|
||||||
./configure
|
|
||||||
|
|
||||||
This is a shell script that automatically determines the system type.
|
|
||||||
There is a single optional parameter, --prefix which indicates the
|
|
||||||
directory tree where the software should be installed. For example,
|
|
||||||
|
|
||||||
./configure --prefix=/opt/free
|
|
||||||
|
|
||||||
will install the chronyd daemon into /opt/free/sbin and the chronyc
|
|
||||||
control program into /opt/free/bin. The default value for the prefix
|
|
||||||
is /usr/local.
|
|
||||||
|
|
||||||
The configure script assumes you want to use gcc as your compiler.
|
|
||||||
If you want to use a different compiler, you can configure this way:
|
|
||||||
|
|
||||||
CC=cc CFLAGS=-O ./configure --prefix=/opt/free
|
|
||||||
|
|
||||||
for Bourne-family shells, or
|
|
||||||
|
|
||||||
setenv CC cc
|
|
||||||
setenv CFLAGS -O
|
|
||||||
./configure --prefix=/opt/free
|
|
||||||
|
|
||||||
for C-family shells.
|
|
||||||
|
|
||||||
If the software cannot (yet) be built on your system, an error message
|
|
||||||
will be shown. Otherwise, `Makefile' will be generated.
|
|
||||||
|
|
||||||
If editline or readline library is available, chronyc will be built
|
|
||||||
with line editing support. If you don't want this, specify the
|
|
||||||
--disable-readline flag to configure. Please refer to the chrony.txt
|
|
||||||
file for more information.
|
|
||||||
|
|
||||||
If a 'timepps.h' header is available (e.g. from the LinuxPPS project
|
|
||||||
(http://linuxpps.org/)), chronyd will be built with PPS API reference
|
|
||||||
clock driver. If the header is installed in a location that isn't
|
|
||||||
normally searched by the compiler, you can add it to the searched
|
|
||||||
locations by setting 'CPPFLAGS' variable to '-I/path/to/timepps'.
|
|
||||||
|
|
||||||
Now type
|
|
||||||
|
|
||||||
make
|
|
||||||
|
|
||||||
to build the programs.
|
|
||||||
|
|
||||||
If you want to build the manual in plain text, HTML and info versions, type
|
|
||||||
|
|
||||||
make docs
|
|
||||||
|
|
||||||
Once the programs have been successfully compiled, they need to be
|
|
||||||
installed in their target locations. This step normally needs to be
|
|
||||||
performed by the superuser, and requires the following command to be
|
|
||||||
entered.
|
|
||||||
|
|
||||||
make install
|
|
||||||
|
|
||||||
This will install the binaries, plain text manual and manpages.
|
|
||||||
|
|
||||||
To install the HTML and info versions of the manual as well, enter the command
|
|
||||||
|
|
||||||
make install-docs
|
|
||||||
|
|
||||||
If you want chrony to appear in the top level info directory listing, you need
|
|
||||||
to run the install-info command manually after this step. install-info takes 2
|
|
||||||
arguments. The first is the path to the chrony.info file you have just
|
|
||||||
installed. This will be the argument you gave to --prefix when you configured
|
|
||||||
(/usr/local by default), with /share/info/chrony.info on the end. The second
|
|
||||||
argument is the location of the file called 'dir'. This will typically be
|
|
||||||
/usr/share/info/dir. So the typical command line would be
|
|
||||||
|
|
||||||
install-info /usr/local/share/info/chrony.info /usr/share/info/dir
|
|
||||||
|
|
||||||
Now that the software is successfully installed, the next step is to
|
|
||||||
set up a configuration file. The contents of this depend on the
|
|
||||||
network environment in which the computer operates. Typical scenarios
|
|
||||||
are described in the manual. The simplest case is for a computer with
|
|
||||||
a permanent Internet connection - suppose you want to use public NTP
|
|
||||||
servers from the pool.ntp.org project as your time reference. You would
|
|
||||||
create an /etc/chrony.conf file containing
|
|
||||||
|
|
||||||
server 0.pool.ntp.org
|
|
||||||
server 1.pool.ntp.org
|
|
||||||
server 2.pool.ntp.org
|
|
||||||
driftfile /var/lib/chrony/drift
|
|
||||||
|
|
||||||
and then run /usr/local/sbin/chronyd.
|
|
||||||
|
|
||||||
|
|
||||||
@@ -154,10 +154,6 @@ chrony.html : chrony.texi
|
|||||||
chrony.info : chrony.texi
|
chrony.info : chrony.texi
|
||||||
makeinfo chrony.texi
|
makeinfo chrony.texi
|
||||||
|
|
||||||
# This is only relevant if you're maintaining the website!
|
|
||||||
faq.php : faq.txt faqgen.pl
|
|
||||||
perl faqgen.pl < faq.txt > faq.php
|
|
||||||
|
|
||||||
.deps:
|
.deps:
|
||||||
@mkdir .deps
|
@mkdir .deps
|
||||||
|
|
||||||
|
|||||||
3
NEWS
3
NEWS
@@ -17,7 +17,7 @@ Enhancements
|
|||||||
* Try to detect unexpected forward time jumps and reset state
|
* Try to detect unexpected forward time jumps and reset state
|
||||||
* Exit with non-zero code when maxchange limit is reached
|
* Exit with non-zero code when maxchange limit is reached
|
||||||
* Improve makestep to not start and stop slew unnecessarily
|
* Improve makestep to not start and stop slew unnecessarily
|
||||||
* Change default corrtimeratio to 3.0 to improve frequency error
|
* Change default corrtimeratio to 3.0 to improve frequency accuracy
|
||||||
* Announce leap second only on last day of June and December
|
* Announce leap second only on last day of June and December
|
||||||
* Use separate connected client sockets for each NTP server
|
* Use separate connected client sockets for each NTP server
|
||||||
* Remove separate NTP implementation used for initstepslew
|
* Remove separate NTP implementation used for initstepslew
|
||||||
@@ -26,6 +26,7 @@ Enhancements
|
|||||||
* Print warning when source is added with unknown key
|
* Print warning when source is added with unknown key
|
||||||
* Take leap second in PPS refclock from locked source
|
* Take leap second in PPS refclock from locked source
|
||||||
* Make reading of RTC for initial trim more reliable
|
* Make reading of RTC for initial trim more reliable
|
||||||
|
* Don't create cmdmon sockets when cmdport is 0
|
||||||
* Add configure option to set default user to drop root privileges
|
* Add configure option to set default user to drop root privileges
|
||||||
* Add configure option to compile with debug messages
|
* Add configure option to compile with debug messages
|
||||||
* Print debug messages when -d is used more than once
|
* Print debug messages when -d is used more than once
|
||||||
|
|||||||
6
README
6
README
@@ -2,6 +2,7 @@ This is the README for chrony.
|
|||||||
|
|
||||||
What is chrony?
|
What is chrony?
|
||||||
===============
|
===============
|
||||||
|
|
||||||
Chrony is a pair of programs for maintaining the accuracy of computer
|
Chrony is a pair of programs for maintaining the accuracy of computer
|
||||||
clocks.
|
clocks.
|
||||||
|
|
||||||
@@ -61,7 +62,7 @@ Chrony can be successfully built and run on
|
|||||||
Any other system will require a porting exercise. You would need to
|
Any other system will require a porting exercise. You would need to
|
||||||
start from one of the existing system-specific drivers and look into
|
start from one of the existing system-specific drivers and look into
|
||||||
the quirks of certain system calls and the kernel on your target
|
the quirks of certain system calls and the kernel on your target
|
||||||
system. (This is described in the manual).
|
system.
|
||||||
|
|
||||||
How do I set it up?
|
How do I set it up?
|
||||||
===================
|
===================
|
||||||
@@ -94,8 +95,7 @@ by sending mail with the subject "subscribe" to
|
|||||||
|
|
||||||
chrony-announce-request@chrony.tuxfamily.org
|
chrony-announce-request@chrony.tuxfamily.org
|
||||||
|
|
||||||
These messages will be copied to chrony-users (see below). New versions
|
These messages will be copied to chrony-users (see below).
|
||||||
are announced also on Freshmeat (http://freshmeat.net/).
|
|
||||||
|
|
||||||
How can I get support for chrony?
|
How can I get support for chrony?
|
||||||
and where can I discuss new features, possible bugs etc?
|
and where can I discuss new features, possible bugs etc?
|
||||||
|
|||||||
@@ -22,16 +22,19 @@ as a minimum
|
|||||||
|
|
||||||
However, you will probably want to include some of the other directives
|
However, you will probably want to include some of the other directives
|
||||||
described in detail in the documentation supplied with the distribution
|
described in detail in the documentation supplied with the distribution
|
||||||
(\fIchrony.txt\fR and \fIchrony.texi\fR). The following directives will be
|
(\fIchrony.txt\fR and \fIchrony.texi\fR). The following directives may be
|
||||||
particularly useful : `driftfile', `commandkey', `keyfile'. The smallest
|
particularly useful : `driftfile', `generatecommandkey', `keyfile', `makestep'.
|
||||||
useful configuration file would look something like
|
Also, the `iburst' server option is useful to speed up the initial
|
||||||
|
synchronization. The smallest useful configuration file would look something
|
||||||
|
like
|
||||||
|
|
||||||
server a.b.c
|
server a.b.c iburst
|
||||||
server d.e.f
|
server d.e.f iburst
|
||||||
server g.h.i
|
server g.h.i iburst
|
||||||
keyfile @SYSCONFDIR@/chrony.keys
|
keyfile @SYSCONFDIR@/chrony.keys
|
||||||
commandkey 1
|
generatecommandkey
|
||||||
driftfile @CHRONYVARDIR@/drift
|
driftfile @CHRONYVARDIR@/drift
|
||||||
|
makestep 10 3
|
||||||
|
|
||||||
|
|
||||||
.SH "SEE ALSO"
|
.SH "SEE ALSO"
|
||||||
|
|||||||
439
chrony.texi.in
439
chrony.texi.in
@@ -35,7 +35,7 @@ Copyright @copyright{} 2009-2014 Miroslav Lichvar
|
|||||||
* Installation:: How to compile and install the software
|
* Installation:: How to compile and install the software
|
||||||
* Typical scenarios:: How to configure the software for some common cases
|
* Typical scenarios:: How to configure the software for some common cases
|
||||||
* Usage reference:: Reference manual
|
* Usage reference:: Reference manual
|
||||||
* Porting guide:: Hints to help with porting the software
|
* FAQ:: Answers to some common questions about chrony
|
||||||
* GPL:: The GNU General Public License
|
* GPL:: The GNU General Public License
|
||||||
@end menu
|
@end menu
|
||||||
@c }}}
|
@c }}}
|
||||||
@@ -353,7 +353,7 @@ the directory tree where the software should be installed. For example,
|
|||||||
@end example
|
@end example
|
||||||
|
|
||||||
will install the @code{chronyd} daemon into /opt/free/sbin and the
|
will install the @code{chronyd} daemon into /opt/free/sbin and the
|
||||||
chronyc control program into /opt/free/bin. The default value for the
|
@code{chronyc} control program into /opt/free/bin. The default value for the
|
||||||
prefix is /usr/local.
|
prefix is /usr/local.
|
||||||
|
|
||||||
The configure script assumes you want to use gcc as your compiler.
|
The configure script assumes you want to use gcc as your compiler.
|
||||||
@@ -381,7 +381,7 @@ editing support. If you don't want this, specify the --disable-readline flag
|
|||||||
to configure. Please refer to @pxref{line editing support} for more information.
|
to configure. Please refer to @pxref{line editing support} for more information.
|
||||||
|
|
||||||
If a @file{timepps.h} header is available (e.g. from the
|
If a @file{timepps.h} header is available (e.g. from the
|
||||||
@uref{http://linuxpps.org/, LinuxPPS project}), chronyd will be built with PPS API
|
@uref{http://linuxpps.org/, LinuxPPS project}), @code{chronyd} will be built with PPS API
|
||||||
reference clock driver. If the header is installed in a location that isn't
|
reference clock driver. If the header is installed in a location that isn't
|
||||||
normally searched by the compiler, you can add it to the searched locations by
|
normally searched by the compiler, you can add it to the searched locations by
|
||||||
setting @code{CPPFLAGS} variable to @code{-I/path/to/timepps}.
|
setting @code{CPPFLAGS} variable to @code{-I/path/to/timepps}.
|
||||||
@@ -431,9 +431,19 @@ install-info /usr/local/share/info/chrony.info /usr/share/info/dir
|
|||||||
@end example
|
@end example
|
||||||
|
|
||||||
Now that the software is successfully installed, the next step is to
|
Now that the software is successfully installed, the next step is to
|
||||||
set up a configuration file. The contents of this depend on the
|
set up a configuration file. The default location of the file
|
||||||
network environment in which the computer operates. Typical scenarios
|
is @file{@SYSCONFDIR@/chrony.conf}. Suppose you want to use public NTP
|
||||||
are described in the following section of the document.
|
servers from the pool.ntp.org project as your time reference. A
|
||||||
|
minimal useful configuration file could be
|
||||||
|
|
||||||
|
@example
|
||||||
|
server 0.pool.ntp.org iburst
|
||||||
|
server 1.pool.ntp.org iburst
|
||||||
|
server 2.pool.ntp.org iburst
|
||||||
|
makestep 10 3
|
||||||
|
@end example
|
||||||
|
|
||||||
|
Then, @code{chronyd} can be run.
|
||||||
@c }}}
|
@c }}}
|
||||||
@menu
|
@menu
|
||||||
* line editing support:: If libraries are in a non-standard place
|
* line editing support:: If libraries are in a non-standard place
|
||||||
@@ -526,8 +536,8 @@ the files to the intended final locations.
|
|||||||
@node Typical scenarios
|
@node Typical scenarios
|
||||||
@chapter Typical operating scenarios
|
@chapter Typical operating scenarios
|
||||||
@menu
|
@menu
|
||||||
* Computers on the net:: Your computer is permanently on the Internet (or on
|
* Computers on the net:: Your computer is on the Internet most of the time
|
||||||
a private network with NTP servers)
|
(or on a private network with NTP servers)
|
||||||
* Infrequent connection:: You connect to the Internet sometimes (e.g. via a modem)
|
* Infrequent connection:: You connect to the Internet sometimes (e.g. via a modem)
|
||||||
* Isolated networks:: You have an isolated network with no reference clocks
|
* Isolated networks:: You have an isolated network with no reference clocks
|
||||||
* Dial-up home PCs:: Additional considerations if you turn your computer off
|
* Dial-up home PCs:: Additional considerations if you turn your computer off
|
||||||
@@ -539,9 +549,9 @@ the files to the intended final locations.
|
|||||||
@node Computers on the net
|
@node Computers on the net
|
||||||
@section Computers connected to the internet
|
@section Computers connected to the internet
|
||||||
In this section we discuss how to configure chrony for computers that
|
In this section we discuss how to configure chrony for computers that
|
||||||
have permanent connections to the internet (or to any network
|
are connected to the Internet (or to any network containing true NTP
|
||||||
containing true NTP servers which ultimately derive their time from a
|
servers which ultimately derive their time from a reference clock)
|
||||||
reference clock).
|
permanently or most of the time.
|
||||||
|
|
||||||
To operate in this mode, you will need to know the names of the NTP
|
To operate in this mode, you will need to know the names of the NTP
|
||||||
server machines you wish to use. You may be able to find names of
|
server machines you wish to use. You may be able to find names of
|
||||||
@@ -576,17 +586,17 @@ server g.h.i
|
|||||||
@end example
|
@end example
|
||||||
|
|
||||||
However, you will probably want to include some of the other directives
|
However, you will probably want to include some of the other directives
|
||||||
described later. The following directives will be particularly useful :
|
described later. The @code{driftfile} and @code{makestep} directives may be
|
||||||
@code{driftfile}, @code{commandkey}, @code{keyfile}. The smallest
|
particularly useful. Also, the @code{iburst} server option is useful to speed
|
||||||
useful configuration file would look something like
|
up the initial synchronization. The smallest useful configuration file would
|
||||||
|
look something like
|
||||||
|
|
||||||
@example
|
@example
|
||||||
server a.b.c
|
server a.b.c iburst
|
||||||
server d.e.f
|
server d.e.f iburst
|
||||||
server g.h.i
|
server g.h.i iburst
|
||||||
keyfile @SYSCONFDIR@/chrony.keys
|
|
||||||
commandkey 1
|
|
||||||
driftfile @CHRONYVARDIR@/drift
|
driftfile @CHRONYVARDIR@/drift
|
||||||
|
makestep 10 3
|
||||||
@end example
|
@end example
|
||||||
@c }}}
|
@c }}}
|
||||||
@c {{{ S:Infrequent connection
|
@c {{{ S:Infrequent connection
|
||||||
@@ -639,21 +649,11 @@ in an offline state, and that they should not be contacted until @code{chronyd}
|
|||||||
receives notification that the link to the internet is present.
|
receives notification that the link to the internet is present.
|
||||||
|
|
||||||
In order to notify @code{chronyd} of the presence of the link, you will need to
|
In order to notify @code{chronyd} of the presence of the link, you will need to
|
||||||
be able to log in to it with the program chronyc. To do this, @code{chronyd}
|
be able to log in to it with the program @code{chronyc}. To do this,
|
||||||
needs to be configured with an administrator password. To set up an
|
@code{chronyd} needs to be configured with an administrator password. The
|
||||||
administrator password, you can create a file @file{@SYSCONFDIR@/chrony.keys}
|
password is read from a file specified by the @code{keyfile} directive. The
|
||||||
containing a single line
|
@code{generatecommandkey} directive can be used to generate a random password
|
||||||
|
automatically on the first @code{chronyd} start.
|
||||||
@example
|
|
||||||
1 ALongAndRandomPassword
|
|
||||||
@end example
|
|
||||||
|
|
||||||
and add the following line to @file{@SYSCONFDIR@/chrony.conf} (the order of the
|
|
||||||
lines does not matter)
|
|
||||||
|
|
||||||
@example
|
|
||||||
commandkey 1
|
|
||||||
@end example
|
|
||||||
|
|
||||||
The smallest useful configuration file would look something like
|
The smallest useful configuration file would look something like
|
||||||
|
|
||||||
@@ -662,8 +662,9 @@ server a.b.c offline
|
|||||||
server d.e.f offline
|
server d.e.f offline
|
||||||
server g.h.i offline
|
server g.h.i offline
|
||||||
keyfile @SYSCONFDIR@/chrony.keys
|
keyfile @SYSCONFDIR@/chrony.keys
|
||||||
commandkey 1
|
generatecommandkey
|
||||||
driftfile @CHRONYVARDIR@/drift
|
driftfile @CHRONYVARDIR@/drift
|
||||||
|
makestep 10 3
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
The next section describes how to tell @code{chronyd} when the internet link
|
The next section describes how to tell @code{chronyd} when the internet link
|
||||||
@@ -728,7 +729,7 @@ master's address is 192.168.169.170)
|
|||||||
|
|
||||||
@example
|
@example
|
||||||
driftfile @CHRONYVARDIR@/drift
|
driftfile @CHRONYVARDIR@/drift
|
||||||
commandkey 25
|
generatecommandkey
|
||||||
keyfile @SYSCONFDIR@/chrony.keys
|
keyfile @SYSCONFDIR@/chrony.keys
|
||||||
initstepslew 10 client1 client3 client6
|
initstepslew 10 client1 client3 client6
|
||||||
local stratum 8
|
local stratum 8
|
||||||
@@ -745,7 +746,7 @@ driftfile @CHRONYVARDIR@/drift
|
|||||||
logdir /var/log/chrony
|
logdir /var/log/chrony
|
||||||
log measurements statistics tracking
|
log measurements statistics tracking
|
||||||
keyfile @SYSCONFDIR@/chrony.keys
|
keyfile @SYSCONFDIR@/chrony.keys
|
||||||
commandkey 24
|
generatecommandkey
|
||||||
local stratum 10
|
local stratum 10
|
||||||
initstepslew 20 master
|
initstepslew 20 master
|
||||||
allow 192.168.169.170
|
allow 192.168.169.170
|
||||||
@@ -879,7 +880,8 @@ logdir /var/log/chrony
|
|||||||
log statistics measurements tracking
|
log statistics measurements tracking
|
||||||
driftfile @CHRONYVARDIR@/drift
|
driftfile @CHRONYVARDIR@/drift
|
||||||
keyfile @SYSCONFDIR@/chrony.keys
|
keyfile @SYSCONFDIR@/chrony.keys
|
||||||
commandkey 25
|
generatecommandkey
|
||||||
|
makestep 10 3
|
||||||
maxupdateskew 100.0
|
maxupdateskew 100.0
|
||||||
dumponexit
|
dumponexit
|
||||||
dumpdir @CHRONYVARDIR@
|
dumpdir @CHRONYVARDIR@
|
||||||
@@ -1438,7 +1440,8 @@ There is also a @code{cmddeny all} directive with similar behaviour to the
|
|||||||
|
|
||||||
The @code{cmdport} directive allows the port that is used for run-time
|
The @code{cmdport} directive allows the port that is used for run-time
|
||||||
command and monitoring (via the program @code{chronyc}) to be altered
|
command and monitoring (via the program @code{chronyc}) to be altered
|
||||||
from its default (323/udp).
|
from its default (323/udp). If set to 0, @code{chronyd} will not open the
|
||||||
|
port, this is useful to disable the @code{chronyc} access completely.
|
||||||
|
|
||||||
An example shows the syntax
|
An example shows the syntax
|
||||||
|
|
||||||
@@ -1687,7 +1690,7 @@ include @SYSCONFDIR@/chrony/local.conf
|
|||||||
@c {{{ initstepslew
|
@c {{{ initstepslew
|
||||||
@node initstepslew directive
|
@node initstepslew directive
|
||||||
@subsection initstepslew
|
@subsection initstepslew
|
||||||
In normal operation, @code{chronyd} always slews the time when it needs to
|
In normal operation, @code{chronyd} slews the time when it needs to
|
||||||
adjust the system clock. For example, to correct a system clock which
|
adjust the system clock. For example, to correct a system clock which
|
||||||
is 1 second slow, @code{chronyd} slightly increases the amount by which the
|
is 1 second slow, @code{chronyd} slightly increases the amount by which the
|
||||||
system clock is advanced on each clock interrupt, until the error is
|
system clock is advanced on each clock interrupt, until the error is
|
||||||
@@ -1719,8 +1722,7 @@ servers as arguments. A maximum of 8 will be used. Each of the servers
|
|||||||
is rapidly polled several times, and a majority voting mechanism used to
|
is rapidly polled several times, and a majority voting mechanism used to
|
||||||
find the most likely range of system clock error that is present. A
|
find the most likely range of system clock error that is present. A
|
||||||
step (or slew) is applied to the system clock to correct this error.
|
step (or slew) is applied to the system clock to correct this error.
|
||||||
@code{chronyd} then enters its normal operating mode (where only slews are
|
@code{chronyd} then enters its normal operating mode.
|
||||||
used).
|
|
||||||
|
|
||||||
An example of use of the command is
|
An example of use of the command is
|
||||||
|
|
||||||
@@ -1741,6 +1743,15 @@ below), the master can be set up with an @code{initstepslew} directive
|
|||||||
which references some or all of the slaves. Then, if the master machine
|
which references some or all of the slaves. Then, if the master machine
|
||||||
has to be rebooted, the slaves can be relied on to 'flywheel' the time
|
has to be rebooted, the slaves can be relied on to 'flywheel' the time
|
||||||
for the master.
|
for the master.
|
||||||
|
|
||||||
|
The @code{initstepslew} directive is functionally similar to a
|
||||||
|
combination of the @code{makestep} and @code{server} directives with
|
||||||
|
the @code{iburst} option. The main difference is that the
|
||||||
|
@code{initstepslew} servers are used only before normal operation
|
||||||
|
begins and that the foreground @code{chronyd} process waits for
|
||||||
|
@code{initstepslew} to finish before exiting. This is useful to
|
||||||
|
prevent programs started in the boot sequence after @code{chronyd}
|
||||||
|
from reading the clock before it's stepped.
|
||||||
@c }}}
|
@c }}}
|
||||||
@c {{{ keyfile
|
@c {{{ keyfile
|
||||||
@node keyfile directive
|
@node keyfile directive
|
||||||
@@ -4478,120 +4489,272 @@ command is issued.
|
|||||||
@c }}}
|
@c }}}
|
||||||
@c }}}
|
@c }}}
|
||||||
@c }}}
|
@c }}}
|
||||||
@c {{{ apx: porting guide
|
@c {{{ Ch:FAQ
|
||||||
@node Porting guide
|
@node FAQ
|
||||||
@appendix Porting guide
|
@chapter Frequently asked questions
|
||||||
@c {{{ section top
|
|
||||||
This appendix discusses issues that have arisen in writing the
|
|
||||||
system-specific parts of the existing ports. This will provide useful
|
|
||||||
information for those attempting to write ports to other systems.
|
|
||||||
|
|
||||||
|
|
||||||
|
@c {{{ Chapter top
|
||||||
@menu
|
@menu
|
||||||
* System driver files:: What needs to go in a driver file for a
|
* Administrative issues::
|
||||||
particular type of system
|
* Chrony compared to other programs::
|
||||||
* Quirks of particular systems:: Problem areas that have been found on ports
|
* Configuration issues::
|
||||||
already written.
|
* Computer is not synchronising::
|
||||||
|
* Issues with chronyc::
|
||||||
|
* Real-time clock issues::
|
||||||
|
* Microsoft Windows::
|
||||||
|
* NTP-specific issues::
|
||||||
|
* Linux-specific issues::
|
||||||
|
* Solaris-specific issues::
|
||||||
@end menu
|
@end menu
|
||||||
@c }}}
|
@c }}}
|
||||||
@c {{{ S:system driver files
|
@c {{{ S:Administrative issues
|
||||||
@node System driver files
|
@node Administrative issues
|
||||||
@section System driver files
|
@section Administrative issues
|
||||||
The system specific parts of the software are contained in files with
|
|
||||||
names like @code{sys_linux.c}.
|
|
||||||
|
|
||||||
The following functions are required in a system driver file:
|
@subsection Where can I get chrony source code?
|
||||||
|
Tarballs are available via the @code{Download} link on the chrony web site.
|
||||||
|
For the current development from the developers' version control system see the
|
||||||
|
@code{Git} link on the web site.
|
||||||
|
|
||||||
@enumerate
|
@subsection Are there any packaged versions of chrony?
|
||||||
@item
|
We are aware of packages for Arch, Debian, Fedora, Gentoo, Mandriva, Slackware,
|
||||||
A function to read the current frequency
|
Ubuntu, FreeBSD and NetBSD. We are not involved with how these are built or
|
||||||
@item
|
distributed.
|
||||||
A function to set the current frequency
|
|
||||||
@item
|
|
||||||
A function to slew the system time by a specified delta
|
|
||||||
@item
|
|
||||||
A function to step the system time by a specified delta
|
|
||||||
@item
|
|
||||||
A function to work out the error at a particular time between the
|
|
||||||
system's clock and @code{chronyd's} estimate of real time. (This is required
|
|
||||||
because some systems have to track real time by making the system time
|
|
||||||
follow it in a 'sawtooth' fashion).
|
|
||||||
@end enumerate
|
|
||||||
|
|
||||||
The @dfn{frequency} is the rate at which the system gains or loses time,
|
@subsection Where is the home page?
|
||||||
measured relative to the system when running uncompensated.
|
It is currently at
|
||||||
|
@uref{http://chrony.tuxfamily.org, http://chrony.tuxfamily.org}.
|
||||||
|
|
||||||
|
@subsection Is there a mailing list?
|
||||||
|
Yes, it's currently at @email{chrony-users@@chrony.tuxfamily.org}. There is a
|
||||||
|
low-volume list called chrony-announce which is just for announcements of new
|
||||||
|
releases or similar matters of high importance. You can join the lists by
|
||||||
|
sending a message with the subject subscribe to
|
||||||
|
@email{chrony-users-request@@chrony.tuxfamily.org} or
|
||||||
|
@email{chrony-announce-request@@chrony.tuxfamily.org} respectively.
|
||||||
|
|
||||||
|
For those who want to contribute to the development of chrony, there is a
|
||||||
|
developers' mailing list. You can subscribe by sending mail with the subject
|
||||||
|
subscribe to @email{chrony-dev-request@@chrony.tuxfamily.org}.
|
||||||
|
|
||||||
|
@subsection What licence is applied to chrony?
|
||||||
|
Starting from version 1.15, chrony is licensed under the GNU General Public
|
||||||
|
License, Version 2. Versions prior to 1.15 were licensed under a custom
|
||||||
|
BSD-like license.
|
||||||
@c }}}
|
@c }}}
|
||||||
@c {{{ system quirks
|
@c {{{ S:Chrony compared to other programs
|
||||||
@node Quirks of particular systems
|
@node Chrony compared to other programs
|
||||||
@section Quirks of particular systems
|
@section Chrony compared to other programs
|
||||||
@c {{{ section top
|
@subsection How does chrony compare to ntpd?
|
||||||
These sections describe quirks in each system type that needed to be
|
Chrony can usually synchronise the system clock faster and with better time
|
||||||
investigated to port the software to each system type.
|
accuracy, but it doesn't implement all NTP features, e.g. broadcast/multicast
|
||||||
|
mode, or authentication based on public-key cryptography. For a more detailed
|
||||||
|
comparison, see section @code{Comparison with ntpd} in the manual.
|
||||||
|
|
||||||
|
If your computer connects to the 'net only for few minutes at a time, you turn
|
||||||
|
your Linux computer off or suspend it frequently, the clock is not very stable
|
||||||
|
(e.g. it is a virtual machine), or you want to use NTP on an isolated network
|
||||||
|
with no hardware clocks in sight, chrony will probably work much better for
|
||||||
|
you.
|
||||||
|
|
||||||
|
The original reason chrony was written was that ntpd (called xntpd at the
|
||||||
|
time) could not to do anything sensible on a PC which was connected to
|
||||||
|
the 'net only for about 5 minutes once or twice a day, mainly to
|
||||||
|
upload/download email and news. The requirements were
|
||||||
|
|
||||||
|
@itemize @bullet
|
||||||
|
@item slew the time to correct it when going online and NTP servers become
|
||||||
|
visible
|
||||||
|
@item determine the rate at which the computer gains or loses time and use this
|
||||||
|
information to keep it reasonably correct between connects to the 'net. This
|
||||||
|
has to be done using a method that does not care about the intermittent
|
||||||
|
availability of the references or the fact the computer is turned off between
|
||||||
|
groups of measurements.
|
||||||
|
@item maintain the time across reboots, by working out the error and drift rate
|
||||||
|
of the computer's real-time clock and using this information to set the system
|
||||||
|
clock correctly at boot up.
|
||||||
|
@end itemize
|
||||||
|
|
||||||
|
Also, when working with isolated networks with no true time references at all
|
||||||
|
ntpd was found to give no help with managing the local clock's gain/loss rate
|
||||||
|
on the NTP master node (which was set from watch). Some automated support was
|
||||||
|
added to chrony to deal with this.
|
||||||
|
|
||||||
@menu
|
|
||||||
* Linux porting quirks::
|
|
||||||
* Solaris 2.5 porting quirks::
|
|
||||||
* SunOS 4.1.4 porting quirks::
|
|
||||||
@end menu
|
|
||||||
@c }}}
|
@c }}}
|
||||||
@c {{{ linux
|
@c {{{ S:Configuration issues
|
||||||
@node Linux porting quirks
|
@node Configuration issues
|
||||||
@subsection Linux
|
@section Configuration issues
|
||||||
The following quirks have been found in developing the Linux port.
|
|
||||||
|
|
||||||
@enumerate 1
|
@subsection I have several computers on a LAN. Should be all clients of an external server?
|
||||||
@item
|
The best configuration is usually to make one computer the master, with the
|
||||||
In order to avoid floating point arithmetic, the kernel uses shifting
|
others as clients of it. Add a @code{local} directive to the master's
|
||||||
and adding to approximate a scaling of 100/128. This approximation
|
chrony.conf file. This configuration will be better because
|
||||||
implies that the frequency set via the @code{adjtimex()} system call is
|
|
||||||
not the frequency that is actually obtained. The method of
|
|
||||||
approximation varies between kernel versions and must be determined by
|
|
||||||
examining the kernel source. An inverse factor must be included in the
|
|
||||||
driver to compensate.
|
|
||||||
@item
|
|
||||||
In some kernel versions, an @code{adjtimex()} system call with the flags
|
|
||||||
bits all zeroed will return the amount of offset still to be corrected.
|
|
||||||
In others (e.g. the 2.0 series beyond 2.0.32), the offset must be
|
|
||||||
changed in order to get the old offset returned (similar to
|
|
||||||
@code{adjtime()} on other systems).
|
|
||||||
|
|
||||||
@end enumerate
|
@itemize @bullet
|
||||||
|
@item the load on the external connection is less
|
||||||
|
@item the load on the external NTP server(s) is less
|
||||||
|
@item if your external connection goes down, the computers on the LAN will
|
||||||
|
maintain a common time with each other.
|
||||||
|
@end itemize
|
||||||
|
|
||||||
|
@subsection Must I specify servers by IP address if DNS is not available on chronyd start?
|
||||||
|
No. Starting from version 1.25, @code{chronyd} will keep trying to resolve the
|
||||||
|
hostnames specified in the @code{server} and @code{peer} directives in
|
||||||
|
increasing intervals until it succeeds. The @code{online} command can be
|
||||||
|
issued from @code{chronyc} to try to resolve them immediately.
|
||||||
|
|
||||||
|
@subsection How can I make chronyd more secure?
|
||||||
|
If you don't need to serve time to NTP clients, you can add @code{port 0} to
|
||||||
|
the @file{chrony.conf} file to disable the NTP server/peer sockets and prevent
|
||||||
|
NTP requests from reaching @code{chronyd}.
|
||||||
|
|
||||||
|
If you don't need to use @code{chronyc} remotely, you can add the following
|
||||||
|
directives to the configuration file to bind the command sockets to the
|
||||||
|
loopback interface
|
||||||
|
|
||||||
|
@example
|
||||||
|
bindcmdaddress 127.0.0.1
|
||||||
|
bindcmdaddress ::1
|
||||||
|
@end example
|
||||||
|
|
||||||
|
If you don't need to use @code{chronyc} at all, you can disable the command
|
||||||
|
sockets by adding @code{cmdport 0} to the configuration file.
|
||||||
@c }}}
|
@c }}}
|
||||||
@c {{{ solaris 2.5
|
@c {{{ S:Computer is not synchronising
|
||||||
@node Solaris 2.5 porting quirks
|
@node Computer is not synchronising
|
||||||
@subsection Solaris 2.5
|
@section Computer is not synchronising
|
||||||
|
|
||||||
The following quirks have been found in developing the Solaris port.
|
This is the most common problem. There are a number of reasons, see the
|
||||||
|
following questions.
|
||||||
|
|
||||||
@enumerate 1
|
@subsection Behind a firewall?
|
||||||
@item
|
If there is a firewall between you and the NTP server you're trying to use,
|
||||||
The @code{adjtime()} system call with a zero argument does not cancel an
|
the packets may be blocked. Try using a tool like wireshark or tcpdump to see
|
||||||
adjustment that is in progress - it just reports the remaining
|
if you're getting responses from the server. If you have an external modem,
|
||||||
adjustment.
|
see if the receive light blinks straight after the transmit light (when the
|
||||||
@item
|
link is quiet apart from the NTP traffic.) Try adding @code{log measurements}
|
||||||
The @code{settimeofday()} system call only observes the seconds part of
|
to the @file{chrony.conf} file and look in the measurements.log file after
|
||||||
the argument - any fractional seconds part is lost.
|
chrony has been running for a short period. See if any measurements appear.
|
||||||
second.
|
|
||||||
@item
|
@subsection Do you have a non-permanent (i.e. intermittent) Internet connection?
|
||||||
The kernel variable @code{dosynctodr} has to be set to zero, otherwise
|
Check that you're using chronyc's @code{online} and @code{offline} commands
|
||||||
the system clock is periodically reset to the real-time clock.
|
appropriately. Again, check in measurements.log to see if you're getting any
|
||||||
@end enumerate
|
data back from the server.
|
||||||
|
|
||||||
|
@subsection In measurements.log, do the '7' and '8' flag columns always show zero?
|
||||||
|
Do you have a @code{local stratum X} directive in the @file{chrony.conf} file? If X
|
||||||
|
is lower than the stratum of the server you're trying to use, this situation
|
||||||
|
will arise. You should always make X quite high (e.g. 10) in this directive.
|
||||||
@c }}}
|
@c }}}
|
||||||
@c {{{ sunos 4.1.4
|
@c {{{ S:Issues with chronyc
|
||||||
@node SunOS 4.1.4 porting quirks
|
@node Issues with chronyc
|
||||||
@subsection SunOS 4.1.4
|
@section Issues with chronyc
|
||||||
The following quirks have been found in developing the SunOS port.
|
|
||||||
|
|
||||||
@enumerate 1
|
@subsection I keep getting the error @code{506 Cannot talk to daemon}
|
||||||
@item
|
Make sure that the @file{chrony.conf} file (on the computer where
|
||||||
The @code{adjtime()} system call truncates its argument to a multiple of
|
@code{chronyd} is running) has a @code{cmdallow} entry for the computer you are
|
||||||
the system's @code{tickadj} variable. (@code{chronyd} sets that to 100,
|
running @code{chronyc} on. This isn't necessary for localhost.
|
||||||
giving a 1 part in 100 slewing capability for correcting offsets.)
|
|
||||||
@item
|
Perhaps @code{chronyd} is not running. Try using the ps command (e.g. on
|
||||||
The kernel variable @code{dosynctodr} has to be set to zero, otherwise
|
Linux, 'ps -auxw') to see if it's running. Or try 'netstat -a' and see if the
|
||||||
the system clock is periodically reset to the real-time clock.
|
ports 123/udp and 323/udp are listening. If @code{chronyd} is not running, you
|
||||||
@end enumerate
|
may have a problem with the way you are trying to start it (e.g. at boot time).
|
||||||
|
|
||||||
|
Perhaps you have a firewall set up in a way that blocks packets on port
|
||||||
|
323/udp. You need to amend the firewall configuration in this case.
|
||||||
|
|
||||||
|
@subsection Is the chronyc<->chronyd protocol documented anywhere?
|
||||||
|
Only by the source code :-) See cmdmon.c (@code{chronyd} side) and client.c
|
||||||
|
(@code{chronyc} side).
|
||||||
@c }}}
|
@c }}}
|
||||||
|
@c {{{ S:Real-time clock issues
|
||||||
|
@node Real-time clock issues
|
||||||
|
@section Real-time clock issues
|
||||||
|
|
||||||
|
@subsection What is the real-time clock (RTC)?
|
||||||
|
This is the clock which keeps the time even when your computer is turned off.
|
||||||
|
It works with 1 second resolution. @code{chronyd} can monitor the rate at
|
||||||
|
which the real-time clock gains or loses time, and compensate for it when you
|
||||||
|
set the system time from it at the next reboot. See the documentation for
|
||||||
|
details.
|
||||||
|
|
||||||
|
@subsection I want to use chronyd's real-time clock support. Must I disable hwclock?
|
||||||
|
The hwclock program is often set-up by default in the boot and shutdown scripts
|
||||||
|
with many Linux installations. If you want to use chronyd's real-time clock
|
||||||
|
support, the important thing is to disable hwclock in the shutdown procedure.
|
||||||
|
If you don't, it will over-write the RTC with a new value, unknown to
|
||||||
|
@code{chronyd}. At the next reboot, @code{chronyd} will compensate this (wrong)
|
||||||
|
time with its estimate of how far the RTC has drifted whilst the power was off,
|
||||||
|
giving a meaningless initial system time.
|
||||||
|
|
||||||
|
There is no need to remove hwclock from the boot process, as long as
|
||||||
|
@code{chronyd} is started after it has run.
|
||||||
|
|
||||||
|
@subsection I just keep getting the '513 RTC driver not running' message
|
||||||
|
For the real time clock support to work, you need the following three things
|
||||||
|
@itemize @bullet
|
||||||
|
@item a kernel that is supported (e.g. 2.2 onwards)
|
||||||
|
@item enhanced RTC support compiled into the kernel
|
||||||
|
@item an @code{rtcfile} directive in your chrony.conf file
|
||||||
|
@end itemize
|
||||||
|
@c }}}
|
||||||
|
@c {{{ S:Microsoft Windows
|
||||||
|
@node Microsoft Windows
|
||||||
|
@section Microsoft Windows
|
||||||
|
|
||||||
|
@subsection Does chrony support Windows?
|
||||||
|
No. The @code{chronyc} program (the command-line client used for configuring
|
||||||
|
@code{chronyd} while it is running) has been successfully built and run under
|
||||||
|
Cygwin in the past. @code{chronyd} is not portable, because part of it is very
|
||||||
|
system-dependent. It needs adapting to work with Windows' equivalent of the
|
||||||
|
adjtimex() call, and it needs to be made to work as an NT service.
|
||||||
|
|
||||||
|
@subsection Are there any plans to support Windows?
|
||||||
|
We have no plans to do this. Anyone is welcome to pick this work up and
|
||||||
|
contribute it back to the project.
|
||||||
|
@c }}}
|
||||||
|
@c {{{ S:NTP-specific issues
|
||||||
|
@node NTP-specific issues
|
||||||
|
@section NTP-specific issues
|
||||||
|
|
||||||
|
@subsection Can chrony be driven from broadcast NTP servers?
|
||||||
|
No, this NTP mode is not implemented yet.
|
||||||
|
|
||||||
|
@subsection Can chronyd transmit broadcast NTP packets (e.g. to synchronise other computers on a private LAN)?
|
||||||
|
Yes. Starting from version 1.17, chrony has this capability.
|
||||||
|
|
||||||
|
@subsection Can chrony keep the system clock a fixed offset away from real time?
|
||||||
|
This is not possible as the program currently stands.
|
||||||
|
|
||||||
|
@subsection What happens if the network connection is dropped without using chronyc's 'offline' command first?
|
||||||
|
In this case @code{chronyd} will keep trying to access the server(s) that it
|
||||||
|
thinks are online. Eventually it will decide that they are unreachable and no
|
||||||
|
longer consider itself synchronised to them. If you have other computers on
|
||||||
|
your LAN accessing the computer that is affected this way, they too will become
|
||||||
|
'unsynchronised', unless you have the 'local' directive set up on the master
|
||||||
|
computer.
|
||||||
|
|
||||||
|
The 'auto_offline' option to the 'server' entry in the chrony.conf file may be
|
||||||
|
useful to avoid this situation.
|
||||||
|
@c }}}
|
||||||
|
@c {{{ S:Linux-specific issues
|
||||||
|
@node Linux-specific issues
|
||||||
|
@section Linux-specific issues
|
||||||
|
|
||||||
|
@subsection I get "Could not open /dev/rtc, Device or resource busy" in my syslog file
|
||||||
|
Some other program running on the system may be using the device.
|
||||||
|
@c }}}
|
||||||
|
@c {{{ S:Solaris-specific issues
|
||||||
|
@node Solaris-specific issues
|
||||||
|
@section Solaris-specific issues
|
||||||
|
|
||||||
|
@subsection On Solaris 2.8, I get an error message about not being able to open kvm to change dosynctodr
|
||||||
|
(The dosynctodr variable controls whether Solaris couples the equivalent of its
|
||||||
|
BIOS clock into its system clock at regular intervals). The Solaris port of
|
||||||
|
chrony was developed in the Solaris 2.5 era. Some aspect of the Solaris kernel
|
||||||
|
has changed which prevents the same technique working. We no longer have root
|
||||||
|
access to any Solaris machines to work on this, and we are reliant on somebody
|
||||||
|
developing the patch and testing it.
|
||||||
@c }}}
|
@c }}}
|
||||||
@c }}}
|
@c }}}
|
||||||
@c {{{ apx:GNU General Public License
|
@c {{{ apx:GNU General Public License
|
||||||
|
|||||||
75
cmdmon.c
75
cmdmon.c
@@ -171,22 +171,19 @@ static ADF_AuthTable access_auth_table;
|
|||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
/* Forward prototypes */
|
/* Forward prototypes */
|
||||||
static int prepare_socket(int family);
|
|
||||||
static void read_from_cmd_socket(void *anything);
|
static void read_from_cmd_socket(void *anything);
|
||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
prepare_socket(int family)
|
prepare_socket(int family, int port_number)
|
||||||
{
|
{
|
||||||
int port_number, sock_fd;
|
int sock_fd;
|
||||||
socklen_t my_addr_len;
|
socklen_t my_addr_len;
|
||||||
union sockaddr_in46 my_addr;
|
union sockaddr_in46 my_addr;
|
||||||
IPAddr bind_address;
|
IPAddr bind_address;
|
||||||
int on_off = 1;
|
int on_off = 1;
|
||||||
|
|
||||||
port_number = CNF_GetCommandPort();
|
|
||||||
|
|
||||||
sock_fd = socket(family, SOCK_DGRAM, 0);
|
sock_fd = socket(family, SOCK_DGRAM, 0);
|
||||||
if (sock_fd < 0) {
|
if (sock_fd < 0) {
|
||||||
LOG(LOGS_ERR, LOGF_CmdMon, "Could not open %s command socket : %s",
|
LOG(LOGS_ERR, LOGF_CmdMon, "Could not open %s command socket : %s",
|
||||||
@@ -265,7 +262,7 @@ prepare_socket(int family)
|
|||||||
void
|
void
|
||||||
CAM_Initialise(int family)
|
CAM_Initialise(int family)
|
||||||
{
|
{
|
||||||
int i;
|
int i, port_number;
|
||||||
|
|
||||||
assert(!initialised);
|
assert(!initialised);
|
||||||
initialised = 1;
|
initialised = 1;
|
||||||
@@ -293,18 +290,20 @@ CAM_Initialise(int family)
|
|||||||
free_replies = NULL;
|
free_replies = NULL;
|
||||||
kept_replies.next = NULL;
|
kept_replies.next = NULL;
|
||||||
|
|
||||||
if (family == IPADDR_UNSPEC || family == IPADDR_INET4)
|
port_number = CNF_GetCommandPort();
|
||||||
sock_fd4 = prepare_socket(AF_INET);
|
|
||||||
|
if (port_number && (family == IPADDR_UNSPEC || family == IPADDR_INET4))
|
||||||
|
sock_fd4 = prepare_socket(AF_INET, port_number);
|
||||||
else
|
else
|
||||||
sock_fd4 = -1;
|
sock_fd4 = -1;
|
||||||
#ifdef HAVE_IPV6
|
#ifdef HAVE_IPV6
|
||||||
if (family == IPADDR_UNSPEC || family == IPADDR_INET6)
|
if (port_number && (family == IPADDR_UNSPEC || family == IPADDR_INET6))
|
||||||
sock_fd6 = prepare_socket(AF_INET6);
|
sock_fd6 = prepare_socket(AF_INET6, port_number);
|
||||||
else
|
else
|
||||||
sock_fd6 = -1;
|
sock_fd6 = -1;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (sock_fd4 < 0
|
if (port_number && sock_fd4 < 0
|
||||||
#ifdef HAVE_IPV6
|
#ifdef HAVE_IPV6
|
||||||
&& sock_fd6 < 0
|
&& sock_fd6 < 0
|
||||||
#endif
|
#endif
|
||||||
@@ -667,46 +666,6 @@ token_acknowledged(unsigned long token, struct timeval *now)
|
|||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
#if 0
|
|
||||||
/* These two routines are not legal if the program is operating as a daemon, since
|
|
||||||
stderr is no longer open */
|
|
||||||
|
|
||||||
static void
|
|
||||||
print_command_packet(CMD_Request *pkt, int length)
|
|
||||||
{
|
|
||||||
unsigned char *x;
|
|
||||||
int i;
|
|
||||||
x = (unsigned char *) pkt;
|
|
||||||
for (i=0; i<length; i++) {
|
|
||||||
fprintf(stderr, "%02x ", x[i]);
|
|
||||||
if (i%16 == 15) {
|
|
||||||
fprintf(stderr, "\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fprintf(stderr, "\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ================================================== */
|
|
||||||
|
|
||||||
static void
|
|
||||||
print_reply_packet(CMD_Reply *pkt)
|
|
||||||
{
|
|
||||||
unsigned char *x;
|
|
||||||
int i;
|
|
||||||
x = (unsigned char *) pkt;
|
|
||||||
for (i=0; i<sizeof(CMD_Reply); i++) {
|
|
||||||
fprintf(stderr, "%02x ", x[i]);
|
|
||||||
if (i%16 == 15) {
|
|
||||||
fprintf(stderr, "\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fprintf(stderr, "\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* ================================================== */
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
transmit_reply(CMD_Reply *msg, union sockaddr_in46 *where_to, int auth_len)
|
transmit_reply(CMD_Reply *msg, union sockaddr_in46 *where_to, int auth_len)
|
||||||
{
|
{
|
||||||
@@ -1629,20 +1588,6 @@ handle_reselect(CMD_Request *rx_message, CMD_Reply *tx_message)
|
|||||||
tx_message->status = htons(STT_SUCCESS);
|
tx_message->status = htons(STT_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ================================================== */
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
/* ================================================== */
|
|
||||||
|
|
||||||
static void
|
|
||||||
handle_(CMD_Request *rx_message, CMD_Reply *tx_message)
|
|
||||||
{
|
|
||||||
int status;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
/* Read a packet and process it */
|
/* Read a packet and process it */
|
||||||
|
|
||||||
|
|||||||
@@ -106,6 +106,9 @@ keyfile /etc/chrony.keys
|
|||||||
|
|
||||||
commandkey 1
|
commandkey 1
|
||||||
|
|
||||||
|
# With this directive a random password will be generated automatically.
|
||||||
|
generatecommandkey
|
||||||
|
|
||||||
# chronyd can save the measurement history for the servers to files when
|
# chronyd can save the measurement history for the servers to files when
|
||||||
# it it exits. This is useful in 2 situations:
|
# it it exits. This is useful in 2 situations:
|
||||||
#
|
#
|
||||||
|
|||||||
268
faq.txt
268
faq.txt
@@ -1,268 +0,0 @@
|
|||||||
@@PROLOGUE
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>Frequently asked questions</title>
|
|
||||||
<meta name="description" content="Chrony FAQ (frequently asked questions)">
|
|
||||||
<meta name="keywords" content="chrony,network time protocol,NTP,RFC 1305,dial-up connection,real time clock,RTC,Linux,FAQ,frequently asked questns">
|
|
||||||
<?php
|
|
||||||
$root = ".";
|
|
||||||
include "$root/styles.php";
|
|
||||||
?>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<?php
|
|
||||||
include 'main_banner.php';
|
|
||||||
include 'header.php';
|
|
||||||
?>
|
|
||||||
<?php pretty_h1("Introduction") ?>
|
|
||||||
<p>
|
|
||||||
This is a set of questions and answers to common problems and issues.
|
|
||||||
<p>
|
|
||||||
As we receive more emails about the software, we will add new questions
|
|
||||||
to this page.
|
|
||||||
<hr>
|
|
||||||
<p>
|
|
||||||
The developers can be reached via the chrony-dev mailing list. See
|
|
||||||
<a href="#question_1.4">question 1.4.</a> for details.
|
|
||||||
<hr>
|
|
||||||
|
|
||||||
<br clear=all>
|
|
||||||
@@ENDPROLOGUE
|
|
||||||
S: Administrative issues
|
|
||||||
|
|
||||||
Q: Where can I get chrony source code?
|
|
||||||
Tarballs are available via the <b>Download</b> link on the Chrony
|
|
||||||
Web site. For the current development from the developers' version control
|
|
||||||
system see the <b>Git</b> link on the Web site.
|
|
||||||
|
|
||||||
Q: Are there any packaged versions of chrony?
|
|
||||||
We are aware of packages for Debian, Fedora, Gentoo, Mandriva, Slackware,
|
|
||||||
and Ubuntu. We are not involved with how these are built or distributed.
|
|
||||||
|
|
||||||
Q: Where is the home page?
|
|
||||||
It is currently at <a href="http://chrony.tuxfamily.org/">http://chrony.tuxfamily.org/</a>.
|
|
||||||
|
|
||||||
Q: Is there a mailing list?
|
|
||||||
Yes, it's currently at chrony-users@chrony.tuxfamily.org. There is a low-volume
|
|
||||||
list called chrony-announce which is just for announcements of new releases or
|
|
||||||
similar matters of high importance. You can join the lists by sending a
|
|
||||||
message with the subject subscribe to <a href="mailto:chrony-users-request@chrony.tuxfamily.org">chrony-users-request@chrony.tuxfamily.org</a> or
|
|
||||||
<a href="mailto:chrony-announce-request@chrony.tuxfamily.org">chrony-announce-request@chrony.tuxfamily.org</a> respectively.
|
|
||||||
|
|
||||||
For those who want to contribute to the development of chrony, there is a
|
|
||||||
developers' mailing list. You can subscribe by sending mail with the
|
|
||||||
subject subscribe to
|
|
||||||
<a href="mailto:chrony-dev-request@chrony.tuxfamily.org">chrony-dev-request@chrony.tuxfamily.org</a>.
|
|
||||||
|
|
||||||
Q: What licence is applied to chrony?
|
|
||||||
Starting from version 1.15, chrony is licensed under the GNU General Public
|
|
||||||
License, Version 2. Versions prior to 1.15 were licensed under a custom BSD-like
|
|
||||||
license.
|
|
||||||
|
|
||||||
S: Chrony compared to other programs
|
|
||||||
Q: How does chrony compare to xntpd?
|
|
||||||
If your computer is permenently connected, or connected for long periods (that
|
|
||||||
is, for the several hours it takes xntpd to settle down), or you need to
|
|
||||||
support hardware reference clocks to your computer, then xntpd will work fine.
|
|
||||||
Apart from not supporting hardware clocks, chrony will work fine too.
|
|
||||||
|
|
||||||
If your computer connects to the 'net for 5 minutes once a day (or something
|
|
||||||
like that), or you turn your Linux computer off when you're not using
|
|
||||||
it, or you want to use NTP on an isolated network with no hardware clocks in
|
|
||||||
sight, chrony will work much better for you.
|
|
||||||
|
|
||||||
The reason I wrote chrony was that I could not get xntpd to do
|
|
||||||
anything sensible on my PC at home, which is connected to the 'net for
|
|
||||||
about 5 minutes once or twice a day, mainly to upload/download email
|
|
||||||
and news. Nowadays it is also turned off for 22-23 hours a day, when
|
|
||||||
not in use. I wanted a program which would :
|
|
||||||
|
|
||||||
- slew the time to correct it when I go online and NTP servers become visible
|
|
||||||
|
|
||||||
- determine the rate at which the computer gains or loses time and use this
|
|
||||||
information to keep it reasonably correct between connects to the 'net. This
|
|
||||||
has to be done using a method that does not care about the intermittent
|
|
||||||
availability of the references or the fact the computer is turned off between
|
|
||||||
groups of measurements..
|
|
||||||
|
|
||||||
- maintain the time across reboots, by working out the error and drift rate of
|
|
||||||
the computer's real-time clock and using this information to set the system
|
|
||||||
clock correctly at boot up. (In the last few months, it became impossible for
|
|
||||||
me to leave my computer powered permanently.)
|
|
||||||
|
|
||||||
Also, when working with isolated networks with no true time references
|
|
||||||
at all, I found xntpd gave me no help with managing the local clock's
|
|
||||||
gain/loss rate on the NTP master node (which I set from my watch). I
|
|
||||||
added some automated support in chrony to deal with this.
|
|
||||||
|
|
||||||
S: Selection of NTP servers
|
|
||||||
Q: I have several computers on a LAN. Should I make one the master, or make them all clients of an external server?
|
|
||||||
I think the best configuration is to make one computer the master, with the
|
|
||||||
others as clients of it. Add a 'local' directive to the master's chrony.conf
|
|
||||||
file. This configuration will be better because
|
|
||||||
|
|
||||||
* the load on the external connection is less
|
|
||||||
* the load on the external NTP server(s) is less
|
|
||||||
* if your external connection goes down, the computers on the LAN will maintain
|
|
||||||
a common time with each other.
|
|
||||||
|
|
||||||
S: My computer is not synchronising.
|
|
||||||
This is the most common problem. There are a number of reasons, see the
|
|
||||||
following questions.
|
|
||||||
|
|
||||||
Q: Behind a firewall?
|
|
||||||
If there is a firewall between you and the NTP server you're trying to use,
|
|
||||||
the packets may be blocked. Try using a tool like etherfind or tcpdump to see
|
|
||||||
if you're getting responses from the server. If you have an external modem,
|
|
||||||
see if the receive light blinks straight after the transmit light (when the
|
|
||||||
link is quiet apart from the NTP traffic.) Try adding 'log measurements' to
|
|
||||||
the chrony.conf file and look in the measurements.log file after chrony has
|
|
||||||
been running for a short period. See if any measurements appear.
|
|
||||||
|
|
||||||
Most people run chronyd on the firewall itself, to avoid all issues of UDP
|
|
||||||
packet forwarding and/or masquerading.
|
|
||||||
|
|
||||||
Q: Do you have a non-permanant (i.e. intermittent) Internet connection?
|
|
||||||
Check that you're using chronyc's 'online' and 'offline' commands
|
|
||||||
appropriately. Again, check in measurements.log to see if you're getting any
|
|
||||||
data back from the server.
|
|
||||||
|
|
||||||
Q: In measurements.log, do the '7' and '8' flag columns always show zero?
|
|
||||||
Do you have a 'local stratum X' directive in the chrony.conf file? If X is
|
|
||||||
lower than the stratum of the server you're trying to use, this situation will
|
|
||||||
arise. You should always make X quite high (e.g. 10) in this directive.
|
|
||||||
|
|
||||||
S: Issues with chronyc
|
|
||||||
|
|
||||||
Q: I keep getting the error '506 Cannot talk to daemon'.
|
|
||||||
Make sure that the chrony.conf file (on the computer where chronyd is running)
|
|
||||||
has a 'cmdallow' entry for the computer you are running chronyc on. This
|
|
||||||
isn't necessary for localhost.
|
|
||||||
|
|
||||||
Perhaps chronyd is not running. Try using the ps command (e.g. on Linux, 'ps
|
|
||||||
-auxw') to see if it's running. Or try 'netstat -a' and see if the ports
|
|
||||||
123/udp and 323/udp are listening. If chronyd is not running, you may have a
|
|
||||||
problem with the way you are trying to start it (e.g. at boot time).
|
|
||||||
|
|
||||||
Perhaps you have a firewall set up in a way that blocks packets on port
|
|
||||||
323/udp. You need to amend the firewall configuration in this case.
|
|
||||||
|
|
||||||
Q: Is the chronyc<->chronyd protocol documented anywhere?
|
|
||||||
Only by the source code :-) See cmdmon.c (chronyd side) and client.c (chronyc
|
|
||||||
side).
|
|
||||||
|
|
||||||
S: Real-time clock issues.
|
|
||||||
Q: What is the real-time clock (RTC)?
|
|
||||||
This is the clock which keeps the time even when your computer is turned off.
|
|
||||||
It works with 1 second resolution. chronyd can monitor the rate at which the
|
|
||||||
real-time clock gains or loses time, and compensate for it when you set the
|
|
||||||
system time from it at the next reboot. See the documentation for details.
|
|
||||||
|
|
||||||
Q: I want to use chronyd's real-time clock support. Must I disable hwclock?
|
|
||||||
The hwclock program is often set-up by default in the boot and shutdown scripts
|
|
||||||
with many Linux installations. If you want to use chronyd's real-time clock
|
|
||||||
support, the important thing is to disable hwclock in the <b>shutdown</b>
|
|
||||||
procedure. If you don't, it will over-write the RTC with a new value, unknown
|
|
||||||
to chronyd. At the next reboot, chronyd will compensate this (wrong) time with
|
|
||||||
its estimate of how far the RTC has drifted whilst the power was off, giving a
|
|
||||||
meaningless initial system time.
|
|
||||||
|
|
||||||
There is no need to remove hwclock from the boot process, as long as chronyd is
|
|
||||||
started after it has run.
|
|
||||||
|
|
||||||
Q: I just keep getting the '513 RTC driver not running' message
|
|
||||||
For the real time clock support to work, you need the following three things:
|
|
||||||
|
|
||||||
* a kernel that is supported (e.g. 2.2 onwards)
|
|
||||||
* enhanced RTC support compiled into the kernel
|
|
||||||
* an 'rtcfile' directive in your chrony.conf file.
|
|
||||||
|
|
||||||
S: Microsoft Windows
|
|
||||||
|
|
||||||
Q: Does chrony support Windows?
|
|
||||||
No. The chronyc program (the command-line client used for configuring
|
|
||||||
chronyd while it is running) has been successfully built and run under Cygwin
|
|
||||||
in the past. chronyd is not portable, because part of it is very
|
|
||||||
system-dependent. It needs adapting to work with Windows' equivalent of the
|
|
||||||
adjtimex() call, and it needs to be made to work as an NT service.
|
|
||||||
|
|
||||||
Q: Are there any plans to support Windows?
|
|
||||||
We have no plans to do this. Anyone is welcome to pick this work up and
|
|
||||||
contribute it back to the project.
|
|
||||||
|
|
||||||
Q: What alternative NTP clients are there for Windows?
|
|
||||||
Some of the names we've seen mentioned are
|
|
||||||
- Automachron
|
|
||||||
- NetTime (nettime.sourceforge.net)
|
|
||||||
|
|
||||||
S: NTP-specific issues
|
|
||||||
Q: Can chrony be driven from broadcast NTP servers?
|
|
||||||
No. I remember looking at how they worked when I was first writing chrony.
|
|
||||||
Since the 'target market' then was dial-up systems, broadcast packets were not
|
|
||||||
relevant so I didn't bother working out how to deal with the complexities of
|
|
||||||
doing the delay estimation.
|
|
||||||
|
|
||||||
I no longer have root access to a LAN environment to develop and test broadcast
|
|
||||||
server support. Neither have I the time to work on this. I would be very
|
|
||||||
happy to accept a patch from anyone who can develop, test and debug the
|
|
||||||
necessary changes!
|
|
||||||
|
|
||||||
Q: Can chronyd transmit broadcast NTP packets (e.g. to synchronise other computers on a private LAN)?
|
|
||||||
Yes. Starting from version 1.17, chrony has this capability.
|
|
||||||
|
|
||||||
Q: Can chrony keep the system clock a fixed offset away from real time?
|
|
||||||
I have not experimented much, but I don't believe this would be possible as
|
|
||||||
the program currently stands.
|
|
||||||
|
|
||||||
Q: What happens if the network connection is dropped without using chronyc's 'offline' command first?
|
|
||||||
In this case chronyd will keep trying to access the server(s) that it thinks
|
|
||||||
are online. Eventually it will decide that they are unreachable and no longer
|
|
||||||
consider itself synchronised to them. If you have other computers on your LAN
|
|
||||||
accessing the computer that is affected this way, they too will become
|
|
||||||
'unsynchronised', unless you have the 'local' directive set up on the master
|
|
||||||
computer.
|
|
||||||
|
|
||||||
The 'auto_offline' option to the 'server' entry in the chrony.conf file may be
|
|
||||||
useful to avoid this situation.
|
|
||||||
|
|
||||||
S: Development
|
|
||||||
|
|
||||||
Q: Can I get the source via git from anywhere?
|
|
||||||
Yes. See the Git link at <a
|
|
||||||
href="http://chrony.tuxfamily.org/">http://chrony.tuxfamily.org</a> for
|
|
||||||
information.
|
|
||||||
|
|
||||||
S: Linux-specific issues
|
|
||||||
|
|
||||||
Q: Why does the source code include kernel header files?
|
|
||||||
The program needs to see the definitions of structures used to interact with
|
|
||||||
the real time clock (via /dev/rtc) and with the adjtimex() system call. Sadly
|
|
||||||
this has led to a number of compilation problems with newer kernels which have
|
|
||||||
been increasingly hard to fix in a way that makes the code compilable on all
|
|
||||||
Linux kernel versions. Hopefully
|
|
||||||
the situation will not deteriorate further with future kernel versions.
|
|
||||||
|
|
||||||
Q: I get "Could not open /dev/rtc, Device or resource busy" in my syslog file.
|
|
||||||
Check that you haven't accidentally got two copies of chronyd running (perhaps
|
|
||||||
defined in different start-up scripts.)
|
|
||||||
|
|
||||||
S: Solaris-specific issues
|
|
||||||
Q: On Solaris 2.8, I get an error message about not being able to open kvm to change dosynctodr.
|
|
||||||
(The dosynctodr variable controls whether Solaris couples the equivalent of its
|
|
||||||
BIOS clock into its system clock at regular intervals). The Solaris port of
|
|
||||||
chrony was developed in the Solaris 2.5 era. Some aspect of the Solaris kernel
|
|
||||||
has changed which prevents the same technique working. I no longer have root
|
|
||||||
access to any Solaris machines to work on this, and am reliant on somebody
|
|
||||||
developing the patch and testing it. A good starting point would be to see if
|
|
||||||
xntpd has been modified to work for Solaris 2.8.
|
|
||||||
|
|
||||||
@@EPILOGUE
|
|
||||||
<hr>
|
|
||||||
|
|
||||||
Back to
|
|
||||||
<a href="mailto:rc@rc0.org.uk?subject=chrony">the author</a>'s
|
|
||||||
<a href="http://www.rc0.org.uk/">main page</a>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@@ENDEPILOGUE
|
|
||||||
140
faqgen.pl
140
faqgen.pl
@@ -1,140 +0,0 @@
|
|||||||
#!/usr/bin/env perl
|
|
||||||
|
|
||||||
# $Header
|
|
||||||
|
|
||||||
# Copyright 2001 Richard P. Curnow
|
|
||||||
# LICENCE
|
|
||||||
|
|
||||||
# A script to generate an HTML FAQ page from a text input file. The input is assumed to consist of the following:
|
|
||||||
# Lines starting with 'S:'. These introduce sections.
|
|
||||||
# Lines starting with 'Q:'. These are the topics of questions.
|
|
||||||
# Body text (either as an introduction to the sections, or as answers to the questions.
|
|
||||||
# The body text is set as pre-formatted.
|
|
||||||
|
|
||||||
$| = 1;
|
|
||||||
|
|
||||||
@prologue = ();
|
|
||||||
@epilogue = ();
|
|
||||||
|
|
||||||
@sections=(); # section titles
|
|
||||||
@sect_text=(); # introductory text in sections
|
|
||||||
|
|
||||||
@questions=(); # questions in sections
|
|
||||||
@answers=(); # answers to questions
|
|
||||||
|
|
||||||
$sn = -1;
|
|
||||||
$had_q = 0;
|
|
||||||
|
|
||||||
#{{{ Parse input
|
|
||||||
while (<>) {
|
|
||||||
if (m/\@\@PROLOG/o) {
|
|
||||||
while (<>) {
|
|
||||||
last if (m/^\@\@ENDPROLOG/);
|
|
||||||
push (@prologue, $_);
|
|
||||||
}
|
|
||||||
} elsif (m/\@\@EPILOG/o) {
|
|
||||||
while (<>) {
|
|
||||||
last if (m/^\@\@ENDEPILOG/);
|
|
||||||
push (@epilogue, $_);
|
|
||||||
}
|
|
||||||
} elsif (m/^[sS]:[ \t]*(.*)$/) {
|
|
||||||
chomp;
|
|
||||||
$qn = -1;
|
|
||||||
++$sn;
|
|
||||||
$sections[$sn] = &guard($1);
|
|
||||||
$sect_text[$sn] = "";
|
|
||||||
$questions[$sn] = [ ];
|
|
||||||
$answers[$sn] = [ ];
|
|
||||||
$had_q = 0;
|
|
||||||
} elsif (/^[qQ]:[ \t]*(.*)$/) {
|
|
||||||
chomp;
|
|
||||||
die unless ($sn >= 0);
|
|
||||||
++$qn;
|
|
||||||
$questions[$sn]->[$qn] = &guard($1);
|
|
||||||
$had_q = 1;
|
|
||||||
} else {
|
|
||||||
if ($had_q) {
|
|
||||||
if ($qn >= 0) {
|
|
||||||
$answers[$sn]->[$qn] .= $_;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if ($sect_text[$sn] ne "" || $_ !~ /^\s*$/) {
|
|
||||||
$sect_text[$sn] .= $_;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#}}}
|
|
||||||
|
|
||||||
# Emit file header
|
|
||||||
if ($#prologue >= 0) {
|
|
||||||
print @prologue;
|
|
||||||
} else {
|
|
||||||
print <<EOF;
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>
|
|
||||||
Chrony Frequently Asked Questions
|
|
||||||
</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<font face=\"arial,helvetica\" size=+4><b>Table of contents</b></font>
|
|
||||||
EOF
|
|
||||||
}
|
|
||||||
|
|
||||||
# Emit table of contents
|
|
||||||
print "<ul>\n";
|
|
||||||
for $sn (0 .. $#sections) {
|
|
||||||
print "<b><li> <a href=\"#section_".($sn+1)."\">".($sn+1).".</a> ".$sections[$sn]."</b>\n";
|
|
||||||
print " <ul>\n";
|
|
||||||
for $qn (0 .. $#{$questions[$sn]}) {
|
|
||||||
$sq = ($sn+1).".".($qn+1);
|
|
||||||
print " <li> <a href=\"#question_".$sq."\">".$sq.".</a> ".$questions[$sn]->[$qn]."\n";
|
|
||||||
#print " <li> ".$sq.". ".$questions[$sn]->[$qn]."\n";
|
|
||||||
}
|
|
||||||
print " </ul>\n";
|
|
||||||
}
|
|
||||||
print "</ul>\n";
|
|
||||||
|
|
||||||
# Emit main sections
|
|
||||||
for $sn (0 .. $#sections) {
|
|
||||||
print "<hr>\n";
|
|
||||||
print "<a name=section_".($sn+1).">\n";
|
|
||||||
#print "<b><font size=+2 face=\"arial,helvetica\">".($sn+1).". ".$sections[$sn]."</font></b>\n";
|
|
||||||
print "<?php pretty_h2(\"".($sn+1).". ".$sections[$sn]."\"); ?>\n";
|
|
||||||
if ($sect_text[$sn] ne "") {
|
|
||||||
print "<pre>\n";
|
|
||||||
print $sect_text[$sn];
|
|
||||||
print "</pre>\n";
|
|
||||||
}
|
|
||||||
for $qn (0 .. $#{$questions[$sn]}) {
|
|
||||||
$sq = ($sn+1).".".($qn+1);
|
|
||||||
print "<p>\n";
|
|
||||||
print "<a name=question_".$sq.">\n";
|
|
||||||
print "<font size=+1 face=\"arial,helvetica\">".$sq.". ".$questions[$sn]->[$qn]."</font>\n";
|
|
||||||
print "<pre>\n";
|
|
||||||
print $answers[$sn]->[$qn];
|
|
||||||
print "</pre>\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Print footer
|
|
||||||
if ($#epilogue >= 0) {
|
|
||||||
print @epilogue;
|
|
||||||
} else {
|
|
||||||
print <<EOF;
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
EOF
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#{{{ sub guard {
|
|
||||||
sub guard {
|
|
||||||
# Hide wierd tags etc
|
|
||||||
my ($x) = @_;
|
|
||||||
return $x;
|
|
||||||
}
|
|
||||||
#}}}
|
|
||||||
|
|
||||||
|
|
||||||
12
keys.c
12
keys.c
@@ -142,7 +142,7 @@ KEY_Finalise(void)
|
|||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
determine_hash_delay(int key_id)
|
determine_hash_delay(unsigned long key_id)
|
||||||
{
|
{
|
||||||
NTP_Packet pkt;
|
NTP_Packet pkt;
|
||||||
struct timeval before, after;
|
struct timeval before, after;
|
||||||
@@ -162,12 +162,12 @@ determine_hash_delay(int key_id)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
LOG(LOGS_INFO, LOGF_Keys, "authentication delay for key %lu: %d useconds", key_id, min_usecs);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Add on a bit extra to allow for copying, conversions etc */
|
/* Add on a bit extra to allow for copying, conversions etc */
|
||||||
return min_usecs + (min_usecs >> 4);
|
min_usecs += min_usecs >> 4;
|
||||||
|
|
||||||
|
DEBUG_LOG(LOGF_Keys, "authentication delay for key %lu: %ld useconds", key_id, min_usecs);
|
||||||
|
|
||||||
|
return min_usecs;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|||||||
34
make_release
34
make_release
@@ -9,6 +9,7 @@ if [ $# -ne 1 ]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
version=$1
|
version=$1
|
||||||
|
tag=$version
|
||||||
subdir=chrony-${version}
|
subdir=chrony-${version}
|
||||||
mandate=$(date +'%B %Y')
|
mandate=$(date +'%B %Y')
|
||||||
|
|
||||||
@@ -21,11 +22,15 @@ fi
|
|||||||
|
|
||||||
[ -d RELEASES ] || mkdir RELEASES
|
[ -d RELEASES ] || mkdir RELEASES
|
||||||
|
|
||||||
git tag -s $version || exit 1
|
|
||||||
|
|
||||||
rm -rf RELEASES/$subdir
|
rm -rf RELEASES/$subdir
|
||||||
|
|
||||||
git archive --format=tar --prefix=RELEASES/${subdir}/ $version | \
|
if [ $version != test ]; then
|
||||||
|
git tag -s $tag || exit 1
|
||||||
|
else
|
||||||
|
tag=HEAD
|
||||||
|
fi
|
||||||
|
|
||||||
|
git archive --format=tar --prefix=RELEASES/${subdir}/ $tag | \
|
||||||
tar xf - || exit 1
|
tar xf - || exit 1
|
||||||
|
|
||||||
cd RELEASES/$subdir || exit 1
|
cd RELEASES/$subdir || exit 1
|
||||||
@@ -45,10 +50,29 @@ mv chrony.txt chrony.txt_
|
|||||||
make distclean
|
make distclean
|
||||||
mv chrony.txt_ chrony.txt
|
mv chrony.txt_ chrony.txt
|
||||||
|
|
||||||
|
awk '/^[1-9] Installation$/{p=1}
|
||||||
|
/^[1-9]\.. Support for line editing/{exit}; p' chrony.txt | \
|
||||||
|
tail -n +4 > INSTALL
|
||||||
|
|
||||||
|
if [ $(wc -l < INSTALL) -gt 100 -o $(wc -l < INSTALL) -lt 85 ]; then
|
||||||
|
echo "INSTALL generated incorrectly?"
|
||||||
|
exit 3
|
||||||
|
fi
|
||||||
|
|
||||||
|
awk '/^[1-9] Frequently asked questions$/{p=1}
|
||||||
|
/^Appendix A GNU General Public License$/{exit}; p' chrony.txt | \
|
||||||
|
tail -n +4 | sed 's/^[1-9]\.\([1-9]\)/\1/' | sed 's/^----/--/' | \
|
||||||
|
sed 's/^====/==/' > FAQ
|
||||||
|
|
||||||
|
if [ $(wc -l < FAQ) -gt 400 -o $(wc -l < FAQ) -lt 200 ]; then
|
||||||
|
echo "FAQ generated incorrectly?"
|
||||||
|
exit 3
|
||||||
|
fi
|
||||||
|
|
||||||
rm -f config.h config.log faqgen.pl make_release chrony.spec.sample .gitignore
|
rm -f config.h config.log faqgen.pl make_release chrony.spec.sample .gitignore
|
||||||
|
|
||||||
cd ..
|
cd ..
|
||||||
tar cv --owner root --group root $subdir | gzip -9 > ${subdir}.tar.gz
|
tar cv --owner root --group root $subdir | gzip -9 > ${subdir}.tar.gz
|
||||||
gpg -b -a -o ${subdir}-tar-gz-asc.txt ${subdir}.tar.gz
|
|
||||||
|
|
||||||
|
|
||||||
|
[ $version != test ] && \
|
||||||
|
gpg -b -a -o ${subdir}-tar-gz-asc.txt ${subdir}.tar.gz
|
||||||
|
|||||||
37
ntp_io.c
37
ntp_io.c
@@ -220,10 +220,6 @@ prepare_socket(int family, int port_number, int client_only)
|
|||||||
assert(0);
|
assert(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
LOG(LOGS_INFO, LOGF_NtpIO, "Initialising, socket fd=%d", sock_fd);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (bind(sock_fd, &my_addr.u, my_addr_len) < 0) {
|
if (bind(sock_fd, &my_addr.u, my_addr_len) < 0) {
|
||||||
LOG(LOGS_ERR, LOGF_NtpIO, "Could not bind %s NTP socket : %s",
|
LOG(LOGS_ERR, LOGF_NtpIO, "Could not bind %s NTP socket : %s",
|
||||||
family == AF_INET ? "IPv4" : "IPv6", strerror(errno));
|
family == AF_INET ? "IPv4" : "IPv6", strerror(errno));
|
||||||
@@ -583,12 +579,21 @@ send_packet(void *packet, int packetlen, NTP_Remote_Address *remote_addr, NTP_Lo
|
|||||||
struct iovec iov;
|
struct iovec iov;
|
||||||
char cmsgbuf[256];
|
char cmsgbuf[256];
|
||||||
int cmsglen;
|
int cmsglen;
|
||||||
socklen_t addrlen;
|
socklen_t addrlen = 0;
|
||||||
|
|
||||||
assert(initialised);
|
assert(initialised);
|
||||||
|
|
||||||
|
if (local_addr->sock_fd == INVALID_SOCK_FD) {
|
||||||
|
DEBUG_LOG(LOGF_NtpIO, "No socket to send to %s:%d",
|
||||||
|
UTI_IPToString(&remote_addr->ip_addr), remote_addr->port);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
switch (remote_addr->ip_addr.family) {
|
switch (remote_addr->ip_addr.family) {
|
||||||
case IPADDR_INET4:
|
case IPADDR_INET4:
|
||||||
|
/* Don't set address with connected socket */
|
||||||
|
if (local_addr->sock_fd != server_sock_fd4 && separate_client_sockets)
|
||||||
|
break;
|
||||||
memset(&remote.in4, 0, sizeof (remote.in4));
|
memset(&remote.in4, 0, sizeof (remote.in4));
|
||||||
addrlen = sizeof (remote.in4);
|
addrlen = sizeof (remote.in4);
|
||||||
remote.in4.sin_family = AF_INET;
|
remote.in4.sin_family = AF_INET;
|
||||||
@@ -597,6 +602,9 @@ send_packet(void *packet, int packetlen, NTP_Remote_Address *remote_addr, NTP_Lo
|
|||||||
break;
|
break;
|
||||||
#ifdef HAVE_IPV6
|
#ifdef HAVE_IPV6
|
||||||
case IPADDR_INET6:
|
case IPADDR_INET6:
|
||||||
|
/* Don't set address with connected socket */
|
||||||
|
if (local_addr->sock_fd != server_sock_fd6 && separate_client_sockets)
|
||||||
|
break;
|
||||||
memset(&remote.in6, 0, sizeof (remote.in6));
|
memset(&remote.in6, 0, sizeof (remote.in6));
|
||||||
addrlen = sizeof (remote.in6);
|
addrlen = sizeof (remote.in6);
|
||||||
remote.in6.sin6_family = AF_INET6;
|
remote.in6.sin6_family = AF_INET6;
|
||||||
@@ -609,16 +617,16 @@ send_packet(void *packet, int packetlen, NTP_Remote_Address *remote_addr, NTP_Lo
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (local_addr->sock_fd == INVALID_SOCK_FD) {
|
if (addrlen) {
|
||||||
DEBUG_LOG(LOGF_NtpIO, "No socket to send to %s:%d",
|
msg.msg_name = &remote.u;
|
||||||
UTI_IPToString(&remote_addr->ip_addr), remote_addr->port);
|
msg.msg_namelen = addrlen;
|
||||||
return;
|
} else {
|
||||||
|
msg.msg_name = NULL;
|
||||||
|
msg.msg_namelen = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
iov.iov_base = packet;
|
iov.iov_base = packet;
|
||||||
iov.iov_len = packetlen;
|
iov.iov_len = packetlen;
|
||||||
msg.msg_name = &remote.u;
|
|
||||||
msg.msg_namelen = addrlen;
|
|
||||||
msg.msg_iov = &iov;
|
msg.msg_iov = &iov;
|
||||||
msg.msg_iovlen = 1;
|
msg.msg_iovlen = 1;
|
||||||
msg.msg_control = cmsgbuf;
|
msg.msg_control = cmsgbuf;
|
||||||
@@ -663,10 +671,9 @@ send_packet(void *packet, int packetlen, NTP_Remote_Address *remote_addr, NTP_Lo
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if 0
|
DEBUG_LOG(LOGF_NtpIO, "Sending to %s:%d from %s fd %d",
|
||||||
LOG(LOGS_INFO, LOGF_NtpIO, "sending to %s:%d from %s",
|
UTI_IPToString(&remote_addr->ip_addr), remote_addr->port,
|
||||||
UTI_IPToString(&remote_addr->ip_addr), remote_addr->port, UTI_IPToString(&remote_addr->local_ip_addr));
|
UTI_IPToString(&local_addr->ip_addr), local_addr->sock_fd);
|
||||||
#endif
|
|
||||||
|
|
||||||
msg.msg_controllen = cmsglen;
|
msg.msg_controllen = cmsglen;
|
||||||
/* This is apparently required on some systems */
|
/* This is apparently required on some systems */
|
||||||
|
|||||||
@@ -200,10 +200,6 @@ NSR_AddSource(NTP_Remote_Address *remote_addr, NTP_Source_Type type, SourceParam
|
|||||||
|
|
||||||
assert(initialised);
|
assert(initialised);
|
||||||
|
|
||||||
#if 0
|
|
||||||
LOG(LOGS_INFO, LOGF_NtpSources, "IP=%s port=%d", UTI_IPToString(&remote_addr->ip_addr), remote_addr->port);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Find empty bin & check that we don't have the address already */
|
/* Find empty bin & check that we don't have the address already */
|
||||||
find_slot(remote_addr, &slot, &found);
|
find_slot(remote_addr, &slot, &found);
|
||||||
if (found) {
|
if (found) {
|
||||||
@@ -457,12 +453,6 @@ NSR_ProcessReceive(NTP_Packet *message, struct timeval *now, double now_err, NTP
|
|||||||
|
|
||||||
assert(initialised);
|
assert(initialised);
|
||||||
|
|
||||||
#if 0
|
|
||||||
LOG(LOGS_INFO, LOGF_NtpSources, "from (%s,%d) at %s",
|
|
||||||
UTI_IPToString(&remote_addr->ip_addr),
|
|
||||||
remote_addr->port, UTI_TimevalToString(now));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
find_slot(remote_addr, &slot, &found);
|
find_slot(remote_addr, &slot, &found);
|
||||||
if (found == 2) { /* Must match IP address AND port number */
|
if (found == 2) { /* Must match IP address AND port number */
|
||||||
NCR_ProcessKnown(message, now, now_err, records[slot].data,
|
NCR_ProcessKnown(message, now, now_err, records[slot].data,
|
||||||
@@ -486,11 +476,6 @@ slew_sources(struct timeval *raw,
|
|||||||
|
|
||||||
for (i=0; i<N_RECORDS; i++) {
|
for (i=0; i<N_RECORDS; i++) {
|
||||||
if (records[i].remote_addr) {
|
if (records[i].remote_addr) {
|
||||||
#if 0
|
|
||||||
LOG(LOGS_INFO, LOGF_Sources, "IP=%s dfreq=%f doff=%f",
|
|
||||||
UTI_IPToString(&records[i].remote_addr->ip_addr), dfreq, doffset);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (change_type == LCL_ChangeUnknownStep) {
|
if (change_type == LCL_ChangeUnknownStep) {
|
||||||
NCR_ResetInstance(records[i].data);
|
NCR_ResetInstance(records[i].data);
|
||||||
} else {
|
} else {
|
||||||
@@ -498,7 +483,6 @@ slew_sources(struct timeval *raw,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|||||||
@@ -908,20 +908,13 @@ static void
|
|||||||
filter_slew_samples(struct MedianFilter *filter, struct timeval *when, double dfreq, double doffset)
|
filter_slew_samples(struct MedianFilter *filter, struct timeval *when, double dfreq, double doffset)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
double delta_time, prev_offset;
|
double delta_time;
|
||||||
struct timeval *sample;
|
struct timeval *sample;
|
||||||
|
|
||||||
for (i = 0; i < filter->used; i++) {
|
for (i = 0; i < filter->used; i++) {
|
||||||
sample = &filter->samples[i].sample_time;
|
sample = &filter->samples[i].sample_time;
|
||||||
UTI_AdjustTimeval(sample, when, sample, &delta_time, dfreq, doffset);
|
UTI_AdjustTimeval(sample, when, sample, &delta_time, dfreq, doffset);
|
||||||
prev_offset = filter->samples[i].offset;
|
|
||||||
filter->samples[i].offset -= delta_time;
|
filter->samples[i].offset -= delta_time;
|
||||||
#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
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
15
reference.c
15
reference.c
@@ -426,10 +426,8 @@ update_fb_drifts(double freq_ppm, double update_interval)
|
|||||||
(freq_ppm - fb_drifts[i].freq);
|
(freq_ppm - fb_drifts[i].freq);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
DEBUG_LOG(LOGF_Reference, "Fallback drift %d updated: %f ppm %f seconds",
|
||||||
LOG(LOGS_INFO, LOGF_Reference, "Fallback drift %d updated: %f ppm %f seconds",
|
|
||||||
i + fb_drift_min, fb_drifts[i].freq, fb_drifts[i].secs);
|
i + fb_drift_min, fb_drifts[i].freq, fb_drifts[i].secs);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -476,18 +474,14 @@ schedule_fb_drift(struct timeval *now)
|
|||||||
if (c > next_fb_drift) {
|
if (c > next_fb_drift) {
|
||||||
LCL_SetAbsoluteFrequency(fb_drifts[c - fb_drift_min].freq);
|
LCL_SetAbsoluteFrequency(fb_drifts[c - fb_drift_min].freq);
|
||||||
next_fb_drift = c;
|
next_fb_drift = c;
|
||||||
#if 0
|
DEBUG_LOG(LOGF_Reference, "Fallback drift %d set", c);
|
||||||
LOG(LOGS_INFO, LOGF_Reference, "Fallback drift %d set", c);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i <= fb_drift_max) {
|
if (i <= fb_drift_max) {
|
||||||
next_fb_drift = i;
|
next_fb_drift = i;
|
||||||
UTI_AddDoubleToTimeval(now, secs - unsynchronised, &when);
|
UTI_AddDoubleToTimeval(now, secs - unsynchronised, &when);
|
||||||
fb_drift_timeout_id = SCH_AddTimeout(&when, fb_drift_timeout, NULL);
|
fb_drift_timeout_id = SCH_AddTimeout(&when, fb_drift_timeout, NULL);
|
||||||
#if 0
|
DEBUG_LOG(LOGF_Reference, "Fallback drift %d scheduled", i);
|
||||||
LOG(LOGS_INFO, LOGF_Reference, "Fallback drift %d scheduled", i);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1127,9 +1121,6 @@ void
|
|||||||
REF_ModifyMaxupdateskew(double new_max_update_skew)
|
REF_ModifyMaxupdateskew(double new_max_update_skew)
|
||||||
{
|
{
|
||||||
max_update_skew = new_max_update_skew * 1.0e-6;
|
max_update_skew = new_max_update_skew * 1.0e-6;
|
||||||
#if 0
|
|
||||||
LOG(LOGS_INFO, LOGF_Reference, "New max update skew = %.3fppm", new_max_update_skew);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|||||||
@@ -570,11 +570,6 @@ RGR_FindBestRobustRegression
|
|||||||
b = X / V;
|
b = X / V;
|
||||||
a = my - b*mx;
|
a = my - b*mx;
|
||||||
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
printf("my=%20.12f mx=%20.12f a=%20.12f b=%20.12f\n", my, mx, a, b);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
s2 = 0.0;
|
s2 = 0.0;
|
||||||
for (i=start; i<n; i++) {
|
for (i=start; i<n; i++) {
|
||||||
resid = y[i] - a - b * x[i];
|
resid = y[i] - a - b * x[i];
|
||||||
|
|||||||
4
sched.c
4
sched.c
@@ -592,7 +592,9 @@ SCH_MainLoop(void)
|
|||||||
|
|
||||||
/* if there are no file descriptors being waited on and no
|
/* if there are no file descriptors being waited on and no
|
||||||
timeout set, this is clearly ridiculous, so stop the run */
|
timeout set, this is clearly ridiculous, so stop the run */
|
||||||
assert(ptv || n_read_fds);
|
if (!ptv && !n_read_fds) {
|
||||||
|
LOG_FATAL(LOGF_Scheduler, "Nothing to do");
|
||||||
|
}
|
||||||
|
|
||||||
/* Copy current set of read file descriptors */
|
/* Copy current set of read file descriptors */
|
||||||
memcpy((void *) &rd, (void *) &read_fds, sizeof(fd_set));
|
memcpy((void *) &rd, (void *) &read_fds, sizeof(fd_set));
|
||||||
|
|||||||
49
sources.c
49
sources.c
@@ -610,13 +610,6 @@ SRC_SelectSource(SRC_Instance updated_inst)
|
|||||||
&(si->variance),
|
&(si->variance),
|
||||||
&(si->select_ok));
|
&(si->select_ok));
|
||||||
|
|
||||||
#if 0
|
|
||||||
LOG(LOGS_INFO, LOGF_Sources, "%s dist=%f lo=%f hi=%f",
|
|
||||||
source_to_string(sources[i]),
|
|
||||||
si->root_distance,
|
|
||||||
si->lo_limit, si->hi_limit);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (si->select_ok) {
|
if (si->select_ok) {
|
||||||
++n_sel_sources;
|
++n_sel_sources;
|
||||||
|
|
||||||
@@ -655,10 +648,8 @@ SRC_SelectSource(SRC_Instance updated_inst)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
DEBUG_LOG(LOGF_Sources, "badstat_sources=%d sel_sources=%d badstat_reach=%x sel_reach=%x",
|
||||||
LOG(LOGS_INFO, LOGF_Sources, "badstat_sources=%d sel_sources=%d badstat_reach=%x sel_reach=%x",
|
|
||||||
n_badstats_sources, n_sel_sources, max_badstat_reach, max_sel_reach);
|
n_badstats_sources, n_sel_sources, max_badstat_reach, max_sel_reach);
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Wait for the next call if we have no source selected and there is
|
/* Wait for the next call if we have no source selected and there is
|
||||||
a source with bad stats (has less than 3 samples) with reachability
|
a source with bad stats (has less than 3 samples) with reachability
|
||||||
@@ -672,10 +663,6 @@ SRC_SelectSource(SRC_Instance updated_inst)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
LOG(LOGS_INFO, LOGF_Sources, "n_endpoints=%d", n_endpoints);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Now sort the endpoint list */
|
/* Now sort the endpoint list */
|
||||||
if (n_endpoints > 0) {
|
if (n_endpoints > 0) {
|
||||||
|
|
||||||
@@ -709,10 +696,6 @@ SRC_SelectSource(SRC_Instance updated_inst)
|
|||||||
best_lo = best_hi = 0.0;
|
best_lo = best_hi = 0.0;
|
||||||
|
|
||||||
for (i=0; i<n_endpoints; i++) {
|
for (i=0; i<n_endpoints; i++) {
|
||||||
#if 0
|
|
||||||
LOG(LOGS_INFO, LOGF_Sources, "i=%d t=%f tag=%d addr=%s", i, sort_list[i].offset, sort_list[i].tag,
|
|
||||||
source_to_string(sources[sort_list[i].index]));
|
|
||||||
#endif
|
|
||||||
switch(sort_list[i].tag) {
|
switch(sort_list[i].tag) {
|
||||||
case LOW:
|
case LOW:
|
||||||
depth++;
|
depth++;
|
||||||
@@ -736,11 +719,6 @@ SRC_SelectSource(SRC_Instance updated_inst)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
LOG(LOGS_INFO, LOGF_Sources, "best_depth=%d best_lo=%f best_hi=%f",
|
|
||||||
best_depth, best_lo, best_hi);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (best_depth <= n_sel_sources/2) {
|
if (best_depth <= n_sel_sources/2) {
|
||||||
/* Could not even get half the reachable sources to agree -
|
/* Could not even get half the reachable sources to agree -
|
||||||
clearly we can't synchronise.
|
clearly we can't synchronise.
|
||||||
@@ -783,14 +761,8 @@ SRC_SelectSource(SRC_Instance updated_inst)
|
|||||||
(sources[i]->sel_info.hi_limit <= best_hi))) {
|
(sources[i]->sel_info.hi_limit <= best_hi))) {
|
||||||
|
|
||||||
sel_sources[n_sel_sources++] = i;
|
sel_sources[n_sel_sources++] = i;
|
||||||
#if 0
|
|
||||||
LOG(LOGS_INFO, LOGF_Sources, "i=%d addr=%s is valid", i, source_to_string(sources[i]));
|
|
||||||
#endif
|
|
||||||
} else {
|
} else {
|
||||||
sources[i]->status = SRC_FALSETICKER;
|
sources[i]->status = SRC_FALSETICKER;
|
||||||
#if 0
|
|
||||||
LOG(LOGS_INFO, LOGF_Sources, "i=%d addr=%s is a falseticker", i, source_to_string(sources[i]));
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -811,10 +783,6 @@ SRC_SelectSource(SRC_Instance updated_inst)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
LOG(LOGS_INFO, LOGF_Sources, "min_distance=%f", min_distance);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Now go through and prune any NTP sources that have excessive
|
/* Now go through and prune any NTP sources that have excessive
|
||||||
variance */
|
variance */
|
||||||
for (i=0; i<n_sel_sources; i++) {
|
for (i=0; i<n_sel_sources; i++) {
|
||||||
@@ -823,9 +791,6 @@ SRC_SelectSource(SRC_Instance updated_inst)
|
|||||||
sqrt(sources[index]->sel_info.variance) > min_distance) {
|
sqrt(sources[index]->sel_info.variance) > min_distance) {
|
||||||
sel_sources[i] = INVALID_SOURCE;
|
sel_sources[i] = INVALID_SOURCE;
|
||||||
sources[index]->status = SRC_JITTERY;
|
sources[index]->status = SRC_JITTERY;
|
||||||
#if 0
|
|
||||||
LOG(LOGS_INFO, LOGF_Sources, "i=%d addr=%s has too much variance", i, source_to_string(sources[i]));
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -884,10 +849,6 @@ SRC_SelectSource(SRC_Instance updated_inst)
|
|||||||
if (stratum < min_stratum) min_stratum = stratum;
|
if (stratum < min_stratum) min_stratum = stratum;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
LOG(LOGS_INFO, LOGF_Sources, "min_stratum=%d", min_stratum);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Update scores and find source with maximum score */
|
/* Update scores and find source with maximum score */
|
||||||
|
|
||||||
max_score_index = INVALID_SOURCE;
|
max_score_index = INVALID_SOURCE;
|
||||||
@@ -936,11 +897,9 @@ SRC_SelectSource(SRC_Instance updated_inst)
|
|||||||
sources[i]->sel_score = 1.0 / distance;
|
sources[i]->sel_score = 1.0 / distance;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
DEBUG_LOG(LOGF_Sources, "select score=%f refid=%x match_refid=%x status=%d dist=%f",
|
||||||
LOG(LOGS_INFO, LOGF_Sources, "select score=%f refid=%x match_refid=%x status=%d dist=%f",
|
|
||||||
sources[i]->sel_score, sources[i]->ref_id, updated_inst ? updated_inst->ref_id : 0,
|
sources[i]->sel_score, sources[i]->ref_id, updated_inst ? updated_inst->ref_id : 0,
|
||||||
sources[i]->status, distance);
|
sources[i]->status, distance);
|
||||||
#endif
|
|
||||||
|
|
||||||
if (max_score < sources[i]->sel_score) {
|
if (max_score < sources[i]->sel_score) {
|
||||||
max_score = sources[i]->sel_score;
|
max_score = sources[i]->sel_score;
|
||||||
@@ -963,10 +922,6 @@ SRC_SelectSource(SRC_Instance updated_inst)
|
|||||||
log_selection_message("Selected source %s",
|
log_selection_message("Selected source %s",
|
||||||
source_to_string(sources[selected_source_index]));
|
source_to_string(sources[selected_source_index]));
|
||||||
|
|
||||||
#if 0
|
|
||||||
LOG(LOGS_INFO, LOGF_Sources, "new_sel_index=%d", selected_source_index);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* New source has been selected, reset all scores */
|
/* New source has been selected, reset all scores */
|
||||||
for (i=0; i < n_sources; i++) {
|
for (i=0; i < n_sources; i++) {
|
||||||
sources[i]->sel_score = 1.0;
|
sources[i]->sel_score = 1.0;
|
||||||
|
|||||||
@@ -363,10 +363,6 @@ find_best_sample_index(SST_Stats inst, double *times_back)
|
|||||||
|
|
||||||
assert(best_index >= 0);
|
assert(best_index >= 0);
|
||||||
inst->best_single_sample = best_index;
|
inst->best_single_sample = best_index;
|
||||||
|
|
||||||
#if 0
|
|
||||||
LOG(LOGS_INFO, LOGF_SourceStats, "n=%d best_index=%d", n, best_index);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
@@ -500,9 +496,6 @@ SST_DoNewRegression(SST_Stats inst)
|
|||||||
times_back_start = inst->runs_samples + best_start;
|
times_back_start = inst->runs_samples + best_start;
|
||||||
prune_register(inst, best_start);
|
prune_register(inst, best_start);
|
||||||
} else {
|
} else {
|
||||||
#if 0
|
|
||||||
LOG(LOGS_INFO, LOGF_SourceStats, "too few points (%d) for regression", inst->n_samples);
|
|
||||||
#endif
|
|
||||||
inst->estimated_frequency = 0.0;
|
inst->estimated_frequency = 0.0;
|
||||||
inst->skew = WORST_CASE_FREQ_BOUND;
|
inst->skew = WORST_CASE_FREQ_BOUND;
|
||||||
times_back_start = 0;
|
times_back_start = 0;
|
||||||
@@ -734,9 +727,8 @@ SST_IsGoodSample(SST_Stats inst, double offset, double delay,
|
|||||||
if (fabs(offset) - delay_increase > allowed_increase)
|
if (fabs(offset) - delay_increase > allowed_increase)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
#if 0
|
DEBUG_LOG(LOGF_SourceStats, "Bad sample: offset=%f delay=%f incr_delay=%f allowed=%f",
|
||||||
LOG(LOGS_INFO, LOGF_SourceStats, "bad sample: offset=%f delay=%f incr_delay=%f allowed=%f", offset, delay, allowed_increase, delay_increase);
|
offset, delay, allowed_increase, delay_increase);
|
||||||
#endif
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
18
sys_linux.c
18
sys_linux.c
@@ -271,11 +271,6 @@ get_version_specific_details(void)
|
|||||||
if (!shift_hz) {
|
if (!shift_hz) {
|
||||||
LOG_FATAL(LOGF_SysLinux, "Can't determine hz (txc.tick=%ld txc.freq=%ld (%.8f) txc.offset=%ld)",
|
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);
|
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
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -397,9 +392,7 @@ SYS_Linux_DropRoot(char *user)
|
|||||||
|
|
||||||
cap_free(cap);
|
cap_free(cap);
|
||||||
|
|
||||||
#if 0
|
DEBUG_LOG(LOGF_SysLinux, "Privileges dropped to user %s", user);
|
||||||
LOG(LOGS_INFO, LOGF_SysLinux, "Privileges dropped to user %s", user);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -428,9 +421,8 @@ void SYS_Linux_SetScheduler(int SchedPriority)
|
|||||||
LOG(LOGS_ERR, LOGF_SysLinux, "sched_setscheduler() failed");
|
LOG(LOGS_ERR, LOGF_SysLinux, "sched_setscheduler() failed");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
#if 0
|
DEBUG_LOG(LOGF_SysLinux, "Enabled SCHED_FIFO with priority %d",
|
||||||
LOG(LOGS_INFO, LOGF_SysLinux, "Enabled SCHED_FIFO with priority %d", sched.sched_priority);
|
sched.sched_priority);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -454,9 +446,7 @@ void SYS_Linux_MemLockAll(int LockAll)
|
|||||||
LOG(LOGS_ERR, LOGF_SysLinux, "mlockall() failed");
|
LOG(LOGS_ERR, LOGF_SysLinux, "mlockall() failed");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
#if 0
|
DEBUG_LOG(LOGF_SysLinux, "Successfully locked into RAM");
|
||||||
LOG(LOGS_INFO, LOGF_SysLinux, "Successfully locked into RAM");
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -409,11 +409,6 @@ set_dosynctodr(unsigned long on_off)
|
|||||||
kvm_close(kt);
|
kvm_close(kt);
|
||||||
|
|
||||||
assert(read_back == on_off);
|
assert(read_back == on_off);
|
||||||
|
|
||||||
#if 0
|
|
||||||
LOG(LOGS_INFO, LOGF_SysSolaris, "Set value of dosynctodr to %d", on_off);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|||||||
@@ -364,11 +364,6 @@ setup_kernel(unsigned long on_off)
|
|||||||
}
|
}
|
||||||
|
|
||||||
kvm_close(kt);
|
kvm_close(kt);
|
||||||
|
|
||||||
#if 0
|
|
||||||
LOG(LOGS_INFO, LOGF_SysSunOS, "Set value of _dosynctodr to %d", on_off);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ export PATH=../../:$PATH
|
|||||||
export CLKNETSIM_PATH=clknetsim
|
export CLKNETSIM_PATH=clknetsim
|
||||||
|
|
||||||
# Known working clknetsim revision
|
# Known working clknetsim revision
|
||||||
clknetsim_revision=326b619e36858c1f88240e17317595509e3d00de
|
clknetsim_revision=2fa4c5eae095457ef7d045864dadec59afbffb18
|
||||||
clknetsim_url=https://github.com/mlichvar/clknetsim/archive/$clknetsim_revision.tar.gz
|
clknetsim_url=https://github.com/mlichvar/clknetsim/archive/$clknetsim_revision.tar.gz
|
||||||
|
|
||||||
# Only Linux is supported
|
# Only Linux is supported
|
||||||
|
|||||||
17
util.c
17
util.c
@@ -164,13 +164,6 @@ UTI_AverageDiffTimevals (struct timeval *earlier,
|
|||||||
be backwards, or something wierd has happened. Maybe when we
|
be backwards, or something wierd has happened. Maybe when we
|
||||||
change the frequency on Linux? */
|
change the frequency on Linux? */
|
||||||
|
|
||||||
/* This seems to be fairly benign, so don't bother logging it */
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
LOG(LOGS_INFO, LOGF_Util, "Earlier=[%s] Later=[%s]",
|
|
||||||
UTI_TimevalToString(earlier), UTI_TimevalToString(later));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Assume the required behaviour is to treat it as zero */
|
/* Assume the required behaviour is to treat it as zero */
|
||||||
*diff = 0.0;
|
*diff = 0.0;
|
||||||
}
|
}
|
||||||
@@ -214,12 +207,12 @@ static int pool_ptr = 0;
|
|||||||
char *
|
char *
|
||||||
UTI_TimevalToString(struct timeval *tv)
|
UTI_TimevalToString(struct timeval *tv)
|
||||||
{
|
{
|
||||||
char buffer[64], *result;
|
char *result;
|
||||||
struct tm stm;
|
|
||||||
stm = *gmtime((time_t *) &(tv->tv_sec));
|
|
||||||
strftime(buffer, sizeof(buffer), "%a %x %X", &stm);
|
|
||||||
result = NEXT_BUFFER;
|
result = NEXT_BUFFER;
|
||||||
snprintf(result, BUFFER_LENGTH, "%s.%06ld", buffer, (unsigned long)(tv->tv_usec));
|
/* TODO: time_t may be wider than long, switch to int64_t before 2038 */
|
||||||
|
snprintf(result, BUFFER_LENGTH, "%ld.%06lu",
|
||||||
|
(long)tv->tv_sec, (unsigned long)tv->tv_usec);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user