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

Daniel P. Berrange berrange at redhat.com
Mon Mar 1 18:44:12 UTC 2010


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




More information about the libvir-list mailing list