[libvirt] [PATCH 2/6] Add new clock mode allowing variable adjustments

Daniel Veillard veillard at redhat.com
Mon Mar 1 14:02:06 UTC 2010


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/
daniel at veillard.com  | Rpmfind RPM search engine http://rpmfind.net/
http://veillard.com/ | virtualization library  http://libvirt.org/




More information about the libvir-list mailing list