On Mon, Mar 01, 2010 at 03:02:06PM +0100, Daniel Veillard wrote: > 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). libvirt would be responsible for doing the right thing during migration - its only the persistent config on disk that apps are responsible for. > > > * 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 :-) ? Hmm, our syntax-check only seems to validate no-TABS for source code files, not schemas/docs > > > <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 -- |: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :| |: http://libvirt.org -o- http://virt-manager.org -o- http://deltacloud.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :| -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list