From e77b0070afa987c2f62c8398545a70083ef93b6c Mon Sep 17 00:00:00 2001 From: Miroslav Lichvar Date: Wed, 11 Dec 2013 11:20:58 +0100 Subject: [PATCH] Add option to read RTC LOCAL/UTC setting from hwclock's adjtime file --- chrony.texi.in | 18 ++++++++++++++++++ conf.c | 13 +++++++++++++ conf.h | 1 + rtc_linux.c | 39 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 71 insertions(+) diff --git a/chrony.texi.in b/chrony.texi.in index 3eb2730..1169e7e 100644 --- a/chrony.texi.in +++ b/chrony.texi.in @@ -1132,6 +1132,7 @@ directives can occur in any order in the file. * dumponexit directive:: Dump measurements when daemon exits * fallbackdrift directive:: Specify fallback drift intervals * generatecommandkey directive:: Generate command key automatically +* hwclockfile directive:: Specify location of hwclock's adjtime file * include directive:: Include a configuration file * initstepslew directive:: Trim the system clock on boot-up * keyfile directive:: Specify location of file containing keys @@ -1644,6 +1645,20 @@ command key from the /dev/urandom file and write it to the key file. The generated key will use SHA1 if @code{chronyd} is compiled with the support, otherwise MD5 will be used. @c }}} +@c {{{ hwclockfile +@node hwclockfile directive +@subsection hwclockfile +The @code{hwclockfile} directive sets the location of the adjtime file which is +used by the @file{/sbin/hwclock} program. With this directive, @code{chronyd} +will parse the file to find out if the RTC keeps local time or UTC. It +overrides the @code{rtconutc} directive (@pxref{rtconutc directive}). + +An example of the command is + +@example +hwclockfile /etc/adjtime +@end example +@c }}} @c {{{ include @node include directive @subsection include @@ -2705,6 +2720,9 @@ or ends. 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/hwclock} program. + +Note that this setting is overriden when the @code{hwclockfile} directive +(@pxref{hwclockfile directive}) is used. @c }}} @c {{{ rtcsync @node rtcsync directive diff --git a/conf.c b/conf.c index fdd0751..0a1f9ed 100644 --- a/conf.c +++ b/conf.c @@ -124,6 +124,9 @@ static int enable_manual=0; incl. daylight saving). */ static int rtc_on_utc = 0; +/* Filename used to read the hwclock(8) LOCAL/UTC setting */ +static char *hwclock_file = NULL; + /* Flag set if the RTC should be automatically synchronised by kernel */ static int rtc_sync = 0; @@ -365,6 +368,8 @@ CNF_ReadFile(const char *filename) parse_fallbackdrift(p); } else if (!strcasecmp(command, "generatecommandkey")) { generate_command_key = parse_null(p); + } else if (!strcasecmp(command, "hwclockfile")) { + parse_string(p, &hwclock_file); } else if (!strcasecmp(command, "include")) { parse_include(p); } else if (!strcasecmp(command, "initstepslew")) { @@ -1620,3 +1625,11 @@ CNF_GetMinSamples(void) { return min_samples; } + +/* ================================================== */ + +char * +CNF_GetHwclockFile(void) +{ + return hwclock_file; +} diff --git a/conf.h b/conf.h index 4f6d623..957aafb 100644 --- a/conf.h +++ b/conf.h @@ -100,5 +100,6 @@ extern int CNF_GetMaxSamples(void); extern int CNF_GetMinSamples(void); extern double CNF_GetRtcAutotrim(void); +extern char *CNF_GetHwclockFile(void); #endif /* GOT_CONF_H */ diff --git a/rtc_linux.c b/rtc_linux.c index d6b5f33..fe75855 100644 --- a/rtc_linux.c +++ b/rtc_linux.c @@ -371,6 +371,43 @@ t_from_rtc(struct tm *stm) { /* ================================================== */ +static void +read_hwclock_file(const char *hwclock_file) +{ + FILE *in; + char line[256]; + int i; + + if (!hwclock_file) + return; + + in = fopen(hwclock_file, "r"); + if (!in) { + LOG(LOGS_WARN, LOGF_RtcLinux, "Could not open hwclockfile %s", + hwclock_file); + return; + } + + /* Read third line from the file. */ + for (i = 0; i < 3; i++) { + if (!fgets(line, sizeof(line), in)) + break; + } + + fclose(in); + + if (i == 3 && !strncmp(line, "LOCAL", 5)) { + rtc_on_utc = 0; + } else if (i == 3 && !strncmp(line, "UTC", 3)) { + rtc_on_utc = 1; + } else { + LOG(LOGS_WARN, LOGF_RtcLinux, "Could not read LOCAL/UTC setting from hwclockfile %s", + hwclock_file); + } +} + +/* ================================================== */ + static void setup_config(void) { @@ -380,6 +417,8 @@ setup_config(void) rtc_on_utc = 0; } + read_hwclock_file(CNF_GetHwclockFile()); + autotrim_threshold = CNF_GetRtcAutotrim(); }