Compare commits

...

31 Commits

Author SHA1 Message Date
Miroslav Lichvar
2dcc16169b Update NEWS 2011-05-04 12:29:40 +02:00
Miroslav Lichvar
a8efd8c398 Update versions in man pages 2011-05-02 13:21:50 +02:00
Miroslav Lichvar
bb40f4aff4 Modify weight calculation again
Dividing the weights by variance or unweighted variance seems to have a
significant negative impact on response with normally distributed
network delays.

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

6
NEWS
View File

@@ -6,6 +6,7 @@ New in version 1.25
* Improve polling interval adjustment * Improve polling interval adjustment
* Improve stability with temporary asymmetric delays * Improve stability with temporary asymmetric delays
* Improve source selection * Improve source selection
* Improve initial synchronisation
* Add delayed server name resolving * Add delayed server name resolving
* Add temperature compensation * Add temperature compensation
* Add nanosecond slewing to Linux driver * Add nanosecond slewing to Linux driver
@@ -13,7 +14,8 @@ New in version 1.25
* Add iburst, minstratum, maxdelaydevratio, polltarget, * Add iburst, minstratum, maxdelaydevratio, polltarget,
prefer, noselect options prefer, noselect options
* Add rtcsync directive to enable Linux 11-minute mode * Add rtcsync directive to enable Linux 11-minute mode
* Add reselectdist, stratumweight, logbanner, maxclockerror directives * Add reselectdist, stratumweight, logbanner, maxclockerror,
include directives
* Add -n option to not detach daemon from terminal * Add -n option to not detach daemon from terminal
* Fix pidfile directive * Fix pidfile directive
* Fix name resolving with disabled IPv6 support * Fix name resolving with disabled IPv6 support
@@ -23,9 +25,9 @@ New in version 1.25
* Fix file descriptor leaks * Fix file descriptor leaks
* Increase burst polling interval and stop on KoD RATE * Increase burst polling interval and stop on KoD RATE
* Set maxupdateskew to 1000 ppm by default * Set maxupdateskew to 1000 ppm by default
* Consider offline sources unreachable
* Require password for clients command * Require password for clients command
* Update drift file at most once per hour * Update drift file at most once per hour
* Use system headers for Linux RTC support
* Reduce default chronyc timeout and make it configurable * Reduce default chronyc timeout and make it configurable
* Avoid large values in chronyc sources and sourcestats output * Avoid large values in chronyc sources and sourcestats output
* Add reselect command to force reselecting best source * Add reselect command to force reselecting best source

12
candm.h
View File

@@ -86,7 +86,8 @@
#define REQ_MODIFY_POLLTARGET 46 #define REQ_MODIFY_POLLTARGET 46
#define REQ_MODIFY_MAXDELAYDEVRATIO 47 #define REQ_MODIFY_MAXDELAYDEVRATIO 47
#define REQ_RESELECT 48 #define REQ_RESELECT 48
#define N_REQUEST_TYPES 49 #define REQ_RESELECTDISTANCE 49
#define N_REQUEST_TYPES 50
/* Special utoken value used to log on with first exchange being the /* Special utoken value used to log on with first exchange being the
password. (This time value has long since gone by) */ password. (This time value has long since gone by) */
@@ -339,6 +340,11 @@ typedef struct {
int32_t EOR; int32_t EOR;
} REQ_Reselect; } REQ_Reselect;
typedef struct {
Float distance;
int32_t EOR;
} REQ_ReselectDistance;
/* ================================================== */ /* ================================================== */
#define PKT_TYPE_CMD_REQUEST 1 #define PKT_TYPE_CMD_REQUEST 1
@@ -359,7 +365,8 @@ typedef struct {
Version 4 : IPv6 addressing added, 64-bit time values, sourcestats Version 4 : IPv6 addressing added, 64-bit time values, sourcestats
and tracking reports extended, added flags to NTP source request, and tracking reports extended, added flags to NTP source request,
trimmed source report, replaced fixed-point format with floating-point trimmed source report, replaced fixed-point format with floating-point
and used also instead of integer microseconds and used also instead of integer microseconds, new commands: modify stratum,
modify polltarget, modify maxdelaydevratio, reselect, reselectdistance
*/ */
@@ -425,6 +432,7 @@ typedef struct {
REQ_MakeStep make_step; REQ_MakeStep make_step;
REQ_Activity activity; REQ_Activity activity;
REQ_Reselect reselect; REQ_Reselect reselect;
REQ_ReselectDistance reselect_distance;
} data; /* Command specific parameters */ } data; /* Command specific parameters */
} CMD_Request; } CMD_Request;

View File

@@ -1179,6 +1179,7 @@ directives can occur in any order in the file.
* dumpdir directive:: Specify directory for dumping measurements * dumpdir directive:: Specify directory for dumping measurements
* dumponexit directive:: Dump measurements when daemon exits * dumponexit directive:: Dump measurements when daemon exits
* fallbackdrift directive:: Specify fallback drift intervals * fallbackdrift directive:: Specify fallback drift intervals
* include directive:: Include a configuration file
* initstepslew directive:: Trim the system clock on boot-up. * initstepslew directive:: Trim the system clock on boot-up.
* keyfile directive:: Specify location of file containing keys * keyfile directive:: Specify location of file containing keys
* linux_hz directive:: Define a non-standard value of the kernel HZ constant * linux_hz directive:: Define a non-standard value of the kernel HZ constant
@@ -1601,6 +1602,17 @@ By default (or if the specified maximum or minimum is 0), no fallbacks
will be used and the clock frequency will stay at the last value will be used and the clock frequency will stay at the last value
calculated before synchronisation was lost. calculated before synchronisation was lost.
@c }}} @c }}}
@c {{{ include
@node include directive
@subsection include
The @code{include} directive includes a specified configuration file.
This is useful when maintaining configuration on multiple hosts to
keep the differences in a separate file.
@example
include /etc/chrony/local.conf
@end example
@c }}}
@c {{{ initstepslew @c {{{ initstepslew
@node initstepslew directive @node initstepslew directive
@subsection initstepslew @subsection initstepslew
@@ -2219,7 +2231,7 @@ The @code{maxclockerror} directive sets the maximum assumed frequency
error of the local clock. This is a frequency stability of the clock, error of the local clock. This is a frequency stability of the clock,
not an absolute frequency error. not an absolute frequency error.
By default, the maximum assumed error is set to 10 ppm. By default, the maximum assumed error is set to 1 ppm.
The syntax is The syntax is
@@ -2326,30 +2338,33 @@ udp/11123.
@c {{{ refclock @c {{{ refclock
@node refclock directive @node refclock directive
@subsection refclock @subsection refclock
The @code{refclock} directive allows reference clocks to be specified. Reference clocks allows very accurate synchronisation and @code{chronyd}
The directive is immediately followed by a refclock driver name and can function as a stratum 1 server. They are specified by the
its parameter. @code{refclock} directive. It has two mandatory parameters, a refclock driver
name and a driver specific parameter.
There are currently three drivers implemented: There are currently three drivers included:
@table @code @table @code
@item PPS @item PPS
Pulse per second (PPS) API driver. The parameter is a path to the PPS PPSAPI (pulse per second) driver. The parameter is the path to a PPS
device. Assert events are used by default. Driver option device. Assert events are used by default. Driver option @code{:clear}
@code{:clear} can be appended to the path to use clear events instead. can be appended to the path if clear events should be used instead.
PPS refclock needs another source (NTP or non-PPS refclock) or local As PPS refclock gets only sub-second time information, it needs another
directive (@pxref{local directive}) enabled to function. For example: source (NTP or non-PPS refclock) or local directive (@pxref{local
directive}) enabled to work. For example:
@example @example
refclock SHM 0 offset 0.5 delay 0.1 refclock PPS /dev/pps0 lock NMEA
refclock PPS /dev/pps0 refclock SHM 0 offset 0.5 delay 0.1 refid NMEA noselect
@end example @end example
@item SHM @item SHM
NTP shared memory driver. The parameter is the number of the NTP shared memory driver. This driver uses a shared memory segment to
shared memory segment that should be used for receiving timestamps, usually receive data from another daemon which communicates with an actual
0, 1, 2 or 3. For example: reference clock. The parameter is the number of a shared memory segment,
usually 0, 1, 2 or 3. For example:
@example @example
refclock SHM 1 poll 3 refid GPS1 refclock SHM 1 poll 3 refid GPS1
@@ -2359,15 +2374,25 @@ A driver option in form @code{:perm=NNN} can be appended to the
segment number to create the segment with permissions other than the segment number to create the segment with permissions other than the
default @code{0600}. default @code{0600}.
Software that can be used as a source of reference time includes Some examples of applications that can be used as SHM sources are @code{gpsd},
@code{gpsd} and @code{shmpps}. @code{shmpps} and @code{radioclk}.
@item SOCK @item SOCK
Unix domain socket driver. The parameter is a path to the socket Unix domain socket driver. It is similar to the SHM driver, but uses a
which is used as the source of timestamps. This is as a better different format and uses a socket instead of shared memory. It does not
alternative to SHM, it does not require polling, the offset require polling, the offset resolution is not limited to microseconds and it
resolution is not limited to microsecond and it supports PPS. supports transmitting of PPS data. The parameter is a path to the socket which
The format for messages sent over the socket is declared in file will be created by @code{chronyd} and used to receive the messages. The format
@code{refclock_sock.c}. of messages sent over the socket is described in the
@code{refclock_sock.c} file.
Recent versions of the @code{gpsd} daemon include support for the SOCK
protocol. The path where the socket should be created is described in the
@code{gpsd(8)} man page. For example:
@example
refclock SOCK /tmp/chrony.tty0.sock
@end example
@end table @end table
The @code{refclock} command also supports a number of subfields (which The @code{refclock} command also supports a number of subfields (which
@@ -2379,7 +2404,8 @@ Timestamps produced by refclock drivers are not used immediately, but
they are stored and processed by a median filter in intervals they are stored and processed by a median filter in intervals
specified by this option. This is defined as a power of 2. The specified by this option. This is defined as a power of 2. The
default is 4 (16 seconds). A shorter interval allows @code{chronyd} default is 4 (16 seconds). A shorter interval allows @code{chronyd}
to react faster to frequency changes, but it may increase noise. to react faster to changes in clock frequency, but it may decrease
the accuracy if the source is too noisy.
@item dpoll @item dpoll
Some drivers are not controlled by external events and thus require Some drivers are not controlled by external events and thus require
polling. Again this is defined as a power of 2 and can be negative polling. Again this is defined as a power of 2 and can be negative
@@ -2388,7 +2414,7 @@ for sub-second intervals. The default is 0 (1 second).
This option is used to specify a reference id of the refclock, as up This option is used to specify a reference id of the refclock, as up
to four ASCII characters. By default, first three characters from to four ASCII characters. By default, first three characters from
driver name and the number of the refclock are used as refid. Each driver name and the number of the refclock are used as refid. Each
refclock has to use an unique refid. refclock must have an unique refid.
@item filter @item filter
This option sets the length of the median filter which is used to This option sets the length of the median filter which is used to
reduce noise. With each poll about 40 percent of the stored samples is reduce noise. With each poll about 40 percent of the stored samples is
@@ -2423,7 +2449,8 @@ for SHM refclock, and 1e-9 (1 nanosecond) for SOCK and PPS refclocks.
@item prefer @item prefer
Prefer this source over sources without prefer option. Prefer this source over sources without prefer option.
@item noselect @item noselect
Never select this source. This is particularly useful for monitoring. Never select this source. This is useful for monitoring or with sources
which are not very accurate, but are locked with a PPS refclock.
@end table @end table
@c }}} @c }}}
@@ -2922,6 +2949,7 @@ interface.
* polltarget command:: Set poll target for a source * polltarget command:: Set poll target for a source
* quit command:: Exit from chronyc * quit command:: Exit from chronyc
* reselect command:: Reselect synchronisation source * reselect command:: Reselect synchronisation source
* reselectdist command:: Set improvement in distance needed to reselect a source
* retries command:: Set maximum number of retries * retries command:: Set maximum number of retries
* rtcdata command:: Display RTC parameters * rtcdata command:: Display RTC parameters
* settime command:: Provide a manual input of the current time * settime command:: Provide a manual input of the current time
@@ -3744,6 +3772,13 @@ available sources.
The @code{reselect} command can be used to force @code{chronyd} to The @code{reselect} command can be used to force @code{chronyd} to
reselect the best synchronisation source. reselect the best synchronisation source.
@c }}} @c }}}
@c {{{ reselectdist command
@node reselectdist command
@subsubsection reselectdist
The @code{reselectdist} command sets the reselect distance. It is equivalent
to the @code{reselectdist} directive in the configuration file
(@pxref{reselectdist directive}).
@c }}}
@c {{{ retries @c {{{ retries
@node retries command @node retries command
@subsubsection retries @subsubsection retries

View File

@@ -1,4 +1,4 @@
.TH CHRONYC 1 "December 04, 2009" chrony "User's Manual" .TH CHRONYC 1 "May 02, 2011" chrony "User's Manual"
.SH NAME .SH NAME
chronyc \- command-line interface for chronyd chronyc \- command-line interface for chronyd
@@ -48,7 +48,7 @@ interactively.
.SH VERSION .SH VERSION
1.24 1.25
.SH BUGS .SH BUGS
To report bugs, please visit \fIhttp://chrony.tuxfamily.org\fR To report bugs, please visit \fIhttp://chrony.tuxfamily.org\fR

View File

@@ -1,4 +1,4 @@
.TH CHRONYD 8 "December 04, 2009" chrony "System Administration" .TH CHRONYD 8 "May 02, 2011" chrony "System Administration"
.SH NAME .SH NAME
chronyd \- chrony background daemon chronyd \- chrony background daemon
@@ -109,7 +109,7 @@ Resolve hostnames only to IPv6 addresses.
\fI/etc/chrony.conf\fR \fI/etc/chrony.conf\fR
.SH VERSION .SH VERSION
Version 1.24 Version 1.25
.SH BUGS .SH BUGS
To report bugs, please visit \fIhttp://chrony.tuxfamily.org/\fR To report bugs, please visit \fIhttp://chrony.tuxfamily.org/\fR

View File

@@ -1787,7 +1787,7 @@ process_cmd_sourcestats(char *line)
char hostname_buf[50]; char hostname_buf[50];
unsigned long n_samples, n_runs, span_seconds; unsigned long n_samples, n_runs, span_seconds;
double resid_freq_ppm, skew_ppm, sd, est_offset, est_offset_err; double resid_freq_ppm, skew_ppm, sd, est_offset;
unsigned long ref_id; unsigned long ref_id;
IPAddr ip_addr; IPAddr ip_addr;
@@ -1827,7 +1827,7 @@ process_cmd_sourcestats(char *line)
skew_ppm = UTI_FloatNetworkToHost(reply.data.sourcestats.skew_ppm); skew_ppm = UTI_FloatNetworkToHost(reply.data.sourcestats.skew_ppm);
sd = UTI_FloatNetworkToHost(reply.data.sourcestats.sd); sd = UTI_FloatNetworkToHost(reply.data.sourcestats.sd);
est_offset = UTI_FloatNetworkToHost(reply.data.sourcestats.est_offset); est_offset = UTI_FloatNetworkToHost(reply.data.sourcestats.est_offset);
est_offset_err = UTI_FloatNetworkToHost(reply.data.sourcestats.est_offset_err); /* est_offset_err = UTI_FloatNetworkToHost(reply.data.sourcestats.est_offset_err); */
if (ip_addr.family == IPADDR_UNSPEC) if (ip_addr.family == IPADDR_UNSPEC)
snprintf(hostname_buf, sizeof(hostname_buf), "%s", UTI_RefidToString(ref_id)); snprintf(hostname_buf, sizeof(hostname_buf), "%s", UTI_RefidToString(ref_id));
@@ -2377,6 +2377,23 @@ process_cmd_activity(const char *line)
/* ================================================== */ /* ================================================== */
static int
process_cmd_reselectdist(CMD_Request *msg, char *line)
{
double dist;
int ok;
msg->command = htons(REQ_RESELECTDISTANCE);
if (sscanf(line, "%lf", &dist) == 1) {
msg->data.reselect_distance.distance = UTI_FloatHostToNetwork(dist);
ok = 1;
} else {
ok = 0;
}
return ok;
}
/* ================================================== */
static void static void
process_cmd_reselect(CMD_Request *msg, char *line) process_cmd_reselect(CMD_Request *msg, char *line)
{ {
@@ -2558,6 +2575,8 @@ process_line(char *line, int *quit)
} else if (!strncmp(p, "activity", 8)) { } else if (!strncmp(p, "activity", 8)) {
ret = process_cmd_activity(p+8); ret = process_cmd_activity(p+8);
do_normal_submit = 0; do_normal_submit = 0;
} else if (!strncmp(p, "reselectdist", 12)) {
do_normal_submit = process_cmd_reselectdist(&tx_message, p+12);
} else if (!strncmp(p, "reselect", 8)) { } else if (!strncmp(p, "reselect", 8)) {
process_cmd_reselect(&tx_message, p+8); process_cmd_reselect(&tx_message, p+8);
} else if (!strncmp(p, "dns ", 4)) { } else if (!strncmp(p, "dns ", 4)) {
@@ -2621,8 +2640,6 @@ process_args(int argc, char **argv, int multi)
} }
} }
strcat(line, "\n");
ret = process_line(line, &quit); ret = process_line(line, &quit);
if (!ret) if (!ret)
break; break;
@@ -2638,11 +2655,11 @@ process_args(int argc, char **argv, int multi)
static void static void
display_gpl(void) display_gpl(void)
{ {
printf("chrony version %s, copyright (C) 1997-2002 Richard P. Curnow\n" printf("chrony version %s\n"
"chrony comes with ABSOLUTELY NO WARRANTY.\n" "Copyright (C) 1997-2003, 2007, 2009-2011 Richard P. Curnow and others\n"
"This is free software, and you are welcome to redistribute it\n" "chrony comes with ABSOLUTELY NO WARRANTY. This is free software, and\n"
"under certain conditions.\n" "you are welcome to redistribute it under certain conditions. See the\n"
"See the GNU General Public License version 2 for details.\n\n", "GNU General Public License version 2 for details.\n\n",
PROGRAM_VERSION_STRING); PROGRAM_VERSION_STRING);
} }

View File

@@ -158,7 +158,8 @@ static int permissions[] = {
PERMIT_AUTH, /* MODIFY_MINSTRATUM */ PERMIT_AUTH, /* MODIFY_MINSTRATUM */
PERMIT_AUTH, /* MODIFY_POLLTARGET */ PERMIT_AUTH, /* MODIFY_POLLTARGET */
PERMIT_AUTH, /* MODIFY_MAXDELAYDEVRATIO */ PERMIT_AUTH, /* MODIFY_MAXDELAYDEVRATIO */
PERMIT_AUTH /* RESELECT */ PERMIT_AUTH, /* RESELECT */
PERMIT_AUTH /* RESELECTDISTANCE */
}; };
/* ================================================== */ /* ================================================== */
@@ -1711,6 +1712,18 @@ handle_activity(CMD_Request *rx_message, CMD_Reply *tx_message)
/* ================================================== */ /* ================================================== */
static void
handle_reselect_distance(CMD_Request *rx_message, CMD_Reply *tx_message)
{
double dist;
dist = UTI_FloatNetworkToHost(rx_message->data.reselect_distance.distance);
SRC_SetReselectDistance(dist);
tx_message->status = htons(STT_SUCCESS);
return;
}
/* ================================================== */
static void static void
handle_reselect(CMD_Request *rx_message, CMD_Reply *tx_message) handle_reselect(CMD_Request *rx_message, CMD_Reply *tx_message)
{ {
@@ -2258,6 +2271,10 @@ read_from_cmd_socket(void *anything)
handle_activity(&rx_message, &tx_message); handle_activity(&rx_message, &tx_message);
break; break;
case REQ_RESELECTDISTANCE:
handle_reselect_distance(&rx_message, &tx_message);
break;
case REQ_RESELECT: case REQ_RESELECT:
handle_reselect(&rx_message, &tx_message); handle_reselect(&rx_message, &tx_message);
break; break;
@@ -2271,7 +2288,7 @@ read_from_cmd_socket(void *anything)
break; break;
default: default:
/* Ignore message */ assert(0);
break; break;
} }
} else { } else {

20
conf.c
View File

@@ -107,6 +107,7 @@ static void parse_linux_freq_scale(const char *);
static void parse_sched_priority(const char *); static void parse_sched_priority(const char *);
static void parse_lockall(const char *); static void parse_lockall(const char *);
static void parse_tempcomp(const char *); static void parse_tempcomp(const char *);
static void parse_include(const char *);
/* ================================================== */ /* ================================================== */
/* Configuration variables */ /* Configuration variables */
@@ -119,7 +120,7 @@ static char *drift_file = NULL;
static char *rtc_file = NULL; static char *rtc_file = NULL;
static unsigned long command_key_id; static unsigned long command_key_id;
static double max_update_skew = 1000.0; static double max_update_skew = 1000.0;
static double max_clock_error = 10; /* in ppm */ static double max_clock_error = 1.0; /* in ppm */
static double reselect_distance = 1e-4; static double reselect_distance = 1e-4;
static double stratum_weight = 1.0; static double stratum_weight = 1.0;
@@ -261,6 +262,7 @@ static const Command commands[] = {
{"tempcomp", 8, parse_tempcomp}, {"tempcomp", 8, parse_tempcomp},
{"reselectdist", 12, parse_reselectdist}, {"reselectdist", 12, parse_reselectdist},
{"stratumweight", 13, parse_stratumweight}, {"stratumweight", 13, parse_stratumweight},
{"include", 7, parse_include},
{"linux_hz", 8, parse_linux_hz}, {"linux_hz", 8, parse_linux_hz},
{"linux_freq_scale", 16, parse_linux_freq_scale}, {"linux_freq_scale", 16, parse_linux_freq_scale},
{"sched_priority", 14, parse_sched_priority}, {"sched_priority", 14, parse_sched_priority},
@@ -313,6 +315,7 @@ CNF_ReadFile(const char *filename)
char line[2048]; char line[2048];
char *p; char *p;
int i, ok; int i, ok;
int prev_line_number;
if (filename == NULL) { if (filename == NULL) {
filename = DEFAULT_CONF_FILE; filename = DEFAULT_CONF_FILE;
@@ -323,6 +326,9 @@ CNF_ReadFile(const char *filename)
LOG(LOGS_ERR, LOGF_Configure, "Could not open configuration file [%s]", filename); LOG(LOGS_ERR, LOGF_Configure, "Could not open configuration file [%s]", filename);
} else { } else {
/* Save current line number in case this is an included file */
prev_line_number = line_number;
line_number = 0; line_number = 0;
/* Success */ /* Success */
@@ -357,6 +363,8 @@ CNF_ReadFile(const char *filename)
} }
line_number = prev_line_number;
fclose(in); fclose(in);
} }
@@ -1218,6 +1226,16 @@ parse_tempcomp(const char *line)
/* ================================================== */ /* ================================================== */
static void
parse_include(const char *line)
{
while (isspace(line[0]))
line++;
CNF_ReadFile(line);
}
/* ================================================== */
static void static void
parse_linux_hz(const char *line) parse_linux_hz(const char *line)
{ {

29
configure vendored
View File

@@ -4,6 +4,7 @@
# chronyd/chronyc - Programs for keeping computer clocks accurate. # chronyd/chronyc - Programs for keeping computer clocks accurate.
# #
# Copyright (C) Richard P. Curnow 1997-2003 # Copyright (C) Richard P. Curnow 1997-2003
# Copyright (C) Miroslav Lichvar 2009
# #
# ======================================================================= # =======================================================================
@@ -101,6 +102,7 @@ For better control, use the options below.
--disable-pps Disable PPS API support --disable-pps Disable PPS API support
--disable-rtc Don't include RTC even on Linux --disable-rtc Don't include RTC even on Linux
--disable-linuxcaps Disable Linux capabilities support --disable-linuxcaps Disable Linux capabilities support
--enable-forcednsretry Force retry on DNS failure
Fine tuning of the installation directories: Fine tuning of the installation directories:
--sysconfdir=DIR chrony.conf location [/etc] --sysconfdir=DIR chrony.conf location [/etc]
@@ -151,6 +153,7 @@ feat_readline=1
try_readline=1 try_readline=1
try_editline=1 try_editline=1
feat_rtc=1 feat_rtc=1
try_rtc=0
feat_linuxcaps=1 feat_linuxcaps=1
try_linuxcaps=0 try_linuxcaps=0
readline_lib="" readline_lib=""
@@ -160,6 +163,7 @@ feat_ipv6=1
feat_pps=1 feat_pps=1
try_setsched=0 try_setsched=0
try_lockmem=0 try_lockmem=0
feat_forcednsretry=0
for option for option
do do
@@ -224,6 +228,9 @@ do
--disable-linuxcaps) --disable-linuxcaps)
feat_linuxcaps=0 feat_linuxcaps=0
;; ;;
--enable-forcednsretry)
feat_forcednsretry=1
;;
--host-system=* ) --host-system=* )
OPERATINGSYSTEM=`echo $option | sed -e 's/^.*=//;'` OPERATINGSYSTEM=`echo $option | sed -e 's/^.*=//;'`
;; ;;
@@ -268,11 +275,8 @@ case $SYSTEM in
;; ;;
Linux* ) Linux* )
EXTRA_OBJECTS="sys_linux.o wrap_adjtimex.o" EXTRA_OBJECTS="sys_linux.o wrap_adjtimex.o"
if [ $feat_rtc -eq 1 ] ; then
EXTRA_OBJECTS="$EXTRA_OBJECTS rtc_linux.o"
EXTRA_DEFS="$EXTRA_DEFS -DFEAT_RTC=1"
fi
try_linuxcaps=1 try_linuxcaps=1
try_rtc=1
try_setsched=1 try_setsched=1
try_lockmem=1 try_lockmem=1
SYSDEFS="-DLINUX" SYSDEFS="-DLINUX"
@@ -350,11 +354,11 @@ then
fi fi
if [ $feat_pps = "1" ] && \ if [ $feat_pps = "1" ] && \
test_code 'PPS API' 'timepps.h' '' '' ' test_code 'PPS API' 'string.h timepps.h' '' '' '
pps_handle_t h; pps_handle_t h;
pps_info_t i; pps_info_t i;
struct timespec ts; struct timespec ts;
return time_pps_fetch(&h, PPS_TSFMT_TSPEC, &i, &ts);' return time_pps_fetch(h, PPS_TSFMT_TSPEC, &i, &ts);'
then then
SYSDEFS="${SYSDEFS} -DHAVE_PPSAPI" SYSDEFS="${SYSDEFS} -DHAVE_PPSAPI"
fi fi
@@ -370,6 +374,14 @@ then
EXTRA_LIBS="-lcap" EXTRA_LIBS="-lcap"
fi fi
if [ $feat_rtc = "1" ] && [ $try_rtc = "1" ] && \
test_code '<linux/rtc.h>' 'sys/ioctl.h linux/rtc.h' '' '' \
'ioctl(1, RTC_UIE_ON&RTC_UIE_OFF&RTC_RD_TIME&RTC_SET_TIME, 0&RTC_UF);'
then
EXTRA_OBJECTS="$EXTRA_OBJECTS rtc_linux.o"
EXTRA_DEFS="$EXTRA_DEFS -DFEAT_RTC=1"
fi
if [ $try_setsched = "1" ] && \ if [ $try_setsched = "1" ] && \
test_code \ test_code \
'sched_setscheduler()' \ 'sched_setscheduler()' \
@@ -392,6 +404,11 @@ then
SYSDEFS="${SYSDEFS} -DHAVE_MLOCKALL" SYSDEFS="${SYSDEFS} -DHAVE_MLOCKALL"
fi fi
if [ $feat_forcednsretry = "1" ]
then
EXTRA_DEFS="$EXTRA_DEFS -DFORCE_DNSRETRY=1"
fi
READLINE_COMPILE="" READLINE_COMPILE=""
READLINE_LINK="" READLINE_LINK=""
if [ $feat_readline = "1" ]; then if [ $feat_readline = "1" ]; then

View File

@@ -0,0 +1,39 @@
# Use public servers from the pool.ntp.org project.
# Please consider joining the pool (http://www.pool.ntp.org/join.html).
server 0.pool.ntp.org iburst
server 1.pool.ntp.org iburst
server 2.pool.ntp.org iburst
server 3.pool.ntp.org iburst
# Ignore stratum in source selection.
stratumweight 0
# Record the rate at which the system clock gains/losses time.
driftfile /var/lib/chrony/drift
# Enable kernel RTC synchronization.
rtcsync
# In first three updates step the system clock instead of slew
# if the adjustment is larger than 100 seconds.
makestep 100 3
# Allow client access from local network.
#allow 192.168/16
# Serve time even if not synchronized to any NTP server.
#local stratum 10
keyfile /etc/chrony.keys
# Specify the key used as password for chronyc.
commandkey 1
# Disable logging of client accesses.
noclientlog
# Send a message to syslog if a clock adjustment is larger than 0.5 seconds.
logchange 0.5
logdir /var/log/chrony
#log measurements statistics tracking

View File

@@ -1,75 +0,0 @@
/* Taken from <asm-$foo/ioctl.h> in the Linux kernel sources.
* The ioctl.h file is pretty similar from one architecture to another.
* */
#ifndef IO_LINUX_H
#define IO_LINUX_H
/* Hmm. These constants vary a bit between systems. */
/* (__sh__ includes both sh and sh64) */
/* (__s390__ includes both s390 and s390x) */
#if defined(__i386__) || defined(__sh__) || defined(__arm__) || defined(__x86_64__) || defined(__s390__)
#define CHRONY_IOC_NRBITS 8
#define CHRONY_IOC_TYPEBITS 8
#define CHRONY_IOC_SIZEBITS 14
#define CHRONY_IOC_DIRBITS 2
#define CHRONY_IOC_NONE 0U
#define CHRONY_IOC_WRITE 1U
#define CHRONY_IOC_READ 2U
#elif defined(__alpha__) || defined(__sparc__) || defined(__ppc__) || defined(__ppc64__) || defined(__sparc64__)
#define CHRONY_IOC_NRBITS 8
#define CHRONY_IOC_TYPEBITS 8
#define CHRONY_IOC_SIZEBITS 13
#define CHRONY_IOC_DIRBITS 2
#define CHRONY_IOC_NONE 1U
#define CHRONY_IOC_READ 2U
#define CHRONY_IOC_WRITE 4U
#elif defined(__mips__) || defined(__mips32__) || defined(__powerpc__)
#define CHRONY_IOC_NRBITS 8
#define CHRONY_IOC_TYPEBITS 8
#define CHRONY_IOC_SIZEBITS 13
#define CHRONY_IOC_DIRBITS 3
#define CHRONY_IOC_NONE 1U
#define CHRONY_IOC_READ 2U
#define CHRONY_IOC_WRITE 4U
#else
#error "I don't know the values of the _IOC_* constants for your architecture"
#endif
#define CHRONY_IOC_NRMASK ((1 << CHRONY_IOC_NRBITS)-1)
#define CHRONY_IOC_TYPEMASK ((1 << CHRONY_IOC_TYPEBITS)-1)
#define CHRONY_IOC_SIZEMASK ((1 << CHRONY_IOC_SIZEBITS)-1)
#define CHRONY_IOC_DIRMASK ((1 << CHRONY_IOC_DIRBITS)-1)
#define CHRONY_IOC_NRSHIFT 0
#define CHRONY_IOC_TYPESHIFT (CHRONY_IOC_NRSHIFT+CHRONY_IOC_NRBITS)
#define CHRONY_IOC_SIZESHIFT (CHRONY_IOC_TYPESHIFT+CHRONY_IOC_TYPEBITS)
#define CHRONY_IOC_DIRSHIFT (CHRONY_IOC_SIZESHIFT+CHRONY_IOC_SIZEBITS)
#define CHRONY_IOC(dir,type,nr,size) \
(((dir) << CHRONY_IOC_DIRSHIFT) | \
((type) << CHRONY_IOC_TYPESHIFT) | \
((nr) << CHRONY_IOC_NRSHIFT) | \
((size) << CHRONY_IOC_SIZESHIFT))
/* used to create numbers */
#define CHRONY_IO(type,nr) CHRONY_IOC(CHRONY_IOC_NONE,(type),(nr),0)
#define CHRONY_IOR(type,nr,size) CHRONY_IOC(CHRONY_IOC_READ,(type),(nr),sizeof(size))
#define CHRONY_IOW(type,nr,size) CHRONY_IOC(CHRONY_IOC_WRITE,(type),(nr),sizeof(size))
#define CHRONY_IOWR(type,nr,size) CHRONY_IOC(CHRONY_IOC_READ|CHRONY_IOC_WRITE,(type),(nr),sizeof(size))
#define RTC_UIE_ON CHRONY_IO('p', 0x03) /* Update int. enable on */
#define RTC_UIE_OFF CHRONY_IO('p', 0x04) /* ... off */
#define RTC_RD_TIME CHRONY_IOR('p', 0x09, struct rtc_time) /* Read RTC time */
#define RTC_SET_TIME CHRONY_IOW('p', 0x0a, struct rtc_time) /* Set RTC time */
/* From mc146818.h */
#define RTC_UIE 0x10 /* update-finished interrupt enable */
#endif

View File

@@ -103,12 +103,11 @@ static double max_clock_error;
static void static void
calculate_sys_precision(void) calculate_sys_precision(void)
{ {
struct timeval tv, old_tv, first_tv; struct timeval tv, old_tv;
int dusec, best_dusec; int dusec, best_dusec;
int iters; int iters;
gettimeofday(&old_tv, NULL); gettimeofday(&old_tv, NULL);
first_tv = old_tv;
best_dusec = 1000000; /* Assume we must be better than a second */ best_dusec = 1000000; /* Assume we must be better than a second */
iters = 0; iters = 0;
do { do {

View File

@@ -30,7 +30,6 @@
#include "main.h" #include "main.h"
#include "conf.h" #include "conf.h"
#include "logging.h" #include "logging.h"
#include "version.h"
#include "mkdirpp.h" #include "mkdirpp.h"
#include "util.h" #include "util.h"
@@ -190,7 +189,6 @@ LOG_OpenSystemLog(void)
#else #else
system_log = 1; system_log = 1;
openlog("chronyd", LOG_PID, LOG_DAEMON); openlog("chronyd", LOG_PID, LOG_DAEMON);
LOG(LOGS_INFO, LOGF_Logging, "chronyd version %s starting", PROGRAM_VERSION_STRING);
#endif #endif
} }

5
main.c
View File

@@ -114,7 +114,6 @@ MAI_CleanupAndExit(void)
static void static void
signal_cleanup(int x) signal_cleanup(int x)
{ {
LOG(LOGS_WARN, LOGF_Main, "chronyd exiting on signal");
if (!initialised) exit(0); if (!initialised) exit(0);
SCH_QuitProgram(); SCH_QuitProgram();
} }
@@ -321,6 +320,8 @@ int main
LOG_OpenSystemLog(); LOG_OpenSystemLog();
} }
LOG(LOGS_INFO, LOGF_Main, "chronyd version %s starting", PROGRAM_VERSION_STRING);
/* Check whether another chronyd may already be running. Do this after /* Check whether another chronyd may already be running. Do this after
* forking, so that message logging goes to the right place (i.e. syslog), in * forking, so that message logging goes to the right place (i.e. syslog), in
* case this chronyd is being run from a boot script. */ * case this chronyd is being run from a boot script. */
@@ -397,6 +398,8 @@ int main
the scheduler. */ the scheduler. */
SCH_MainLoop(); SCH_MainLoop();
LOG(LOGS_INFO, LOGF_Main, "chronyd exiting");
MAI_CleanupAndExit(); MAI_CleanupAndExit();
return 0; return 0;

View File

@@ -56,7 +56,11 @@ DNS_Name2IPAddress(const char *name, IPAddr *addr)
result = getaddrinfo(name, NULL, &hints, &res); result = getaddrinfo(name, NULL, &hints, &res);
if (result) { if (result) {
#ifdef FORCE_DNSRETRY
return DNS_TryAgain;
#else
return result == EAI_AGAIN ? DNS_TryAgain : DNS_Failure; return result == EAI_AGAIN ? DNS_TryAgain : DNS_Failure;
#endif
} }
for (ai = res; !result && ai != NULL; ai = ai->ai_next) { for (ai = res; !result && ai != NULL; ai = ai->ai_next) {
@@ -94,8 +98,13 @@ DNS_Name2IPAddress(const char *name, IPAddr *addr)
return DNS_Success; return DNS_Success;
} }
#ifdef FORCE_DNSRETRY
return DNS_TryAgain;
#else
return DNS_Failure; return DNS_Failure;
#endif #endif
#endif
} }
/* ================================================== */ /* ================================================== */

View File

@@ -1661,6 +1661,8 @@ NCR_SlewTimes(NCR_Instance inst, struct timeval *when, double dfreq, double doff
#ifdef TRACEON #ifdef TRACEON
LOG(LOGS_INFO, LOGF_NtpCore, "tx prev=[%s] new=[%s]", LOG(LOGS_INFO, LOGF_NtpCore, "tx prev=[%s] new=[%s]",
UTI_TimevalToString(&prev), UTI_TimevalToString(&inst->local_tx)); UTI_TimevalToString(&prev), UTI_TimevalToString(&inst->local_tx));
#else
(void)prev;
#endif #endif
} }

View File

@@ -147,6 +147,8 @@ PKL_CommandLength(CMD_Request *r)
return offsetof(CMD_Request, data.activity.EOR); return offsetof(CMD_Request, data.activity.EOR);
case REQ_RESELECT: case REQ_RESELECT:
return offsetof(CMD_Request, data.reselect.EOR); return offsetof(CMD_Request, data.reselect.EOR);
case REQ_RESELECTDISTANCE:
return offsetof(CMD_Request, data.reselect_distance.EOR);
case REQ_MODIFY_MINSTRATUM: case REQ_MODIFY_MINSTRATUM:
return offsetof(CMD_Request, data.modify_minstratum.EOR); return offsetof(CMD_Request, data.modify_minstratum.EOR);
case REQ_MODIFY_POLLTARGET: case REQ_MODIFY_POLLTARGET:

View File

@@ -825,8 +825,8 @@ filter_get_sample(struct MedianFilter *filter, struct timeval *sample_time, doub
prev_avg_var = filter->avg_var; prev_avg_var = filter->avg_var;
/* update exponential moving average of the variance */ /* update exponential moving average of the variance */
if (filter->avg_var_n > 100) { if (filter->avg_var_n > 50) {
filter->avg_var += dof / (dof + 100.0) * (var - filter->avg_var); filter->avg_var += dof / (dof + 50.0) * (var - filter->avg_var);
} else { } else {
filter->avg_var = (filter->avg_var * filter->avg_var_n + var * dof) / filter->avg_var = (filter->avg_var * filter->avg_var_n + var * dof) /
(dof + filter->avg_var_n); (dof + filter->avg_var_n);
@@ -867,6 +867,8 @@ filter_slew_samples(struct MedianFilter *filter, struct timeval *when, double df
#if 0 #if 0
LOG(LOGS_INFO, LOGF_Refclock, "i=%d old_off=%.9f new_off=%.9f", LOG(LOGS_INFO, LOGF_Refclock, "i=%d old_off=%.9f new_off=%.9f",
i, prev_offset, filter->samples[i].offset); i, prev_offset, filter->samples[i].offset);
#else
(void)prev_offset;
#endif #endif
} }
} }

View File

@@ -138,6 +138,7 @@ REF_Initialise(void)
/* We have read valid data */ /* We have read valid data */
our_frequency_ppm = file_freq_ppm; our_frequency_ppm = file_freq_ppm;
our_skew = 1.0e-6 * file_skew_ppm; our_skew = 1.0e-6 * file_skew_ppm;
LOG(LOGS_INFO, LOGF_Reference, "Frequency %.3f +- %.3f ppm read from %s", file_freq_ppm, file_skew_ppm, drift_file);
} else { } else {
LOG(LOGS_WARN, LOGF_Reference, "Could not parse valid frequency and skew from driftfile %s", LOG(LOGS_WARN, LOGF_Reference, "Could not parse valid frequency and skew from driftfile %s",
drift_file); drift_file);
@@ -147,9 +148,6 @@ REF_Initialise(void)
drift_file); drift_file);
} }
fclose(in); fclose(in);
} else {
LOG(LOGS_WARN, LOGF_Reference, "Could not open driftfile %s for reading",
drift_file);
} }
drift_file_age = 0.0; drift_file_age = 0.0;
@@ -365,7 +363,7 @@ schedule_fb_drift(struct timeval *now)
UTI_DiffTimevalsToDouble(&unsynchronised, now, &last_ref_update); UTI_DiffTimevalsToDouble(&unsynchronised, now, &last_ref_update);
for (c = 0, i = fb_drift_min; i <= fb_drift_max; i++) { for (c = secs = 0, i = fb_drift_min; i <= fb_drift_max; i++) {
secs = 1 << i; secs = 1 << i;
if (fb_drifts[i - fb_drift_min].secs < secs) if (fb_drifts[i - fb_drift_min].secs < secs)
@@ -532,10 +530,10 @@ REF_SetReference(int stratum,
double delta_freq1, delta_freq2; double delta_freq1, delta_freq2;
double skew1, skew2; double skew1, skew2;
double our_frequency; double our_frequency;
double abs_freq_ppm; double abs_freq_ppm;
double update_interval; double update_interval;
double elapsed;
struct timeval now;
assert(initialised); assert(initialised);
@@ -572,10 +570,13 @@ REF_SetReference(int stratum,
else else
our_ref_ip.family = IPADDR_UNSPEC; our_ref_ip.family = IPADDR_UNSPEC;
our_ref_time = *ref_time; our_ref_time = *ref_time;
our_offset = offset;
our_root_delay = root_delay; our_root_delay = root_delay;
our_root_dispersion = root_dispersion; our_root_dispersion = root_dispersion;
LCL_ReadCookedTime(&now, NULL);
UTI_DiffTimevalsToDouble(&elapsed, &now, ref_time);
our_offset = offset + elapsed * frequency;
update_leap_status(leap); update_leap_status(leap);
/* Eliminate updates that are based on totally unreliable frequency /* Eliminate updates that are based on totally unreliable frequency
@@ -629,14 +630,14 @@ REF_SetReference(int stratum,
abs_freq_ppm = LCL_ReadAbsoluteFrequency(); abs_freq_ppm = LCL_ReadAbsoluteFrequency();
write_log(ref_time, write_log(&now,
our_ref_ip.family != IPADDR_UNSPEC ? UTI_IPToString(&our_ref_ip) : UTI_RefidToString(our_ref_id), our_ref_ip.family != IPADDR_UNSPEC ? UTI_IPToString(&our_ref_ip) : UTI_RefidToString(our_ref_id),
our_stratum, our_stratum,
abs_freq_ppm, abs_freq_ppm,
1.0e6*our_skew, 1.0e6*our_skew,
our_offset); our_offset);
UTI_DiffTimevalsToDouble(&update_interval, ref_time, &last_ref_update); UTI_DiffTimevalsToDouble(&update_interval, &now, &last_ref_update);
if (drift_file) { if (drift_file) {
/* Update drift file at most once per hour */ /* Update drift file at most once per hour */
@@ -652,7 +653,7 @@ REF_SetReference(int stratum,
update_fb_drifts(abs_freq_ppm, update_interval); update_fb_drifts(abs_freq_ppm, update_interval);
} }
last_ref_update = *ref_time; last_ref_update = now;
last_ref_update_interval = update_interval; last_ref_update_interval = update_interval;
/* And now set the freq and offset to zero */ /* And now set the freq and offset to zero */

View File

@@ -298,6 +298,10 @@ RGR_FindBestRegression
nruns = n_runs_from_residuals(resid, n - resid_start); nruns = n_runs_from_residuals(resid, n - resid_start);
if (nruns > critical_runs[n - resid_start] || n - start <= MIN_SAMPLES_FOR_REGRESS) { if (nruns > critical_runs[n - resid_start] || n - start <= MIN_SAMPLES_FOR_REGRESS) {
if (resid_start < 0) {
/* Ignore extra samples in returned nruns */
nruns = n_runs_from_residuals(resid - resid_start, n);
}
break; break;
} else { } else {
/* Try dropping one sample at a time until the runs test passes. */ /* Try dropping one sample at a time until the runs test passes. */

View File

@@ -45,6 +45,7 @@
#include <errno.h> #include <errno.h>
#include <assert.h> #include <assert.h>
#include <string.h> #include <string.h>
#include <linux/rtc.h>
#include "logging.h" #include "logging.h"
#include "sched.h" #include "sched.h"
@@ -54,22 +55,9 @@
#include "regress.h" #include "regress.h"
#include "rtc.h" #include "rtc.h"
#include "rtc_linux.h" #include "rtc_linux.h"
#include "io_linux.h"
#include "conf.h" #include "conf.h"
#include "memory.h" #include "memory.h"
struct rtc_time {
int tm_sec;
int tm_min;
int tm_hour;
int tm_mday;
int tm_mon;
int tm_year;
int tm_wday;
int tm_yday;
int tm_isdst;
};
/* ================================================== */ /* ================================================== */
/* Forward prototypes */ /* Forward prototypes */
@@ -244,14 +232,12 @@ run_regression(int new_sample,
{ {
double rtc_rel[MAX_SAMPLES]; /* Relative times on RTC axis */ double rtc_rel[MAX_SAMPLES]; /* Relative times on RTC axis */
double offsets[MAX_SAMPLES]; /* How much the RTC is fast of the system clock */ double offsets[MAX_SAMPLES]; /* How much the RTC is fast of the system clock */
int i, n; int i;
double est_intercept, est_slope; double est_intercept, est_slope;
int best_new_start; int best_new_start;
if (n_samples > 0) { if (n_samples > 0) {
n = n_samples - 1;
for (i=0; i<n_samples; i++) { for (i=0; i<n_samples; i++) {
rtc_rel[i] = rtc_trim[i] + (double)(rtc_sec[i] - rtc_ref); rtc_rel[i] = rtc_trim[i] + (double)(rtc_sec[i] - rtc_ref);
offsets[i] = ((double) (rtc_ref - system_times[i].tv_sec) - offsets[i] = ((double) (rtc_ref - system_times[i].tv_sec) -
@@ -319,6 +305,8 @@ slew_samples
dfreq, doffset, dfreq, doffset,
old_seconds_fast, 1.0e6 * old_gain_rate, old_seconds_fast, 1.0e6 * old_gain_rate,
coef_seconds_fast, 1.0e6 * coef_gain_rate); coef_seconds_fast, 1.0e6 * coef_gain_rate);
#else
(void)old_seconds_fast; (void)old_gain_rate;
#endif #endif
} }
@@ -681,6 +669,9 @@ set_rtc(time_t new_rtc_time)
rtc_raw.tm_mday = rtc_tm.tm_mday; rtc_raw.tm_mday = rtc_tm.tm_mday;
rtc_raw.tm_mon = rtc_tm.tm_mon; rtc_raw.tm_mon = rtc_tm.tm_mon;
rtc_raw.tm_year = rtc_tm.tm_year; rtc_raw.tm_year = rtc_tm.tm_year;
rtc_raw.tm_wday = rtc_tm.tm_wday;
rtc_raw.tm_yday = rtc_tm.tm_yday;
rtc_raw.tm_isdst = rtc_tm.tm_isdst;
status = ioctl(fd, RTC_SET_TIME, &rtc_raw); status = ioctl(fd, RTC_SET_TIME, &rtc_raw);
if (status < 0) { if (status < 0) {
@@ -846,7 +837,7 @@ read_from_device(void *any)
return; return;
} }
if ((data & RTC_UIE) == RTC_UIE) { if ((data & RTC_UF) == RTC_UF) {
/* Update interrupt detected */ /* Update interrupt detected */
/* Read RTC time, sandwiched between two polls of the system clock /* Read RTC time, sandwiched between two polls of the system clock

View File

@@ -368,8 +368,12 @@ SRC_UpdateReachability(SRC_Instance inst, int reachable)
void void
SRC_ResetReachability(SRC_Instance inst) SRC_ResetReachability(SRC_Instance inst)
{ {
/* This should be disabled until source selection is modified to keep
a peer selected even when not reachable */
#if 0
inst->reachability = 0; inst->reachability = 0;
SRC_UpdateReachability(inst, 0); SRC_UpdateReachability(inst, 0);
#endif
} }
/* ================================================== */ /* ================================================== */
@@ -420,9 +424,9 @@ void
SRC_SelectSource(unsigned long match_addr) SRC_SelectSource(unsigned long match_addr)
{ {
int i, j, index, old_selected_index; int i, j, index, old_selected_index;
struct timeval now; struct timeval now, ref_time;
double src_offset, src_offset_sd, src_frequency, src_skew; double src_offset, src_offset_sd, src_frequency, src_skew;
double src_accrued_dispersion; double src_root_delay, src_root_dispersion;
int n_endpoints, j1, j2; int n_endpoints, j1, j2;
double best_lo, best_hi; double best_lo, best_hi;
int depth, best_depth; int depth, best_depth;
@@ -430,7 +434,6 @@ SRC_SelectSource(unsigned long match_addr)
double distance, sel_src_distance; double distance, sel_src_distance;
int stratum, min_stratum; int stratum, min_stratum;
struct SelectInfo *si; struct SelectInfo *si;
double total_root_dispersion;
int n_badstats_sources; int n_badstats_sources;
int max_sel_reach, max_badstat_reach; int max_sel_reach, max_badstat_reach;
int max_score_index; int max_score_index;
@@ -842,25 +845,20 @@ SRC_SelectSource(unsigned long match_addr)
/* Now just use the statistics of the selected source for /* Now just use the statistics of the selected source for
trimming the local clock */ trimming the local clock */
LCL_ReadCookedTime(&now, NULL); SST_GetTrackingData(sources[selected_source_index]->stats, &ref_time,
SST_GetTrackingData(sources[selected_source_index]->stats, &now,
&src_offset, &src_offset_sd, &src_offset, &src_offset_sd,
&src_accrued_dispersion, &src_frequency, &src_skew,
&src_frequency, &src_skew); &src_root_delay, &src_root_dispersion);
total_root_dispersion = (src_accrued_dispersion +
sources[selected_source_index]->sel_info.root_dispersion);
REF_SetReference(min_stratum, leap_status, REF_SetReference(min_stratum, leap_status,
sources[selected_source_index]->ref_id, sources[selected_source_index]->ref_id,
sources[selected_source_index]->ip_addr, sources[selected_source_index]->ip_addr,
&now, &ref_time,
src_offset, src_offset,
src_frequency, src_frequency,
src_skew, src_skew,
sources[selected_source_index]->sel_info.root_delay, src_root_delay,
total_root_dispersion); src_root_dispersion);
} }
} else { } else {
@@ -897,6 +895,17 @@ SRC_ReselectSource(void)
/* ================================================== */ /* ================================================== */
void
SRC_SetReselectDistance(double distance)
{
if (reselect_distance != distance) {
reselect_distance = distance;
LOG(LOGS_INFO, LOGF_Sources, "New reselect distance %f", distance);
}
}
/* ================================================== */
double double
SRC_PredictOffset(SRC_Instance inst, struct timeval *when) SRC_PredictOffset(SRC_Instance inst, struct timeval *when)
{ {
@@ -1083,6 +1092,7 @@ SRC_ReportSource(int index, RPT_SourceReport *report, struct timeval *now)
case SRC_JITTERY: case SRC_JITTERY:
report->state = RPT_JITTERY; report->state = RPT_JITTERY;
break; break;
case SRC_OK:
case SRC_BAD_STATS: case SRC_BAD_STATS:
case SRC_UNREACHABLE: case SRC_UNREACHABLE:
report->state = RPT_UNREACH; report->state = RPT_UNREACH;

View File

@@ -140,6 +140,9 @@ extern void SRC_SelectSource(unsigned long match_addr);
/* Force reselecting the best source */ /* Force reselecting the best source */
extern void SRC_ReselectSource(void); extern void SRC_ReselectSource(void);
/* Set reselect distance */
extern void SRC_SetReselectDistance(double distance);
/* Predict the offset of the local clock relative to a given source at /* Predict the offset of the local clock relative to a given source at
a given local cooked time. Positive indicates local clock is FAST a given local cooked time. Positive indicates local clock is FAST
relative to reference. */ relative to reference. */

View File

@@ -384,7 +384,7 @@ SST_DoNewRegression(SST_Stats inst)
int best_start, times_back_start; int best_start, times_back_start;
double est_intercept, est_slope, est_var, est_intercept_sd, est_slope_sd; double est_intercept, est_slope, est_var, est_intercept_sd, est_slope_sd;
int i, j, nruns; int i, j, nruns;
double min_distance; double min_distance, mean_distance;
double sd_weight, sd; double sd_weight, sd;
double old_skew, old_freq, stress; double old_skew, old_freq, stress;
@@ -395,17 +395,19 @@ SST_DoNewRegression(SST_Stats inst)
offsets[i + inst->runs_samples] = inst->offsets[get_runsbuf_index(inst, i)]; offsets[i + inst->runs_samples] = inst->offsets[get_runsbuf_index(inst, i)];
} }
for (i = 0, min_distance = DBL_MAX; i < inst->n_samples; i++) { for (i = 0, mean_distance = 0.0, min_distance = DBL_MAX; i < inst->n_samples; i++) {
j = get_buf_index(inst, i); j = get_buf_index(inst, i);
peer_distances[i] = 0.5 * inst->peer_delays[j] + inst->peer_dispersions[j]; peer_distances[i] = 0.5 * inst->peer_delays[j] + inst->peer_dispersions[j];
mean_distance += peer_distances[i];
if (peer_distances[i] < min_distance) { if (peer_distances[i] < min_distance) {
min_distance = peer_distances[i]; min_distance = peer_distances[i];
} }
} }
mean_distance /= inst->n_samples;
/* And now, work out the weight vector */ /* And now, work out the weight vector */
sd = sqrt(inst->variance); sd = mean_distance - min_distance;
if (sd > min_distance || sd <= 0.0) if (sd > min_distance || sd <= 0.0)
sd = min_distance; sd = min_distance;
@@ -572,6 +574,8 @@ SST_GetSelectionData(SST_Stats inst, struct timeval *now,
LOG(LOGS_INFO, LOGF_SourceStats, "n=%d off=%f del=%f dis=%f var=%f pdist=%f avoff=%f avok=%d selok=%d", LOG(LOGS_INFO, LOGF_SourceStats, "n=%d off=%f del=%f dis=%f var=%f pdist=%f avoff=%f avok=%d selok=%d",
inst->n_samples, *best_offset, *best_root_delay, *best_root_dispersion, *variance, inst->n_samples, *best_offset, *best_root_delay, *best_root_dispersion, *variance,
peer_distance, average_offset, average_ok, *select_ok); peer_distance, average_offset, average_ok, *select_ok);
#else
(void)average_ok;
#endif #endif
return; return;
@@ -580,32 +584,30 @@ SST_GetSelectionData(SST_Stats inst, struct timeval *now,
/* ================================================== */ /* ================================================== */
void void
SST_GetTrackingData(SST_Stats inst, struct timeval *now, SST_GetTrackingData(SST_Stats inst, struct timeval *ref_time,
double *average_offset, double *offset_sd, double *average_offset, double *offset_sd,
double *accrued_dispersion, double *frequency, double *skew,
double *frequency, double *skew) double *root_delay, double *root_dispersion)
{ {
int i, j; int i, j;
double peer_distance; double elapsed_sample;
double elapsed_offset, elapsed_sample;
i = get_runsbuf_index(inst, inst->best_single_sample); i = get_runsbuf_index(inst, inst->best_single_sample);
j = get_buf_index(inst, inst->best_single_sample); j = get_buf_index(inst, inst->best_single_sample);
*ref_time = inst->offset_time;
*average_offset = inst->estimated_offset;
*offset_sd = inst->estimated_offset_sd;
*frequency = inst->estimated_frequency; *frequency = inst->estimated_frequency;
*skew = inst->skew; *skew = inst->skew;
*root_delay = inst->root_delays[j];
peer_distance = inst->peer_dispersions[j] + 0.5 * inst->peer_delays[j]; UTI_DiffTimevalsToDouble(&elapsed_sample, &inst->offset_time, &inst->sample_times[i]);
UTI_DiffTimevalsToDouble(&elapsed_offset, now, &(inst->offset_time)); *root_dispersion = inst->root_dispersions[j] + inst->skew * elapsed_sample;
*average_offset = inst->estimated_offset + inst->estimated_frequency * elapsed_offset;
*offset_sd = inst->estimated_offset_sd + elapsed_offset * inst->skew;
UTI_DiffTimevalsToDouble(&elapsed_sample, now, &inst->sample_times[i]);
*accrued_dispersion = inst->skew * elapsed_sample;
#ifdef TRACEON #ifdef TRACEON
LOG(LOGS_INFO, LOGF_SourceStats, "n=%d freq=%f (%.3fppm) skew=%f (%.3fppm) pdist=%f avoff=%f offsd=%f accrdis=%f", LOG(LOGS_INFO, LOGF_SourceStats, "n=%d freq=%f (%.3fppm) skew=%f (%.3fppm) avoff=%f offsd=%f disp=%f",
inst->n_samples, *frequency, 1.0e6* *frequency, *skew, 1.0e6* *skew, peer_distance, *average_offset, *offset_sd, *accrued_dispersion); inst->n_samples, *frequency, 1.0e6* *frequency, *skew, 1.0e6* *skew, *average_offset, *offset_sd, *root_dispersion);
#endif #endif
} }
@@ -620,6 +622,9 @@ SST_SlewSamples(SST_Stats inst, struct timeval *when, double dfreq, double doffs
struct timeval *sample, prev; struct timeval *sample, prev;
double prev_offset, prev_freq; double prev_offset, prev_freq;
if (!inst->n_samples)
return;
for (m = -inst->runs_samples; m < inst->n_samples; m++) { for (m = -inst->runs_samples; m < inst->n_samples; m++) {
i = get_runsbuf_index(inst, m); i = get_runsbuf_index(inst, m);
sample = &(inst->sample_times[i]); sample = &(inst->sample_times[i]);
@@ -631,6 +636,8 @@ SST_SlewSamples(SST_Stats inst, struct timeval *when, double dfreq, double doffs
LOG(LOGS_INFO, LOGF_SourceStats, "i=%d old_st=[%s] new_st=[%s] old_off=%f new_off=%f", LOG(LOGS_INFO, LOGF_SourceStats, "i=%d old_st=[%s] new_st=[%s] old_off=%f new_off=%f",
i, UTI_TimevalToString(&prev), UTI_TimevalToString(sample), i, UTI_TimevalToString(&prev), UTI_TimevalToString(sample),
prev_offset, inst->offsets[i]); prev_offset, inst->offsets[i]);
#else
(void)prev_offset;
#endif #endif
} }
@@ -648,6 +655,8 @@ SST_SlewSamples(SST_Stats inst, struct timeval *when, double dfreq, double doffs
UTI_TimevalToString(&prev), UTI_TimevalToString(&(inst->offset_time)), UTI_TimevalToString(&prev), UTI_TimevalToString(&(inst->offset_time)),
prev_offset, inst->estimated_offset, prev_offset, inst->estimated_offset,
1.0e6*prev_freq, 1.0e6*inst->estimated_frequency); 1.0e6*prev_freq, 1.0e6*inst->estimated_frequency);
#else
(void)prev; (void)prev_freq;
#endif #endif
return; return;

View File

@@ -89,10 +89,10 @@ SST_GetSelectionData(SST_Stats inst, struct timeval *now,
/* Get data needed when setting up tracking on this source */ /* Get data needed when setting up tracking on this source */
extern void extern void
SST_GetTrackingData(SST_Stats inst, struct timeval *now, SST_GetTrackingData(SST_Stats inst, struct timeval *ref_time,
double *average_offset, double *offset_sd, double *average_offset, double *offset_sd,
double *accrued_dispersion, double *frequency, double *skew,
double *frequency, double *skew); double *root_delay, double *root_dispersion);
/* Get parameters for using this source as the reference */ /* Get parameters for using this source as the reference */
extern void extern void

View File

@@ -493,14 +493,22 @@ initiate_slew(void)
max_allowed_tick = nominal_tick + max_tick_bias; max_allowed_tick = nominal_tick + max_tick_bias;
if (offset_register > 0) { if (offset_register > 0) {
if (current_tick <= min_allowed_tick) {
return;
}
slewing_tick = current_tick - slew_delta_tick; slewing_tick = current_tick - slew_delta_tick;
if (slewing_tick <= min_allowed_tick) { if (slewing_tick < min_allowed_tick) {
slewing_tick = min_allowed_tick + 1; slewing_tick = min_allowed_tick;
} }
} else { } else {
if (current_tick >= max_allowed_tick) {
return;
}
slewing_tick = current_tick + slew_delta_tick; slewing_tick = current_tick + slew_delta_tick;
if (slewing_tick >= max_allowed_tick) { if (slewing_tick > max_allowed_tick) {
slewing_tick = max_allowed_tick - 1; slewing_tick = max_allowed_tick;
} }
} }
@@ -509,6 +517,8 @@ initiate_slew(void)
delta_total_tick = (double) tick_adjust / 1.0e6; delta_total_tick = (double) tick_adjust / 1.0e6;
dseconds = - offset_register * (current_total_tick + delta_total_tick) / delta_total_tick; dseconds = - offset_register * (current_total_tick + delta_total_tick) / delta_total_tick;
assert(dseconds > 0.0);
/* Now set the thing off */ /* Now set the thing off */
if (gettimeofday(&T0, NULL) < 0) { if (gettimeofday(&T0, NULL) < 0) {
LOG_FATAL(LOGF_SysLinux, "gettimeofday() failed"); LOG_FATAL(LOGF_SysLinux, "gettimeofday() failed");
@@ -662,8 +672,8 @@ set_frequency(double freq_ppm)
scaled_freq = -freq_scale * required_freq; scaled_freq = -freq_scale * required_freq;
} }
min_allowed_tick = nominal_tick - max_tick_bias + 5; min_allowed_tick = nominal_tick - max_tick_bias;
max_allowed_tick = nominal_tick + max_tick_bias - 5; max_allowed_tick = nominal_tick + max_tick_bias;
if (required_tick < min_allowed_tick || required_tick > max_allowed_tick) { if (required_tick < min_allowed_tick || required_tick > max_allowed_tick) {
LOG(LOGS_WARN, LOGF_SysLinux, "Required tick %ld outside allowed range (%ld .. %ld)", required_tick, min_allowed_tick, max_allowed_tick); LOG(LOGS_WARN, LOGF_SysLinux, "Required tick %ld outside allowed range (%ld .. %ld)", required_tick, min_allowed_tick, max_allowed_tick);
@@ -895,8 +905,10 @@ get_version_specific_details(void)
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 { } else {
#if 0
LOG(LOGS_INFO, LOGF_SysLinux, "Initial txc.tick=%ld txc.freq=%ld (%.8f) txc.offset=%ld => hz=%d shift_hz=%d", 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); tmx_params.tick, tmx_params.freq, tmx_params.dfreq, tmx_params.offset, hz, shift_hz);
#endif
} }
CNF_GetLinuxHz(&set_config_hz, &config_hz); CNF_GetLinuxHz(&set_config_hz, &config_hz);
@@ -1046,10 +1058,11 @@ get_version_specific_details(void)
/* Override freq_scale if it appears in conf file */ /* Override freq_scale if it appears in conf file */
CNF_GetLinuxFreqScale(&set_config_freq_scale, &config_freq_scale); CNF_GetLinuxFreqScale(&set_config_freq_scale, &config_freq_scale);
calculated_freq_scale = freq_scale; calculated_freq_scale = freq_scale;
if (set_config_freq_scale) freq_scale = config_freq_scale; if (set_config_freq_scale) {
freq_scale = config_freq_scale;
LOG(LOGS_INFO, LOGF_SysLinux, "calculated_freq_scale=%.8f freq_scale=%.8f", LOG(LOGS_INFO, LOGF_SysLinux, "calculated_freq_scale=%.8f freq_scale=%.8f",
calculated_freq_scale, freq_scale); calculated_freq_scale, freq_scale);
}
} }
@@ -1154,7 +1167,9 @@ SYS_Linux_DropRoot(char *user)
cap_free(cap); cap_free(cap);
#if 0
LOG(LOGS_INFO, LOGF_SysLinux, "Privileges dropped to user %s", user); LOG(LOGS_INFO, LOGF_SysLinux, "Privileges dropped to user %s", user);
#endif
} }
#endif #endif
@@ -1183,7 +1198,9 @@ 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
LOG(LOGS_INFO, LOGF_SysLinux, "Enabled SCHED_FIFO with priority %d", sched.sched_priority); LOG(LOGS_INFO, LOGF_SysLinux, "Enabled SCHED_FIFO with priority %d", sched.sched_priority);
#endif
} }
} }
} }
@@ -1207,7 +1224,9 @@ void SYS_Linux_MemLockAll(int LockAll)
LOG(LOGS_ERR, LOGF_SysLinux, "mlockall() failed"); LOG(LOGS_ERR, LOGF_SysLinux, "mlockall() failed");
} }
else { else {
#if 0
LOG(LOGS_INFO, LOGF_SysLinux, "Successfully locked into RAM"); LOG(LOGS_INFO, LOGF_SysLinux, "Successfully locked into RAM");
#endif
} }
} }
} }