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