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[] = { static QemuOptsList *lists[] = {
&qemu_drive_opts, &qemu_drive_opts,
&qemu_chardev_opts, &qemu_chardev_opts,

View File

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

View File

@ -681,15 +681,9 @@ slows down the IDE transfers).
ETEXI ETEXI
#ifdef TARGET_I386 #ifdef TARGET_I386
DEF("rtc-td-hack", 0, QEMU_OPTION_rtc_td_hack, HXCOMM Deprecated by -rtc
"-rtc-td-hack use it to fix time drift in Windows ACPI HAL\n") DEF("rtc-td-hack", 0, QEMU_OPTION_rtc_td_hack, "")
#endif #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 #ifdef TARGET_I386
DEF("no-fd-bootchk", 0, QEMU_OPTION_no_fd_bootchk, 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 ?. are available use -clock ?.
ETEXI ETEXI
DEF("localtime", 0, QEMU_OPTION_localtime, \ HXCOMM Options deprecated by -rtc
"-localtime set the real time clock to local time [default=utc]\n") DEF("localtime", 0, QEMU_OPTION_localtime, "")
STEXI DEF("startdate", HAS_ARG, QEMU_OPTION_startdate, "")
@item -localtime
Set the real time clock to local time (the default is to UTC #ifdef TARGET_I386
time). This option is needed to have correct date in MS-DOS or DEF("rtc", HAS_ARG, QEMU_OPTION_rtc, \
Windows. "-rtc [base=utc|localtime|date][,driftfix=none|slew]\n" \
ETEXI " 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 STEXI
@item -startdate @var{date} @item -rtc [base=utc|localtime|@var{date}][,driftfix=none|slew]
Set the initial date of the real time clock. Valid formats for Specify @option{base} as @code{utc} or @code{localtime} to let the RTC start at the current
@var{date} are: @code{now} or @code{2006-06-17T16:01:21} or UTC or local time, respectively. @code{localtime} is required for correct date in
@code{2006-06-17}. The default value is @code{now}. 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 ETEXI
DEF("icount", HAS_ARG, QEMU_OPTION_icount, \ 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); 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 #ifdef _WIN32
static void socket_cleanup(void) static void socket_cleanup(void)
{ {
@ -5382,42 +5450,15 @@ int main(int argc, char **argv, char **envp)
configure_alarms(optarg); configure_alarms(optarg);
break; break;
case QEMU_OPTION_startdate: case QEMU_OPTION_startdate:
{ configure_rtc_date_offset(optarg, 1);
struct tm tm; break;
time_t rtc_start_date; case QEMU_OPTION_rtc:
if (!strcmp(optarg, "now")) { opts = qemu_opts_parse(&qemu_rtc_opts, optarg, NULL);
rtc_date_offset = -1; if (!opts) {
} else { fprintf(stderr, "parse error: %s\n", optarg);
if (sscanf(optarg, "%d-%d-%dT%d:%d:%d", exit(1);
&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(opts);
break; break;
case QEMU_OPTION_tb_size: case QEMU_OPTION_tb_size:
tb_size = strtol(optarg, NULL, 0); tb_size = strtol(optarg, NULL, 0);