https://bugzilla.redhat.com/show_bug.cgi?id=964177 Though both libvirt and QEMU's document say RTC_CHANGE returns the offset from the host UTC, qemu actually returns the offset from the specified date instead when specific date is privided (-rtc base=$date). It's not safe for qemu to fix it in code, it worked like that for 3 years, changing it now may break other QEMU use cases. What qemu tries to do is to fix the document: http://lists.gnu.org/archive/html/qemu-devel/2013-05/msg04782.html And in libvirt side, instead of reply on the qemu, this covert the offset returned from qemu to the offset from host UTC, by: /* * a: the offset from qemu RTC_CHANGE event * b: The specified date (-rtc base=$date) * c: the host date when libvirt gets the RTC_CHANGE event * offset: What libvirt will report */ offset = a + (b - c); The specified date (-rtc base=$date) is recorded in clock's def as an internal only member (may be useful to exposed outside?). --- src/conf/domain_conf.h | 3 +++ src/qemu/qemu_command.c | 3 +++ src/qemu/qemu_process.c | 12 ++++++++++++ 3 files changed, 18 insertions(+) diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 3a71d6c..3947a56 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -1767,6 +1767,9 @@ struct _virDomainClockDef { struct { long long adjustment; int basis; + + /* Store the start time of guest process, internaly only */ + time_t starttime; } variable; /* Timezone name, when diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index c4a162a..9254525 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -5518,6 +5518,9 @@ qemuBuildClockArgStr(virDomainClockDefPtr def) now += def->data.variable.adjustment; gmtime_r(&now, &nowbits); + /* Store the starttime of qemu process */ + def->data.variable.starttime = now; + virBufferAsprintf(&buf, "base=%d-%02d-%02dT%02d:%02d:%02d", nowbits.tm_year + 1900, nowbits.tm_mon + 1, diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index d4fd4fb..e6f0b6d 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -796,6 +796,18 @@ qemuProcessHandleRTCChange(qemuMonitorPtr mon ATTRIBUTE_UNUSED, virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver); virObjectLock(vm); + + /* QEMU's RTC_CHANGE event returns the offset from the specified + * date instead of the host UTC if a specific date is provided + * (-rtc base=$date). We need to convert it to be offset from + * host UTC. + */ + if (vm->def->clock.offset == VIR_DOMAIN_CLOCK_OFFSET_VARIABLE) { + time_t now = time(NULL); + + offset += vm->def->clock.data.variable.starttime - now; + } + event = virDomainEventRTCChangeNewFromObj(vm, offset); if (vm->def->clock.offset == VIR_DOMAIN_CLOCK_OFFSET_VARIABLE) -- 1.8.1.4 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list