Add makestep directive

This commit is contained in:
Miroslav Lichvar 2010-01-25 15:33:56 +01:00
parent 15e154c09d
commit 8a00758cf5
7 changed files with 89 additions and 10 deletions

View file

@ -1184,6 +1184,7 @@ directives can occur in any order in the file.
* logchange directive:: Generate syslog messages if large offsets occur
* logdir directive:: Specify directory for logging
* mailonchange directive:: Send email if a clock correction above a threshold occurs
* makestep directive:: Step system clock if large correction is needed
* manual directive:: Allow manual entry using chronyc's settime cmd.
* maxupdateskew directive:: Stop bad estimates upsetting machine clock
* noclientlog directive:: Prevent chronyd from gathering data about clients
@ -2085,6 +2086,32 @@ mailonchange root@@localhost 0.5
This would send a mail message to root if a change of more than 0.5
seconds were applied to the system clock.
@c }}}
@c {{{ makestep
@node makestep directive
@subsection makestep
Normally chronyd will cause the system to gradually correct any time
offset, by slowing down or speeding up the clock as required. In
certain situations, the system clock may be so far adrift that this
slewing process would take a very long time to correct the system clock.
This directive forces @code{chronyd} to step system clock if the
adjustment is larger than a threshold value, but only if there were no
more clock updates since @code{chronyd} was started than a specified
limit (a negative value can be used to disable the limit).
This is particularly useful when using reference clocks, because the
@code{initstepslew} directive (@pxref{initstepslew directive}) works
only with NTP sources.
An example of the use of this directive is
@example
makestep 1000 10
@end example
This would step system clock if the adjustment is larger than 1000
seconds, but only in the first ten clock updates.
@c }}}
@c {{{ manual
@node manual directive
@subsection manual
@ -3075,6 +3102,10 @@ clock by the equivalent amount, making it correct immediately.
BE WARNED - certain software will be seriously affected by such jumps to
the system time. (That is the reason why chronyd uses slewing
normally.)
The @code{makestep} directive in the configuration file can be used
to step the clock automatically when the adjustment is larger than a
specified threshold, see @ref{makestep directive}.
@c }}}
@c {{{ manual
@node manual command

View file

@ -1676,13 +1676,8 @@ handle_manual_delete(CMD_Request *rx_message, CMD_Reply *tx_message)
static void
handle_make_step(CMD_Request *rx_message, CMD_Reply *tx_message)
{
int status;
status = LCL_MakeStep();
if (status) {
tx_message->status = htons(STT_SUCCESS);
} else {
tx_message->status = htons(STT_NOTENABLED);
}
LCL_MakeStep(0.0);
tx_message->status = htons(STT_SUCCESS);
return;
}

28
conf.c
View file

@ -92,6 +92,7 @@ static void parse_cmdport(const char *);
static void parse_rtconutc(const char *);
static void parse_noclientlog(const char *);
static void parse_clientloglimit(const char *);
static void parse_makestep(const char *);
static void parse_logchange(const char *);
static void parse_mailonchange(const char *);
static void parse_bindaddress(const char *);
@ -146,6 +147,10 @@ static int enable_manual=0;
incl. daylight saving). */
static int rtc_on_utc = 0;
/* Limit and threshold for clock stepping */
static int make_step_limit = 0;
static double make_step_threshold = 0.0;
/* Flag set if we should log to syslog when a time adjustment
exceeding the threshold is initiated */
static int do_log_change = 0;
@ -220,6 +225,7 @@ static const Command commands[] = {
{"rtconutc", 8, parse_rtconutc},
{"noclientlog", 11, parse_noclientlog},
{"clientloglimit", 14, parse_clientloglimit},
{"makestep", 8, parse_makestep},
{"logchange", 9, parse_logchange},
{"mailonchange", 12, parse_mailonchange},
{"bindaddress", 11, parse_bindaddress},
@ -788,6 +794,19 @@ parse_clientloglimit(const char *line)
/* ================================================== */
static void
parse_makestep(const char *line)
{
if (sscanf(line, "%lf %d", &make_step_threshold, &make_step_limit) != 2) {
make_step_limit = 0;
LOG(LOGS_WARN, LOGF_Configure,
"Could not read threshold or update limit for stepping clock at line %d\n",
line_number);
}
}
/* ================================================== */
static void
parse_logchange(const char *line)
{
@ -1319,6 +1338,15 @@ CNF_GetRTCOnUTC(void)
/* ================================================== */
void
CNF_GetMakeStep(int *limit, double *threshold)
{
*limit = make_step_limit;
*threshold = make_step_threshold;
}
/* ================================================== */
void
CNF_GetLogChange(int *enabled, double *threshold)
{

1
conf.h
View file

@ -60,6 +60,7 @@ extern int CNF_GetDumpOnExit(void);
extern int CNF_GetManualEnabled(void);
extern int CNF_GetCommandPort(void);
extern int CNF_GetRTCOnUTC(void);
extern void CNF_GetMakeStep(int *limit, double *threshold);
extern void CNF_GetLogChange(int *enabled, double *threshold);
extern void CNF_GetMailOnChange(int *enabled, double *threshold, char **user);
extern int CNF_GetNoClientLog(void);

View file

@ -555,10 +555,10 @@ lcl_RegisterSystemDrivers(lcl_ReadFrequencyDriver read_freq,
/* ================================================== */
/* Look at the current difference between the system time and the NTP
time, and make a step to cancel it. */
time, and make a step to cancel it if it's larger than the threshold. */
int
LCL_MakeStep(void)
LCL_MakeStep(double threshold)
{
struct timeval raw;
double correction;
@ -566,6 +566,9 @@ LCL_MakeStep(void)
LCL_ReadRawTime(&raw);
correction = LCL_GetOffsetCorrection(&raw);
if (fabs(correction) <= threshold)
return 0;
/* Cancel remaining slew and make the step */
LCL_AccumulateOffset(correction);
LCL_ApplyStepOffset(-correction);

View file

@ -179,7 +179,7 @@ extern void LCL_Finalise(void);
/* Routine to convert the outstanding system clock error to a step and
apply it, e.g. if the system clock has ended up an hour wrong due
to a timezone problem. */
extern int LCL_MakeStep(void);
extern int LCL_MakeStep(double threshold);
/* Routine to schedule a leap second. Leap second will be inserted
at the end of the day if argument is positive, deleted if negative,

View file

@ -61,6 +61,10 @@ static double max_update_skew;
/* Flag indicating that we are initialised */
static int initialised = 0;
/* Threshold and update limit for stepping clock */
static int make_step_limit;
static double make_step_threshold;
/* Flag and threshold for logging clock changes to syslog */
static int do_log_change;
static double log_change_threshold;
@ -161,6 +165,7 @@ REF_Initialise(void)
enable_local_stratum = CNF_AllowLocalReference(&local_stratum);
CNF_GetMakeStep(&make_step_limit, &make_step_threshold);
CNF_GetLogChange(&do_log_change, &log_change_threshold);
CNF_GetMailOnChange(&do_mail_change, &mail_change_threshold, &mail_change_user);
@ -318,6 +323,19 @@ maybe_log_offset(double offset)
/* ================================================== */
static void
maybe_make_step()
{
if (make_step_limit == 0) {
return;
} else if (make_step_limit > 0) {
make_step_limit--;
}
LCL_MakeStep(make_step_threshold);
}
/* ================================================== */
static void
update_leap_status(NTP_Leap leap)
{
@ -487,6 +505,8 @@ REF_SetReference(int stratum,
our_residual_freq = frequency;
}
maybe_make_step();
abs_freq_ppm = LCL_ReadAbsoluteFrequency();
write_log(ref_time,
@ -530,6 +550,7 @@ REF_SetManualReference
maybe_log_offset(offset);
LCL_AccumulateFrequencyAndOffset(frequency, offset);
maybe_make_step();
abs_freq_ppm = LCL_ReadAbsoluteFrequency();