[libvirt] [PATCHv2 libvirt] qemu: Issue rtc-reset-reinjection command after guest-set-time

Marcelo Tosatti mtosatti at redhat.com
Tue Aug 19 16:57:13 UTC 2014


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@nongnu.org/msg236435.html
> >>
> >>Signed-off-by: Michal Privoznik <mprivozn at redhat.com>
> >>---
> >>
> >>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.




More information about the libvir-list mailing list