Refactor RTC command line switches

Deprecate -localtime, -setdate and -rtc-td-hack in favor of a new
unified command line switch:

    -rtc [base=utc|localtime|date][,driftfix=none|slew]

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
This commit is contained in:
Jan Kiszka 2009-09-15 13:36:04 +02:00 committed by Anthony Liguori
parent 21d5d12bb0
commit 1ed2fc1fa3
4 changed files with 119 additions and 57 deletions

View File

@ -151,6 +151,23 @@ QemuOptsList qemu_device_opts = {
},
};
QemuOptsList qemu_rtc_opts = {
.name = "rtc",
.head = QTAILQ_HEAD_INITIALIZER(qemu_rtc_opts.head),
.desc = {
{
.name = "base",
.type = QEMU_OPT_STRING,
#ifdef TARGET_I386
},{
.name = "driftfix",
.type = QEMU_OPT_STRING,
#endif
},
{ /* end if list */ }
},
};
static QemuOptsList *lists[] = {
&qemu_drive_opts,
&qemu_chardev_opts,

View File

@ -4,6 +4,7 @@
extern QemuOptsList qemu_drive_opts;
extern QemuOptsList qemu_chardev_opts;
extern QemuOptsList qemu_device_opts;
extern QemuOptsList qemu_rtc_opts;
int qemu_set_option(const char *str);

View File

@ -681,15 +681,9 @@ slows down the IDE transfers).
ETEXI
#ifdef TARGET_I386
DEF("rtc-td-hack", 0, QEMU_OPTION_rtc_td_hack,
"-rtc-td-hack use it to fix time drift in Windows ACPI HAL\n")
HXCOMM Deprecated by -rtc
DEF("rtc-td-hack", 0, QEMU_OPTION_rtc_td_hack, "")
#endif
STEXI
@item -rtc-td-hack
Use it if you experience time drift problem in Windows with ACPI HAL.
This option will try to figure out how many timer interrupts were not
processed by the Windows guest and will re-inject them.
ETEXI
#ifdef TARGET_I386
DEF("no-fd-bootchk", 0, QEMU_OPTION_no_fd_bootchk,
@ -1500,23 +1494,32 @@ Force the use of the given methods for timer alarm. To see what timers
are available use -clock ?.
ETEXI
DEF("localtime", 0, QEMU_OPTION_localtime, \
"-localtime set the real time clock to local time [default=utc]\n")
STEXI
@item -localtime
Set the real time clock to local time (the default is to UTC
time). This option is needed to have correct date in MS-DOS or
Windows.
ETEXI
HXCOMM Options deprecated by -rtc
DEF("localtime", 0, QEMU_OPTION_localtime, "")
DEF("startdate", HAS_ARG, QEMU_OPTION_startdate, "")
#ifdef TARGET_I386
DEF("rtc", HAS_ARG, QEMU_OPTION_rtc, \
"-rtc [base=utc|localtime|date][,driftfix=none|slew]\n" \
" set the RTC base, enable drift fix for clock ticks\n")
#else
DEF("rtc", HAS_ARG, QEMU_OPTION_rtc, \
"-rtc [base=utc|localtime|date]\n" \
" set the RTC base and clock\n")
#endif
DEF("startdate", HAS_ARG, QEMU_OPTION_startdate, \
"-startdate select initial date of the clock\n")
STEXI
@item -startdate @var{date}
Set the initial date of the real time clock. Valid formats for
@var{date} are: @code{now} or @code{2006-06-17T16:01:21} or
@code{2006-06-17}. The default value is @code{now}.
@item -rtc [base=utc|localtime|@var{date}][,driftfix=none|slew]
Specify @option{base} as @code{utc} or @code{localtime} to let the RTC start at the current
UTC or local time, respectively. @code{localtime} is required for correct date in
MS-DOS or Windows. To start at a specific point in time, provide @var{date} in the
format @code{2006-06-17T16:01:21} or @code{2006-06-17}. The default base is UTC.
Enable @option{driftfix} (i386 targets only) if you experience time drift problems,
specifically with Windows' ACPI HAL. This option will try to figure out how
many timer interrupts were not processed by the Windows guest and will
re-inject them.
ETEXI
DEF("icount", HAS_ARG, QEMU_OPTION_icount, \

111
vl.c
View File

@ -1582,6 +1582,74 @@ int qemu_timedate_diff(struct tm *tm)
return seconds - time(NULL);
}
static void configure_rtc_date_offset(const char *startdate, int legacy)
{
time_t rtc_start_date;
struct tm tm;
if (!strcmp(startdate, "now") && legacy) {
rtc_date_offset = -1;
} else {
if (sscanf(startdate, "%d-%d-%dT%d:%d:%d",
&tm.tm_year,
&tm.tm_mon,
&tm.tm_mday,
&tm.tm_hour,
&tm.tm_min,
&tm.tm_sec) == 6) {
/* OK */
} else if (sscanf(startdate, "%d-%d-%d",
&tm.tm_year,
&tm.tm_mon,
&tm.tm_mday) == 3) {
tm.tm_hour = 0;
tm.tm_min = 0;
tm.tm_sec = 0;
} else {
goto date_fail;
}
tm.tm_year -= 1900;
tm.tm_mon--;
rtc_start_date = mktimegm(&tm);
if (rtc_start_date == -1) {
date_fail:
fprintf(stderr, "Invalid date format. Valid formats are:\n"
"'2006-06-17T16:01:21' or '2006-06-17'\n");
exit(1);
}
rtc_date_offset = time(NULL) - rtc_start_date;
}
}
static void configure_rtc(QemuOpts *opts)
{
const char *value;
value = qemu_opt_get(opts, "base");
if (value) {
if (!strcmp(value, "utc")) {
rtc_utc = 1;
} else if (!strcmp(value, "localtime")) {
rtc_utc = 0;
} else {
configure_rtc_date_offset(value, 0);
}
}
#ifdef CONFIG_TARGET_I386
value = qemu_opt_get(opts, "driftfix");
if (value) {
if (!strcmp(buf, "slew")) {
rtc_td_hack = 1;
} else if (!strcmp(buf, "none")) {
rtc_td_hack = 0;
} else {
fprintf(stderr, "qemu: invalid option value '%s'\n", value);
exit(1);
}
}
#endif
}
#ifdef _WIN32
static void socket_cleanup(void)
{
@ -5382,42 +5450,15 @@ int main(int argc, char **argv, char **envp)
configure_alarms(optarg);
break;
case QEMU_OPTION_startdate:
{
struct tm tm;
time_t rtc_start_date;
if (!strcmp(optarg, "now")) {
rtc_date_offset = -1;
} else {
if (sscanf(optarg, "%d-%d-%dT%d:%d:%d",
&tm.tm_year,
&tm.tm_mon,
&tm.tm_mday,
&tm.tm_hour,
&tm.tm_min,
&tm.tm_sec) == 6) {
/* OK */
} else if (sscanf(optarg, "%d-%d-%d",
&tm.tm_year,
&tm.tm_mon,
&tm.tm_mday) == 3) {
tm.tm_hour = 0;
tm.tm_min = 0;
tm.tm_sec = 0;
} else {
goto date_fail;
}
tm.tm_year -= 1900;
tm.tm_mon--;
rtc_start_date = mktimegm(&tm);
if (rtc_start_date == -1) {
date_fail:
fprintf(stderr, "Invalid date format. Valid format are:\n"
"'now' or '2006-06-17T16:01:21' or '2006-06-17'\n");
exit(1);
}
rtc_date_offset = time(NULL) - rtc_start_date;
}
configure_rtc_date_offset(optarg, 1);
break;
case QEMU_OPTION_rtc:
opts = qemu_opts_parse(&qemu_rtc_opts, optarg, NULL);
if (!opts) {
fprintf(stderr, "parse error: %s\n", optarg);
exit(1);
}
configure_rtc(opts);
break;
case QEMU_OPTION_tb_size:
tb_size = strtol(optarg, NULL, 0);