aboutsummaryrefslogtreecommitdiff
path: root/vl.c
diff options
context:
space:
mode:
Diffstat (limited to 'vl.c')
-rw-r--r--vl.c84
1 files changed, 51 insertions, 33 deletions
diff --git a/vl.c b/vl.c
index 4e25c78bff..d15e086140 100644
--- a/vl.c
+++ b/vl.c
@@ -147,8 +147,13 @@ bool enable_cpu_pm = false;
int nb_nics;
NICInfo nd_table[MAX_NICS];
int autostart;
-static int rtc_utc = 1;
-static int rtc_date_offset = -1; /* -1 means no change */
+static enum {
+ RTC_BASE_UTC,
+ RTC_BASE_LOCALTIME,
+ RTC_BASE_DATETIME,
+} rtc_base_type = RTC_BASE_UTC;
+static int rtc_host_datetime_offset = -1; /* valid only for host rtc_clock and
+ rtc_base_type=RTC_BASE_DATETIME */
QEMUClockType rtc_clock;
int vga_interface_type = VGA_NONE;
static DisplayOptions dpy;
@@ -782,26 +787,30 @@ void qemu_system_vmstop_request(RunState state)
/***********************************************************/
/* real time host monotonic timer */
-static time_t qemu_time(void)
+static time_t qemu_timedate(void)
{
return qemu_clock_get_ms(QEMU_CLOCK_HOST) / 1000;
}
/***********************************************************/
-/* host time/date access */
+/* RTC reference time/date access */
void qemu_get_timedate(struct tm *tm, int offset)
{
- time_t ti = qemu_time();
+ time_t ti = qemu_timedate();
ti += offset;
- if (rtc_date_offset == -1) {
- if (rtc_utc)
- gmtime_r(&ti, tm);
- else
- localtime_r(&ti, tm);
- } else {
- ti -= rtc_date_offset;
+
+ switch (rtc_base_type) {
+ case RTC_BASE_UTC:
gmtime_r(&ti, tm);
+ break;
+ case RTC_BASE_LOCALTIME:
+ localtime_r(&ti, tm);
+ break;
+ case RTC_BASE_DATETIME:
+ ti -= rtc_host_datetime_offset;
+ gmtime_r(&ti, tm);
+ break;
}
}
@@ -809,23 +818,30 @@ int qemu_timedate_diff(struct tm *tm)
{
time_t seconds;
- if (rtc_date_offset == -1)
- if (rtc_utc)
- seconds = mktimegm(tm);
- else {
- struct tm tmp = *tm;
- tmp.tm_isdst = -1; /* use timezone to figure it out */
- seconds = mktime(&tmp);
- }
- else
- seconds = mktimegm(tm) + rtc_date_offset;
-
- return seconds - qemu_time();
+ switch (rtc_base_type) {
+ case RTC_BASE_UTC:
+ seconds = mktimegm(tm);
+ break;
+ case RTC_BASE_LOCALTIME:
+ {
+ struct tm tmp = *tm;
+ tmp.tm_isdst = -1; /* use timezone to figure it out */
+ seconds = mktime(&tmp);
+ break;
+ }
+ case RTC_BASE_DATETIME:
+ seconds = mktimegm(tm) + rtc_host_datetime_offset;
+ break;
+ default:
+ abort();
+ }
+
+ return seconds - qemu_timedate();
}
-static void configure_rtc_date_offset(const char *startdate)
+static void configure_rtc_host_datetime_offset(const char *startdate)
{
- time_t rtc_start_date;
+ time_t rtc_start_datetime;
struct tm tm;
if (sscanf(startdate, "%d-%d-%dT%d:%d:%d", &tm.tm_year, &tm.tm_mon,
@@ -841,15 +857,16 @@ static void configure_rtc_date_offset(const char *startdate)
}
tm.tm_year -= 1900;
tm.tm_mon--;
- rtc_start_date = mktimegm(&tm);
- if (rtc_start_date == -1) {
+ rtc_start_datetime = mktimegm(&tm);
+ if (rtc_start_datetime == -1) {
date_fail:
- error_report("invalid date format");
+ error_report("invalid datetime format");
error_printf("valid formats: "
"'2006-06-17T16:01:21' or '2006-06-17'\n");
exit(1);
}
- rtc_date_offset = qemu_time() - rtc_start_date;
+ rtc_host_datetime_offset = (qemu_clock_get_ms(QEMU_CLOCK_HOST) / 1000)
+ - rtc_start_datetime;
}
static void configure_rtc(QemuOpts *opts)
@@ -859,15 +876,16 @@ static void configure_rtc(QemuOpts *opts)
value = qemu_opt_get(opts, "base");
if (value) {
if (!strcmp(value, "utc")) {
- rtc_utc = 1;
+ rtc_base_type = RTC_BASE_UTC;
} else if (!strcmp(value, "localtime")) {
Error *blocker = NULL;
- rtc_utc = 0;
+ rtc_base_type = RTC_BASE_LOCALTIME;
error_setg(&blocker, QERR_REPLAY_NOT_SUPPORTED,
"-rtc base=localtime");
replay_add_blocker(blocker);
} else {
- configure_rtc_date_offset(value);
+ rtc_base_type = RTC_BASE_DATETIME;
+ configure_rtc_host_datetime_offset(value);
}
}
value = qemu_opt_get(opts, "clock");