Add rtcsync directive

The directive enables the 11 minute kernel mode. It cannot be used
when the normal RTC tracking is enabled.
This commit is contained in:
Miroslav Lichvar 2010-05-14 14:41:11 +02:00
parent 5fb0a9d53b
commit a080d00352
8 changed files with 74 additions and 10 deletions

View file

@ -1197,6 +1197,7 @@ directives can occur in any order in the file.
* rtcdevice directive:: Specify name of enhanced RTC device (if not /dev/rtc)
* rtcfile directive:: Specify the file where real-time clock data is stored
* rtconutc directive:: Specify that the real time clock keeps UTC not local time
* rtcsync directive:: Specify that RTC should be automatically synchronised by kernel
* server directive:: Specify an NTP server
* sched_priority directive:: Require real-time scheduling and specify a priority for it.
* lock_all directive:: Require that chronyd be locked into RAM.
@ -2458,6 +2459,17 @@ If the @code{rtconutc} directive appears, it means the RTC is required
to keep UTC. The directive takes no arguments. It is equivalent to
specifying the @code{-u} switch to the Linux @file{/sbin/clock} program.
@c }}}
@c {{{ rtcsync
@node rtcsync directive
@subsection rtcsync
The @code{rtcsync} directive will enable a kernel mode where the
system time is copied to the real time clock (RTC) every 11 minutes.
This directive is supported only on Linux and cannot be used when the
normal RTC tracking is enabled, i.e. when the @code{rtcfile} directive
is used.
@c }}}
@c {{{ sched_priority
@node sched_priority directive
@subsection sched_priority

View file

@ -36,6 +36,7 @@ struct timex {
};
#define ADJ_FREQUENCY 0x0002 /* frequency offset */
#define ADJ_MAXERROR 0x0004 /* maximum time error */
#define ADJ_STATUS 0x0010 /* clock status */
#define ADJ_TICK 0x4000 /* tick value */
#define ADJ_OFFSET_SINGLESHOT 0x8001 /* old-fashioned adjtime */

21
conf.c
View file

@ -90,6 +90,7 @@ static void parse_cmdallow(const char *);
static void parse_cmddeny(const char *);
static void parse_cmdport(const char *);
static void parse_rtconutc(const char *);
static void parse_rtcsync(const char *);
static void parse_noclientlog(const char *);
static void parse_clientloglimit(const char *);
static void parse_fallbackdrift(const char *);
@ -150,6 +151,9 @@ static int enable_manual=0;
incl. daylight saving). */
static int rtc_on_utc = 0;
/* Flag set if the RTC should be automatically synchronised by kernel */
static int rtc_sync = 0;
/* Limit and threshold for clock stepping */
static int make_step_limit = 0;
static double make_step_threshold = 0.0;
@ -235,6 +239,7 @@ static const Command commands[] = {
{"cmddeny", 7, parse_cmddeny},
{"cmdport", 7, parse_cmdport},
{"rtconutc", 8, parse_rtconutc},
{"rtcsync", 7, parse_rtcsync},
{"noclientlog", 11, parse_noclientlog},
{"clientloglimit", 14, parse_clientloglimit},
{"fallbackdrift", 13, parse_fallbackdrift},
@ -784,6 +789,14 @@ parse_rtconutc(const char *line)
/* ================================================== */
static void
parse_rtcsync(const char *line)
{
rtc_sync = 1;
}
/* ================================================== */
static void
parse_noclientlog(const char *line)
{
@ -1394,6 +1407,14 @@ CNF_GetRTCOnUTC(void)
/* ================================================== */
int
CNF_GetRTCSync(void)
{
return rtc_sync;
}
/* ================================================== */
void
CNF_GetMakeStep(int *limit, double *threshold)
{

1
conf.h
View file

@ -61,6 +61,7 @@ extern int CNF_GetDumpOnExit(void);
extern int CNF_GetManualEnabled(void);
extern int CNF_GetCommandPort(void);
extern int CNF_GetRTCOnUTC(void);
extern int CNF_GetRTCSync(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);

4
rtc.c
View file

@ -86,6 +86,10 @@ RTC_Initialise(void)
file_name = CNF_GetRtcFile();
if (file_name) {
if (CNF_GetRTCSync()) {
LOG_FATAL(LOGF_Rtc, "rtcfile directive cannot be used with rtcsync");
}
if (driver.init) {
if ((driver.init)()) {
ok = 1;

View file

@ -991,6 +991,8 @@ SYS_Linux_Initialise(void)
lcl_RegisterSystemDrivers(read_frequency, set_frequency,
accrue_offset, apply_step_offset,
get_offset_correction, set_leap);
TMX_SetSync(CNF_GetRTCSync());
}
/* ================================================== */

View file

@ -39,8 +39,7 @@
#include "chrony_timex.h"
#include "wrap_adjtimex.h"
/* Save leap status between calls */
static int leap_status = 0;
static int status = 0;
int
TMX_SetTick(long tick)
@ -75,9 +74,16 @@ TMX_SetFrequency(double *freq, long tick)
txc.freq = (long)(*freq * (double)(1 << SHIFT_USEC));
*freq = txc.freq / (double)(1 << SHIFT_USEC);
txc.tick = tick;
txc.status = STA_UNSYNC; /* Prevent any of the FLL/PLL stuff coming
up */
txc.status |= leap_status; /* Preserve leap bits */
/* Prevent any of the FLL/PLL stuff coming up */
txc.status = status;
if (!(status & STA_UNSYNC)) {
/* maxerror has to be reset periodically to prevent kernel
from enabling UNSYNC flag */
txc.modes |= ADJ_MAXERROR;
txc.maxerror = 0;
}
return adjtimex(&txc);
}
@ -165,16 +171,32 @@ TMX_SetLeap(int leap)
{
struct timex txc;
status &= ~(STA_INS | STA_DEL);
if (leap > 0) {
leap_status = STA_INS;
status |= STA_INS;
} else if (leap < 0) {
leap_status = STA_DEL;
} else {
leap_status = 0;
status |= STA_DEL;
}
txc.modes = ADJ_STATUS;
txc.status = STA_UNSYNC | leap_status;
txc.status = status;
return adjtimex(&txc);
}
int TMX_SetSync(int sync)
{
struct timex txc;
if (sync) {
status &= ~STA_UNSYNC;
} else {
status |= STA_UNSYNC;
}
txc.modes = ADJ_STATUS;
txc.status = status;
return adjtimex(&txc);
}

View file

@ -76,6 +76,7 @@ int TMX_GetOffsetLeftOld(long *offset);
int TMX_GetOffsetLeft(long *offset);
int TMX_ReadCurrentParams(struct tmx_params *params);
int TMX_SetLeap(int leap);
int TMX_SetSync(int sync);
#endif /* GOT_WRAP_ADJTIMEX_H */