From e4d7433ef0201bd5c5ce0ecaa2ca85a68ca48df6 Mon Sep 17 00:00:00 2001 From: "Daniel P. Berrange" Date: Tue, 2 Feb 2010 18:28:44 +0000 Subject: [PATCH] Allow a timezone to be specified instead of sync to host timezone This extends the XML to allow for 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 | 15 +++++++++++++++ src/conf/domain_conf.c | 24 ++++++++++++++++++++---- src/conf/domain_conf.h | 13 ++++++++++--- src/xen/xend_internal.c | 10 ++++++++-- src/xen/xm_internal.c | 17 ++++++++++++----- 5 files changed, 65 insertions(+), 14 deletions(-) diff --git a/docs/schemas/domain.rng b/docs/schemas/domain.rng index 820729fa77..5a8c82be23 100644 --- a/docs/schemas/domain.rng +++ b/docs/schemas/domain.rng @@ -304,6 +304,16 @@ utc + + + timezone + + + + + + + variable @@ -1633,4 +1643,9 @@ (-|\+)?[0-9]+ + + + [a-zA-Z0-9_\.\+\-/]+ + + diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 7820634046..df1ec18e2f 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -235,7 +235,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__, \ @@ -657,6 +658,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); @@ -3584,8 +3588,17 @@ static virDomainDefPtr virDomainDefParseXML(virCapsPtr caps, switch (def->clock.offset) { case VIR_DOMAIN_CLOCK_OFFSET_VARIABLE: if (virXPathLongLong("number(./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; } @@ -5547,7 +5560,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 e597ea8f7f..bb6b3aad18 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -635,6 +635,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, }; @@ -644,9 +645,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 860cd6a7e6..5f46e9f5be 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 4c2066698d..014cbfc16f 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)); -- GitLab