diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index 6b067230956ea28864f34b1d687e0051810f80c4..cb7532e2bd85f1cd8aafaa5bbd94daf44172793a 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -559,7 +559,7 @@
...
<cpu match='exact'>
- <model>core2duo</model>
+ <model fallback='allow'>core2duo</model>
<vendor>Intel</vendor>
<topology sockets='1' cores='2' threads='1'/>
<feature policy='disable' name='lahf_lm'/>
@@ -609,7 +609,15 @@
The content of the model
element specifies CPU model
requested by the guest. The list of available CPU models and their
definition can be found in cpu_map.xml
file installed
- in libvirt's data directory.
+ in libvirt's data directory. If a hypervisor is not able to use the
+ exact CPU model, libvirt automatically falls back to a closest model
+ supported by the hypervisor while maintaining the list of CPU
+ features. Since 0.9.10 , an optional
+ fallback
attribute can be used to forbid this behavior,
+ in which case an attempt to start a domain requesting an unsupported
+ CPU model will fail. Supported values for fallback
+ attribute are: allow
(this is the default), and
+ forbid
.
vendor
Since 0.8.3 the content of the
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index b54fd68ac7eb80fc01819f5e831ceba7c57780d0..133b7f7a826d71c33f324eb863c74ae74d57bdf9 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -2571,6 +2571,14 @@
+
+
+
+ allow
+ forbid
+
+
+
diff --git a/src/conf/cpu_conf.c b/src/conf/cpu_conf.c
index 348299b5fcd30e7a48e7a8480f70d7131aa8bfee..c8e29e4cd8dc0e798683092c57399e8412c62652 100644
--- a/src/conf/cpu_conf.c
+++ b/src/conf/cpu_conf.c
@@ -44,6 +44,10 @@ VIR_ENUM_IMPL(virCPUMatch, VIR_CPU_MATCH_LAST,
"exact",
"strict")
+VIR_ENUM_IMPL(virCPUFallback, VIR_CPU_FALLBACK_LAST,
+ "allow",
+ "forbid")
+
VIR_ENUM_IMPL(virCPUFeaturePolicy, VIR_CPU_FEATURE_LAST,
"force",
"require",
@@ -97,6 +101,7 @@ virCPUDefCopy(const virCPUDefPtr cpu)
copy->type = cpu->type;
copy->match = cpu->match;
+ copy->fallback = cpu->fallback;
copy->sockets = cpu->sockets;
copy->cores = cpu->cores;
copy->threads = cpu->threads;
@@ -209,6 +214,21 @@ virCPUDefParseXML(const xmlNodePtr node,
goto error;
}
+ if (def->model && def->type == VIR_CPU_TYPE_GUEST) {
+ const char *fallback;
+
+ fallback = virXPathString("string(./model[1]/@fallback)", ctxt);
+ if (fallback) {
+ def->fallback = virCPUFallbackTypeFromString(fallback);
+ VIR_FREE(fallback);
+ if (def->fallback < 0) {
+ virCPUReportError(VIR_ERR_XML_ERROR, "%s",
+ _("Invalid fallback attribute"));
+ goto error;
+ }
+ }
+ }
+
def->vendor = virXPathString("string(./vendor[1])", ctxt);
if (def->vendor && !def->model) {
virCPUReportError(VIR_ERR_INTERNAL_ERROR,
@@ -455,8 +475,22 @@ virCPUDefFormatBuf(virBufferPtr buf,
return -1;
}
- if (def->model)
- virBufferAsprintf(buf, "%s \n", def->model);
+ if (def->model) {
+ virBufferAddLit(buf, "type == VIR_CPU_TYPE_GUEST) {
+ const char *fallback;
+
+ fallback = virCPUFallbackTypeToString(def->fallback);
+ if (!fallback) {
+ virCPUReportError(VIR_ERR_INTERNAL_ERROR,
+ _("Unexpected CPU fallback value: %d"),
+ def->fallback);
+ return -1;
+ }
+ virBufferAsprintf(buf, " fallback='%s'", fallback);
+ }
+ virBufferAsprintf(buf, ">%s \n", def->model);
+ }
if (def->vendor) {
virBufferAsprintf(buf, "%s \n", def->vendor);
diff --git a/src/conf/cpu_conf.h b/src/conf/cpu_conf.h
index efff47378a648a4c05a22b190eff5e02195166c0..0c50f90b156791fae3ec850849094892cbe8ef16 100644
--- a/src/conf/cpu_conf.h
+++ b/src/conf/cpu_conf.h
@@ -48,6 +48,15 @@ enum virCPUMatch {
VIR_ENUM_DECL(virCPUMatch)
+enum virCPUFallback {
+ VIR_CPU_FALLBACK_ALLOW,
+ VIR_CPU_FALLBACK_FORBID,
+
+ VIR_CPU_FALLBACK_LAST
+};
+
+VIR_ENUM_DECL(virCPUFallback)
+
enum virCPUFeaturePolicy {
VIR_CPU_FEATURE_FORCE,
VIR_CPU_FEATURE_REQUIRE,
@@ -83,6 +92,7 @@ struct _virCPUDef {
int match; /* enum virCPUMatch */
char *arch;
char *model;
+ int fallback; /* enum virCPUFallback */
char *vendor;
unsigned int sockets;
unsigned int cores;
diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c
index 4a4272e83960fb649c2b1b183d29473e55a65b07..ad2d5cda45fedb9088e6872922f9afb9113b5f6e 100644
--- a/src/cpu/cpu_x86.c
+++ b/src/cpu/cpu_x86.c
@@ -1294,8 +1294,21 @@ x86Decode(virCPUDefPtr cpu,
}
if (!allowed) {
- VIR_DEBUG("CPU model %s not allowed by hypervisor; ignoring",
- candidate->name);
+ if (preferred && STREQ(candidate->name, preferred)) {
+ if (cpu->fallback != VIR_CPU_FALLBACK_ALLOW) {
+ virCPUReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("CPU model %s is not supported by hypervisor"),
+ preferred);
+ goto out;
+ } else {
+ VIR_WARN("Preferred CPU model %s not allowed by"
+ " hypervisor; closest supported model will be"
+ " used", preferred);
+ }
+ } else {
+ VIR_DEBUG("CPU model %s not allowed by hypervisor; ignoring",
+ candidate->name);
+ }
goto next;
}
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 98824ac95abb279d07aae53c147e067a8f4c3073..d2789263c843e24f2e071dcbdc4a93e9951187ca 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -3511,6 +3511,7 @@ qemuBuildCpuArgStr(const struct qemud_driver *driver,
preferred = def->cpu->model;
guest->type = VIR_CPU_TYPE_GUEST;
+ guest->fallback = def->cpu->fallback;
if (cpuDecode(guest, data, cpus, ncpus, preferred) < 0)
goto cleanup;
diff --git a/tests/cputest.c b/tests/cputest.c
index 5b7b951ccc6fd226c8476d1f9228c9757090017f..2dd89f28bed4c5c67770f27046571d2a93d65d80 100644
--- a/tests/cputest.c
+++ b/tests/cputest.c
@@ -287,6 +287,7 @@ cpuTestGuestData(const void *arg)
guest->type = VIR_CPU_TYPE_GUEST;
guest->match = VIR_CPU_MATCH_EXACT;
+ guest->fallback = cpu->fallback;
if (cpuDecode(guest, guestData, data->models,
data->nmodels, data->preferred) < 0) {
if (data->result < 0) {
@@ -620,6 +621,7 @@ mymain(void)
DO_TEST_GUESTDATA("x86", "host", "guest", models, "Penryn", 0);
DO_TEST_GUESTDATA("x86", "host", "guest", models, "qemu64", 0);
DO_TEST_GUESTDATA("x86", "host", "guest", nomodel, NULL, -1);
+ DO_TEST_GUESTDATA("x86", "host", "guest-nofallback", models, "Penryn", -1);
free(map);
return (ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
diff --git a/tests/cputestdata/x86-baseline-1-result.xml b/tests/cputestdata/x86-baseline-1-result.xml
index e376f7442f125569c8c74be8dfe64c98c83c2a2a..99e43d018ff9d894a76ce524ed92099fd91f6bab 100644
--- a/tests/cputestdata/x86-baseline-1-result.xml
+++ b/tests/cputestdata/x86-baseline-1-result.xml
@@ -1,5 +1,5 @@
- Conroe
+ Conroe
Intel
diff --git a/tests/cputestdata/x86-baseline-2-result.xml b/tests/cputestdata/x86-baseline-2-result.xml
index 3fd0551ba8c022e281edd1a0c029cc56a31f7943..76c13aa505bace44c25f1857360b7be5b0c06274 100644
--- a/tests/cputestdata/x86-baseline-2-result.xml
+++ b/tests/cputestdata/x86-baseline-2-result.xml
@@ -1,4 +1,4 @@
- core2duo
+ core2duo
diff --git a/tests/cputestdata/x86-baseline-no-vendor-result.xml b/tests/cputestdata/x86-baseline-no-vendor-result.xml
index 0fc089256f7bd8c2ae4ad048ba76dc3d56bcab14..8b97d2c130924c203db26bcee24cad4eec9a921f 100644
--- a/tests/cputestdata/x86-baseline-no-vendor-result.xml
+++ b/tests/cputestdata/x86-baseline-no-vendor-result.xml
@@ -1,5 +1,5 @@
- Opteron_G2
+ Opteron_G2
diff --git a/tests/cputestdata/x86-baseline-some-vendors-result.xml b/tests/cputestdata/x86-baseline-some-vendors-result.xml
index 2ddfcc5807c303efd2d92b73d2036fa8f42700f0..bac0e5d38f2fcf4250291bedc1f4716a8c7280a0 100644
--- a/tests/cputestdata/x86-baseline-some-vendors-result.xml
+++ b/tests/cputestdata/x86-baseline-some-vendors-result.xml
@@ -1,3 +1,3 @@
- Opteron_G1
+ Opteron_G1
diff --git a/tests/cputestdata/x86-guest-nofallback.xml b/tests/cputestdata/x86-guest-nofallback.xml
new file mode 100644
index 0000000000000000000000000000000000000000..babe47d05f435d81c1d52501ac56039411ce69a4
--- /dev/null
+++ b/tests/cputestdata/x86-guest-nofallback.xml
@@ -0,0 +1,18 @@
+
+ Penryn
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/cputestdata/x86-host+guest,model486-result.xml b/tests/cputestdata/x86-host+guest,model486-result.xml
index fb1bb4b950d8660dd4263d243411392fcd16ce5a..9fd67eb1a74350d538010e76dd7827060cb157b8 100644
--- a/tests/cputestdata/x86-host+guest,model486-result.xml
+++ b/tests/cputestdata/x86-host+guest,model486-result.xml
@@ -1,6 +1,6 @@
x86_64
- 486
+ 486
diff --git a/tests/cputestdata/x86-host+guest,models,Penryn-result.xml b/tests/cputestdata/x86-host+guest,models,Penryn-result.xml
index 955946537c4605825f8c4da4a136dd6a1f7e5c6f..9ae11c95006fcdd7668a8e6e69900f0f19ebf6ca 100644
--- a/tests/cputestdata/x86-host+guest,models,Penryn-result.xml
+++ b/tests/cputestdata/x86-host+guest,models,Penryn-result.xml
@@ -1,6 +1,6 @@
x86_64
- Nehalem
+ Nehalem
diff --git a/tests/cputestdata/x86-host+guest,models,qemu64-result.xml b/tests/cputestdata/x86-host+guest,models,qemu64-result.xml
index b41863eb594038ac2306d872b515e164f8df1ac8..7582ddc8c5ab97dad7588018416ae452f382b123 100644
--- a/tests/cputestdata/x86-host+guest,models,qemu64-result.xml
+++ b/tests/cputestdata/x86-host+guest,models,qemu64-result.xml
@@ -1,6 +1,6 @@
x86_64
- qemu64
+ qemu64
diff --git a/tests/cputestdata/x86-host+guest,models-result.xml b/tests/cputestdata/x86-host+guest,models-result.xml
index 955946537c4605825f8c4da4a136dd6a1f7e5c6f..9ae11c95006fcdd7668a8e6e69900f0f19ebf6ca 100644
--- a/tests/cputestdata/x86-host+guest,models-result.xml
+++ b/tests/cputestdata/x86-host+guest,models-result.xml
@@ -1,6 +1,6 @@
x86_64
- Nehalem
+ Nehalem
diff --git a/tests/cputestdata/x86-host+guest-result.xml b/tests/cputestdata/x86-host+guest-result.xml
index 544a388f7678c03e69d01f79ae409e6ed2256431..e596c4320992543f25f967437e6deb72a536a42f 100644
--- a/tests/cputestdata/x86-host+guest-result.xml
+++ b/tests/cputestdata/x86-host+guest-result.xml
@@ -1,6 +1,6 @@
x86_64
- Penryn
+ Penryn
diff --git a/tests/cputestdata/x86-host+guest.xml b/tests/cputestdata/x86-host+guest.xml
index c3fca8775426968aef3048744f1edf48c887b4e8..2a786fd3aa335cf484425d921b25772c14e7d422 100644
--- a/tests/cputestdata/x86-host+guest.xml
+++ b/tests/cputestdata/x86-host+guest.xml
@@ -1,5 +1,5 @@
- Penryn
+ Penryn
diff --git a/tests/cputestdata/x86-host+min.xml b/tests/cputestdata/x86-host+min.xml
index d22c7b6c1c77b570b382d0a4f5b93ca93d744813..fe55058992e8516e0b75df3a01151731b3aa70f6 100644
--- a/tests/cputestdata/x86-host+min.xml
+++ b/tests/cputestdata/x86-host+min.xml
@@ -1,5 +1,5 @@
- Penryn
+ Penryn
diff --git a/tests/cputestdata/x86-host+nehalem-force-result.xml b/tests/cputestdata/x86-host+nehalem-force-result.xml
index 162685f02269272dcd50b2036e78c44757fe48c6..41e7356796dbb119c68929ea673196e4633d2e5d 100644
--- a/tests/cputestdata/x86-host+nehalem-force-result.xml
+++ b/tests/cputestdata/x86-host+nehalem-force-result.xml
@@ -1,4 +1,4 @@
x86_64
- Nehalem
+ Nehalem
diff --git a/tests/cputestdata/x86-host+pentium3.xml b/tests/cputestdata/x86-host+pentium3.xml
index d141d9e333d038b0412a313126c8acd55ff465c8..e122ba53d6e6ddee87f6d810b9ecf832000dd0f4 100644
--- a/tests/cputestdata/x86-host+pentium3.xml
+++ b/tests/cputestdata/x86-host+pentium3.xml
@@ -1,5 +1,5 @@
- pentium3
+ pentium3
diff --git a/tests/cputestdata/x86-host+strict-force-extra-result.xml b/tests/cputestdata/x86-host+strict-force-extra-result.xml
index e47933cc3298803d7865d99e9428c25ae130397e..f3d52a14b3cc3d84e7b7d915544df9fbb25ab6d2 100644
--- a/tests/cputestdata/x86-host+strict-force-extra-result.xml
+++ b/tests/cputestdata/x86-host+strict-force-extra-result.xml
@@ -1,6 +1,6 @@
x86_64
- Penryn
+ Penryn
diff --git a/tests/cputestdata/x86-host-better+pentium3,core2duo-result.xml b/tests/cputestdata/x86-host-better+pentium3,core2duo-result.xml
index c2d8ddd636a80207ca2aac5480b14b642f9c5093..5d4528bd6d1aaf1669f3219c7ed6df70fe997aa2 100644
--- a/tests/cputestdata/x86-host-better+pentium3,core2duo-result.xml
+++ b/tests/cputestdata/x86-host-better+pentium3,core2duo-result.xml
@@ -1,6 +1,6 @@
x86_64
- core2duo
+ core2duo
diff --git a/tests/cputestdata/x86-host-better+pentium3,pentium3-result.xml b/tests/cputestdata/x86-host-better+pentium3,pentium3-result.xml
index 6e246a80323d0eee7862306dbe791f21e3cd9504..1530a07e0ac351e292281593f518d3a8c5bd2cc8 100644
--- a/tests/cputestdata/x86-host-better+pentium3,pentium3-result.xml
+++ b/tests/cputestdata/x86-host-better+pentium3,pentium3-result.xml
@@ -1,6 +1,6 @@
x86_64
- pentium3
+ pentium3
diff --git a/tests/cputestdata/x86-host-better+pentium3-result.xml b/tests/cputestdata/x86-host-better+pentium3-result.xml
index b918363e6977555ea84c932f045cb3e773ac874e..917d63f06992754f2b5b14e00dcd8b6417e87144 100644
--- a/tests/cputestdata/x86-host-better+pentium3-result.xml
+++ b/tests/cputestdata/x86-host-better+pentium3-result.xml
@@ -1,6 +1,6 @@
x86_64
- Nehalem
+ Nehalem
diff --git a/tests/cputestdata/x86-host-worse+guest-result.xml b/tests/cputestdata/x86-host-worse+guest-result.xml
index 036177a58fafcda7f5a0af836289f7d342c4f59a..78e170adbc7b2d0ee4f19eae73b11e313c7ea55d 100644
--- a/tests/cputestdata/x86-host-worse+guest-result.xml
+++ b/tests/cputestdata/x86-host-worse+guest-result.xml
@@ -1,6 +1,6 @@
x86_64
- Penryn
+ Penryn
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-cpu-exact1.xml b/tests/qemuxml2argvdata/qemuxml2argv-cpu-exact1.xml
index d6db442ad94be0a6eb569df4dfa9a289c4c7f00b..b5fd49c5f7a7ff2e7909626396cbb0cd41167c65 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-cpu-exact1.xml
+++ b/tests/qemuxml2argvdata/qemuxml2argv-cpu-exact1.xml
@@ -9,7 +9,7 @@
- qemu64
+ qemu64
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-cpu-exact2-nofallback.args b/tests/qemuxml2argvdata/qemuxml2argv-cpu-exact2-nofallback.args
new file mode 100644
index 0000000000000000000000000000000000000000..198d0d8f171f8fbf57484fd4f5fbf858af5a51ef
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-cpu-exact2-nofallback.args
@@ -0,0 +1,4 @@
+LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test ./qemu.sh -S -M pc \
+-cpu core2duo,+lahf_lm,+3dnowext,+xtpr,+ds_cpl,+tm,+ht,+ds,-nx -m 214 -smp 6 \
+-nographic -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot n -net \
+none -serial none -parallel none -usb
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-cpu-exact2-nofallback.xml b/tests/qemuxml2argvdata/qemuxml2argv-cpu-exact2-nofallback.xml
new file mode 100644
index 0000000000000000000000000000000000000000..11de634f3d5592d2bb5fe50ab4dcddbaf6690d79
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-cpu-exact2-nofallback.xml
@@ -0,0 +1,35 @@
+
+ QEMUGuest1
+ c7a5fdbd-edaf-9455-926a-d65c16db1809
+ 219100
+ 219100
+ 6
+
+ hvm
+
+
+
+ core2duo
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ destroy
+ restart
+ destroy
+
+ /./qemu.sh
+
+
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-cpu-fallback.args b/tests/qemuxml2argvdata/qemuxml2argv-cpu-fallback.args
new file mode 100644
index 0000000000000000000000000000000000000000..658f1412a73718cf7ffe3f8bcf46c839616254c0
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-cpu-fallback.args
@@ -0,0 +1,19 @@
+LC_ALL=C \
+PATH=/bin \
+HOME=/home/test \
+USER=test \
+LOGNAME=test \
+./qemu.sh \
+-S \
+-M pc \
+-cpu Penryn,-sse4.1 \
+-m 214 \
+-smp 6 \
+-nographic \
+-monitor unix:/tmp/test-monitor,server,nowait \
+-no-acpi \
+-boot n \
+-net none \
+-serial none \
+-parallel none \
+-usb
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-cpu-fallback.xml b/tests/qemuxml2argvdata/qemuxml2argv-cpu-fallback.xml
new file mode 100644
index 0000000000000000000000000000000000000000..7bd28a87d3c5f235a628465fd612076224ca9173
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-cpu-fallback.xml
@@ -0,0 +1,25 @@
+
+ QEMUGuest1
+ c7a5fdbd-edaf-9455-926a-d65c16db1809
+ 219100
+ 219100
+ 6
+
+ hvm
+
+
+
+ Westmere
+
+
+
+
+
+
+ destroy
+ restart
+ destroy
+
+ /./qemu.sh
+
+
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-cpu-nofallback.xml b/tests/qemuxml2argvdata/qemuxml2argv-cpu-nofallback.xml
new file mode 100644
index 0000000000000000000000000000000000000000..7f1f09a900d90ccb01c84a60b58a6ea15a86aeca
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-cpu-nofallback.xml
@@ -0,0 +1,25 @@
+
+ QEMUGuest1
+ c7a5fdbd-edaf-9455-926a-d65c16db1809
+ 219100
+ 219100
+ 6
+
+ hvm
+
+
+
+ Westmere
+
+
+
+
+
+
+ destroy
+ restart
+ destroy
+
+ /./qemu.sh
+
+
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
index fd3c9bbd533ee1d99f0eb4baf9548c00ae5b6904..e5161938dabe5c1b07aa82456008c050d1cea600 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -84,7 +84,8 @@ static int testCompareXMLToArgvFiles(const char *xml,
const char *migrateFrom,
int migrateFd,
bool json,
- bool expectError)
+ bool expectError,
+ bool expectFailure)
{
char *expectargv = NULL;
int len;
@@ -98,19 +99,13 @@ static int testCompareXMLToArgvFiles(const char *xml,
virCommandPtr cmd = NULL;
if (!(conn = virGetConnect()))
- goto fail;
+ goto out;
conn->secretDriver = &fakeSecretDriver;
- len = virtTestLoadFile(cmdline, &expectargv);
- if (len < 0)
- goto fail;
- if (len && expectargv[len - 1] == '\n')
- expectargv[len - 1] = '\0';
-
if (!(vmdef = virDomainDefParseFile(driver.caps, xml,
QEMU_EXPECTED_VIRT_TYPES,
VIR_DOMAIN_XML_INACTIVE)))
- goto fail;
+ goto out;
/*
* For test purposes, we may want to fake emulator's output by providing
@@ -124,12 +119,12 @@ static int testCompareXMLToArgvFiles(const char *xml,
*/
if (vmdef->emulator && STRPREFIX(vmdef->emulator, "/.")) {
if (!(emulator = strdup(vmdef->emulator + 1)))
- goto fail;
+ goto out;
free(vmdef->emulator);
vmdef->emulator = NULL;
if (virAsprintf(&vmdef->emulator, "%s/qemuxml2argvdata/%s",
abs_srcdir, emulator) < 0)
- goto fail;
+ goto out;
}
if (qemuCapsGet(extraFlags, QEMU_CAPS_DOMID))
@@ -149,7 +144,7 @@ static int testCompareXMLToArgvFiles(const char *xml,
QEMU_CAPS_LAST);
if (qemudCanonicalizeMachine(&driver, vmdef) < 0)
- goto fail;
+ goto out;
if (qemuCapsGet(extraFlags, QEMU_CAPS_DEVICE)) {
qemuDomainPCIAddressSetPtr pciaddrs;
@@ -157,14 +152,14 @@ static int testCompareXMLToArgvFiles(const char *xml,
if (qemuDomainAssignSpaprVIOAddresses(vmdef)) {
if (expectError)
goto ok;
- goto fail;
+ goto out;
}
if (!(pciaddrs = qemuDomainPCIAddressSetCreate(vmdef)))
- goto fail;
+ goto out;
if (qemuAssignDevicePCISlots(vmdef, pciaddrs) < 0)
- goto fail;
+ goto out;
qemuDomainPCIAddressSetFree(pciaddrs);
}
@@ -183,35 +178,50 @@ static int testCompareXMLToArgvFiles(const char *xml,
}
if (qemuAssignDeviceAliases(vmdef, extraFlags) < 0)
- goto fail;
+ goto out;
if (!(cmd = qemuBuildCommandLine(conn, &driver,
vmdef, &monitor_chr, json, extraFlags,
migrateFrom, migrateFd, NULL,
- VIR_NETDEV_VPORT_PROFILE_OP_NO_OP)))
- goto fail;
+ VIR_NETDEV_VPORT_PROFILE_OP_NO_OP))) {
+ if (expectFailure) {
+ ret = 0;
+ virResetLastError();
+ }
+ goto out;
+ } else if (expectFailure) {
+ if (virTestGetDebug())
+ fprintf(stderr, "qemuBuildCommandLine should have failed\n");
+ goto out;
+ }
if (!!virGetLastError() != expectError) {
if (virTestGetDebug() && (log = virtTestLogContentAndReset()))
fprintf(stderr, "\n%s", log);
- goto fail;
+ goto out;
}
if (!(actualargv = virCommandToString(cmd)))
- goto fail;
+ goto out;
if (emulator) {
/* Skip the abs_srcdir portion of replacement emulator. */
char *start_skip = strstr(actualargv, abs_srcdir);
char *end_skip = strstr(actualargv, emulator);
if (!start_skip || !end_skip)
- goto fail;
+ goto out;
memmove(start_skip, end_skip, strlen(end_skip) + 1);
}
+ len = virtTestLoadFile(cmdline, &expectargv);
+ if (len < 0)
+ goto out;
+ if (len && expectargv[len - 1] == '\n')
+ expectargv[len - 1] = '\0';
+
if (STRNEQ(expectargv, actualargv)) {
virtTestDifference(stderr, expectargv, actualargv);
- goto fail;
+ goto out;
}
ok:
@@ -222,7 +232,7 @@ static int testCompareXMLToArgvFiles(const char *xml,
ret = 0;
- fail:
+out:
free(log);
free(emulator);
free(expectargv);
@@ -240,6 +250,7 @@ struct testInfo {
const char *migrateFrom;
int migrateFd;
bool expectError;
+ bool expectFailure;
};
static int
@@ -260,7 +271,8 @@ testCompareXMLToArgvHelper(const void *data)
info->migrateFrom, info->migrateFd,
qemuCapsGet(info->extraFlags,
QEMU_CAPS_MONITOR_JSON),
- info->expectError);
+ info->expectError,
+ info->expectFailure);
cleanup:
free(xml);
@@ -299,10 +311,12 @@ mymain(void)
return EXIT_FAILURE;
}
-# define DO_TEST_FULL(name, migrateFrom, migrateFd, expectError, ...) \
+# define DO_TEST_FULL(name, migrateFrom, migrateFd, \
+ expectError, expectFailure, ...) \
do { \
struct testInfo info = { \
- name, NULL, migrateFrom, migrateFd, expectError \
+ name, NULL, migrateFrom, migrateFd, \
+ expectError, expectFailure \
}; \
if (!(info.extraFlags = qemuCapsNew())) \
return EXIT_FAILURE; \
@@ -314,7 +328,10 @@ mymain(void)
} while (0)
# define DO_TEST(name, expectError, ...) \
- DO_TEST_FULL(name, NULL, -1, expectError, __VA_ARGS__)
+ DO_TEST_FULL(name, NULL, -1, expectError, false, __VA_ARGS__)
+
+# define DO_TEST_FAILURE(name, ...) \
+ DO_TEST_FULL(name, NULL, -1, false, true, __VA_ARGS__)
# define NONE QEMU_CAPS_LAST
@@ -643,17 +660,17 @@ mymain(void)
DO_TEST("hostdev-pci-address-device", false,
QEMU_CAPS_PCIDEVICE, QEMU_CAPS_DEVICE, QEMU_CAPS_NODEFCONFIG);
- DO_TEST_FULL("restore-v1", "stdio", 7, false,
+ DO_TEST_FULL("restore-v1", "stdio", 7, false, false,
QEMU_CAPS_MIGRATE_KVM_STDIO);
- DO_TEST_FULL("restore-v2", "stdio", 7, false,
+ DO_TEST_FULL("restore-v2", "stdio", 7, false, false,
QEMU_CAPS_MIGRATE_QEMU_EXEC);
- DO_TEST_FULL("restore-v2", "exec:cat", 7, false,
+ DO_TEST_FULL("restore-v2", "exec:cat", 7, false, false,
QEMU_CAPS_MIGRATE_QEMU_EXEC);
- DO_TEST_FULL("restore-v2-fd", "stdio", 7, false,
+ DO_TEST_FULL("restore-v2-fd", "stdio", 7, false, false,
QEMU_CAPS_MIGRATE_QEMU_FD);
- DO_TEST_FULL("restore-v2-fd", "fd:7", 7, false,
+ DO_TEST_FULL("restore-v2-fd", "fd:7", 7, false, false,
QEMU_CAPS_MIGRATE_QEMU_FD);
- DO_TEST_FULL("migrate", "tcp:10.0.0.1:5000", -1, false,
+ DO_TEST_FULL("migrate", "tcp:10.0.0.1:5000", -1, false, false,
QEMU_CAPS_MIGRATE_QEMU_TCP);
DO_TEST("qemu-ns", false, NONE);
@@ -667,6 +684,9 @@ mymain(void)
DO_TEST("cpu-minimum2", false, NONE);
DO_TEST("cpu-exact1", false, NONE);
DO_TEST("cpu-exact2", false, NONE);
+ DO_TEST("cpu-exact2-nofallback", false, NONE);
+ DO_TEST("cpu-fallback", false, NONE);
+ DO_TEST_FAILURE("cpu-nofallback", NONE);
DO_TEST("cpu-strict1", false, NONE);
DO_TEST("cpu-numa1", false, NONE);
DO_TEST("cpu-numa2", false, QEMU_CAPS_SMP_TOPOLOGY);
diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-graphics-spice-timeout.xml b/tests/qemuxml2xmloutdata/qemuxml2xmlout-graphics-spice-timeout.xml
new file mode 100644
index 0000000000000000000000000000000000000000..caa5f0a0c0385ac79db15808ee04716244800d8f
--- /dev/null
+++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-graphics-spice-timeout.xml
@@ -0,0 +1,86 @@
+
+ f14
+ 553effab-b5e1-2d80-dfe3-da4344826c43
+ 1048576
+ 1048576
+ 2
+
+ hvm
+
+
+
+
+
+
+
+
+
+
+ core2duo
+ Intel
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ destroy
+ restart
+ restart
+
+ /./qemu.sh
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c
index ad1903bcbc31b52643946d966283dd563112ceab..293c2a7d5f3e9692a1dbd0e39d35ee712618e08e 100644
--- a/tests/qemuxml2xmltest.c
+++ b/tests/qemuxml2xmltest.c
@@ -149,7 +149,6 @@ mymain(void)
DO_TEST("graphics-sdl-fullscreen");
DO_TEST("graphics-spice");
DO_TEST("graphics-spice-compression");
- DO_TEST("graphics-spice-timeout");
DO_TEST("graphics-spice-qxl-vga");
DO_TEST("input-usbmouse");
DO_TEST("input-usbtablet");
@@ -209,6 +208,7 @@ mymain(void)
DO_TEST_DIFFERENT("console-virtio");
DO_TEST_DIFFERENT("serial-target-port-auto");
DO_TEST_DIFFERENT("graphics-listen-network2");
+ DO_TEST_DIFFERENT("graphics-spice-timeout");
virCapabilitiesFree(driver.caps);
diff --git a/tests/testutilsqemu.c b/tests/testutilsqemu.c
index fa6422a70608175f70bafe0b70caf8f3e5652e5b..c6adec924c34c5f3f09504342872f8d6316cfcd5 100644
--- a/tests/testutilsqemu.c
+++ b/tests/testutilsqemu.c
@@ -115,6 +115,7 @@ virCapsPtr testQemuCapsInit(void) {
0, /* match */
(char *) "x86_64", /* arch */
(char *) "core2duo", /* model */
+ 0, /* fallback */
(char *) "Intel", /* vendor */
1, /* sockets */
2, /* cores */