Allow a timezone to be specified instead of sync to host timezone

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
This commit is contained in:
Daniel P. Berrange 2010-02-02 18:28:44 +00:00
parent 200c83b29d
commit e4d7433ef0
5 changed files with 65 additions and 14 deletions

View File

@ -304,6 +304,16 @@
<attribute name="offset"> <attribute name="offset">
<value>utc</value> <value>utc</value>
</attribute> </attribute>
<group>
<attribute name="offset">
<value>timezone</value>
</attribute>
<optional>
<attribute name="timezone">
<ref name="timeZone"/>
</attribute>
</optional>
</group>
<group> <group>
<attribute name="offset"> <attribute name="offset">
<value>variable</value> <value>variable</value>
@ -1633,4 +1643,9 @@
<param name="pattern">(-|\+)?[0-9]+</param> <param name="pattern">(-|\+)?[0-9]+</param>
</data> </data>
</define> </define>
<define name="timeZone">
<data type="string">
<param name="pattern">[a-zA-Z0-9_\.\+\-/]+</param>
</data>
</define>
</grammar> </grammar>

View File

@ -235,7 +235,8 @@ VIR_ENUM_IMPL(virDomainNetdevMacvtap, VIR_DOMAIN_NETDEV_MACVTAP_MODE_LAST,
VIR_ENUM_IMPL(virDomainClockOffset, VIR_DOMAIN_CLOCK_OFFSET_LAST, VIR_ENUM_IMPL(virDomainClockOffset, VIR_DOMAIN_CLOCK_OFFSET_LAST,
"utc", "utc",
"localtime", "localtime",
"variable"); "variable",
"timezone");
#define virDomainReportError(code, fmt...) \ #define virDomainReportError(code, fmt...) \
virReportErrorHelper(NULL, VIR_FROM_DOMAIN, code, __FILE__, \ virReportErrorHelper(NULL, VIR_FROM_DOMAIN, code, __FILE__, \
@ -657,6 +658,9 @@ void virDomainDefFree(virDomainDefPtr def)
VIR_FREE(def->os.bootloader); VIR_FREE(def->os.bootloader);
VIR_FREE(def->os.bootloaderArgs); 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->name);
VIR_FREE(def->cpumask); VIR_FREE(def->cpumask);
VIR_FREE(def->emulator); VIR_FREE(def->emulator);
@ -3584,8 +3588,17 @@ static virDomainDefPtr virDomainDefParseXML(virCapsPtr caps,
switch (def->clock.offset) { switch (def->clock.offset) {
case VIR_DOMAIN_CLOCK_OFFSET_VARIABLE: case VIR_DOMAIN_CLOCK_OFFSET_VARIABLE:
if (virXPathLongLong("number(./clock/@adjustment)", ctxt, if (virXPathLongLong("number(./clock/@adjustment)", ctxt,
&def->clock.adjustment) < 0) &def->clock.data.adjustment) < 0)
def->clock.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; break;
} }
@ -5547,7 +5560,10 @@ char *virDomainDefFormat(virDomainDefPtr def,
virDomainClockOffsetTypeToString(def->clock.offset)); virDomainClockOffsetTypeToString(def->clock.offset));
switch (def->clock.offset) { switch (def->clock.offset) {
case VIR_DOMAIN_CLOCK_OFFSET_VARIABLE: 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; break;
} }
virBufferAddLit(&buf, "/>\n"); virBufferAddLit(&buf, "/>\n");

View File

@ -635,6 +635,7 @@ enum virDomainClockOffsetType {
VIR_DOMAIN_CLOCK_OFFSET_UTC = 0, VIR_DOMAIN_CLOCK_OFFSET_UTC = 0,
VIR_DOMAIN_CLOCK_OFFSET_LOCALTIME = 1, VIR_DOMAIN_CLOCK_OFFSET_LOCALTIME = 1,
VIR_DOMAIN_CLOCK_OFFSET_VARIABLE = 2, VIR_DOMAIN_CLOCK_OFFSET_VARIABLE = 2,
VIR_DOMAIN_CLOCK_OFFSET_TIMEZONE = 3,
VIR_DOMAIN_CLOCK_OFFSET_LAST, VIR_DOMAIN_CLOCK_OFFSET_LAST,
}; };
@ -644,9 +645,15 @@ typedef virDomainClockDef *virDomainClockDefPtr;
struct _virDomainClockDef { struct _virDomainClockDef {
int offset; int offset;
/* Adjustment in seconds, relative to UTC, when union {
* offset == VIR_DOMAIN_CLOCK_OFFSET_VARIABLE */ /* Adjustment in seconds, relative to UTC, when
long long adjustment; * 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 #define VIR_DOMAIN_CPUMASK_LEN 1024

View File

@ -5846,9 +5846,15 @@ xenDaemonFormatSxpr(virConnectPtr conn,
virBufferVSprintf(&buf, "(on_crash '%s')", tmp); virBufferVSprintf(&buf, "(on_crash '%s')", tmp);
/* Set localtime here for current XenD (both PV & HVM) */ /* 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)"); 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, virXendError(conn, VIR_ERR_CONFIG_UNSUPPORTED,
_("unsupported clock offset '%s'"), _("unsupported clock offset '%s'"),
virDomainClockOffsetTypeToString(def->clock.offset)); virDomainClockOffsetTypeToString(def->clock.offset));

View File

@ -2328,13 +2328,20 @@ virConfPtr xenXMDomainConfigFormat(virConnectPtr conn,
goto no_memory; goto no_memory;
if (def->clock.offset == VIR_DOMAIN_CLOCK_OFFSET_LOCALTIME || if (def->clock.offset == VIR_DOMAIN_CLOCK_OFFSET_LOCALTIME) {
def->clock.offset == VIR_DOMAIN_CLOCK_OFFSET_UTC) { if (def->clock.data.timezone) {
if (xenXMConfigSetInt(conf, "localtime", xenXMError(conn, VIR_ERR_CONFIG_UNSUPPORTED,
def->clock.offset == VIR_DOMAIN_CLOCK_OFFSET_LOCALTIME ? _("configurable timezones are not supported"));
1 : 0) < 0) 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; goto no_memory;
} else { } else {
/* XXX We could support Xen's rtc clock offset */
xenXMError(conn, VIR_ERR_CONFIG_UNSUPPORTED, xenXMError(conn, VIR_ERR_CONFIG_UNSUPPORTED,
_("unsupported clock offset '%s'"), _("unsupported clock offset '%s'"),
virDomainClockOffsetTypeToString(def->clock.offset)); virDomainClockOffsetTypeToString(def->clock.offset));