[libvirt] [PATCH] qemu: Report the offset from host UTC for RTC_CHANGE event

Osier Yang jyang at redhat.com
Tue Jun 4 13:09:47 UTC 2013


On 04/06/13 20:59, Eric Blake wrote:
> On 06/04/2013 05:49 AM, Osier Yang wrote:
>> 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
> s/privided/provided/
>
>> (-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
> s/covert/convert/
>
>> 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(+)
> Incomplete.  You need to track the start time across libvirtd restarts
> (in internal XML) for this to reliably work for an event received after
> a restart; you also have to cope with a libvirtd restart not finding the
> field in internal XML (because the libvirtd restart was due to upgrading
> libvirt in the meantime).

Oh, right...

>> 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 */
> Spelling; either 'internal' or 'internally'
>
>> +            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;
> Is there anything we can read out of /proc/nnn for the qemu process that
> would give us a more accurate start time?  In fact, why not use
> virProcessGetStartTime()?  And if virProcessGetStartTime is reliable
> across libvirtd restarts, then you might not need to store a time_t
> starttime in _virDomainClockDef.
>

I tried this.

virProcessGetStartTime reads the "starttime" from /proc/$pid/stat,
which is either jiffies or clock ticks since the system boot. Something
like this (sysinfo.uptime is from system boot time too):

     if (vm->def->clock.offset == VIR_DOMAIN_CLOCK_OFFSET_VARIABLE) {
         if (virProcessGetStartTime(vm->pid, &starttime) < 0) {
             VIR_WARN("unable to get domain process start time");
         } else {
             struct sysinfo info;
             ignore_value(sysinfo(&info));

             /* Convert domain process's starttime (jiffies) into seconds */
             starttime = starttime / sysconf(_SC_CLK_TCK);

             /* Seconds of date specified with "-rtc=$date" */
             rtctime = starttime + 
vm->def->clock.data.variable.orig_adjustment;

             /* QEMU's RTC_CHANGE event returns the offset from the 
specified
              * date instead of the host UTC if a specific date is provided
              * to "-rtc" (-rtc=$date). To emit a offset from host UTC, we
              * need to plus the "offset" from qemu with the "offset" 
between
              * the specific date and current host date.
              */
             offset += rtctime - info.uptime;
         }
     }

Don't mind the "ignore_value(sysinfo(&info))", it's draft code.

I changed to store the whole specified date in "starttime" of clock def,
because I don't know if there is a portable lib call instead of the 
"sysinfo",
do you have any ideas? Thanks.

Osier




More information about the libvir-list mailing list