On Thu, Feb 18, 2010 at 05:54:28PM +0000, Daniel P. Berrange wrote: > This introduces a third option for clock offset synchronization, > that allows an arbitrary / variable adjustment to be set. In > essence the XML contains the time delta in seconds, relative to > UTC. > > <clock offset='variable' adjustment='123465'/> > > The difference from 'utc' mode, is that management apps should > track adjustments and preserve them at next reboot.
hum ... if the management layer start to track time of delta w.r.t. UTC as defined by node clock, I also assume they manage the variations in clock when migrating too (or that the nodes clocks are actually properly sync'ed). > * docs/schemas/domain.rng: Schema for new clock mode > * src/conf/domain_conf.c, src/conf/domain_conf.h: Parse > new clock time delta > * src/libvirt_private.syms, src/util/xml.c, src/util/xml.h: Add > virXPathLongLong() method > --- > docs/schemas/domain.rng | 25 +++++++++++++++++--- > src/conf/domain_conf.c | 18 +++++++++++++- > src/conf/domain_conf.h | 5 ++++ > src/libvirt_private.syms | 1 + > src/util/xml.c | 54 > ++++++++++++++++++++++++++++++++++++++++++++++ > src/util/xml.h | 5 +++- > 6 files changed, 101 insertions(+), 7 deletions(-) > > diff --git a/docs/schemas/domain.rng b/docs/schemas/domain.rng > index 1ff0944..d295bfe 100644 > --- a/docs/schemas/domain.rng > +++ b/docs/schemas/domain.rng > @@ -297,12 +297,24 @@ > <define name="clock"> > <optional> > <element name="clock"> > - <attribute name="offset"> > - <choice> > + <choice> > + <attribute name="offset"> hum isn't that inserting tabs in the XML that we remove from time to time :-) ? > <value>localtime</value> > + </attribute> > + <attribute name="offset"> > <value>utc</value> > - </choice> > - </attribute> > + </attribute> > + <group> > + <attribute name="offset"> > + <value>variable</value> > + </attribute> > + <optional> > + <attribute name="adjustment"> > + <ref name="timeDelta"/> > + </attribute> > + </optional> > + </group> > + </choice> > <empty/> > </element> > </optional> > @@ -1567,4 +1579,9 @@ > <param name='pattern'>[a-zA-Z0-9\-_]+</param> > </data> > </define> > + <define name="timeDelta"> > + <data type="string"> actually we could use XSD integer there http://www.w3.org/TR/xmlschema-2/#integer but this won't change much > + <param name="pattern">(-|\+)?[0-9]+</param> > + </data> > + </define> > </grammar> > diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c > index f86b4eb..49d5d19 100644 > --- a/src/conf/domain_conf.c > +++ b/src/conf/domain_conf.c > @@ -231,7 +231,8 @@ VIR_ENUM_IMPL(virDomainNetdevMacvtap, > VIR_DOMAIN_NETDEV_MACVTAP_MODE_LAST, > > VIR_ENUM_IMPL(virDomainClockOffset, VIR_DOMAIN_CLOCK_OFFSET_LAST, > "utc", > - "localtime"); > + "localtime", > + "variable"); > > #define virDomainReportError(code, fmt...) \ > virReportErrorHelper(NULL, VIR_FROM_DOMAIN, code, __FILE__, \ > @@ -3492,6 +3493,13 @@ static virDomainDefPtr virDomainDefParseXML(virCapsPtr > caps, > } else { > def->clock.offset = VIR_DOMAIN_CLOCK_OFFSET_UTC; > } > + switch (def->clock.offset) { > + case VIR_DOMAIN_CLOCK_OFFSET_VARIABLE: > + if (virXPathLongLong("./clock/@adjustment", ctxt, > + &def->clock.adjustment) < 0) > + def->clock.adjustment = 0; Hum, should probably give an error message here > + break; > + } > > def->os.bootloader = virXPathString("string(./bootloader)", ctxt); > def->os.bootloaderArgs = virXPathString("string(./bootloader_args)", > ctxt); > @@ -5399,8 +5407,14 @@ char *virDomainDefFormat(virDomainDefPtr def, > if (virCPUDefFormatBuf(&buf, def->cpu, " ", 0) < 0) > goto cleanup; > > - virBufferVSprintf(&buf, " <clock offset='%s'/>\n", > + virBufferVSprintf(&buf, " <clock offset='%s'", > virDomainClockOffsetTypeToString(def->clock.offset)); > + switch (def->clock.offset) { > + case VIR_DOMAIN_CLOCK_OFFSET_VARIABLE: > + virBufferVSprintf(&buf, " adjustment='%lld'", def->clock.adjustment); > + break; > + } > + virBufferAddLit(&buf, "/>\n"); > > if (virDomainLifecycleDefFormat(&buf, def->onPoweroff, > "on_poweroff") < 0) > diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h > index fbbe683..f5fe016 100644 > --- a/src/conf/domain_conf.h > +++ b/src/conf/domain_conf.h > @@ -612,6 +612,7 @@ struct _virSecurityLabelDef { > enum virDomainClockOffsetType { > VIR_DOMAIN_CLOCK_OFFSET_UTC = 0, > VIR_DOMAIN_CLOCK_OFFSET_LOCALTIME = 1, > + VIR_DOMAIN_CLOCK_OFFSET_VARIABLE = 2, > > VIR_DOMAIN_CLOCK_OFFSET_LAST, > }; > @@ -620,6 +621,10 @@ typedef struct _virDomainClockDef virDomainClockDef; > typedef virDomainClockDef *virDomainClockDefPtr; > struct _virDomainClockDef { > int offset; > + > + /* Adjustment in seconds, relative to UTC, when > + * offset == VIR_DOMAIN_CLOCK_OFFSET_VARIABLE */ > + long long adjustment; > }; > > #define VIR_DOMAIN_CPUMASK_LEN 1024 > diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms > index 1af34bd..41bde8e 100644 > --- a/src/libvirt_private.syms > +++ b/src/libvirt_private.syms > @@ -629,6 +629,7 @@ virXPathStringLimit; > virXPathBoolean; > virXPathNumber; > virXPathULong; > +virXPathLongLong; > virXPathULongLong; > virXPathLongHex; > virXPathULongHex; > diff --git a/src/util/xml.c b/src/util/xml.c > index 46ea9aa..14c8345 100644 > --- a/src/util/xml.c > +++ b/src/util/xml.c > @@ -364,6 +364,60 @@ virXPathULongLong(const char *xpath, > return (ret); > } > > +/** > + * virXPathULongLong: > + * @xpath: the XPath string to evaluate > + * @ctxt: an XPath context > + * @value: the returned long long value > + * > + * Convenience function to evaluate an XPath number > + * > + * Returns 0 in case of success in which case @value is set, > + * or -1 if the XPath evaluation failed or -2 if the > + * value doesn't have a long format. > + */ > +int > +virXPathLongLong(const char *xpath, > + xmlXPathContextPtr ctxt, > + long long *value) > +{ > + xmlXPathObjectPtr obj; > + xmlNodePtr relnode; > + int ret = 0; > + > + if ((ctxt == NULL) || (xpath == NULL) || (value == NULL)) { > + virXMLError(VIR_ERR_INTERNAL_ERROR, > + "%s", _("Invalid parameter to virXPathLongLong()")); > + return (-1); > + } > + relnode = ctxt->node; > + obj = xmlXPathEval(BAD_CAST xpath, ctxt); > + ctxt->node = relnode; > + if ((obj != NULL) && (obj->type == XPATH_STRING) && > + (obj->stringval != NULL) && (obj->stringval[0] != 0)) { > + char *conv = NULL; > + unsigned long long val; > + > + val = strtoll((const char *) obj->stringval, &conv, 10); > + if (conv == (const char *) obj->stringval) { > + ret = -2; > + } else { > + *value = val; > + } > + } else if ((obj != NULL) && (obj->type == XPATH_NUMBER) && > + (!(isnan(obj->floatval)))) { > + *value = (long long) obj->floatval; > + if (*value != obj->floatval) { > + ret = -2; > + } > + } else { > + ret = -1; > + } > + > + xmlXPathFreeObject(obj); > + return (ret); > +} > + > char * > virXMLPropString(xmlNodePtr node, > const char *name) > diff --git a/src/util/xml.h b/src/util/xml.h > index 246672d..af721bb 100644 > --- a/src/util/xml.h > +++ b/src/util/xml.h > @@ -30,7 +30,10 @@ int virXPathULong(const char *xpath, > int virXPathULongLong(const char *xpath, > xmlXPathContextPtr ctxt, > unsigned long long *value); > -int virXPathLongHex(const char *xpath, > +int virXPathLongLong(const char *xpath, > + xmlXPathContextPtr ctxt, > + long long *value); > +int virXPathLongHex (const char *xpath, > xmlXPathContextPtr ctxt, > long *value); > int virXPathULongHex(const char *xpath, > -- > 1.6.6 ACK Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ dan...@veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/ -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list