vl: refactor -rtc option references

Improve code readability and prepare for fixing bug #1797033

Signed-off-by: Artem Pisarenko <artem.k.pisarenko@gmail.com>
Message-Id: <9330a48899f997431a34460014886d118a7c0960.1539846575.git.artem.k.pisarenko@gmail.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
Artem Pisarenko 2018-10-18 13:12:53 +06:00 committed by Paolo Bonzini
parent 238d1240d9
commit 7e166ebd8c
1 changed files with 50 additions and 32 deletions

82
vl.c
View File

@ -147,8 +147,13 @@ bool enable_cpu_pm = false;
int nb_nics; int nb_nics;
NICInfo nd_table[MAX_NICS]; NICInfo nd_table[MAX_NICS];
int autostart; int autostart;
static int rtc_utc = 1; static enum {
static int rtc_date_offset = -1; /* -1 means no change */ 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; QEMUClockType rtc_clock;
int vga_interface_type = VGA_NONE; int vga_interface_type = VGA_NONE;
static DisplayOptions dpy; static DisplayOptions dpy;
@ -782,26 +787,30 @@ void qemu_system_vmstop_request(RunState state)
/***********************************************************/ /***********************************************************/
/* real time host monotonic timer */ /* 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; 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) void qemu_get_timedate(struct tm *tm, int offset)
{ {
time_t ti = qemu_time(); time_t ti = qemu_timedate();
ti += offset; ti += offset;
if (rtc_date_offset == -1) {
if (rtc_utc) switch (rtc_base_type) {
gmtime_r(&ti, tm); case RTC_BASE_UTC:
else
localtime_r(&ti, tm);
} else {
ti -= rtc_date_offset;
gmtime_r(&ti, tm); 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; time_t seconds;
if (rtc_date_offset == -1) switch (rtc_base_type) {
if (rtc_utc) case RTC_BASE_UTC:
seconds = mktimegm(tm); seconds = mktimegm(tm);
else { break;
struct tm tmp = *tm; case RTC_BASE_LOCALTIME:
tmp.tm_isdst = -1; /* use timezone to figure it out */ {
seconds = mktime(&tmp); struct tm tmp = *tm;
} tmp.tm_isdst = -1; /* use timezone to figure it out */
else seconds = mktime(&tmp);
seconds = mktimegm(tm) + rtc_date_offset; break;
}
case RTC_BASE_DATETIME:
seconds = mktimegm(tm) + rtc_host_datetime_offset;
break;
default:
abort();
}
return seconds - qemu_time(); 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; struct tm tm;
if (sscanf(startdate, "%d-%d-%dT%d:%d:%d", &tm.tm_year, &tm.tm_mon, 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_year -= 1900;
tm.tm_mon--; tm.tm_mon--;
rtc_start_date = mktimegm(&tm); rtc_start_datetime = mktimegm(&tm);
if (rtc_start_date == -1) { if (rtc_start_datetime == -1) {
date_fail: date_fail:
error_report("invalid date format"); error_report("invalid datetime format");
error_printf("valid formats: " error_printf("valid formats: "
"'2006-06-17T16:01:21' or '2006-06-17'\n"); "'2006-06-17T16:01:21' or '2006-06-17'\n");
exit(1); 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) static void configure_rtc(QemuOpts *opts)
@ -859,15 +876,16 @@ static void configure_rtc(QemuOpts *opts)
value = qemu_opt_get(opts, "base"); value = qemu_opt_get(opts, "base");
if (value) { if (value) {
if (!strcmp(value, "utc")) { if (!strcmp(value, "utc")) {
rtc_utc = 1; rtc_base_type = RTC_BASE_UTC;
} else if (!strcmp(value, "localtime")) { } else if (!strcmp(value, "localtime")) {
Error *blocker = NULL; Error *blocker = NULL;
rtc_utc = 0; rtc_base_type = RTC_BASE_LOCALTIME;
error_setg(&blocker, QERR_REPLAY_NOT_SUPPORTED, error_setg(&blocker, QERR_REPLAY_NOT_SUPPORTED,
"-rtc base=localtime"); "-rtc base=localtime");
replay_add_blocker(blocker); replay_add_blocker(blocker);
} else { } else {
configure_rtc_date_offset(value); rtc_base_type = RTC_BASE_DATETIME;
configure_rtc_host_datetime_offset(value);
} }
} }
value = qemu_opt_get(opts, "clock"); value = qemu_opt_get(opts, "clock");