提交 4ee2b318 编写于 作者: L Laine Stump

Changes to clock timer XML to match final design.

The clock timer XML is being updated in the following ways (based on
further off-list discussion that was missed during the initial
implementation):

1) 'wallclock' is changed to 'track', and the possible values are 'boot'
 (corresponds to old 'host'), 'guest', and 'wall'.

2) 'mode' has an additional value 'smpsafe'

3) when tickpolicy='catchup', there can be an optional sub-element of
   timer called 'catchup':

   <catchup threshold=123 slew=120 limit=10000/>

Those three values are all longs, always optional, and if they are present,
they are positive. Internally, 0 indicates "unspecified".

* docs/schemas/domain.rng: updated RNG definition to account for changes

* src/conf/domain_conf.h: change the C struct and enums to match changes.

* src/conf/domain_conf.c: timer parse and format functions changed to
                          handle the new selections and new element.

* src/libvirt_private.syms: *TimerWallclock* changes to *TimerTrack*

* src/qemu/qemu_conf.c: again, account for Wallclock --> Track change.
上级 8a7b4be5
...@@ -344,10 +344,11 @@ ...@@ -344,10 +344,11 @@
</choice> </choice>
</attribute> </attribute>
<optional> <optional>
<attribute name="wallclock"> <attribute name="track">
<choice> <choice>
<value>host</value> <value>boot</value>
<value>guest</value> <value>guest</value>
<value>wall</value>
</choice> </choice>
</attribute> </attribute>
</optional> </optional>
...@@ -361,6 +362,9 @@ ...@@ -361,6 +362,9 @@
</choice> </choice>
</attribute> </attribute>
</optional> </optional>
<optional>
<ref name="catchup"/>
</optional>
<optional> <optional>
<attribute name="frequency"> <attribute name="frequency">
<ref name="unsignedInt"/> <ref name="unsignedInt"/>
...@@ -373,6 +377,7 @@ ...@@ -373,6 +377,7 @@
<value>native</value> <value>native</value>
<value>emulate</value> <value>emulate</value>
<value>paravirt</value> <value>paravirt</value>
<value>smpsafe</value>
</choice> </choice>
</attribute> </attribute>
</optional> </optional>
...@@ -387,6 +392,21 @@ ...@@ -387,6 +392,21 @@
<empty/> <empty/>
</element> </element>
</define> </define>
<define name="catchup">
<element name="catchup">
<optional>
<attribute name="threshold">
<ref name="unsignedInt"/>
</attribute>
<attribute name="slew">
<ref name="unsignedInt"/>
</attribute>
<attribute name="limit">
<ref name="unsignedInt"/>
</attribute>
</optional>
</element>
</define>
<!-- <!--
A bootloader may be used to extract the OS information instead of A bootloader may be used to extract the OS information instead of
defining the OS parameter in the instance. It points just to the defining the OS parameter in the instance. It points just to the
......
...@@ -252,9 +252,10 @@ VIR_ENUM_IMPL(virDomainTimerName, VIR_DOMAIN_TIMER_NAME_LAST, ...@@ -252,9 +252,10 @@ VIR_ENUM_IMPL(virDomainTimerName, VIR_DOMAIN_TIMER_NAME_LAST,
"hpet", "hpet",
"tsc"); "tsc");
VIR_ENUM_IMPL(virDomainTimerWallclock, VIR_DOMAIN_TIMER_WALLCLOCK_LAST, VIR_ENUM_IMPL(virDomainTimerTrack, VIR_DOMAIN_TIMER_TRACK_LAST,
"host", "boot",
"guest"); "guest",
"wall");
VIR_ENUM_IMPL(virDomainTimerTickpolicy, VIR_DOMAIN_TIMER_TICKPOLICY_LAST, VIR_ENUM_IMPL(virDomainTimerTickpolicy, VIR_DOMAIN_TIMER_TICKPOLICY_LAST,
"delay", "delay",
...@@ -266,7 +267,8 @@ VIR_ENUM_IMPL(virDomainTimerMode, VIR_DOMAIN_TIMER_MODE_LAST, ...@@ -266,7 +267,8 @@ VIR_ENUM_IMPL(virDomainTimerMode, VIR_DOMAIN_TIMER_MODE_LAST,
"auto", "auto",
"native", "native",
"emulate", "emulate",
"paravirt"); "paravirt",
"smpsafe");
#define virDomainReportError(code, ...) \ #define virDomainReportError(code, ...) \
virReportErrorHelper(NULL, VIR_FROM_DOMAIN, code, __FILE__, \ virReportErrorHelper(NULL, VIR_FROM_DOMAIN, code, __FILE__, \
...@@ -2575,7 +2577,7 @@ virDomainTimerDefParseXML(const xmlNodePtr node, ...@@ -2575,7 +2577,7 @@ virDomainTimerDefParseXML(const xmlNodePtr node,
char *name = NULL; char *name = NULL;
char *present = NULL; char *present = NULL;
char *tickpolicy = NULL; char *tickpolicy = NULL;
char *wallclock = NULL; char *track = NULL;
char *mode = NULL; char *mode = NULL;
virDomainTimerDefPtr def; virDomainTimerDefPtr def;
...@@ -2623,12 +2625,12 @@ virDomainTimerDefParseXML(const xmlNodePtr node, ...@@ -2623,12 +2625,12 @@ virDomainTimerDefParseXML(const xmlNodePtr node,
} }
} }
def->wallclock = -1; def->track = -1;
wallclock = virXMLPropString(node, "wallclock"); track = virXMLPropString(node, "track");
if (wallclock != NULL) { if (track != NULL) {
if ((def->wallclock = virDomainTimerWallclockTypeFromString(wallclock)) < 0) { if ((def->track = virDomainTimerTrackTypeFromString(track)) < 0) {
virDomainReportError(VIR_ERR_INTERNAL_ERROR, virDomainReportError(VIR_ERR_INTERNAL_ERROR,
_("unknown timer wallclock '%s'"), wallclock); _("unknown timer track '%s'"), track);
goto error; goto error;
} }
} }
...@@ -2636,7 +2638,7 @@ virDomainTimerDefParseXML(const xmlNodePtr node, ...@@ -2636,7 +2638,7 @@ virDomainTimerDefParseXML(const xmlNodePtr node,
int ret = virXPathULong("string(./frequency)", ctxt, &def->frequency); int ret = virXPathULong("string(./frequency)", ctxt, &def->frequency);
if (ret == -1) { if (ret == -1) {
def->frequency = 0; def->frequency = 0;
} else if (ret <= 0) { } else if (ret < 0) {
virDomainReportError(VIR_ERR_INTERNAL_ERROR, virDomainReportError(VIR_ERR_INTERNAL_ERROR,
"%s", _("invalid timer frequency")); "%s", _("invalid timer frequency"));
goto error; goto error;
...@@ -2652,11 +2654,42 @@ virDomainTimerDefParseXML(const xmlNodePtr node, ...@@ -2652,11 +2654,42 @@ virDomainTimerDefParseXML(const xmlNodePtr node,
} }
} }
xmlNodePtr catchup = virXPathNode("./catchup", ctxt);
if (catchup != NULL) {
ret = virXPathULong("string(./catchup/@threshold)", ctxt,
&def->catchup.threshold);
if (ret == -1) {
def->catchup.threshold = 0;
} else if (ret < 0) {
virDomainReportError(VIR_ERR_INTERNAL_ERROR,
"%s", _("invalid catchup threshold"));
goto error;
}
ret = virXPathULong("string(./catchup/@slew)", ctxt, &def->catchup.slew);
if (ret == -1) {
def->catchup.slew = 0;
} else if (ret < 0) {
virDomainReportError(VIR_ERR_INTERNAL_ERROR,
"%s", _("invalid catchup slew"));
goto error;
}
ret = virXPathULong("string(./catchup/@limit)", ctxt, &def->catchup.limit);
if (ret == -1) {
def->catchup.limit = 0;
} else if (ret < 0) {
virDomainReportError(VIR_ERR_INTERNAL_ERROR,
"%s", _("invalid catchup limit"));
goto error;
}
}
cleanup: cleanup:
VIR_FREE(name); VIR_FREE(name);
VIR_FREE(present); VIR_FREE(present);
VIR_FREE(tickpolicy); VIR_FREE(tickpolicy);
VIR_FREE(wallclock); VIR_FREE(track);
VIR_FREE(mode); VIR_FREE(mode);
ctxt->node = oldnode; ctxt->node = oldnode;
...@@ -5474,16 +5507,16 @@ virDomainTimerDefFormat(virBufferPtr buf, ...@@ -5474,16 +5507,16 @@ virDomainTimerDefFormat(virBufferPtr buf,
if ((def->name == VIR_DOMAIN_TIMER_NAME_PLATFORM) if ((def->name == VIR_DOMAIN_TIMER_NAME_PLATFORM)
|| (def->name == VIR_DOMAIN_TIMER_NAME_RTC)) { || (def->name == VIR_DOMAIN_TIMER_NAME_RTC)) {
if (def->wallclock != -1) { if (def->track != -1) {
const char *wallclock const char *track
= virDomainTimerWallclockTypeToString(def->wallclock); = virDomainTimerTrackTypeToString(def->track);
if (!wallclock) { if (!track) {
virDomainReportError(VIR_ERR_INTERNAL_ERROR, virDomainReportError(VIR_ERR_INTERNAL_ERROR,
_("unexpected timer wallclock %d"), _("unexpected timer track %d"),
def->wallclock); def->track);
return -1; return -1;
} }
virBufferVSprintf(buf, " wallclock='%s'", wallclock); virBufferVSprintf(buf, " track='%s'", track);
} }
} }
...@@ -5505,7 +5538,23 @@ virDomainTimerDefFormat(virBufferPtr buf, ...@@ -5505,7 +5538,23 @@ virDomainTimerDefFormat(virBufferPtr buf,
} }
} }
virBufferAddLit(buf, "/>\n"); if ((def->catchup.threshold == 0)
&& (def->catchup.slew == 0)
&& (def->catchup.limit == 0)) {
virBufferAddLit(buf, "/>\n");
} else {
virBufferAddLit(buf, ">\n <catchup ");
if (def->catchup.threshold > 0) {
virBufferVSprintf(buf, " threshold='%lu'", def->catchup.threshold);
}
if (def->catchup.slew > 0) {
virBufferVSprintf(buf, " slew='%lu'", def->catchup.slew);
}
if (def->catchup.limit > 0) {
virBufferVSprintf(buf, " limit='%lu'", def->catchup.limit);
}
virBufferAddLit(buf, "/>\n </timer>\n");
}
return 0; return 0;
} }
......
...@@ -659,11 +659,12 @@ enum virDomainTimerNameType { ...@@ -659,11 +659,12 @@ enum virDomainTimerNameType {
VIR_DOMAIN_TIMER_NAME_LAST, VIR_DOMAIN_TIMER_NAME_LAST,
}; };
enum virDomainTimerWallclockType { enum virDomainTimerTrackType {
VIR_DOMAIN_TIMER_WALLCLOCK_HOST = 0, VIR_DOMAIN_TIMER_TRACK_BOOT = 0,
VIR_DOMAIN_TIMER_WALLCLOCK_GUEST, VIR_DOMAIN_TIMER_TRACK_GUEST,
VIR_DOMAIN_TIMER_TRACK_WALL,
VIR_DOMAIN_TIMER_WALLCLOCK_LAST, VIR_DOMAIN_TIMER_TRACK_LAST,
}; };
enum virDomainTimerTickpolicyType { enum virDomainTimerTickpolicyType {
...@@ -680,10 +681,19 @@ enum virDomainTimerModeType { ...@@ -680,10 +681,19 @@ enum virDomainTimerModeType {
VIR_DOMAIN_TIMER_MODE_NATIVE, VIR_DOMAIN_TIMER_MODE_NATIVE,
VIR_DOMAIN_TIMER_MODE_EMULATE, VIR_DOMAIN_TIMER_MODE_EMULATE,
VIR_DOMAIN_TIMER_MODE_PARAVIRT, VIR_DOMAIN_TIMER_MODE_PARAVIRT,
VIR_DOMAIN_TIMER_MODE_SMPSAFE,
VIR_DOMAIN_TIMER_MODE_LAST, VIR_DOMAIN_TIMER_MODE_LAST,
}; };
typedef struct _virDomainTimerCatchupDef virDomainTimerCatchupDef;
typedef virDomainTimerCatchupDef *virDomainTimerCatchupDefPtr;
struct _virDomainTimerCatchupDef {
unsigned long threshold;
unsigned long slew;
unsigned long limit;
};
typedef struct _virDomainTimerDef virDomainTimerDef; typedef struct _virDomainTimerDef virDomainTimerDef;
typedef virDomainTimerDef *virDomainTimerDefPtr; typedef virDomainTimerDef *virDomainTimerDefPtr;
struct _virDomainTimerDef { struct _virDomainTimerDef {
...@@ -691,8 +701,10 @@ struct _virDomainTimerDef { ...@@ -691,8 +701,10 @@ struct _virDomainTimerDef {
int present; /* unspecified = -1, no = 0, yes = 1 */ int present; /* unspecified = -1, no = 0, yes = 1 */
int tickpolicy; /* none|catchup|merge|discard */ int tickpolicy; /* none|catchup|merge|discard */
/* wallclock is only valid for name='platform|rtc' */ virDomainTimerCatchupDef catchup;
int wallclock; /* host|guest */
/* track is only valid for name='platform|rtc' */
int track; /* host|guest */
/* frequency & mode are only valid for name='tsc' */ /* frequency & mode are only valid for name='tsc' */
unsigned long frequency; /* in Hz, unspecified = 0 */ unsigned long frequency; /* in Hz, unspecified = 0 */
...@@ -1032,7 +1044,7 @@ VIR_ENUM_DECL(virDomainClockOffset) ...@@ -1032,7 +1044,7 @@ VIR_ENUM_DECL(virDomainClockOffset)
VIR_ENUM_DECL(virDomainNetdevMacvtap) VIR_ENUM_DECL(virDomainNetdevMacvtap)
VIR_ENUM_DECL(virDomainTimerName) VIR_ENUM_DECL(virDomainTimerName)
VIR_ENUM_DECL(virDomainTimerWallclock) VIR_ENUM_DECL(virDomainTimerTrack)
VIR_ENUM_DECL(virDomainTimerTickpolicy) VIR_ENUM_DECL(virDomainTimerTickpolicy)
VIR_ENUM_DECL(virDomainTimerMode) VIR_ENUM_DECL(virDomainTimerMode)
......
...@@ -199,8 +199,8 @@ virDomainClockOffsetTypeFromString; ...@@ -199,8 +199,8 @@ virDomainClockOffsetTypeFromString;
virDomainDiskErrorPolicyTypeToString; virDomainDiskErrorPolicyTypeToString;
virDomainTimerNameTypeToString; virDomainTimerNameTypeToString;
virDomainTimerNameTypeFromString; virDomainTimerNameTypeFromString;
virDomainTimerWallclockTypeToString; virDomainTimerTrackTypeToString;
virDomainTimerWallclockTypeFromString; virDomainTimerTrackTypeFromString;
virDomainTimerTickpolicyTypeToString; virDomainTimerTickpolicyTypeToString;
virDomainTimerTickpolicyTypeFromString; virDomainTimerTickpolicyTypeFromString;
virDomainTimerModeTypeToString; virDomainTimerModeTypeToString;
......
...@@ -3183,11 +3183,22 @@ qemuBuildClockArgStr(virDomainClockDefPtr def) ...@@ -3183,11 +3183,22 @@ qemuBuildClockArgStr(virDomainClockDefPtr def)
int i; int i;
for (i = 0; i < def->ntimers; i++) { for (i = 0; i < def->ntimers; i++) {
if (def->timers[i]->name == VIR_DOMAIN_TIMER_NAME_RTC) { if (def->timers[i]->name == VIR_DOMAIN_TIMER_NAME_RTC) {
if (def->timers[i]->wallclock == VIR_DOMAIN_TIMER_WALLCLOCK_HOST) { switch (def->timers[i]->track) {
virBufferAddLit(&buf, ",clock=host"); case -1: /* unspecified - use hypervisor default */
} else if (def->timers[i]->wallclock == VIR_DOMAIN_TIMER_WALLCLOCK_GUEST) { break;
case VIR_DOMAIN_TIMER_TRACK_BOOT:
qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("unsupported rtc timer track '%s'"),
virDomainTimerTrackTypeToString(def->timers[i]->track));
goto error;
case VIR_DOMAIN_TIMER_TRACK_GUEST:
virBufferAddLit(&buf, ",clock=vm"); virBufferAddLit(&buf, ",clock=vm");
break;
case VIR_DOMAIN_TIMER_TRACK_WALL:
virBufferAddLit(&buf, ",clock=host");
break;
} }
switch (def->timers[i]->tickpolicy) { switch (def->timers[i]->tickpolicy) {
case -1: case -1:
case VIR_DOMAIN_TIMER_TICKPOLICY_DELAY: case VIR_DOMAIN_TIMER_TICKPOLICY_DELAY:
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册