This extends the XML to allow for <clock offset='localtime' 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 | 25 ++++++++++++++++++++----- src/conf/domain_conf.h | 12 +++++++++--- src/xen/xend_internal.c | 10 ++++++++-- src/xen/xm_internal.c | 16 +++++++++++----- 5 files changed, 63 insertions(+), 18 deletions(-) diff --git a/docs/schemas/domain.rng b/docs/schemas/domain.rng index 5c48a8b..95c7d8e 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> @@ -1543,4 +1550,9 @@ <param name="pattern">(-|\+)?[0-9]+</param> </data> </define> + <define name="timeZone"> + <data type="string"> + <param name="pattern">[a-zA-Z0-9_\.\+\-/]+</param> + </data> + </define> </grammar> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 0c502b9..c5eb086 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -640,6 +640,9 @@ void virDomainDefFree(virDomainDefPtr def) VIR_FREE(def->os.bootloader); VIR_FREE(def->os.bootloaderArgs); + if (def->clock.offset == VIR_DOMAIN_CLOCK_OFFSET_LOCALTIME) + VIR_FREE(def->clock.data.timezone); + VIR_FREE(def->name); VIR_FREE(def->cpumask); VIR_FREE(def->emulator); @@ -3480,10 +3483,16 @@ static virDomainDefPtr virDomainDefParseXML(virConnectPtr conn, } else { def->clock.offset = VIR_DOMAIN_CLOCK_OFFSET_UTC; } - if (def->clock.offset == VIR_DOMAIN_CLOCK_OFFSET_VARIABLE) { + switch (def->clock.offset) { + case VIR_DOMAIN_CLOCK_OFFSET_LOCALTIME: + def->clock.data.timezone = virXPathString(conn, "string(./clock/@timezone)", ctxt); + break; + + case VIR_DOMAIN_CLOCK_OFFSET_VARIABLE: if (virXPathLongLong(conn, "./clock/@adjustment", ctxt, - &def->clock.adjustment) < 0) - def->clock.adjustment = 0; + &def->clock.data.adjustment) < 0) + def->clock.data.adjustment = 0; + break; } def->os.bootloader = virXPathString(conn, "string(./bootloader)", ctxt); @@ -5427,8 +5436,14 @@ char *virDomainDefFormat(virConnectPtr conn, virBufferVSprintf(&buf, " <clock offset='%s'", virDomainClockOffsetTypeToString(def->clock.offset)); - if (def->clock.offset == VIR_DOMAIN_CLOCK_OFFSET_VARIABLE) { - virBufferVSprintf(&buf, " adjustment='%lld'", def->clock.adjustment); + switch (def->clock.offset) { + case VIR_DOMAIN_CLOCK_OFFSET_LOCALTIME: + if (def->clock.data.timezone) + virBufferEscapeString(&buf, " timezone='%s'", def->clock.data.timezone); + break; + case VIR_DOMAIN_CLOCK_OFFSET_VARIABLE: + virBufferVSprintf(&buf, " adjustment='%lld'", def->clock.data.adjustment); + break; } virBufferAddLit(&buf, "/>\n"); diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 4df28e5..0261979 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -607,9 +607,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/xen/xend_internal.c b/src/xen/xend_internal.c index 98f6103..c6b5b6b 100644 --- a/src/xen/xend_internal.c +++ b/src/xen/xend_internal.c @@ -5788,9 +5788,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 4e7f844..88f472a 100644 --- a/src/xen/xm_internal.c +++ b/src/xen/xm_internal.c @@ -2328,11 +2328,17 @@ 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) { + virXendError(conn, VIR_ERR_CONFIG_UNSUPPORTED, + _("configurable timezones are not supported")); + goto error; + } + + 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 { xenXMError(conn, VIR_ERR_CONFIG_UNSUPPORTED, -- 1.6.6 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list