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