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 :|