[Libvir] [PATCH] pae/nonpae capabilities for paravirt xen guests

Daniel P. Berrange berrange at redhat.com
Mon Mar 26 19:39:16 UTC 2007


On Fri, Mar 23, 2007 at 12:24:57PM -0700, David Lutterkort wrote:
> I noticed that the guest capabilities on a xen dom0 always contain both
> the pae and nonpae feature - AFAIK, you can't mix pae/nonpae guests and
> hosts, and only one of the features should be there.

So it turned out to be a bit more complicated. The <guest> blocks are
supposed to be keyed off (machine,os-type) tuples eg (i686,xen) or
(x86_64,hvm), etc.  The impl was in fact though doing a linear conversion
from Xen's /sys/hypervisor/properties/capabilities which is keyed off a
(machine,os-type,flags) tuple (where flags==pae). So we needed to collapse
one level of cardinaility from the Xen data - hence the <pae/> & <nonpae/>
flags can both be used at once.

Anyway the collapsing was not correct, so I'm attaching a patch to address
that. This does a couple of other things too

 - Re-factors xenGetCapabilities so that it merely opens the /proc & /sysfs
   files and then passes the handle down to xenMakeCapabilitiesXML method.
 - Adds a huge test suite which has a library of various cpuinfo &
   capabilities files from various archs and calls xenMakeCapabilitiesXML
   with all of them
 - Removes the <emulator> element from paravirt <guest> block since it is
   only relevant to HVM.
 - Adds PowerPC support

Regards,
Dan.
-- 
|=- Red Hat, Engineering, Emerging Technologies, Boston.  +1 978 392 2496 -=|
|=-           Perl modules: http://search.cpan.org/~danberr/              -=|
|=-               Projects: http://freshmeat.net/~danielpb/               -=|
|=-  GnuPG: 7D3B9505   F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505  -=| 
-------------- next part --------------
? tests/xencapstest
Index: tests/Makefile.am
===================================================================
RCS file: /data/cvs/libvirt/tests/Makefile.am,v
retrieving revision 1.17
diff -u -p -r1.17 Makefile.am
--- tests/Makefile.am	15 Mar 2007 07:43:16 -0000	1.17
+++ tests/Makefile.am	26 Mar 2007 19:17:28 -0000
@@ -1,6 +1,6 @@
 ## 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...
 #
@@ -31,9 +31,9 @@ LDADDS = \
 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
@@ -80,6 +80,11 @@ conftest_SOURCES = \
 conftest_LDFLAGS =
 conftest_LDADD = $(LDADDS)
 
+xencapstest_SOURCES = \
+	xencapstest.c testutils.h testutils.c
+xencapstest_LDFLAGS =
+xencapstest_LDADD = $(LDADDS)
+
 reconnect_SOURCES = \
 	reconnect.c
 reconnect_LDFLAGS =
Index: tests/xencapstest.c
===================================================================
RCS file: tests/xencapstest.c
diff -N tests/xencapstest.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/xencapstest.c	26 Mar 2007 19:17:28 -0000
@@ -0,0 +1,199 @@
+#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);
+}
Index: tests/xencapsdata/.cvsignore
===================================================================
RCS file: tests/xencapsdata/.cvsignore
diff -N tests/xencapsdata/.cvsignore
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/xencapsdata/.cvsignore	26 Mar 2007 19:17:28 -0000
@@ -0,0 +1,2 @@
+Makefile
+Makefile.in
Index: tests/xencapsdata/Makefile.am
===================================================================
RCS file: tests/xencapsdata/Makefile.am
diff -N tests/xencapsdata/Makefile.am
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/xencapsdata/Makefile.am	26 Mar 2007 19:17:28 -0000
@@ -0,0 +1,2 @@
+
+EXTRA_DIST = $(wildcard *.xml) $(wildcard *.cpuinfo) $(wildcard *.caps)
Index: tests/xencapsdata/xen-i686-pae-hvm.caps
===================================================================
RCS file: tests/xencapsdata/xen-i686-pae-hvm.caps
diff -N tests/xencapsdata/xen-i686-pae-hvm.caps
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/xencapsdata/xen-i686-pae-hvm.caps	26 Mar 2007 19:17:28 -0000
@@ -0,0 +1 @@
+xen-3.0-x86_32p hvm-3.0-x86_32 hvm-3.0-x86_32p
Index: tests/xencapsdata/xen-i686-pae-hvm.cpuinfo
===================================================================
RCS file: tests/xencapsdata/xen-i686-pae-hvm.cpuinfo
diff -N tests/xencapsdata/xen-i686-pae-hvm.cpuinfo
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/xencapsdata/xen-i686-pae-hvm.cpuinfo	26 Mar 2007 19:17:28 -0000
@@ -0,0 +1,38 @@
+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
+
Index: tests/xencapsdata/xen-i686-pae-hvm.xml
===================================================================
RCS file: tests/xencapsdata/xen-i686-pae-hvm.xml
diff -N tests/xencapsdata/xen-i686-pae-hvm.xml
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/xencapsdata/xen-i686-pae-hvm.xml	26 Mar 2007 19:17:28 -0000
@@ -0,0 +1,37 @@
+<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>
Index: tests/xencapsdata/xen-i686-pae.caps
===================================================================
RCS file: tests/xencapsdata/xen-i686-pae.caps
diff -N tests/xencapsdata/xen-i686-pae.caps
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/xencapsdata/xen-i686-pae.caps	26 Mar 2007 19:17:28 -0000
@@ -0,0 +1 @@
+xen-3.0-x86_32p
Index: tests/xencapsdata/xen-i686-pae.cpuinfo
===================================================================
RCS file: tests/xencapsdata/xen-i686-pae.cpuinfo
diff -N tests/xencapsdata/xen-i686-pae.cpuinfo
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/xencapsdata/xen-i686-pae.cpuinfo	26 Mar 2007 19:17:28 -0000
@@ -0,0 +1,20 @@
+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
+
+
Index: tests/xencapsdata/xen-i686-pae.xml
===================================================================
RCS file: tests/xencapsdata/xen-i686-pae.xml
diff -N tests/xencapsdata/xen-i686-pae.xml
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/xencapsdata/xen-i686-pae.xml	26 Mar 2007 19:17:28 -0000
@@ -0,0 +1,21 @@
+<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>
Index: tests/xencapsdata/xen-i686.caps
===================================================================
RCS file: tests/xencapsdata/xen-i686.caps
diff -N tests/xencapsdata/xen-i686.caps
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/xencapsdata/xen-i686.caps	26 Mar 2007 19:17:28 -0000
@@ -0,0 +1 @@
+xen-3.0-x86_32
Index: tests/xencapsdata/xen-i686.cpuinfo
===================================================================
RCS file: tests/xencapsdata/xen-i686.cpuinfo
diff -N tests/xencapsdata/xen-i686.cpuinfo
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/xencapsdata/xen-i686.cpuinfo	26 Mar 2007 19:17:28 -0000
@@ -0,0 +1,19 @@
+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
+
Index: tests/xencapsdata/xen-i686.xml
===================================================================
RCS file: tests/xencapsdata/xen-i686.xml
diff -N tests/xencapsdata/xen-i686.xml
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/xencapsdata/xen-i686.xml	26 Mar 2007 19:17:28 -0000
@@ -0,0 +1,20 @@
+<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>
Index: tests/xencapsdata/xen-ia64-be-hvm.caps
===================================================================
RCS file: tests/xencapsdata/xen-ia64-be-hvm.caps
diff -N tests/xencapsdata/xen-ia64-be-hvm.caps
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/xencapsdata/xen-ia64-be-hvm.caps	26 Mar 2007 19:17:28 -0000
@@ -0,0 +1 @@
+xen-3.0-ia64be hvm-3.0-ia64be
Index: tests/xencapsdata/xen-ia64-be-hvm.cpuinfo
===================================================================
RCS file: tests/xencapsdata/xen-ia64-be-hvm.cpuinfo
diff -N tests/xencapsdata/xen-ia64-be-hvm.cpuinfo
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/xencapsdata/xen-ia64-be-hvm.cpuinfo	26 Mar 2007 19:17:28 -0000
@@ -0,0 +1,29 @@
+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
Index: tests/xencapsdata/xen-ia64-be-hvm.xml
===================================================================
RCS file: tests/xencapsdata/xen-ia64-be-hvm.xml
diff -N tests/xencapsdata/xen-ia64-be-hvm.xml
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/xencapsdata/xen-ia64-be-hvm.xml	26 Mar 2007 19:17:28 -0000
@@ -0,0 +1,35 @@
+<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>
Index: tests/xencapsdata/xen-ia64-be.caps
===================================================================
RCS file: tests/xencapsdata/xen-ia64-be.caps
diff -N tests/xencapsdata/xen-ia64-be.caps
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/xencapsdata/xen-ia64-be.caps	26 Mar 2007 19:17:28 -0000
@@ -0,0 +1 @@
+xen-3.0-ia64be
Index: tests/xencapsdata/xen-ia64-be.cpuinfo
===================================================================
RCS file: tests/xencapsdata/xen-ia64-be.cpuinfo
diff -N tests/xencapsdata/xen-ia64-be.cpuinfo
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/xencapsdata/xen-ia64-be.cpuinfo	26 Mar 2007 19:17:28 -0000
@@ -0,0 +1,29 @@
+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
Index: tests/xencapsdata/xen-ia64-be.xml
===================================================================
RCS file: tests/xencapsdata/xen-ia64-be.xml
diff -N tests/xencapsdata/xen-ia64-be.xml
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/xencapsdata/xen-ia64-be.xml	26 Mar 2007 19:17:28 -0000
@@ -0,0 +1,20 @@
+<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>
Index: tests/xencapsdata/xen-ia64-hvm.caps
===================================================================
RCS file: tests/xencapsdata/xen-ia64-hvm.caps
diff -N tests/xencapsdata/xen-ia64-hvm.caps
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/xencapsdata/xen-ia64-hvm.caps	26 Mar 2007 19:17:28 -0000
@@ -0,0 +1 @@
+xen-3.0-ia64 hvm-3.0-ia64
Index: tests/xencapsdata/xen-ia64-hvm.cpuinfo
===================================================================
RCS file: tests/xencapsdata/xen-ia64-hvm.cpuinfo
diff -N tests/xencapsdata/xen-ia64-hvm.cpuinfo
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/xencapsdata/xen-ia64-hvm.cpuinfo	26 Mar 2007 19:17:28 -0000
@@ -0,0 +1,29 @@
+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
Index: tests/xencapsdata/xen-ia64-hvm.xml
===================================================================
RCS file: tests/xencapsdata/xen-ia64-hvm.xml
diff -N tests/xencapsdata/xen-ia64-hvm.xml
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/xencapsdata/xen-ia64-hvm.xml	26 Mar 2007 19:17:28 -0000
@@ -0,0 +1,33 @@
+<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>
Index: tests/xencapsdata/xen-ia64.caps
===================================================================
RCS file: tests/xencapsdata/xen-ia64.caps
diff -N tests/xencapsdata/xen-ia64.caps
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/xencapsdata/xen-ia64.caps	26 Mar 2007 19:17:28 -0000
@@ -0,0 +1 @@
+xen-3.0-ia64
Index: tests/xencapsdata/xen-ia64.cpuinfo
===================================================================
RCS file: tests/xencapsdata/xen-ia64.cpuinfo
diff -N tests/xencapsdata/xen-ia64.cpuinfo
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/xencapsdata/xen-ia64.cpuinfo	26 Mar 2007 19:17:28 -0000
@@ -0,0 +1,29 @@
+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
Index: tests/xencapsdata/xen-ia64.xml
===================================================================
RCS file: tests/xencapsdata/xen-ia64.xml
diff -N tests/xencapsdata/xen-ia64.xml
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/xencapsdata/xen-ia64.xml	26 Mar 2007 19:17:28 -0000
@@ -0,0 +1,19 @@
+<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>
Index: tests/xencapsdata/xen-ppc64.caps
===================================================================
RCS file: tests/xencapsdata/xen-ppc64.caps
diff -N tests/xencapsdata/xen-ppc64.caps
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/xencapsdata/xen-ppc64.caps	26 Mar 2007 19:17:28 -0000
@@ -0,0 +1 @@
+xen-3.0-powerpc64
Index: tests/xencapsdata/xen-ppc64.cpuinfo
===================================================================
RCS file: tests/xencapsdata/xen-ppc64.cpuinfo
diff -N tests/xencapsdata/xen-ppc64.cpuinfo
Index: tests/xencapsdata/xen-ppc64.xml
===================================================================
RCS file: tests/xencapsdata/xen-ppc64.xml
diff -N tests/xencapsdata/xen-ppc64.xml
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/xencapsdata/xen-ppc64.xml	26 Mar 2007 19:17:28 -0000
@@ -0,0 +1,19 @@
+<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>
Index: tests/xencapsdata/xen-x86_64-hvm.caps
===================================================================
RCS file: tests/xencapsdata/xen-x86_64-hvm.caps
diff -N tests/xencapsdata/xen-x86_64-hvm.caps
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/xencapsdata/xen-x86_64-hvm.caps	26 Mar 2007 19:17:28 -0000
@@ -0,0 +1 @@
+xen-3.0-x86_64 hvm-3.0-x86_32 hvm-3.0-x86_32p hvm-3.0-x86_64
Index: tests/xencapsdata/xen-x86_64-hvm.cpuinfo
===================================================================
RCS file: tests/xencapsdata/xen-x86_64-hvm.cpuinfo
diff -N tests/xencapsdata/xen-x86_64-hvm.cpuinfo
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/xencapsdata/xen-x86_64-hvm.cpuinfo	26 Mar 2007 19:17:28 -0000
@@ -0,0 +1,47 @@
+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
Index: tests/xencapsdata/xen-x86_64-hvm.xml
===================================================================
RCS file: tests/xencapsdata/xen-x86_64-hvm.xml
diff -N tests/xencapsdata/xen-x86_64-hvm.xml
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/xencapsdata/xen-x86_64-hvm.xml	26 Mar 2007 19:17:28 -0000
@@ -0,0 +1,50 @@
+<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>
Index: tests/xencapsdata/xen-x86_64.caps
===================================================================
RCS file: tests/xencapsdata/xen-x86_64.caps
diff -N tests/xencapsdata/xen-x86_64.caps
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/xencapsdata/xen-x86_64.caps	26 Mar 2007 19:17:28 -0000
@@ -0,0 +1 @@
+xen-3.0-x86_64
Index: tests/xencapsdata/xen-x86_64.cpuinfo
===================================================================
RCS file: tests/xencapsdata/xen-x86_64.cpuinfo
diff -N tests/xencapsdata/xen-x86_64.cpuinfo
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/xencapsdata/xen-x86_64.cpuinfo	26 Mar 2007 19:17:28 -0000
@@ -0,0 +1,47 @@
+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
Index: tests/xencapsdata/xen-x86_64.xml
===================================================================
RCS file: tests/xencapsdata/xen-x86_64.xml
diff -N tests/xencapsdata/xen-x86_64.xml
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/xencapsdata/xen-x86_64.xml	26 Mar 2007 19:17:28 -0000
@@ -0,0 +1,20 @@
+<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>
Index: src/xen_internal.c
===================================================================
RCS file: /data/cvs/libvirt/src/xen_internal.c,v
retrieving revision 1.67
diff -u -p -r1.67 xen_internal.c
--- src/xen_internal.c	23 Mar 2007 09:18:24 -0000	1.67
+++ src/xen_internal.c	26 Mar 2007 19:18:33 -0000
@@ -85,7 +85,7 @@ static const char *flags_hvm_re = "^flag
 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;
 
 /*
@@ -1472,27 +1472,29 @@ xenHypervisorGetVersion(virConnectPtr co
 /**
  * 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;
@@ -1502,34 +1504,22 @@ xenHypervisorGetCapabilities (virConnect
 
     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.
      *
@@ -1553,63 +1543,81 @@ xenHypervisorGetCapabilities (virConnect
      *    |   +----------- 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;
-            }
-            else {
-                guest_archs[nr_guest_archs].model = ""; /* can never happen */
+                /* 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;
             }
-            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;
@@ -1620,19 +1628,15 @@ xenHypervisorGetCapabilities (virConnect
     <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, "\
@@ -1650,25 +1654,23 @@ xenHypervisorGetCapabilities (virConnect
         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,
@@ -1679,7 +1681,12 @@ xenHypervisorGetCapabilities (virConnect
         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;
         }
@@ -1707,6 +1714,53 @@ xenHypervisorGetCapabilities (virConnect
     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;
 }
 
 /**
Index: src/xen_internal.h
===================================================================
RCS file: /data/cvs/libvirt/src/xen_internal.h,v
retrieving revision 1.17
diff -u -p -r1.17 xen_internal.h
--- src/xen_internal.h	15 Mar 2007 17:24:57 -0000	1.17
+++ src/xen_internal.h	26 Mar 2007 19:18:33 -0000
@@ -23,6 +23,11 @@ int	xenHypervisorClose		(virConnectPtr c
 int	xenHypervisorGetVersion		(virConnectPtr conn,
 				 	 unsigned long *hvVer);
 char *
+        xenHypervisorMakeCapabilitiesXML (virConnectPtr conn,
+					  const char *hostmachine,
+					  FILE *cpuinfo,
+					  FILE *capabilities);
+char *
         xenHypervisorGetCapabilities    (virConnectPtr conn);
 unsigned long
         xenHypervisorGetDomMaxMemory	(virConnectPtr conn,


More information about the libvir-list mailing list