On Mon, Aug 18, 2014 at 06:29:42PM +0200, Michal Privoznik wrote: > On 18.08.2014 17:28, Eric Blake wrote: > >On 08/14/2014 02:24 AM, Michal Privoznik wrote: > >>https://bugzilla.redhat.com/show_bug.cgi?id=1103245 > >> > >>An advice appeared there on the qemu-devel list [1]. When a domain is > >>suspended and then resumed guest kernel is not aware of this. So we've > >>introduced virDomainSetTime API that resets the time within guest > >>using qemu-ga. On the other hand, qemu itself is trying to make RTC > >>beat faster to catch the difference. But if we don't tell qemu that > >>guest's time was reset via the other method, both mechanisms are > >>applied resulting in again wrong guest time. In order to avoid summing > >>both corrections we need to tell qemu that it should not use the RTC > >>injection if the guest time is set via guest agent. > >> > >>1: http://www.mail-archive.com/qemu-devel@xxxxxxxxxx/msg236435.html > >> > >>Signed-off-by: Michal Privoznik <mprivozn@xxxxxxxxxx> > >>--- > >> > >>Notes: > >> diff to v1: > >> -fixed command name in subject > >> -added testcase > >> > > > >>+++ b/src/qemu/qemu_driver.c > >>@@ -16879,6 +16879,16 @@ qemuDomainSetTime(virDomainPtr dom, > >> rv = qemuAgentSetTime(priv->agent, seconds, nseconds, rtcSync); > >> qemuDomainObjExitAgent(vm); > >> > >>+ if (!virDomainObjIsActive(vm)) { > >>+ virReportError(VIR_ERR_OPERATION_INVALID, > >>+ "%s", _("domain is not running")); > >>+ goto endjob; > >>+ } > >>+ > >>+ qemuDomainObjEnterMonitor(driver, vm); > >>+ rv = qemuMonitorRTCResetReinjection(priv->mon); > >>+ qemuDomainObjExitMonitor(driver, vm); > > > >We have four combinations: > > > >1. old qemu, old qga: command fails because qga doesn't support it, qemu > >tries to catch up time manually (might eventually match real time) > > > >2. new qemu, old qga: command fails because qga doesn't support it, qemu > >tries to catch up time manually (might eventually match real time) > > > >3. new qemu, new qga: both qga and qemu commands work, no additional > >catchup attempted and guest is now accurate > > > >4. old qemu, new qga: qga succeeds, but qemu command fails, so we have > >overcorrected and qemu is trying to catch up time manually > >(overcorrected, so it cannot match real time) > > > >I guess reporting failure in those three cases is fine, although I'm > >still worried about case 4. I'd feel a lot better if there were a > >qemu_capabilities.h bit that detects if the qemu command is present, and > >skip even attempting the qga command unless we ALSO know the qemu > >command is present (that is, use the capability check to completely > >avoid case 4, by turning it into the same behavior as case 1). > > Okay. Although I've just realized one (corner) case. From my > understanding of rtc-reset-reinjection time it's only necessary if > guest was suspended for a while and the guest's RTC clock skewed. > But what if I start fresh new guest and just want to set its time > (leave aside the reasoning why would I do that for a while)? Is the > rtc-reset-reinjection necessary? I wouldn't say. But on the other > hand - libvirt doesn't know if the RTC is synced already or not. > Hence it's safer for libvirt to issue the command every single time. > > In fact, there are two ways to set guest time: > > a) {"execute":"guest-set-time"} > > b) {"execute":"guest-set-time, "arguments":{"time":1234567890}} > > While in the case a) guest time is set by reading from guest's RTC, > in case of b) guest time is set by calling settimeofday() and RTC is > written thereafter. > > So is the rtc-reset-reinjection necessary only for case a) and in > case b) QEMU somehow detects RTC write and cancels the reinjection > itself? > > Michal rtc-reset-reinjection has been introduced because certain Windows versions will advance the guest system time (via rtc interrupt reinjection). So if libvirt adjusts the guest system time via guest-set-time, allowing rtc interrupt reinjection to compensate for lost time, as well, will cause an incorrect guest system time. So you should always use the guest-set-time rtc-reset-reinjection pair. -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list