[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