Compare commits
3 commits
master
...
topic/hwcl
Author | SHA1 | Date | |
---|---|---|---|
|
628cd548a7 | ||
|
1010d2f771 | ||
|
b200c2aab0 |
10 changed files with 191 additions and 101 deletions
|
@ -141,6 +141,8 @@ edit_cmd = sed \
|
|||
-e 's|@usrsbin_execdir[@]|$(usrsbin_execdir)|g' \
|
||||
-e 's|@VERSION[@]|$(VERSION)|g' \
|
||||
-e 's|@ADJTIME_PATH[@]|$(ADJTIME_PATH)|g' \
|
||||
-e 's|@CLOCKMODE_PATH[@]|$(CLOCKMODE_PATH)|g' \
|
||||
-e 's|@CLOCKDRIFT_PATH[@]|$(CLOCKDRIFT_PATH)|g' \
|
||||
-e 's|@LIBUUID_VERSION[@]|$(LIBUUID_VERSION)|g' \
|
||||
-e 's|@LIBMOUNT_VERSION[@]|$(LIBMOUNT_VERSION)|g' \
|
||||
-e 's|@LIBMOUNT_MAJOR_VERSION[@]|$(LIBMOUNT_MAJOR_VERSION)|g' \
|
||||
|
|
15
configure.ac
15
configure.ac
|
@ -2572,14 +2572,23 @@ AC_ARG_VAR([SOLIB_LDFLAGS],
|
|||
[LDFLAGS used for shared libraries])
|
||||
|
||||
AC_ARG_VAR([ADJTIME_PATH],
|
||||
[Path to hwclock adjtime file, default /etc/adjtime])
|
||||
[Path to adjtime file; fallback if CLOCKMODE_PATH or CLOCKDRIFT_PATH do not exist, default is /etc/adjtime])
|
||||
AS_IF([test "x$ADJTIME_PATH" = x], [ADJTIME_PATH="/etc/adjtime"])
|
||||
AC_DEFINE_UNQUOTED([CONFIG_ADJTIME_PATH], "$ADJTIME_PATH", [Path to hwclock adjtime file])
|
||||
AC_DEFINE_UNQUOTED([CONFIG_ADJTIME_FILE], "$ADJTIME_PATH", [Path to adjtime file])
|
||||
|
||||
AC_ARG_VAR([CLOCKMODE_PATH],
|
||||
[Path to hwclock utc/local setting file, default ADJTIME_PATH])
|
||||
AS_IF([test "x$CLOCKMODE_PATH" = x], [CLOCKMODE_PATH=$ADJTIME_PATH])
|
||||
AC_DEFINE_UNQUOTED([CONFIG_HWCLOCK_MODE_FILE], "$CLOCKMODE_PATH", [Path to hwclock utc/local mode file])
|
||||
|
||||
AC_ARG_VAR([CLOCKDRIFT_PATH],
|
||||
[Path to hwclock drift status file, default /var/lib/hwclock/drift])
|
||||
AS_IF([test "x$CLOCKDRIFT_PATH" = x], [CLOCKDRIFT_PATH="/var/lib/hwclock/drift"])
|
||||
AC_DEFINE_UNQUOTED([CONFIG_HWCLOCK_DRIFT_FILE], "$CLOCKDRIFT_PATH", [Path to hwclock drift status file])
|
||||
|
||||
|
||||
LIBS=""
|
||||
|
||||
|
||||
AC_CONFIG_HEADERS([config.h])
|
||||
|
||||
#
|
||||
|
|
|
@ -156,11 +156,9 @@
|
|||
#define _PATH_DEV_BYPARTUUID "/dev/disk/by-partuuid"
|
||||
|
||||
/* hwclock paths */
|
||||
#ifdef CONFIG_ADJTIME_PATH
|
||||
# define _PATH_ADJTIME CONFIG_ADJTIME_PATH
|
||||
#else
|
||||
# define _PATH_ADJTIME "/etc/adjtime"
|
||||
#endif
|
||||
#define _PATH_HWCLOCK_DRIFT_FILE CONFIG_HWCLOCK_DRIFT_FILE
|
||||
#define _PATH_HWCLOCK_MODE_FILE CONFIG_HWCLOCK_MODE_FILE
|
||||
#define _PATH_ADJTIME CONFIG_ADJTIME_FILE
|
||||
|
||||
#ifdef __ia64__
|
||||
# define _PATH_RTC_DEV "/dev/efirtc"
|
||||
|
|
|
@ -89,4 +89,8 @@ int strtime_short(const time_t *t, struct timeval *now, int flags, char *buf, si
|
|||
extern time_t timegm(struct tm *tm);
|
||||
#endif
|
||||
|
||||
const char *ul_hwclock_get_drift_file(void);
|
||||
const char *ul_hwclock_get_mode_file(void);
|
||||
int ul_hwclock_mode_is_utc(const char *modefile, int *rc);
|
||||
|
||||
#endif /* UTIL_LINUX_TIME_UTIL_H */
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include "nls.h"
|
||||
#include "strutils.h"
|
||||
#include "timeutils.h"
|
||||
#include "pathnames.h"
|
||||
|
||||
#define WHITESPACE " \t\n\r"
|
||||
|
||||
|
@ -568,6 +569,59 @@ time_t timegm(struct tm *tm)
|
|||
}
|
||||
#endif /* HAVE_TIMEGM */
|
||||
|
||||
/* hwclock drift information */
|
||||
const char *ul_hwclock_get_drift_file(void)
|
||||
{
|
||||
if (access(_PATH_HWCLOCK_DRIFT_FILE, F_OK) == 0)
|
||||
return _PATH_HWCLOCK_DRIFT_FILE;
|
||||
|
||||
return ul_hwclock_get_mode_file();
|
||||
}
|
||||
|
||||
const char *ul_hwclock_get_mode_file(void)
|
||||
{
|
||||
if (strcmp(_PATH_HWCLOCK_MODE_FILE, _PATH_ADJTIME) != 0
|
||||
&& access(_PATH_HWCLOCK_MODE_FILE, F_OK) == 0)
|
||||
return _PATH_HWCLOCK_MODE_FILE;
|
||||
|
||||
return _PATH_ADJTIME; /* backward compatible default */
|
||||
}
|
||||
|
||||
int ul_hwclock_mode_is_utc(const char *modefile, int *rc)
|
||||
{
|
||||
FILE *fp = NULL;
|
||||
char linebuf[8];
|
||||
|
||||
*rc = EINVAL;
|
||||
|
||||
if (!modefile)
|
||||
modefile = ul_hwclock_get_mode_file();
|
||||
|
||||
fp = fopen(modefile, "r");
|
||||
if (!fp) {
|
||||
*rc = errno;
|
||||
goto dflt;
|
||||
}
|
||||
if (skip_fline(fp) || skip_fline(fp)) /* skip two lines */
|
||||
goto dflt;
|
||||
if (!fgets(linebuf, sizeof linebuf, fp)) /* read 3rd line */
|
||||
goto dflt;
|
||||
|
||||
fclose(fp);
|
||||
fp = NULL;
|
||||
|
||||
if (strncmp(linebuf, "LOCAL", 5) == 0) {
|
||||
*rc = 0;
|
||||
return 0;
|
||||
}
|
||||
if (strncmp(linebuf, "UTC", 3) == 0)
|
||||
*rc = 0;
|
||||
dflt:
|
||||
if (fp)
|
||||
fclose(fp);
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifdef TEST_PROGRAM_TIMEUTILS
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
|
@ -576,16 +630,29 @@ int main(int argc, char *argv[])
|
|||
char buf[ISO_BUFSIZ];
|
||||
|
||||
if (argc < 2) {
|
||||
fprintf(stderr, "usage: %s [<time> [<usec>]] | [--timestamp <str>]\n", argv[0]);
|
||||
fprintf(stderr, "usage: %1$s <time> [<usec>]\n"
|
||||
" %1$s --timestamp <str>\n"
|
||||
" %1$s --clockmode\n",
|
||||
argv[0]);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (strcmp(argv[1], "--timestamp") == 0) {
|
||||
if (strcmp(argv[1], "--clockmode") == 0) {
|
||||
int rc = 0,
|
||||
utc = ul_hwclockmode_is_utc(NULL, &rc);
|
||||
|
||||
printf("%s: mode is %s [rc=%d]\n",
|
||||
ul_hwclock_get_mode_file(),
|
||||
utc ? "UTC" : "LOCAL", rc);
|
||||
return rc ? EXIT_FAILURE : EXIT_SUCCESS;
|
||||
|
||||
} else if (strcmp(argv[1], "--timestamp") == 0) {
|
||||
usec_t usec = 0;
|
||||
|
||||
parse_timestamp(argv[2], &usec);
|
||||
tv.tv_sec = (time_t) (usec / 1000000);
|
||||
tv.tv_usec = usec % 1000000;
|
||||
|
||||
} else {
|
||||
tv.tv_sec = strtos64_or_err(argv[1], "failed to parse <time>");
|
||||
if (argc == 3)
|
||||
|
|
|
@ -74,8 +74,8 @@ the kernel uses the fixed Hardware Clock epoch of 1900.
|
|||
Predict what the Hardware Clock will read in the future based upon the
|
||||
time given by the
|
||||
.B \-\-date
|
||||
option and the information in
|
||||
.IR @ADJTIME_PATH@ .
|
||||
option and the information in clock drift file, see the discussion below,
|
||||
under FILES section.
|
||||
This is useful, for example, to account for drift when setting a
|
||||
Hardware Clock wakeup (aka alarm). See
|
||||
.BR \%rtcwake (8).
|
||||
|
@ -103,8 +103,8 @@ Showing the Hardware Clock time is the default when no function is specified.
|
|||
The
|
||||
.B \-\-get
|
||||
function also applies drift correction to the time read, based upon the
|
||||
information in
|
||||
.IR @ADJTIME_PATH@ .
|
||||
information in clock drift file, see the discussion below,
|
||||
under FILES section.
|
||||
Do not use this function if the Hardware Clock is being modified by
|
||||
anything other than the current operating system's
|
||||
.B \%hwclock
|
||||
|
@ -123,9 +123,8 @@ for the system. If the Hardware Clock is kept in local time then the time read
|
|||
from it must be shifted to the UTC timescale before using it to set the System
|
||||
Clock. The
|
||||
.B \%\-\-hctosys
|
||||
function does this based upon the information in the
|
||||
.I @ADJTIME_PATH@
|
||||
file or the command line arguments
|
||||
function does this based upon the information in the clock mode file (see below)
|
||||
or the command line arguments
|
||||
.BR \%\-\-localtime " and " \-\-utc .
|
||||
Note: no daylight saving adjustment is made. See the discussion below, under
|
||||
.BR "LOCAL vs UTC" .
|
||||
|
@ -163,13 +162,12 @@ something has changed the Hardware Clock, like NTP's \%'11\ minute\ mode', then
|
|||
will set the time incorrectly by including drift compensation.
|
||||
.sp
|
||||
Drift compensation can be inhibited by setting the drift factor in
|
||||
.I @ADJTIME_PATH@
|
||||
to zero. This setting will be persistent as long as the
|
||||
drift (adjtime) file to zero. This setting will be persistent as long as the
|
||||
.BR \%\-\-update\-drift " option is not used with " \%\-\-systohc
|
||||
at shutdown (or anywhere else). Another way to inhibit this is by using the
|
||||
.BR \%\-\-noadjfile " option when calling the " \%\-\-hctosys
|
||||
function. A third method is to delete the
|
||||
.IR @ADJTIME_PATH@ " file."
|
||||
function. A third method is to delete the drift file, see the discussion below,
|
||||
under FILES section.
|
||||
.B Hwclock
|
||||
will then default to using the UTC timescale for the Hardware Clock. If
|
||||
the Hardware Clock is ticking local time it will need to be defined in
|
||||
|
@ -194,8 +192,8 @@ the Hardware Clock while its Linux instance is not running.
|
|||
.B \-\-set
|
||||
Set the Hardware Clock to the time given by the
|
||||
.B \-\-date
|
||||
option, and update the timestamps in
|
||||
.IR @ADJTIME_PATH@ .
|
||||
option, and update the timestamps in clock drift file, see the discussion below,
|
||||
under FILES section.
|
||||
With the
|
||||
.B \%\-\-update-drift
|
||||
option also (re)calculate the drift factor. Try it without the option if
|
||||
|
@ -234,7 +232,7 @@ changed then a reboot would be required to inform the kernel.
|
|||
.TP
|
||||
.BR \-w , \ \-\-systohc
|
||||
Set the Hardware Clock from the System Clock, and update the timestamps in
|
||||
.IR @ADJTIME_PATH@ .
|
||||
clock drift file, see the discussion below, under FILES section.
|
||||
With the
|
||||
.B \%\-\-update-drift
|
||||
option also (re)calculate the drift factor. Try it without the option if
|
||||
|
@ -251,8 +249,12 @@ Display help text and exit.
|
|||
.SH OPTIONS
|
||||
.
|
||||
.TP
|
||||
.BI \-\-adjfile= filename
|
||||
.RI "Override the default " @ADJTIME_PATH@ " file path."
|
||||
.BI \-\-drift-file= filename
|
||||
.RI "Override the default " @CLOCKDRIFT_PATH@ " file path."
|
||||
.
|
||||
.TP
|
||||
.BI \-\-mode-file= filename
|
||||
.RI "Override the default " @CLOCKMODE_PATH@ " file path."
|
||||
.
|
||||
.TP
|
||||
.BI \%\-\-date= date_string
|
||||
|
@ -371,8 +373,8 @@ If you specify neither
|
|||
then the one last given with a set function
|
||||
.RB ( \-\-set ", " \%\-\-systohc ", or " \%\-\-adjust ),
|
||||
as recorded in
|
||||
.IR @ADJTIME_PATH@ ,
|
||||
will be used. If the adjtime file doesn't exist, the default is UTC.
|
||||
.IR @CLOCKMODE_PATH@ ,
|
||||
will be used. If the clock mode file doesn't exist, the default is UTC.
|
||||
.sp
|
||||
Note: daylight saving time changes may be inconsistent when the
|
||||
Hardware Clock is kept in local time. See the discussion below, under
|
||||
|
@ -381,7 +383,7 @@ Hardware Clock is kept in local time. See the discussion below, under
|
|||
.TP
|
||||
.B \-\-noadjfile
|
||||
Disable the facilities provided by
|
||||
.IR @ADJTIME_PATH@ .
|
||||
.IR @CLOCKDRIFT_PATH@ .
|
||||
.B \%hwclock
|
||||
will not read nor write to that file with this option. Either
|
||||
.BR \-\-utc " or " \%\-\-localtime
|
||||
|
@ -390,14 +392,14 @@ must be specified when using this option.
|
|||
.TP
|
||||
.B \-\-test
|
||||
Do not actually change anything on the system, that is, the Clocks or
|
||||
.I @ADJTIME_PATH@
|
||||
.I @CLOCKDRIFT_PATH@
|
||||
.RB ( \%\-\-verbose
|
||||
is implicit with this option).
|
||||
.
|
||||
.TP
|
||||
.B \-\-update\-drift
|
||||
Update the Hardware Clock's drift factor in
|
||||
.IR @ADJTIME_PATH@ .
|
||||
.IR @CLOCKDRIFT_PATH@ .
|
||||
It can only be used with
|
||||
.BR \-\-set " or " \%\-\-systohc ,
|
||||
.sp
|
||||
|
@ -432,7 +434,7 @@ the RTC is not read).
|
|||
.RB "Having " \%hwclock
|
||||
calculate the drift factor is a good starting point, but for optimal
|
||||
results it will likely need to be adjusted by directly editing the
|
||||
.I @ADJTIME_PATH@
|
||||
.I @CLOCKDRIFT_PATH@
|
||||
file. For most configurations once a machine's optimal drift factor is
|
||||
crafted it should not need to be changed. Therefore, the old behavior to
|
||||
automatically (re)calculate drift was changed and now requires this
|
||||
|
@ -577,9 +579,9 @@ function lets you apply systematic drift corrections to the
|
|||
Hardware Clock.
|
||||
.PP
|
||||
It works like this:
|
||||
.BR \%hwclock " keeps a file,"
|
||||
.IR @ADJTIME_PATH@ ,
|
||||
that keeps some historical information. This is called the adjtime file.
|
||||
.BR \%hwclock " keeps a drift file (aka adjtime file),
|
||||
that keeps some historical information. The file uses adjtime file format,
|
||||
see the discussion below, under FILES section.
|
||||
.PP
|
||||
Suppose you start with no adjtime file. You issue a
|
||||
.B \%hwclock\ \-\-set
|
||||
|
@ -613,7 +615,7 @@ the systematic drift rate is (re)calculated by comparing the fully drift
|
|||
corrected current Hardware Clock time with the new set time, from that
|
||||
it derives the 24 hour drift rate based on the last calibrated timestamp
|
||||
from the adjtime file. This updated drift factor is then saved in
|
||||
.IR @ADJTIME_PATH@ .
|
||||
.IR @CLOCKDRIFT_PATH@ .
|
||||
.PP
|
||||
A small amount of error creeps in when
|
||||
the Hardware Clock is set, so
|
||||
|
@ -665,6 +667,12 @@ command line.
|
|||
.PP
|
||||
You can use an adjtime file that was previously used with the
|
||||
.BR \%clock "(8) program with " \%hwclock .
|
||||
.PP
|
||||
Since v2.37
|
||||
.B hwclock
|
||||
can read "UTC" or "LOCAL" (line 3) from a different file than clock
|
||||
drift infomation. The both files has to use "adjtime" file format.
|
||||
See the discussion below, under FILES section.
|
||||
.
|
||||
.SS Automatic Hardware Clock Synchronization by the Kernel
|
||||
You should be aware of another way that the Hardware Clock is kept
|
||||
|
@ -839,8 +847,8 @@ then the System Clock must be set correctly (step 6a) just before doing so.
|
|||
.RB "Having " hwclock
|
||||
calculate the drift factor is a good starting point, but for optimal
|
||||
results it will likely need to be adjusted by directly editing the
|
||||
.I @ADJTIME_PATH@
|
||||
file. Continue to test and refine the drift factor until the Hardware
|
||||
clock drift file, see the discussion below, under FILES section.
|
||||
Continue to test and refine the drift factor until the Hardware
|
||||
Clock is corrected properly at startup. To check this, first make sure
|
||||
that the System Time is correct before shutdown and then use
|
||||
.BR \%sntp ", or " \%date\ \-Ins
|
||||
|
@ -951,8 +959,15 @@ If this variable is set its value takes precedence over the system
|
|||
configured timezone database directory path.
|
||||
.SH FILES
|
||||
.TP
|
||||
.I @ADJTIME_PATH@
|
||||
The configuration and state file for hwclock.
|
||||
.I @CLOCKMODE_PATH@
|
||||
The clock mode (e.g. UTC or LOCAL) file in the "adjtime" file format. For the format see
|
||||
also
|
||||
.B The Adjtime File
|
||||
above.
|
||||
.TP
|
||||
.I @CLOCKDRIFT_PATH@
|
||||
The clock drift file in the "adjtime" file format. May be the same file as the clock mode
|
||||
file. If the file does not exist then defaults to clock mode file (see above).
|
||||
.TP
|
||||
.I /etc/localtime
|
||||
The system timezone file.
|
||||
|
|
|
@ -204,9 +204,15 @@ hw_clock_is_utc(const struct hwclock_control *ctl,
|
|||
ret = 1; /* --utc explicitly given on command line */
|
||||
else if (ctl->local_opt)
|
||||
ret = 0; /* --localtime explicitly given */
|
||||
else
|
||||
/* get info from adjtime file - default is UTC */
|
||||
ret = (adjtime->local_utc != LOCAL);
|
||||
else {
|
||||
int rc = -1;
|
||||
|
||||
if (!adjtime || strcmp(ctl->mode_file_name, ctl->drift_file_name) != 0)
|
||||
/* no adjtime read, or mode requested from a different file */
|
||||
ret = ul_hwclock_mode_is_utc(ctl->mode_file_name, &rc);
|
||||
if (rc != 0)
|
||||
ret = (adjtime->local_utc != LOCAL);
|
||||
}
|
||||
|
||||
if (ctl->verbose)
|
||||
printf(_("Assuming hardware clock is kept in %s time.\n"),
|
||||
|
@ -228,12 +234,15 @@ static int read_adjtime(const struct hwclock_control *ctl,
|
|||
char line2[81]; /* String: second line of adjtime file */
|
||||
char line3[81]; /* String: third line of adjtime file */
|
||||
|
||||
if (access(ctl->adj_file_name, R_OK) != 0)
|
||||
if (access(ctl->drift_file_name, R_OK) != 0)
|
||||
return EXIT_SUCCESS;
|
||||
|
||||
adjfile = fopen(ctl->adj_file_name, "r"); /* open file for reading */
|
||||
if (ctl->verbose)
|
||||
printf(_("Reading %s\n"), ctl->drift_file_name);
|
||||
|
||||
adjfile = fopen(ctl->drift_file_name, "r"); /* open file for reading */
|
||||
if (adjfile == NULL) {
|
||||
warn(_("cannot open %s"), ctl->adj_file_name);
|
||||
warn(_("cannot open %s"), ctl->drift_file_name);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
|
@ -894,18 +903,18 @@ static int save_adjtime(const struct hwclock_control *ctl,
|
|||
|
||||
if (ctl->verbose){
|
||||
printf(_("New %s data:\n%s"),
|
||||
ctl->adj_file_name, content);
|
||||
ctl->drift_file_name, content);
|
||||
}
|
||||
|
||||
if (!ctl->testing) {
|
||||
fp = fopen(ctl->adj_file_name, "w");
|
||||
fp = fopen(ctl->drift_file_name, "w");
|
||||
if (fp == NULL) {
|
||||
warn(_("cannot open %s"), ctl->adj_file_name);
|
||||
warn(_("cannot open %s"), ctl->drift_file_name);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (fputs(content, fp) < 0 || close_stream(fp) != 0) {
|
||||
warn(_("cannot update %s"), ctl->adj_file_name);
|
||||
warn(_("cannot update %s"), ctl->drift_file_name);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
|
@ -1150,6 +1159,8 @@ static void out_version(void)
|
|||
static void __attribute__((__noreturn__))
|
||||
usage(void)
|
||||
{
|
||||
const char *drift_file = ul_hwclock_get_drift_file();
|
||||
|
||||
fputs(USAGE_HEADER, stdout);
|
||||
printf(_(" %s [function] [option...]\n"), program_invocation_short_name);
|
||||
|
||||
|
@ -1185,9 +1196,12 @@ usage(void)
|
|||
#endif
|
||||
puts(_(" --update-drift update the RTC drift factor"));
|
||||
printf(_(
|
||||
" --noadjfile do not use %1$s\n"), _PATH_ADJTIME);
|
||||
" --noadjfile do not use %s\n"), drift_file);
|
||||
printf(_(
|
||||
" --adjfile <file> use an alternate file to %1$s\n"), _PATH_ADJTIME);
|
||||
" --drift-file <file> use an alternate file to %s\n"), drift_file);
|
||||
printf(_(
|
||||
" --mode-file <file> use an alternate file to %s\n"), ul_hwclock_get_mode_file());
|
||||
|
||||
puts(_(" --test dry run; implies --verbose"));
|
||||
puts(_(" -v, --verbose display more details"));
|
||||
fputs(USAGE_SEPARATOR, stdout);
|
||||
|
@ -1213,7 +1227,8 @@ int main(int argc, char **argv)
|
|||
|
||||
/* Long only options. */
|
||||
enum {
|
||||
OPT_ADJFILE = CHAR_MAX + 1,
|
||||
OPT_DRIFTFILE = CHAR_MAX + 1,
|
||||
OPT_MODEFILE,
|
||||
OPT_DATE,
|
||||
OPT_DELAY,
|
||||
OPT_DIRECTISA,
|
||||
|
@ -1255,7 +1270,9 @@ int main(int argc, char **argv)
|
|||
#ifdef __linux__
|
||||
{ "rtc", required_argument, NULL, 'f' },
|
||||
#endif
|
||||
{ "adjfile", required_argument, NULL, OPT_ADJFILE },
|
||||
{ "adjfile", required_argument, NULL, OPT_DRIFTFILE }, /* deprecated */
|
||||
{ "drift-file", required_argument, NULL, OPT_DRIFTFILE },
|
||||
{ "mode-file", required_argument, NULL, OPT_MODEFILE },
|
||||
{ "systz", no_argument, NULL, OPT_SYSTZ },
|
||||
{ "predict", no_argument, NULL, OPT_PREDICT },
|
||||
{ "get", no_argument, NULL, OPT_GET },
|
||||
|
@ -1268,7 +1285,7 @@ int main(int argc, char **argv)
|
|||
OPT_GET, OPT_GETEPOCH, OPT_PREDICT,
|
||||
OPT_SET, OPT_SETEPOCH, OPT_SYSTZ },
|
||||
{ 'l', 'u' },
|
||||
{ OPT_ADJFILE, OPT_NOADJFILE },
|
||||
{ OPT_DRIFTFILE, OPT_NOADJFILE },
|
||||
{ OPT_NOADJFILE, OPT_UPDATE },
|
||||
{ 0 }
|
||||
};
|
||||
|
@ -1376,8 +1393,11 @@ int main(int argc, char **argv)
|
|||
case OPT_DELAY:
|
||||
ctl.rtc_delay = strtod_or_err(optarg, "invalid --delay argument");
|
||||
break;
|
||||
case OPT_ADJFILE:
|
||||
ctl.adj_file_name = optarg; /* --adjfile */
|
||||
case OPT_DRIFTFILE:
|
||||
ctl.drift_file_name = optarg; /* --drift-file */
|
||||
break;
|
||||
case OPT_MODEFILE:
|
||||
ctl.mode_file_name = optarg; /* --mode-file */
|
||||
break;
|
||||
case OPT_SYSTZ:
|
||||
ctl.systz = 1; /* --systz */
|
||||
|
@ -1415,8 +1435,10 @@ int main(int argc, char **argv)
|
|||
errtryhelp(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (!ctl.adj_file_name)
|
||||
ctl.adj_file_name = _PATH_ADJTIME;
|
||||
if (!ctl.drift_file_name)
|
||||
ctl.drift_file_name = ul_hwclock_get_drift_file();
|
||||
if (!ctl.mode_file_name)
|
||||
ctl.mode_file_name = ul_hwclock_get_mode_file();
|
||||
|
||||
if (ctl.update && !ctl.set && !ctl.systohc) {
|
||||
warnx(_("--update-drift requires --set or --systohc"));
|
||||
|
|
|
@ -21,7 +21,10 @@ UL_DEBUG_DECLARE_MASK(hwclock);
|
|||
|
||||
struct hwclock_control {
|
||||
char *date_opt;
|
||||
char *adj_file_name;
|
||||
|
||||
const char *drift_file_name; /* adjtime file with drift status */
|
||||
const char *mode_file_name; /* adjtime file with UTC/LOCAL */
|
||||
|
||||
double rtc_delay; /* --delay <seconds> */
|
||||
#if defined(__linux__) && defined(__alpha__)
|
||||
char *epoch_option;
|
||||
|
|
|
@ -56,7 +56,7 @@ entering a system sleep.
|
|||
.SH OPTIONS
|
||||
.TP
|
||||
.BR \-A , " \-\-adjfile " \fIfile
|
||||
Specify an alternative path to the adjust file.
|
||||
Specify an alternative path to the file with hwclock UTC or LOCAL mode.
|
||||
.TP
|
||||
.BR \-a , " \-\-auto"
|
||||
Read the clock mode (whether the hardware clock is set to UTC or local time)
|
||||
|
@ -167,7 +167,7 @@ Some PC systems can't currently exit sleep states such as \fBmem\fP
|
|||
using only the kernel code accessed by this driver.
|
||||
They need help from userspace code to make the framebuffer work again.
|
||||
.SH FILES
|
||||
.I @ADJTIME_PATH@
|
||||
.I @CLOCKMODE_PATH@
|
||||
.SH HISTORY
|
||||
The program was posted several times on LKML and other lists
|
||||
before appearing in kernel commit message for Linux 2.6 in the GIT
|
||||
|
|
|
@ -50,7 +50,6 @@
|
|||
# define RTC_AF 0x20 /* Alarm interrupt */
|
||||
#endif
|
||||
|
||||
#define ADJTIME_ZONE_BUFSIZ 8
|
||||
#define SYS_WAKEUP_PATH_TEMPLATE "/sys/class/rtc/%s/device/power/wakeup"
|
||||
#define SYS_POWER_STATE_PATH "/sys/power/state"
|
||||
#define DEFAULT_RTC_DEVICE "/dev/rtc0"
|
||||
|
@ -83,7 +82,7 @@ enum clock_modes {
|
|||
struct rtcwake_control {
|
||||
char *mode_str; /* name of the requested mode */
|
||||
char **possible_modes; /* modes listed in /sys/power/state */
|
||||
char *adjfile; /* adjtime file path */
|
||||
char *clock_mode_file; /* file in adjtime format with hwclock timezone */
|
||||
enum clock_modes clock_mode; /* hwclock timezone */
|
||||
time_t sys_time; /* system time */
|
||||
time_t rtc_time; /* hardware time */
|
||||
|
@ -104,8 +103,8 @@ static void __attribute__((__noreturn__)) usage(void)
|
|||
fputs(USAGE_OPTIONS, out);
|
||||
fputs(_(" -a, --auto reads the clock mode from adjust file (default)\n"), out);
|
||||
fprintf(out,
|
||||
_(" -A, --adjfile <file> specifies the path to the adjust file\n"
|
||||
" the default is %s\n"), _PATH_ADJTIME);
|
||||
_(" -A, --adjfile <file> path to the file with hwclock mode\n"
|
||||
" the default is %s\n"), ul_hwclock_get_mode_file());
|
||||
fputs(_(" --date <timestamp> date time of timestamp to wake\n"), out);
|
||||
fputs(_(" -d, --device <device> select rtc device (rtc0|rtc1|...)\n"), out);
|
||||
fputs(_(" -n, --dry-run does everything, but suspend\n"), out);
|
||||
|
@ -304,36 +303,6 @@ static void suspend_system(struct rtcwake_control *ctl)
|
|||
errx(EXIT_FAILURE, _("write error"));
|
||||
}
|
||||
|
||||
static int read_clock_mode(struct rtcwake_control *ctl)
|
||||
{
|
||||
FILE *fp;
|
||||
char linebuf[ADJTIME_ZONE_BUFSIZ];
|
||||
|
||||
fp = fopen(ctl->adjfile, "r");
|
||||
if (!fp)
|
||||
return -1;
|
||||
/* skip two lines */
|
||||
if (skip_fline(fp) || skip_fline(fp)) {
|
||||
fclose(fp);
|
||||
return -1;
|
||||
}
|
||||
/* read third line */
|
||||
if (!fgets(linebuf, sizeof linebuf, fp)) {
|
||||
fclose(fp);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (strncmp(linebuf, "UTC", 3) == 0)
|
||||
ctl->clock_mode = CM_UTC;
|
||||
else if (strncmp(linebuf, "LOCAL", 5) == 0)
|
||||
ctl->clock_mode = CM_LOCAL;
|
||||
else if (ctl->verbose)
|
||||
warnx(_("unexpected third line in: %s: %s"), ctl->adjfile, linebuf);
|
||||
|
||||
fclose(fp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int print_alarm(struct rtcwake_control *ctl, int fd)
|
||||
{
|
||||
struct rtc_wkalrm wake;
|
||||
|
@ -424,7 +393,6 @@ int main(int argc, char **argv)
|
|||
{
|
||||
struct rtcwake_control ctl = {
|
||||
.mode_str = "suspend", /* default mode */
|
||||
.adjfile = _PATH_ADJTIME,
|
||||
.clock_mode = CM_AUTO
|
||||
};
|
||||
char *devname = DEFAULT_RTC_DEVICE;
|
||||
|
@ -473,7 +441,7 @@ int main(int argc, char **argv)
|
|||
switch (t) {
|
||||
case 'A':
|
||||
/* for better compatibility with hwclock */
|
||||
ctl.adjfile = optarg;
|
||||
ctl.clock_mode_file = optarg;
|
||||
break;
|
||||
case 'a':
|
||||
ctl.clock_mode = CM_AUTO;
|
||||
|
@ -529,9 +497,11 @@ int main(int argc, char **argv)
|
|||
}
|
||||
}
|
||||
|
||||
if (ctl.clock_mode == CM_AUTO && read_clock_mode(&ctl) < 0) {
|
||||
printf(_("%s: assuming RTC uses UTC ...\n"), program_invocation_short_name);
|
||||
ctl.clock_mode = CM_UTC;
|
||||
if (ctl.clock_mode == CM_AUTO) {
|
||||
ctl.clock_mode = ul_hwclock_mode_is_utc(ctl.clock_mode_file, &rc);
|
||||
if (rc)
|
||||
printf(_("%s: failed to get clock mode; assuming RTC uses UTC\n"),
|
||||
program_invocation_short_name);
|
||||
}
|
||||
|
||||
if (ctl.verbose)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue