[libvirt] [PATCH 4/6] Allow a timezone to be specified instead of sync to host timezone

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


On Thu, Feb 18, 2010 at 05:54:30PM +0000, Daniel P. Berrange wrote:
> This extends the XML to allow for
> 
>   <clock offset='timezone' timezone='Europe/Paris'/>
> 
> This is useful if the admin has not configured any timezone on the
> host OS, but still wants to synchronize a guest to a specific one.
> 
> * src/conf/domain_conf.h, src/conf/domain_conf.c: Support extra
>   'timezone' attribute on clock configuration
> * docs/schemas/domain.rng: Add 'timezone' attribute
> * src/xen/xend_internal.c, src/xen/xm_internal.c: Reject configs
>   with a configurable timezone
> ---
>  docs/schemas/domain.rng |   18 +++++++++++++++---
>  src/conf/domain_conf.c  |   24 ++++++++++++++++++++----
>  src/conf/domain_conf.h  |   13 ++++++++++---
>  src/qemu/qemu_conf.c    |    2 +-
>  src/xen/xend_internal.c |   10 ++++++++--
>  src/xen/xm_internal.c   |   17 ++++++++++++-----
>  6 files changed, 66 insertions(+), 18 deletions(-)
> 
> diff --git a/docs/schemas/domain.rng b/docs/schemas/domain.rng
> index d295bfe..4a36a97 100644
> --- a/docs/schemas/domain.rng
> +++ b/docs/schemas/domain.rng
> @@ -298,9 +298,16 @@
>      <optional>
>        <element name="clock">
>  	<choice>
> -          <attribute name="offset">
> -            <value>localtime</value>
> -	  </attribute>
> +	  <group>
> +            <attribute name="offset">
> +              <value>localtime</value>
> +	    </attribute>
> +	    <optional>
> +	      <attribute name="timezone">
> +		<ref name="timeZone"/>
> +	      </attribute>
> +	    </optional>
> +	  </group>
>            <attribute name="offset">
>              <value>utc</value>
>  	  </attribute>
> @@ -1584,4 +1591,9 @@
>        <param name="pattern">(-|\+)?[0-9]+</param>
>      </data>
>    </define>
> +  <define name="timeZone">
> +    <data type="string">
> +      <param name="pattern">[a-zA-Z0-9_\.\+\-/]+</param>

  Hum ... I wonder if we should not add ':' as it's used for POSIX TZ

> +    </data>
> +  </define>
>  </grammar>
> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
> index 49d5d19..ed5d9fd 100644
> --- a/src/conf/domain_conf.c
> +++ b/src/conf/domain_conf.c
> @@ -232,7 +232,8 @@ VIR_ENUM_IMPL(virDomainNetdevMacvtap, VIR_DOMAIN_NETDEV_MACVTAP_MODE_LAST,
>  VIR_ENUM_IMPL(virDomainClockOffset, VIR_DOMAIN_CLOCK_OFFSET_LAST,
>                "utc",
>                "localtime",
> -              "variable");
> +              "variable",
> +              "timezone");
>  
>  #define virDomainReportError(code, fmt...)                           \
>      virReportErrorHelper(NULL, VIR_FROM_DOMAIN, code, __FILE__,      \
> @@ -650,6 +651,9 @@ void virDomainDefFree(virDomainDefPtr def)
>      VIR_FREE(def->os.bootloader);
>      VIR_FREE(def->os.bootloaderArgs);
>  
> +    if (def->clock.offset == VIR_DOMAIN_CLOCK_OFFSET_TIMEZONE)
> +        VIR_FREE(def->clock.data.timezone);
> +
>      VIR_FREE(def->name);
>      VIR_FREE(def->cpumask);
>      VIR_FREE(def->emulator);
> @@ -3496,8 +3500,17 @@ static virDomainDefPtr virDomainDefParseXML(virCapsPtr caps,
>      switch (def->clock.offset) {
>      case VIR_DOMAIN_CLOCK_OFFSET_VARIABLE:
>          if (virXPathLongLong("./clock/@adjustment", ctxt,
> -                             &def->clock.adjustment) < 0)
> -            def->clock.adjustment = 0;
> +                             &def->clock.data.adjustment) < 0)
> +            def->clock.data.adjustment = 0;
> +        break;
> +
> +    case VIR_DOMAIN_CLOCK_OFFSET_TIMEZONE:
> +        def->clock.data.timezone = virXPathString("string(./clock/@timezone)", ctxt);
> +        if (!def->clock.data.timezone) {
> +            virDomainReportError(VIR_ERR_INTERNAL_ERROR, "%s",
> +                                 _("missing 'timezone' attribute for clock with offset='timezone'"));
> +            goto error;
> +        }
>          break;
>      }
>  
> @@ -5411,7 +5424,10 @@ char *virDomainDefFormat(virDomainDefPtr def,
>                        virDomainClockOffsetTypeToString(def->clock.offset));
>      switch (def->clock.offset) {
>      case VIR_DOMAIN_CLOCK_OFFSET_VARIABLE:
> -        virBufferVSprintf(&buf, " adjustment='%lld'", def->clock.adjustment);
> +        virBufferVSprintf(&buf, " adjustment='%lld'", def->clock.data.adjustment);
> +        break;
> +    case VIR_DOMAIN_CLOCK_OFFSET_TIMEZONE:
> +        virBufferEscapeString(&buf, " timezone='%s'", def->clock.data.timezone);
>          break;
>      }
>      virBufferAddLit(&buf, "/>\n");
> diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
> index f5fe016..1dcfaa5 100644
> --- a/src/conf/domain_conf.h
> +++ b/src/conf/domain_conf.h
> @@ -613,6 +613,7 @@ enum virDomainClockOffsetType {
>      VIR_DOMAIN_CLOCK_OFFSET_UTC = 0,
>      VIR_DOMAIN_CLOCK_OFFSET_LOCALTIME = 1,
>      VIR_DOMAIN_CLOCK_OFFSET_VARIABLE = 2,
> +    VIR_DOMAIN_CLOCK_OFFSET_TIMEZONE = 3,
>  
>      VIR_DOMAIN_CLOCK_OFFSET_LAST,
>  };
> @@ -622,9 +623,15 @@ typedef virDomainClockDef *virDomainClockDefPtr;
>  struct _virDomainClockDef {
>      int offset;
>  
> -    /* Adjustment in seconds, relative to UTC, when
> -     * offset == VIR_DOMAIN_CLOCK_OFFSET_VARIABLE */
> -    long long adjustment;
> +    union {
> +        /* Adjustment in seconds, relative to UTC, when
> +         * offset == VIR_DOMAIN_CLOCK_OFFSET_VARIABLE */
> +        long long adjustment;
> +
> +        /* Timezone name, when
> +         * offset == VIR_DOMAIN_CLOCK_OFFSET_LOCALTIME */
> +        char *timezone;
> +    } data;
>  };
>  
>  #define VIR_DOMAIN_CPUMASK_LEN 1024
> diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c
> index 112a7c2..cd0dd7f 100644
> --- a/src/qemu/qemu_conf.c
> +++ b/src/qemu/qemu_conf.c
> @@ -2990,7 +2990,7 @@ qemuBuildClockArgStr(virDomainClockDefPtr def)
>          time_t now = time(NULL);
>          struct tm nowbits;
>  
> -        now += def->adjustment;
> +        now += def->data.adjustment;
>          gmtime_r(&now, &nowbits);
>  
>          virBufferVSprintf(&buf, "base=%d-%d-%dT%d:%d:%d",
> diff --git a/src/xen/xend_internal.c b/src/xen/xend_internal.c
> index c88ea64..3a14d91 100644
> --- a/src/xen/xend_internal.c
> +++ b/src/xen/xend_internal.c
> @@ -5846,9 +5846,15 @@ xenDaemonFormatSxpr(virConnectPtr conn,
>      virBufferVSprintf(&buf, "(on_crash '%s')", tmp);
>  
>      /* Set localtime here for current XenD (both PV & HVM) */
> -    if (def->clock.offset == VIR_DOMAIN_CLOCK_OFFSET_LOCALTIME)
> +    if (def->clock.offset == VIR_DOMAIN_CLOCK_OFFSET_LOCALTIME) {
> +        if (def->clock.data.timezone) {
> +            virXendError(conn, VIR_ERR_CONFIG_UNSUPPORTED,
> +                         _("configurable timezones are not supported"));
> +            goto error;
> +        }
> +
>          virBufferAddLit(&buf, "(localtime 1)");
> -    else if (def->clock.offset != VIR_DOMAIN_CLOCK_OFFSET_UTC) {
> +    } else if (def->clock.offset != VIR_DOMAIN_CLOCK_OFFSET_UTC) {
>          virXendError(conn, VIR_ERR_CONFIG_UNSUPPORTED,
>                       _("unsupported clock offset '%s'"),
>                       virDomainClockOffsetTypeToString(def->clock.offset));
> diff --git a/src/xen/xm_internal.c b/src/xen/xm_internal.c
> index 4c20666..014cbfc 100644
> --- a/src/xen/xm_internal.c
> +++ b/src/xen/xm_internal.c
> @@ -2328,13 +2328,20 @@ virConfPtr xenXMDomainConfigFormat(virConnectPtr conn,
>              goto no_memory;
>  
>  
> -        if (def->clock.offset == VIR_DOMAIN_CLOCK_OFFSET_LOCALTIME ||
> -            def->clock.offset == VIR_DOMAIN_CLOCK_OFFSET_UTC) {
> -            if (xenXMConfigSetInt(conf, "localtime",
> -                                  def->clock.offset == VIR_DOMAIN_CLOCK_OFFSET_LOCALTIME ?
> -                                  1 : 0) < 0)
> +        if (def->clock.offset == VIR_DOMAIN_CLOCK_OFFSET_LOCALTIME) {
> +            if (def->clock.data.timezone) {
> +                xenXMError(conn, VIR_ERR_CONFIG_UNSUPPORTED,
> +                           _("configurable timezones are not supported"));
> +                goto cleanup;
> +            }
> +
> +            if (xenXMConfigSetInt(conf, "localtime", 1) < 0)
> +                goto no_memory;
> +        } else if (def->clock.offset == VIR_DOMAIN_CLOCK_OFFSET_UTC) {
> +            if (xenXMConfigSetInt(conf, "localtime", 0) < 0)
>                  goto no_memory;
>          } else {
> +            /* XXX We could support Xen's rtc clock offset */
>              xenXMError(conn, VIR_ERR_CONFIG_UNSUPPORTED,
>                         _("unsupported clock offset '%s'"),
>                         virDomainClockOffsetTypeToString(def->clock.offset));

  ACK, looks fine,

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