+Tue Mar 27 10:39:00 EDT 2007 Daniel P. Berrange <berrange@redhat.com>
+
+ * src/xen_internal.c: Fix handling of PAE flags in capabilities XML
+ generation & merge duplicate (arch,os-type) entries.
+ * tests/xencapstest.c: Added a test suite for various Xen capabilities
+ data sets
+ * tests/xencapsdata/*: Added data files for Xen capabilities tests
+ * configure.ac, tests/Makefile.am: Added tests/xencapsdata/ directory
+
Tue Mar 27 11:26:00 BST 2007 Richard W.M. Jones <rjones@redhat.com>
* qemud/qemud.c: If using FORTIFY_SOURCE, remove warning
tests/xml2sexprdata/Makefile \
tests/sexpr2xmldata/Makefile \
tests/xmconfigdata/Makefile \
+ tests/xencapsdata/Makefile \
tests/virshdata/Makefile tests/confdata/Makefile)
static regex_t flags_hvm_rec;
static const char *flags_pae_re = "^flags[[:blank:]]+:.* pae[[:space:]]";
static regex_t flags_pae_rec;
-static const char *xen_cap_re = "(xen|hvm)-[[:digit:]]+\\.[[:digit:]]+-(x86_32|x86_64|ia64)(p|be)?";
+static const char *xen_cap_re = "(xen|hvm)-[[:digit:]]+\\.[[:digit:]]+-(x86_32|x86_64|ia64|powerpc64)(p|be)?";
static regex_t xen_cap_rec;
/*
/**
* xenHypervisorGetCapabilities:
* @conn: pointer to the connection block
+ * @cpuinfo: file handle containing /proc/cpuinfo data, or NULL
+ * @capabilities: file handle containing /sys/hypervisor/properties/capabilities data, or NULL
*
* Return the capabilities of this hypervisor.
*/
char *
-xenHypervisorGetCapabilities (virConnectPtr conn)
+xenHypervisorMakeCapabilitiesXML(virConnectPtr conn ATTRIBUTE_UNUSED,
+ const char *hostmachine,
+ FILE *cpuinfo, FILE *capabilities)
{
- struct utsname utsname;
char line[1024], *str, *token;
regmatch_t subs[4];
char *saveptr = NULL;
- FILE *fp;
int i, r;
char hvm_type[4] = ""; /* "vmx" or "svm" (or "" if not in CPU). */
int host_pae = 0;
struct guest_arch {
- const char *token;
const char *model;
int bits;
int hvm;
int pae;
+ int nonpae;
int ia64_be;
} guest_archs[32];
int nr_guest_archs = 0;
memset(guest_archs, 0, sizeof(guest_archs));
- /* Really, this never fails - look at the man-page. */
- uname (&utsname);
-
/* /proc/cpuinfo: flags: Intel calls HVM "vmx", AMD calls it "svm".
* It's not clear if this will work on IA64, let alone other
* architectures and non-Linux. (XXX)
*/
- fp = fopen ("/proc/cpuinfo", "r");
- if (fp == NULL) {
- if (errno == ENOENT)
- goto nocpuinfo;
- virXenPerror (conn, "/proc/cpuinfo");
- return NULL;
- }
-
- while (fgets (line, sizeof line, fp)) {
- if (regexec (&flags_hvm_rec, line, sizeof(subs)/sizeof(regmatch_t), subs, 0) == 0
- && subs[0].rm_so != -1) {
- strncpy (hvm_type,
- &line[subs[1].rm_so], subs[1].rm_eo-subs[1].rm_so+1);
- hvm_type[subs[1].rm_eo-subs[1].rm_so] = '\0';
- } else if (regexec (&flags_pae_rec, line, 0, NULL, 0) == 0)
- host_pae = 1;
+ if (cpuinfo) {
+ while (fgets (line, sizeof line, cpuinfo)) {
+ if (regexec (&flags_hvm_rec, line, sizeof(subs)/sizeof(regmatch_t), subs, 0) == 0
+ && subs[0].rm_so != -1) {
+ strncpy (hvm_type,
+ &line[subs[1].rm_so], subs[1].rm_eo-subs[1].rm_so+1);
+ hvm_type[subs[1].rm_eo-subs[1].rm_so] = '\0';
+ } else if (regexec (&flags_pae_rec, line, 0, NULL, 0) == 0)
+ host_pae = 1;
+ }
}
- fclose (fp);
-
- nocpuinfo:
/* Most of the useful info is in /sys/hypervisor/properties/capabilities
* which is documented in the code in xen-unstable.hg/xen/arch/.../setup.c.
*
* | +----------- the version of Xen, eg. "3.0"
* +--------------- "xen" or "hvm" for para or full virt respectively
*/
- fp = fopen ("/sys/hypervisor/properties/capabilities", "r");
- if (fp == NULL) {
- if (errno == ENOENT)
- goto noxencaps;
- virXenPerror (conn, "/sys/hypervisor/properties/capabilities");
- return NULL;
- }
/* Expecting one line in this file - ignore any more. */
- if (!fgets (line, sizeof line, fp)) {
- fclose (fp);
- goto noxencaps;
- }
+ if (fgets (line, sizeof line, capabilities)) {
+ /* Split the line into tokens. strtok_r is OK here because we "own"
+ * this buffer. Parse out the features from each token.
+ */
+ for (str = line, nr_guest_archs = 0;
+ nr_guest_archs < sizeof guest_archs / sizeof guest_archs[0]
+ && (token = strtok_r (str, " ", &saveptr)) != NULL;
+ str = NULL) {
+
+ if (regexec (&xen_cap_rec, token, sizeof subs / sizeof subs[0],
+ subs, 0) == 0) {
+ int hvm = strncmp (&token[subs[1].rm_so], "hvm", 3) == 0;
+ const char *model;
+ int bits, pae = 0, nonpae = 0, ia64_be = 0;
+ if (strncmp (&token[subs[2].rm_so], "x86_32", 6) == 0) {
+ model = "i686";
+ bits = 32;
+ if (strncmp (&token[subs[3].rm_so], "p", 1) == 0)
+ pae = 1;
+ else
+ nonpae = 1;
+ }
+ else if (strncmp (&token[subs[2].rm_so], "x86_64", 6) == 0) {
+ model = "x86_64";
+ bits = 64;
+ }
+ else if (strncmp (&token[subs[2].rm_so], "ia64", 4) == 0) {
+ model = "ia64";
+ bits = 64;
+ if (strncmp (&token[subs[3].rm_so], "be", 2) == 0)
+ ia64_be = 1;
+ }
+ else if (strncmp (&token[subs[2].rm_so], "powerpc64", 4) == 0) {
+ model = "ppc64";
+ bits = 64;
+ } else {
+ /* XXX surely no other Xen archs exist */
+ continue;
+ }
- fclose (fp);
+ /* Search for existing matching (model,hvm) tuple */
+ for (i = 0 ; i < nr_guest_archs ; i++) {
+ if (!strcmp(guest_archs[i].model, model) &&
+ guest_archs[i].hvm == hvm) {
+ break;
+ }
+ }
- /* Split the line into tokens. strtok_r is OK here because we "own"
- * this buffer. Parse out the features from each token.
- */
- for (str = line, nr_guest_archs = 0;
- nr_guest_archs < sizeof guest_archs / sizeof guest_archs[0]
- && (token = strtok_r (str, " ", &saveptr)) != NULL;
- str = NULL) {
- if (regexec (&xen_cap_rec, token, sizeof subs / sizeof subs[0],
- subs, 0) == 0) {
- token[subs[0].rm_eo] = '\0';
- guest_archs[nr_guest_archs].token = token;
- guest_archs[nr_guest_archs].hvm =
- strncmp (&token[subs[1].rm_so], "hvm", 3) == 0;
- if (strncmp (&token[subs[2].rm_so], "x86_32", 6) == 0) {
- guest_archs[nr_guest_archs].model = "i686";
- guest_archs[nr_guest_archs].bits = 32;
- }
- else if (strncmp (&token[subs[2].rm_so], "x86_64", 6) == 0) {
- guest_archs[nr_guest_archs].model = "x86_64";
- guest_archs[nr_guest_archs].bits = 64;
- }
- else if (strncmp (&token[subs[2].rm_so], "ia64", 4) == 0) {
- guest_archs[nr_guest_archs].model = "ia64";
- guest_archs[nr_guest_archs].bits = 64;
+ /* Too many arch flavours - highly unlikely ! */
+ if (i >= sizeof(guest_archs)/sizeof(guest_archs[0]))
+ continue;
+ /* Didn't find a match, so create a new one */
+ if (i == nr_guest_archs)
+ nr_guest_archs++;
+
+ guest_archs[i].model = model;
+ guest_archs[i].bits = bits;
+ guest_archs[i].hvm = hvm;
+
+ /* Careful not to overwrite a previous positive
+ setting with a negative one here - some archs
+ can do both pae & non-pae, but Xen reports
+ separately capabilities so we're merging archs */
+ if (pae)
+ guest_archs[i].pae = pae;
+ if (nonpae)
+ guest_archs[i].nonpae = nonpae;
+ if (ia64_be)
+ guest_archs[i].ia64_be = ia64_be;
}
- else {
- guest_archs[nr_guest_archs].model = ""; /* can never happen */
- }
- guest_archs[nr_guest_archs].pae =
- guest_archs[nr_guest_archs].ia64_be = 0;
- if (subs[2].rm_so != -1) {
- if (strncmp (&token[subs[3].rm_so], "p", 1) == 0)
- guest_archs[nr_guest_archs].pae = 1;
- else if (strncmp (&token[subs[3].rm_so], "be", 2) == 0)
- guest_archs[nr_guest_archs].ia64_be = 1;
- }
- nr_guest_archs++;
}
}
- noxencaps:
/* Construct the final XML. */
xml = virBufferNew (1024);
if (!xml) return NULL;
<cpu>\n\
<arch>%s</arch>\n\
<features>\n",
- utsname.machine);
- if (r == -1) return NULL;
+ hostmachine);
+ if (r == -1) goto vir_buffer_failed;
if (strcmp (hvm_type, "") != 0) {
r = virBufferVSprintf (xml,
"\
<%s/>\n",
hvm_type);
- if (r == -1) {
- vir_buffer_failed:
- virBufferFree (xml);
- return NULL;
- }
+ if (r == -1) goto vir_buffer_failed;
}
if (host_pae) {
r = virBufferAdd (xml, "\
r = virBufferVSprintf (xml,
"\
\n\
- <!-- %s -->\n\
<guest>\n\
<os_type>%s</os_type>\n\
<arch name=\"%s\">\n\
<wordsize>%d</wordsize>\n\
- <domain type=\"xen\"></domain>\n\
- <emulator>/usr/lib%s/xen/bin/qemu-dm</emulator>\n",
- guest_archs[i].token,
+ <domain type=\"xen\"></domain>\n",
guest_archs[i].hvm ? "hvm" : "xen",
guest_archs[i].model,
- guest_archs[i].bits,
- guest_archs[i].bits == 64 ? "64" : "");
+ guest_archs[i].bits);
if (r == -1) goto vir_buffer_failed;
if (guest_archs[i].hvm) {
- r = virBufferAdd (xml,
+ r = virBufferVSprintf (xml,
"\
+ <emulator>/usr/lib%s/xen/bin/qemu-dm</emulator>\n\
<machine>pc</machine>\n\
<machine>isapc</machine>\n\
- <loader>/usr/lib/xen/boot/hvmloader</loader>\n", -1);
+ <loader>/usr/lib/xen/boot/hvmloader</loader>\n",
+ guest_archs[i].bits == 64 ? "64" : "");
if (r == -1) goto vir_buffer_failed;
}
r = virBufferAdd (xml,
if (guest_archs[i].pae) {
r = virBufferAdd (xml,
"\
- <pae/>\n\
+ <pae/>\n", -1);
+ if (r == -1) goto vir_buffer_failed;
+ }
+ if (guest_archs[i].nonpae) {
+ r = virBufferAdd (xml,
+ "\
<nonpae/>\n", -1);
if (r == -1) goto vir_buffer_failed;
}
virBufferFree (xml);
return xml_str;
+
+ vir_buffer_failed:
+ virBufferFree (xml);
+ return NULL;
+}
+
+/**
+ * xenHypervisorGetCapabilities:
+ * @conn: pointer to the connection block
+ *
+ * Return the capabilities of this hypervisor.
+ */
+char *
+xenHypervisorGetCapabilities (virConnectPtr conn)
+{
+ char *xml;
+ FILE *cpuinfo, *capabilities;
+ struct utsname utsname;
+
+ /* Really, this never fails - look at the man-page. */
+ uname (&utsname);
+
+ cpuinfo = fopen ("/proc/cpuinfo", "r");
+ if (cpuinfo == NULL) {
+ if (errno != ENOENT) {
+ virXenPerror (conn, "/proc/cpuinfo");
+ return NULL;
+ }
+ }
+
+ capabilities = fopen ("/sys/hypervisor/properties/capabilities", "r");
+ if (capabilities == NULL) {
+ if (errno != ENOENT) {
+ fclose(cpuinfo);
+ virXenPerror (conn, "/sys/hypervisor/properties/capabilities");
+ return NULL;
+ }
+ }
+
+ xml = xenHypervisorMakeCapabilitiesXML(conn, utsname.machine, cpuinfo, capabilities);
+
+ if (cpuinfo)
+ fclose(cpuinfo);
+ if (capabilities)
+ fclose(capabilities);
+
+ return xml;
}
/**
int xenHypervisorClose (virConnectPtr conn);
int xenHypervisorGetVersion (virConnectPtr conn,
unsigned long *hvVer);
+char *
+ xenHypervisorMakeCapabilitiesXML (virConnectPtr conn,
+ const char *hostmachine,
+ FILE *cpuinfo,
+ FILE *capabilities);
char *
xenHypervisorGetCapabilities (virConnectPtr conn);
unsigned long
## Process this file with automake to produce Makefile.in
-SUBDIRS = virshdata confdata sexpr2xmldata xml2sexprdata xmconfigdata
+SUBDIRS = virshdata confdata sexpr2xmldata xml2sexprdata xmconfigdata xencapsdata
# Wierd libtool related juju...
#
EXTRA_DIST = xmlrpcserver.py test_conf.sh
noinst_PROGRAMS = xmlrpctest xml2sexprtest sexpr2xmltest virshtest conftest \
- reconnect xmconfigtest
+ reconnect xmconfigtest xencapstest
-TESTS = xml2sexprtest sexpr2xmltest virshtest test_conf.sh xmconfigtest
+TESTS = xml2sexprtest sexpr2xmltest virshtest test_conf.sh xmconfigtest xencapstest
if ENABLE_XEN_TESTS
TESTS += reconnect
endif
conftest_LDFLAGS =
conftest_LDADD = $(LDADDS)
+xencapstest_SOURCES = \
+ xencapstest.c testutils.h testutils.c
+xencapstest_LDFLAGS =
+xencapstest_LDADD = $(LDADDS)
+
reconnect_SOURCES = \
reconnect.c
reconnect_LDFLAGS =
--- /dev/null
+Makefile
+Makefile.in
--- /dev/null
+
+EXTRA_DIST = $(wildcard *.xml) $(wildcard *.cpuinfo) $(wildcard *.caps)
--- /dev/null
+xen-3.0-x86_32p hvm-3.0-x86_32 hvm-3.0-x86_32p
--- /dev/null
+processor : 0
+vendor_id : GenuineIntel
+cpu family : 6
+model : 15
+model name : Intel(R) Core(TM)2 CPU T7600 @ 2.33GHz
+stepping : 6
+cpu MHz : 2327.560
+cache size : 4096 KB
+fdiv_bug : no
+hlt_bug : no
+f00f_bug : no
+coma_bug : no
+fpu : yes
+fpu_exception : yes
+cpuid level : 10
+wp : yes
+flags : fpu tsc msr pae mce cx8 apic mtrr mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe lm constant_tsc pni monitor ds_cpl vmx est tm2 cx16 xtpr lahf_lm
+bogomips : 5821.44
+
+processor : 1
+vendor_id : GenuineIntel
+cpu family : 6
+model : 15
+model name : Intel(R) Core(TM)2 CPU T7600 @ 2.33GHz
+stepping : 6
+cpu MHz : 2327.560
+cache size : 4096 KB
+fdiv_bug : no
+hlt_bug : no
+f00f_bug : no
+coma_bug : no
+fpu : yes
+fpu_exception : yes
+cpuid level : 10
+wp : yes
+flags : fpu tsc msr pae mce cx8 apic mtrr mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe lm constant_tsc pni monitor ds_cpl vmx est tm2 cx16 xtpr lahf_lm
+bogomips : 5821.44
+
--- /dev/null
+<capabilities>
+ <host>
+ <cpu>
+ <arch>i686</arch>
+ <features>
+ <vmx/>
+ </features>
+ </cpu>
+ </host>
+
+ <guest>
+ <os_type>xen</os_type>
+ <arch name="i686">
+ <wordsize>32</wordsize>
+ <domain type="xen"></domain>
+ </arch>
+ <features>
+ <pae/>
+ </features>
+ </guest>
+
+ <guest>
+ <os_type>hvm</os_type>
+ <arch name="i686">
+ <wordsize>32</wordsize>
+ <domain type="xen"></domain>
+ <emulator>/usr/lib/xen/bin/qemu-dm</emulator>
+ <machine>pc</machine>
+ <machine>isapc</machine>
+ <loader>/usr/lib/xen/boot/hvmloader</loader>
+ </arch>
+ <features>
+ <pae/>
+ <nonpae/>
+ </features>
+ </guest>
+</capabilities>
--- /dev/null
+xen-3.0-x86_32p
--- /dev/null
+processor : 0
+vendor_id : GenuineIntel
+cpu family : 6
+model : 15
+model name : Intel(R) Core(TM)2 CPU T7600 @ 2.33GHz
+stepping : 6
+cpu MHz : 2327.560
+cache size : 4096 KB
+fdiv_bug : no
+hlt_bug : no
+f00f_bug : no
+coma_bug : no
+fpu : yes
+fpu_exception : yes
+cpuid level : 10
+wp : yes
+flags : fpu tsc msr pae mce cx8 apic mtrr mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe lm constant_tsc pni monitor ds_cpl vmx est tm2 cx16 xtpr lahf_lm
+bogomips : 5821.44
+
+
--- /dev/null
+<capabilities>
+ <host>
+ <cpu>
+ <arch>i686</arch>
+ <features>
+ <vmx/>
+ </features>
+ </cpu>
+ </host>
+
+ <guest>
+ <os_type>xen</os_type>
+ <arch name="i686">
+ <wordsize>32</wordsize>
+ <domain type="xen"></domain>
+ </arch>
+ <features>
+ <pae/>
+ </features>
+ </guest>
+</capabilities>
--- /dev/null
+xen-3.0-x86_32
--- /dev/null
+processor : 0
+vendor_id : GenuineIntel
+cpu family : 6
+model : 15
+model name : Intel(R) Core(TM)2 CPU T7600 @ 2.33GHz
+stepping : 6
+cpu MHz : 2327.560
+cache size : 4096 KB
+fdiv_bug : no
+hlt_bug : no
+f00f_bug : no
+coma_bug : no
+fpu : yes
+fpu_exception : yes
+cpuid level : 10
+wp : yes
+flags : fpu tsc msr mce cx8 apic mtrr mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe lm constant_tsc pni monitor
+bogomips : 5821.44
+
--- /dev/null
+<capabilities>
+ <host>
+ <cpu>
+ <arch>i686</arch>
+ <features>
+ </features>
+ </cpu>
+ </host>
+
+ <guest>
+ <os_type>xen</os_type>
+ <arch name="i686">
+ <wordsize>32</wordsize>
+ <domain type="xen"></domain>
+ </arch>
+ <features>
+ <nonpae/>
+ </features>
+ </guest>
+</capabilities>
--- /dev/null
+xen-3.0-ia64be hvm-3.0-ia64be
--- /dev/null
+processor : 0
+vendor : Xen/ia64
+arch : IA-64
+family : 32
+model : 0
+revision : 7
+archrev : 0
+features : branchlong, 16-byte atomic ops
+cpu number : 0
+cpu regs : 4
+cpu MHz : 1594.000670
+itc MHz : 399.165930
+BogoMIPS : 3186.68
+siblings : 1
+
+processor : 1
+vendor : Xen/ia64
+arch : IA-64
+family : 32
+model : 0
+revision : 7
+archrev : 0
+features : branchlong, 16-byte atomic ops
+cpu number : 0
+cpu regs : 4
+cpu MHz : 1594.000670
+itc MHz : 399.165930
+BogoMIPS : 3186.68
+siblings : 1
--- /dev/null
+<capabilities>
+ <host>
+ <cpu>
+ <arch>ia64</arch>
+ <features>
+ </features>
+ </cpu>
+ </host>
+
+ <guest>
+ <os_type>xen</os_type>
+ <arch name="ia64">
+ <wordsize>64</wordsize>
+ <domain type="xen"></domain>
+ </arch>
+ <features>
+ <ia64_be/>
+ </features>
+ </guest>
+
+ <guest>
+ <os_type>hvm</os_type>
+ <arch name="ia64">
+ <wordsize>64</wordsize>
+ <domain type="xen"></domain>
+ <emulator>/usr/lib64/xen/bin/qemu-dm</emulator>
+ <machine>pc</machine>
+ <machine>isapc</machine>
+ <loader>/usr/lib/xen/boot/hvmloader</loader>
+ </arch>
+ <features>
+ <ia64_be/>
+ </features>
+ </guest>
+</capabilities>
--- /dev/null
+xen-3.0-ia64be
--- /dev/null
+processor : 0
+vendor : Xen/ia64
+arch : IA-64
+family : 32
+model : 0
+revision : 7
+archrev : 0
+features : branchlong, 16-byte atomic ops
+cpu number : 0
+cpu regs : 4
+cpu MHz : 1594.000670
+itc MHz : 399.165930
+BogoMIPS : 3186.68
+siblings : 1
+
+processor : 1
+vendor : Xen/ia64
+arch : IA-64
+family : 32
+model : 0
+revision : 7
+archrev : 0
+features : branchlong, 16-byte atomic ops
+cpu number : 0
+cpu regs : 4
+cpu MHz : 1594.000670
+itc MHz : 399.165930
+BogoMIPS : 3186.68
+siblings : 1
--- /dev/null
+<capabilities>
+ <host>
+ <cpu>
+ <arch>ia64</arch>
+ <features>
+ </features>
+ </cpu>
+ </host>
+
+ <guest>
+ <os_type>xen</os_type>
+ <arch name="ia64">
+ <wordsize>64</wordsize>
+ <domain type="xen"></domain>
+ </arch>
+ <features>
+ <ia64_be/>
+ </features>
+ </guest>
+</capabilities>
--- /dev/null
+xen-3.0-ia64 hvm-3.0-ia64
--- /dev/null
+processor : 0
+vendor : Xen/ia64
+arch : IA-64
+family : 32
+model : 0
+revision : 7
+archrev : 0
+features : branchlong, 16-byte atomic ops
+cpu number : 0
+cpu regs : 4
+cpu MHz : 1594.000670
+itc MHz : 399.165930
+BogoMIPS : 3186.68
+siblings : 1
+
+processor : 1
+vendor : Xen/ia64
+arch : IA-64
+family : 32
+model : 0
+revision : 7
+archrev : 0
+features : branchlong, 16-byte atomic ops
+cpu number : 0
+cpu regs : 4
+cpu MHz : 1594.000670
+itc MHz : 399.165930
+BogoMIPS : 3186.68
+siblings : 1
--- /dev/null
+<capabilities>
+ <host>
+ <cpu>
+ <arch>ia64</arch>
+ <features>
+ </features>
+ </cpu>
+ </host>
+
+ <guest>
+ <os_type>xen</os_type>
+ <arch name="ia64">
+ <wordsize>64</wordsize>
+ <domain type="xen"></domain>
+ </arch>
+ <features>
+ </features>
+ </guest>
+
+ <guest>
+ <os_type>hvm</os_type>
+ <arch name="ia64">
+ <wordsize>64</wordsize>
+ <domain type="xen"></domain>
+ <emulator>/usr/lib64/xen/bin/qemu-dm</emulator>
+ <machine>pc</machine>
+ <machine>isapc</machine>
+ <loader>/usr/lib/xen/boot/hvmloader</loader>
+ </arch>
+ <features>
+ </features>
+ </guest>
+</capabilities>
--- /dev/null
+xen-3.0-ia64
--- /dev/null
+processor : 0
+vendor : Xen/ia64
+arch : IA-64
+family : 32
+model : 0
+revision : 7
+archrev : 0
+features : branchlong, 16-byte atomic ops
+cpu number : 0
+cpu regs : 4
+cpu MHz : 1594.000670
+itc MHz : 399.165930
+BogoMIPS : 3186.68
+siblings : 1
+
+processor : 1
+vendor : Xen/ia64
+arch : IA-64
+family : 32
+model : 0
+revision : 7
+archrev : 0
+features : branchlong, 16-byte atomic ops
+cpu number : 0
+cpu regs : 4
+cpu MHz : 1594.000670
+itc MHz : 399.165930
+BogoMIPS : 3186.68
+siblings : 1
--- /dev/null
+<capabilities>
+ <host>
+ <cpu>
+ <arch>ia64</arch>
+ <features>
+ </features>
+ </cpu>
+ </host>
+
+ <guest>
+ <os_type>xen</os_type>
+ <arch name="ia64">
+ <wordsize>64</wordsize>
+ <domain type="xen"></domain>
+ </arch>
+ <features>
+ </features>
+ </guest>
+</capabilities>
--- /dev/null
+xen-3.0-powerpc64
--- /dev/null
+<capabilities>
+ <host>
+ <cpu>
+ <arch>ppc64</arch>
+ <features>
+ </features>
+ </cpu>
+ </host>
+
+ <guest>
+ <os_type>xen</os_type>
+ <arch name="ppc64">
+ <wordsize>64</wordsize>
+ <domain type="xen"></domain>
+ </arch>
+ <features>
+ </features>
+ </guest>
+</capabilities>
--- /dev/null
+xen-3.0-x86_64 hvm-3.0-x86_32 hvm-3.0-x86_32p hvm-3.0-x86_64
--- /dev/null
+processor : 0
+vendor_id : AuthenticAMD
+cpu family : 15
+model : 67
+model name : AMD Athlon(tm) 64 X2 Dual Core Processor 5200+
+stepping : 2
+cpu MHz : 2600.000
+cache size : 1024 KB
+physical id : 0
+siblings : 1
+core id : 0
+cpu cores : 1
+fpu : yes
+fpu_exception : yes
+cpuid level : 1
+wp : yes
+flags : fpu tsc msr pae mce cx8 apic mtrr mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt rdtscp lm 3dnowext 3dnow pni cx16 lahf_lm cmp_legacy svm cr8_legacy
+bogomips : 6469.52
+TLB size : 1024 4K pages
+clflush size : 64
+cache_alignment : 64
+address sizes : 40 bits physical, 48 bits virtual
+power management: ts fid vid ttp tm stc
+
+processor : 1
+vendor_id : AuthenticAMD
+cpu family : 15
+model : 67
+model name : AMD Athlon(tm) 64 X2 Dual Core Processor 5200+
+stepping : 2
+cpu MHz : 2600.000
+cache size : 1024 KB
+physical id : 1
+siblings : 1
+core id : 0
+cpu cores : 1
+fpu : yes
+fpu_exception : yes
+cpuid level : 1
+wp : yes
+flags : fpu tsc msr pae mce cx8 apic mtrr mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt rdtscp lm 3dnowext 3dnow pni cx16 lahf_lm cmp_legacy svm cr8_legacy
+bogomips : 6469.52
+TLB size : 1024 4K pages
+clflush size : 64
+cache_alignment : 64
+address sizes : 40 bits physical, 48 bits virtual
+power management: ts fid vid ttp tm stc
--- /dev/null
+<capabilities>
+ <host>
+ <cpu>
+ <arch>x86_64</arch>
+ <features>
+ <svm/>
+ </features>
+ </cpu>
+ </host>
+
+ <guest>
+ <os_type>xen</os_type>
+ <arch name="x86_64">
+ <wordsize>64</wordsize>
+ <domain type="xen"></domain>
+ </arch>
+ <features>
+ </features>
+ </guest>
+
+ <guest>
+ <os_type>hvm</os_type>
+ <arch name="i686">
+ <wordsize>32</wordsize>
+ <domain type="xen"></domain>
+ <emulator>/usr/lib/xen/bin/qemu-dm</emulator>
+ <machine>pc</machine>
+ <machine>isapc</machine>
+ <loader>/usr/lib/xen/boot/hvmloader</loader>
+ </arch>
+ <features>
+ <pae/>
+ <nonpae/>
+ </features>
+ </guest>
+
+ <guest>
+ <os_type>hvm</os_type>
+ <arch name="x86_64">
+ <wordsize>64</wordsize>
+ <domain type="xen"></domain>
+ <emulator>/usr/lib64/xen/bin/qemu-dm</emulator>
+ <machine>pc</machine>
+ <machine>isapc</machine>
+ <loader>/usr/lib/xen/boot/hvmloader</loader>
+ </arch>
+ <features>
+ </features>
+ </guest>
+</capabilities>
--- /dev/null
+xen-3.0-x86_64
--- /dev/null
+processor : 0
+vendor_id : AuthenticAMD
+cpu family : 15
+model : 67
+model name : AMD Athlon(tm) 64 X2 Dual Core Processor 5200+
+stepping : 2
+cpu MHz : 2600.000
+cache size : 1024 KB
+physical id : 0
+siblings : 1
+core id : 0
+cpu cores : 1
+fpu : yes
+fpu_exception : yes
+cpuid level : 1
+wp : yes
+flags : fpu tsc msr pae mce cx8 apic mtrr mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt rdtscp lm 3dnowext 3dnow pni cx16 lahf_lm cmp_legacy svm cr8_legacy
+bogomips : 6469.52
+TLB size : 1024 4K pages
+clflush size : 64
+cache_alignment : 64
+address sizes : 40 bits physical, 48 bits virtual
+power management: ts fid vid ttp tm stc
+
+processor : 1
+vendor_id : AuthenticAMD
+cpu family : 15
+model : 67
+model name : AMD Athlon(tm) 64 X2 Dual Core Processor 5200+
+stepping : 2
+cpu MHz : 2600.000
+cache size : 1024 KB
+physical id : 1
+siblings : 1
+core id : 0
+cpu cores : 1
+fpu : yes
+fpu_exception : yes
+cpuid level : 1
+wp : yes
+flags : fpu tsc msr pae mce cx8 apic mtrr mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt rdtscp lm 3dnowext 3dnow pni cx16 lahf_lm cmp_legacy svm cr8_legacy
+bogomips : 6469.52
+TLB size : 1024 4K pages
+clflush size : 64
+cache_alignment : 64
+address sizes : 40 bits physical, 48 bits virtual
+power management: ts fid vid ttp tm stc
--- /dev/null
+<capabilities>
+ <host>
+ <cpu>
+ <arch>x86_64</arch>
+ <features>
+ <svm/>
+ </features>
+ </cpu>
+ </host>
+
+ <guest>
+ <os_type>xen</os_type>
+ <arch name="x86_64">
+ <wordsize>64</wordsize>
+ <domain type="xen"></domain>
+ </arch>
+ <features>
+ </features>
+ </guest>
+</capabilities>
--- /dev/null
+#include <stdio.h>
+#include <string.h>
+
+#include "xml.h"
+#include "testutils.h"
+#include "internal.h"
+#include "xen_internal.h"
+
+static char *progname;
+
+#define MAX_FILE 4096
+
+static int testCompareFiles(const char *hostmachine,
+ const char *xml,
+ const char *cpuinfo,
+ const char *capabilities) {
+ char xmlData[MAX_FILE];
+ char *expectxml = &(xmlData[0]);
+ char *actualxml = NULL;
+ FILE *fp1 = NULL, *fp2 = NULL;
+
+ int ret = -1;
+
+ if (virtTestLoadFile(xml, &expectxml, MAX_FILE) < 0)
+ goto fail;
+
+ if (!(fp1 = fopen(cpuinfo, "r")))
+ goto fail;
+
+ if (!(fp2 = fopen(capabilities, "r")))
+ goto fail;
+
+ if (!(actualxml = xenHypervisorMakeCapabilitiesXML(NULL, hostmachine, fp1, fp2)))
+ goto fail;
+
+ if (getenv("DEBUG_TESTS")) {
+ printf("Expect %d '%s'\n", (int)strlen(expectxml), expectxml);
+ printf("Actual %d '%s'\n", (int)strlen(actualxml), actualxml);
+ }
+ if (strcmp(expectxml, actualxml))
+ goto fail;
+
+ ret = 0;
+
+ fail:
+
+ if (actualxml)
+ free(actualxml);
+ if (fp1)
+ fclose(fp1);
+ if (fp2)
+ fclose(fp2);
+
+ return ret;
+}
+
+static int testXeni686(void *data ATTRIBUTE_UNUSED) {
+ return testCompareFiles("i686",
+ "xencapsdata/xen-i686.xml",
+ "xencapsdata/xen-i686.cpuinfo",
+ "xencapsdata/xen-i686.caps");
+}
+
+static int testXeni686PAE(void *data ATTRIBUTE_UNUSED) {
+ return testCompareFiles("i686",
+ "xencapsdata/xen-i686-pae.xml",
+ "xencapsdata/xen-i686-pae.cpuinfo",
+ "xencapsdata/xen-i686-pae.caps");
+}
+
+static int testXeni686PAEHVM(void *data ATTRIBUTE_UNUSED) {
+ return testCompareFiles("i686",
+ "xencapsdata/xen-i686-pae-hvm.xml",
+ "xencapsdata/xen-i686-pae-hvm.cpuinfo",
+ "xencapsdata/xen-i686-pae-hvm.caps");
+}
+
+/* No PAE + HVM is non-sensical - all VMX capable
+ CPUs have PAE */
+/*
+static int testXeni686HVM(void *data ATTRIBUTE_UNUSED) {
+ return testCompareFiles("i686",
+ "xencapsdata/xen-i686-hvm.xml",
+ "xencapsdata/xen-i686.cpuinfo",
+ "xencapsdata/xen-i686-hvm.caps");
+}
+*/
+
+static int testXenx86_64(void *data ATTRIBUTE_UNUSED) {
+ return testCompareFiles("x86_64",
+ "xencapsdata/xen-x86_64.xml",
+ "xencapsdata/xen-x86_64.cpuinfo",
+ "xencapsdata/xen-x86_64.caps");
+}
+static int testXenx86_64HVM(void *data ATTRIBUTE_UNUSED) {
+ return testCompareFiles("x86_64",
+ "xencapsdata/xen-x86_64-hvm.xml",
+ "xencapsdata/xen-x86_64-hvm.cpuinfo",
+ "xencapsdata/xen-x86_64-hvm.caps");
+}
+
+static int testXenia64(void *data ATTRIBUTE_UNUSED) {
+ return testCompareFiles("ia64",
+ "xencapsdata/xen-ia64.xml",
+ "xencapsdata/xen-ia64.cpuinfo",
+ "xencapsdata/xen-ia64.caps");
+}
+static int testXenia64BE(void *data ATTRIBUTE_UNUSED) {
+ return testCompareFiles("ia64",
+ "xencapsdata/xen-ia64-be.xml",
+ "xencapsdata/xen-ia64-be.cpuinfo",
+ "xencapsdata/xen-ia64-be.caps");
+}
+
+static int testXenia64HVM(void *data ATTRIBUTE_UNUSED) {
+ return testCompareFiles("ia64",
+ "xencapsdata/xen-ia64-hvm.xml",
+ "xencapsdata/xen-ia64-hvm.cpuinfo",
+ "xencapsdata/xen-ia64-hvm.caps");
+}
+static int testXenia64BEHVM(void *data ATTRIBUTE_UNUSED) {
+ return testCompareFiles("ia64",
+ "xencapsdata/xen-ia64-be-hvm.xml",
+ "xencapsdata/xen-ia64-be-hvm.cpuinfo",
+ "xencapsdata/xen-ia64-be-hvm.caps");
+}
+
+static int testXenppc64(void *data ATTRIBUTE_UNUSED) {
+ return testCompareFiles("ppc64",
+ "xencapsdata/xen-ppc64.xml",
+ "xencapsdata/xen-ppc64.cpuinfo",
+ "xencapsdata/xen-ppc64.caps");
+}
+
+
+int
+main(int argc, char **argv)
+{
+ int ret = 0;
+
+ progname = argv[0];
+
+ if (argc > 1) {
+ fprintf(stderr, "Usage: %s\n", progname);
+ exit(EXIT_FAILURE);
+ }
+
+ virInitialize();
+
+ if (virtTestRun("Capabilities for i686, no PAE, no HVM",
+ 1, testXeni686, NULL) != 0)
+ ret = -1;
+
+ if (virtTestRun("Capabilities for i686, PAE, no HVM",
+ 1, testXeni686PAE, NULL) != 0)
+ ret = -1;
+
+ /* No PAE + HVM is non-sensical - all VMX capable
+ CPUs have PAE */
+ /*if (virtTestRun("Capabilities for i686, no PAE, HVM",
+ 1, testXeni686HVM, NULL) != 0)
+ ret = -1;
+ */
+
+ if (virtTestRun("Capabilities for i686, PAE, HVM",
+ 1, testXeni686PAEHVM, NULL) != 0)
+ ret = -1;
+
+ if (virtTestRun("Capabilities for x86_64, no HVM",
+ 1, testXenx86_64, NULL) != 0)
+ ret = -1;
+
+ if (virtTestRun("Capabilities for x86_64, HVM",
+ 1, testXenx86_64HVM, NULL) != 0)
+ ret = -1;
+
+ if (virtTestRun("Capabilities for ia64, no HVM, LE",
+ 1, testXenia64, NULL) != 0)
+ ret = -1;
+
+ if (virtTestRun("Capabilities for ia64, HVM, LE",
+ 1, testXenia64HVM, NULL) != 0)
+ ret = -1;
+
+ if (virtTestRun("Capabilities for ia64, no HVM, BE",
+ 1, testXenia64BE, NULL) != 0)
+ ret = -1;
+
+ if (virtTestRun("Capabilities for ia64, HVM, BE",
+ 1, testXenia64BEHVM, NULL) != 0)
+ ret = -1;
+
+ if (virtTestRun("Capabilities for ppc64",
+ 1, testXenppc64, NULL) != 0)
+ ret = -1;
+
+
+ exit(ret==0 ? EXIT_SUCCESS : EXIT_FAILURE);
+}