[libvirt] [PATCH 4/6] Convert capabilities / domain_conf to use virArch

Daniel P. Berrange berrange at redhat.com
Tue Dec 11 14:53:39 UTC 2012


From: "Daniel P. Berrange" <berrange at redhat.com>

Convert the host capabilities and domain config structs to
use the virArch datatype. Update the parsers and all drivers
to take account of datatype change

Signed-off-by: Daniel P. Berrange <berrange at redhat.com>
---
 src/conf/capabilities.c          | 86 +++++++++++++++++-----------------
 src/conf/capabilities.h          | 24 +++++-----
 src/conf/domain_conf.c           | 36 +++++++++------
 src/conf/domain_conf.h           |  2 +-
 src/esx/esx_driver.c             | 14 ++++--
 src/libxl/libxl_conf.c           | 38 ++++++---------
 src/libxl/libxl_driver.c         | 11 ++---
 src/lxc/lxc_conf.c               | 17 ++-----
 src/lxc/lxc_container.c          | 32 +++++++------
 src/lxc/lxc_container.h          |  2 +-
 src/lxc/lxc_controller.c         | 13 ++----
 src/openvz/openvz_conf.c         | 11 ++---
 src/openvz/openvz_driver.c       |  1 -
 src/parallels/parallels_driver.c | 24 +++++-----
 src/phyp/phyp_driver.c           | 12 ++---
 src/qemu/qemu_capabilities.c     | 99 +++++++++++++++++-----------------------
 src/qemu/qemu_command.c          | 40 ++++++++--------
 src/qemu/qemu_command.h          |  2 +-
 src/qemu/qemu_conf.c             |  1 -
 src/qemu/qemu_driver.c           |  1 -
 src/security/virt-aa-helper.c    | 29 ++++--------
 src/test/test_driver.c           |  7 ++-
 src/uml/uml_conf.c               | 15 ++----
 src/vbox/vbox_tmpl.c             | 20 +++-----
 src/vmware/vmware_conf.c         | 34 +++++++-------
 src/vmx/vmx.c                    | 16 +++----
 src/xen/xen_hypervisor.c         | 66 ++++++++++-----------------
 src/xen/xen_hypervisor.h         |  2 +-
 src/xenxs/xen_xm.c               |  8 ++--
 29 files changed, 284 insertions(+), 379 deletions(-)

diff --git a/src/conf/capabilities.c b/src/conf/capabilities.c
index a8ee2cf..97d1b80 100644
--- a/src/conf/capabilities.c
+++ b/src/conf/capabilities.c
@@ -42,14 +42,14 @@ VIR_ENUM_IMPL(virCapsHostPMTarget, VIR_NODE_SUSPEND_TARGET_LAST,
 
 /**
  * virCapabilitiesNew:
- * @arch: host machine architecture
+ * @hostarch: host machine architecture
  * @offlineMigrate: non-zero if offline migration is available
  * @liveMigrate: non-zero if live migration is available
  *
  * Allocate a new capabilities object
  */
 virCapsPtr
-virCapabilitiesNew(const char *arch,
+virCapabilitiesNew(virArch hostarch,
                    int offlineMigrate,
                    int liveMigrate)
 {
@@ -58,16 +58,11 @@ virCapabilitiesNew(const char *arch,
     if (VIR_ALLOC(caps) < 0)
         return NULL;
 
-    if ((caps->host.arch = strdup(arch)) == NULL)
-        goto no_memory;
+    caps->host.arch = hostarch;
     caps->host.offlineMigrate = offlineMigrate;
     caps->host.liveMigrate = liveMigrate;
 
     return caps;
-
- no_memory:
-    virCapabilitiesFree(caps);
-    return NULL;
 }
 
 static void
@@ -125,7 +120,6 @@ virCapabilitiesFreeGuest(virCapsGuestPtr guest)
 
     VIR_FREE(guest->ostype);
 
-    VIR_FREE(guest->arch.name);
     VIR_FREE(guest->arch.defaultInfo.emulator);
     VIR_FREE(guest->arch.defaultInfo.loader);
     for (i = 0 ; i < guest->arch.defaultInfo.nmachines ; i++)
@@ -180,8 +174,6 @@ virCapabilitiesFree(virCapsPtr caps) {
         VIR_FREE(caps->host.migrateTrans[i]);
     VIR_FREE(caps->host.migrateTrans);
 
-    VIR_FREE(caps->host.arch);
-
     for (i = 0; i < caps->host.nsecModels; i++) {
         VIR_FREE(caps->host.secModels[i].model);
         VIR_FREE(caps->host.secModels[i].doi);
@@ -353,7 +345,7 @@ virCapabilitiesFreeMachines(virCapsGuestMachinePtr *machines,
  * virCapabilitiesAddGuest:
  * @caps: capabilities to extend
  * @ostype: guest operating system type ('hvm' or 'xen')
- * @arch: guest CPU architecture ('i686', or 'x86_64', etc)
+ * @arch: guest CPU architecture
  * @wordsize: number of bits in CPU word
  * @emulator: path to default device emulator for arch/ostype
  * @loader: path to default BIOS loader for arch/ostype
@@ -367,8 +359,7 @@ virCapabilitiesFreeMachines(virCapsGuestMachinePtr *machines,
 virCapsGuestPtr
 virCapabilitiesAddGuest(virCapsPtr caps,
                         const char *ostype,
-                        const char *arch,
-                        int wordsize,
+                        virArch arch,
                         const char *emulator,
                         const char *loader,
                         int nmachines,
@@ -382,9 +373,8 @@ virCapabilitiesAddGuest(virCapsPtr caps,
     if ((guest->ostype = strdup(ostype)) == NULL)
         goto no_memory;
 
-    if ((guest->arch.name = strdup(arch)) == NULL)
-        goto no_memory;
-    guest->arch.wordsize = wordsize;
+    guest->arch.id = arch;
+    guest->arch.wordsize = virArchGetWordSize(arch);
 
     if (emulator &&
         (guest->arch.defaultInfo.emulator = strdup(emulator)) == NULL)
@@ -505,18 +495,18 @@ virCapabilitiesAddGuestFeature(virCapsGuestPtr guest,
 /**
  * virCapabilitiesSupportsGuestArch:
  * @caps: capabilities to query
- * @arch: Architecture to search for (eg, 'i686', 'x86_64')
+ * @arch: Architecture to search for
  *
  * Returns non-zero if the capabilities support the
  * requested architecture
  */
 extern int
 virCapabilitiesSupportsGuestArch(virCapsPtr caps,
-                                 const char *arch)
+                                 virArch arch)
 {
     int i;
     for (i = 0 ; i < caps->nguests ; i++) {
-        if (STREQ(caps->guests[i]->arch.name, arch))
+        if (caps->guests[i]->arch.id == arch)
             return 1;
     }
     return 0;
@@ -548,7 +538,7 @@ virCapabilitiesSupportsGuestOSType(virCapsPtr caps,
  * virCapabilitiesSupportsGuestOSTypeArch:
  * @caps: capabilities to query
  * @ostype: OS type to search for (eg 'hvm', 'xen')
- * @arch: Architecture to search for (eg, 'i686', 'x86_64')
+ * @arch: Architecture to search for
  *
  * Returns non-zero if the capabilities support the
  * requested operating system type
@@ -556,12 +546,12 @@ virCapabilitiesSupportsGuestOSType(virCapsPtr caps,
 extern int
 virCapabilitiesSupportsGuestOSTypeArch(virCapsPtr caps,
                                        const char *ostype,
-                                       const char *arch)
+                                       virArch arch)
 {
     int i;
     for (i = 0 ; i < caps->nguests ; i++) {
         if (STREQ(caps->guests[i]->ostype, ostype) &&
-            STREQ(caps->guests[i]->arch.name, arch))
+            (caps->guests[i]->arch.id == arch))
             return 1;
     }
     return 0;
@@ -576,28 +566,35 @@ virCapabilitiesSupportsGuestOSTypeArch(virCapsPtr caps,
  * Returns the first architecture able to run the
  * requested operating system type
  */
-extern const char *
+extern virArch
 virCapabilitiesDefaultGuestArch(virCapsPtr caps,
                                 const char *ostype,
                                 const char *domain)
 {
     int i, j;
-    const char *arch = NULL;
+
+    /* First try to find one matching host arch */
     for (i = 0 ; i < caps->nguests ; i++) {
         if (STREQ(caps->guests[i]->ostype, ostype)) {
             for (j = 0 ; j < caps->guests[i]->arch.ndomains ; j++) {
-                if (STREQ(caps->guests[i]->arch.domains[j]->type, domain)) {
-                    /* Use the first match... */
-                    if (!arch)
-                        arch = caps->guests[i]->arch.name;
-                    /* ...unless we can match the host's architecture. */
-                    if (STREQ(caps->guests[i]->arch.name, caps->host.arch))
-                        return caps->guests[i]->arch.name;
-                }
+                if (STREQ(caps->guests[i]->arch.domains[j]->type, domain) &&
+                    (caps->guests[i]->arch.id == caps->host.arch))
+                    return caps->guests[i]->arch.id;
             }
         }
     }
-    return arch;
+
+    /* Otherwise find the first match */
+    for (i = 0 ; i < caps->nguests ; i++) {
+        if (STREQ(caps->guests[i]->ostype, ostype)) {
+            for (j = 0 ; j < caps->guests[i]->arch.ndomains ; j++) {
+                if (STREQ(caps->guests[i]->arch.domains[j]->type, domain))
+                    return caps->guests[i]->arch.id;
+            }
+        }
+    }
+
+    return VIR_ARCH_I686;
 }
 
 /**
@@ -614,7 +611,7 @@ virCapabilitiesDefaultGuestArch(virCapsPtr caps,
 extern const char *
 virCapabilitiesDefaultGuestMachine(virCapsPtr caps,
                                    const char *ostype,
-                                   const char *arch,
+                                   virArch arch,
                                    const char *domain)
 {
     int i;
@@ -623,11 +620,12 @@ virCapabilitiesDefaultGuestMachine(virCapsPtr caps,
         virCapsGuestPtr guest = caps->guests[i];
         int j;
 
-        if (!STREQ(guest->ostype, ostype) || !STREQ(guest->arch.name, arch))
+        if (!STREQ(guest->ostype, ostype) ||
+            (guest->arch.id != arch))
             continue;
 
         for (j = 0; j < guest->arch.ndomains; j++) {
-            virCapsGuestDomainPtr dom= guest->arch.domains[j];
+            virCapsGuestDomainPtr dom = guest->arch.domains[j];
 
             if (!STREQ(dom->type, domain))
                 continue;
@@ -659,14 +657,14 @@ virCapabilitiesDefaultGuestMachine(virCapsPtr caps,
 extern const char *
 virCapabilitiesDefaultGuestEmulator(virCapsPtr caps,
                                     const char *ostype,
-                                    const char *arch,
+                                    virArch arch,
                                     const char *domain)
 {
     int i, j;
     for (i = 0 ; i < caps->nguests ; i++) {
         char *emulator;
         if (STREQ(caps->guests[i]->ostype, ostype) &&
-            STREQ(caps->guests[i]->arch.name, arch)) {
+            (caps->guests[i]->arch.id == arch)) {
             emulator = caps->guests[i]->arch.defaultInfo.emulator;
             for (j = 0 ; j < caps->guests[i]->arch.ndomains ; j++) {
                 if (STREQ(caps->guests[i]->arch.domains[j]->type, domain)) {
@@ -703,8 +701,9 @@ virCapabilitiesFormatXML(virCapsPtr caps)
         virBufferAsprintf(&xml,"    <uuid>%s</uuid>\n", host_uuid);
     }
     virBufferAddLit(&xml, "    <cpu>\n");
-    virBufferAsprintf(&xml, "      <arch>%s</arch>\n",
-                      caps->host.arch);
+    if (caps->host.arch)
+        virBufferAsprintf(&xml, "      <arch>%s</arch>\n",
+                          virArchToString(caps->host.arch));
 
     if (caps->host.nfeatures) {
         virBufferAddLit(&xml, "      <features>\n");
@@ -788,8 +787,9 @@ virCapabilitiesFormatXML(virCapsPtr caps)
         virBufferAddLit(&xml, "  <guest>\n");
         virBufferAsprintf(&xml, "    <os_type>%s</os_type>\n",
                           caps->guests[i]->ostype);
-        virBufferAsprintf(&xml, "    <arch name='%s'>\n",
-                          caps->guests[i]->arch.name);
+        if (caps->guests[i]->arch.id)
+            virBufferAsprintf(&xml, "    <arch name='%s'>\n",
+                              virArchToString(caps->guests[i]->arch.id));
         virBufferAsprintf(&xml, "      <wordsize>%d</wordsize>\n",
                           caps->guests[i]->arch.wordsize);
         if (caps->guests[i]->arch.defaultInfo.emulator)
diff --git a/src/conf/capabilities.h b/src/conf/capabilities.h
index 641f279..3cdbcaa 100644
--- a/src/conf/capabilities.h
+++ b/src/conf/capabilities.h
@@ -27,6 +27,7 @@
 # include "internal.h"
 # include "buf.h"
 # include "cpu_conf.h"
+# include "virarch.h"
 # include "virmacaddr.h"
 
 # include <libxml/xpath.h>
@@ -65,8 +66,8 @@ struct _virCapsGuestDomain {
 typedef struct _virCapsGuestArch virCapsGuestArch;
 typedef virCapsGuestArch *virCapsGuestArchptr;
 struct _virCapsGuestArch {
-    char *name;
-    int wordsize;
+    virArch id;
+    unsigned int wordsize;
     virCapsGuestDomainInfo defaultInfo;
     size_t ndomains;
     size_t ndomains_max;
@@ -101,7 +102,7 @@ struct _virCapsHostSecModel {
 typedef struct _virCapsHost virCapsHost;
 typedef virCapsHost *virCapsHostPtr;
 struct _virCapsHost {
-    char *arch;
+    virArch arch;
     size_t nfeatures;
     size_t nfeatures_max;
     char **features;
@@ -150,7 +151,7 @@ struct _virCaps {
     unsigned int emulatorRequired : 1;
     const char *defaultDiskDriverName;
     int defaultDiskDriverType; /* enum virStorageFileFormat */
-    int (*defaultConsoleTargetType)(const char *ostype, const char *arch);
+    int (*defaultConsoleTargetType)(const char *ostype, virArch guestarch);
     void *(*privateDataAllocFunc)(void);
     void (*privateDataFreeFunc)(void *);
     int (*privateDataXMLFormat)(virBufferPtr, void *);
@@ -163,7 +164,7 @@ struct _virCaps {
 
 
 extern virCapsPtr
-virCapabilitiesNew(const char *arch,
+virCapabilitiesNew(virArch hostarch,
                    int offlineMigrate,
                    int liveMigrate);
 
@@ -218,8 +219,7 @@ virCapabilitiesFreeMachines(virCapsGuestMachinePtr *machines,
 extern virCapsGuestPtr
 virCapabilitiesAddGuest(virCapsPtr caps,
                         const char *ostype,
-                        const char *arch,
-                        int wordsize,
+                        virArch arch,
                         const char *emulator,
                         const char *loader,
                         int nmachines,
@@ -241,29 +241,29 @@ virCapabilitiesAddGuestFeature(virCapsGuestPtr guest,
 
 extern int
 virCapabilitiesSupportsGuestArch(virCapsPtr caps,
-                                 const char *arch);
+                                 virArch arch);
 extern int
 virCapabilitiesSupportsGuestOSType(virCapsPtr caps,
                                    const char *ostype);
 extern int
 virCapabilitiesSupportsGuestOSTypeArch(virCapsPtr caps,
                                        const char *ostype,
-                                       const char *arch);
+                                       virArch arch);
 
 
-extern const char *
+extern virArch
 virCapabilitiesDefaultGuestArch(virCapsPtr caps,
                                 const char *ostype,
                                 const char *domain);
 extern const char *
 virCapabilitiesDefaultGuestMachine(virCapsPtr caps,
                                    const char *ostype,
-                                   const char *arch,
+                                   virArch arch,
                                    const char *domain);
 extern const char *
 virCapabilitiesDefaultGuestEmulator(virCapsPtr caps,
                                     const char *ostype,
-                                    const char *arch,
+                                    virArch arch,
                                     const char *domain);
 
 extern char *
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 6aa5f79..1f978db 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -1694,7 +1694,6 @@ void virDomainDefFree(virDomainDefPtr def)
     VIR_FREE(def->redirdevs);
 
     VIR_FREE(def->os.type);
-    VIR_FREE(def->os.arch);
     VIR_FREE(def->os.machine);
     VIR_FREE(def->os.init);
     for (i = 0 ; def->os.initargv && def->os.initargv[i] ; i++)
@@ -8357,7 +8356,7 @@ static char *virDomainDefDefaultEmulator(virDomainDefPtr def,
     if (!emulator) {
         virReportError(VIR_ERR_INTERNAL_ERROR,
                        _("no emulator for domain %s os type %s on architecture %s"),
-                       type, def->os.type, def->os.arch);
+                       type, def->os.type, virArchToString(def->os.arch));
         return NULL;
     }
 
@@ -9412,12 +9411,20 @@ static virDomainDefPtr virDomainDefParseXML(virCapsPtr caps,
         goto error;
     }
 
-    def->os.arch = virXPathString("string(./os/type[1]/@arch)", ctxt);
-    if (def->os.arch) {
+    tmp = virXPathString("string(./os/type[1]/@arch)", ctxt);
+    if (tmp) {
+        virArch arch = virArchFromString(tmp);
+        if (!arch) {
+            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                           _("Unknown architecture %s"),
+                           tmp);
+            goto error;
+        }
+
         if (!virCapabilitiesSupportsGuestArch(caps, def->os.arch)) {
             virReportError(VIR_ERR_INTERNAL_ERROR,
                            _("No guest options available for arch '%s'"),
-                           def->os.arch);
+                           virArchToString(def->os.arch));
             goto error;
         }
 
@@ -9426,20 +9433,17 @@ static virDomainDefPtr virDomainDefParseXML(virCapsPtr caps,
                                                     def->os.arch)) {
             virReportError(VIR_ERR_INTERNAL_ERROR,
                            _("No os type '%s' available for arch '%s'"),
-                           def->os.type, def->os.arch);
+                           def->os.type, virArchToString(def->os.arch));
             goto error;
         }
     } else {
-        const char *defaultArch = virCapabilitiesDefaultGuestArch(caps, def->os.type, virDomainVirtTypeToString(def->virtType));
-        if (defaultArch == NULL) {
+        def->os.arch = virCapabilitiesDefaultGuestArch(caps, def->os.type, virDomainVirtTypeToString(def->virtType));
+        if (!def->os.arch) {
             virReportError(VIR_ERR_INTERNAL_ERROR,
                            _("no supported architecture for os type '%s'"),
                            def->os.type);
             goto error;
         }
-        if (!(def->os.arch = strdup(defaultArch))) {
-            goto no_memory;
-        }
     }
 
     def->os.machine = virXPathString("string(./os/type[1]/@machine)", ctxt);
@@ -10050,7 +10054,8 @@ static virDomainDefPtr virDomainDefParseXML(virCapsPtr caps,
 
         def->memballoon = memballoon;
         VIR_FREE(nodes);
-    } else if (!STREQ(def->os.arch,"s390x")) {
+    } else if ((def->os.arch != VIR_ARCH_S390) &&
+               (def->os.arch != VIR_ARCH_S390X)) {
         /* TODO: currently no balloon support on s390 -> no default balloon */
         if (def->virtType == VIR_DOMAIN_VIRT_XEN ||
             def->virtType == VIR_DOMAIN_VIRT_QEMU ||
@@ -11222,10 +11227,11 @@ bool virDomainDefCheckABIStability(virDomainDefPtr src,
                        dst->os.type, src->os.type);
         goto cleanup;
     }
-    if (STRNEQ(src->os.arch, dst->os.arch)) {
+    if (src->os.arch != dst->os.arch){
         virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                        _("Target domain architecture %s does not match source %s"),
-                       dst->os.arch, src->os.arch);
+                       virArchToString(dst->os.arch),
+                       virArchToString(src->os.arch));
         goto cleanup;
     }
     if (STRNEQ(src->os.machine, dst->os.machine)) {
@@ -13935,7 +13941,7 @@ virDomainDefFormatInternal(virDomainDefPtr def,
 
     virBufferAddLit(buf, "    <type");
     if (def->os.arch)
-        virBufferAsprintf(buf, " arch='%s'", def->os.arch);
+        virBufferAsprintf(buf, " arch='%s'", virArchToString(def->os.arch));
     if (def->os.machine)
         virBufferAsprintf(buf, " machine='%s'", def->os.machine);
     /*
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 7ad5377..ce36472 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -1479,7 +1479,7 @@ typedef struct _virDomainOSDef virDomainOSDef;
 typedef virDomainOSDef *virDomainOSDefPtr;
 struct _virDomainOSDef {
     char *type;
-    char *arch;
+    virArch arch;
     char *machine;
     size_t nBootDevs;
     int bootDevs[VIR_DOMAIN_BOOT_LAST];
diff --git a/src/esx/esx_driver.c b/src/esx/esx_driver.c
index a858298..4171beb 100644
--- a/src/esx/esx_driver.c
+++ b/src/esx/esx_driver.c
@@ -569,7 +569,7 @@ esxLookupHostSystemBiosUuid(esxPrivate *priv, unsigned char *uuid)
 
 
 static int esxDefaultConsoleType(const char *ostype ATTRIBUTE_UNUSED,
-                                 const char *arch ATTRIBUTE_UNUSED)
+                                 virArch arch ATTRIBUTE_UNUSED)
 {
     return VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_SERIAL;
 }
@@ -587,9 +587,9 @@ esxCapsInit(esxPrivate *priv)
     }
 
     if (supportsLongMode == esxVI_Boolean_True) {
-        caps = virCapabilitiesNew("x86_64", 1, 1);
+        caps = virCapabilitiesNew(VIR_ARCH_X86_64, 1, 1);
     } else {
-        caps = virCapabilitiesNew("i686", 1, 1);
+        caps = virCapabilitiesNew(VIR_ARCH_I686, 1, 1);
     }
 
     if (caps == NULL) {
@@ -608,7 +608,9 @@ esxCapsInit(esxPrivate *priv)
     }
 
     /* i686 */
-    guest = virCapabilitiesAddGuest(caps, "hvm", "i686", 32, NULL, NULL, 0,
+    guest = virCapabilitiesAddGuest(caps, "hvm",
+                                    VIR_ARCH_I686,
+                                    NULL, NULL, 0,
                                     NULL);
 
     if (guest == NULL) {
@@ -622,7 +624,9 @@ esxCapsInit(esxPrivate *priv)
 
     /* x86_64 */
     if (supportsLongMode == esxVI_Boolean_True) {
-        guest = virCapabilitiesAddGuest(caps, "hvm", "x86_64", 64, NULL, NULL,
+        guest = virCapabilitiesAddGuest(caps, "hvm",
+                                        VIR_ARCH_X86_64,
+                                        NULL, NULL,
                                         0, NULL);
 
         if (guest == NULL) {
diff --git a/src/libxl/libxl_conf.c b/src/libxl/libxl_conf.c
index 5b6d6fb..e456b1e 100644
--- a/src/libxl/libxl_conf.c
+++ b/src/libxl/libxl_conf.c
@@ -29,7 +29,6 @@
 #include <libxl.h>
 #include <sys/types.h>
 #include <sys/socket.h>
-#include <sys/utsname.h>
 
 #include "internal.h"
 #include "logging.h"
@@ -53,7 +52,7 @@
 
 
 struct guest_arch {
-    const char *model;
+    virArch arch;
     int bits;
     int hvm;
     int pae;
@@ -156,9 +155,8 @@ libxlBuildCapabilities(const char *hostmachine,
 
         if ((guest = virCapabilitiesAddGuest(caps,
                                              guest_archs[i].hvm ? "hvm" : "xen",
-                                             guest_archs[i].model,
-                                             guest_archs[i].bits,
-                                             (STREQ(hostmachine, "x86_64") ?
+                                             guest_archs[i].arch,
+                                             ((hostarch == VIR_ARCH_X86_64) ?
                                               "/usr/lib64/xen/bin/qemu-dm" :
                                               "/usr/lib/xen/bin/qemu-dm"),
                                              (guest_archs[i].hvm ?
@@ -230,7 +228,7 @@ libxlBuildCapabilities(const char *hostmachine,
 }
 
 static virCapsPtr
-libxlMakeCapabilitiesInternal(const char *hostmachine,
+libxlMakeCapabilitiesInternal(virArch hostarch,
                               libxl_physinfo *phy_info,
                               char *capabilities)
 {
@@ -285,12 +283,11 @@ libxlMakeCapabilitiesInternal(const char *hostmachine,
         if (regexec(&xen_cap_rec, token, sizeof(subs) / sizeof(subs[0]),
                     subs, 0) == 0) {
             int hvm = STRPREFIX(&token[subs[1].rm_so], "hvm");
-            const char *model;
-            int bits, pae = 0, nonpae = 0, ia64_be = 0;
+            virArch arch;
+            int pae = 0, nonpae = 0, ia64_be = 0;
 
             if (STRPREFIX(&token[subs[2].rm_so], "x86_32")) {
-                model = "i686";
-                bits = 32;
+                arch = VIR_ARCH_I686;
                 if (subs[3].rm_so != -1 &&
                     STRPREFIX(&token[subs[3].rm_so], "p"))
                     pae = 1;
@@ -298,26 +295,24 @@ libxlMakeCapabilitiesInternal(const char *hostmachine,
                     nonpae = 1;
             }
             else if (STRPREFIX(&token[subs[2].rm_so], "x86_64")) {
-                model = "x86_64";
-                bits = 64;
+                arch = VIR_ARCH_X86_64;
             }
             else if (STRPREFIX(&token[subs[2].rm_so], "ia64")) {
-                model = "ia64";
-                bits = 64;
+                arch = VIR_ARCH_ITANIUM;
                 if (subs[3].rm_so != -1 &&
                     STRPREFIX(&token[subs[3].rm_so], "be"))
                     ia64_be = 1;
             }
             else if (STRPREFIX(&token[subs[2].rm_so], "powerpc64")) {
-                model = "ppc64";
-                bits = 64;
+                arch = VIR_ARCH_PPC64;
             } else {
+                /* XXX arm ? */
                 continue;
             }
 
             /* Search for existing matching (model,hvm) tuple */
             for (i = 0 ; i < nr_guest_archs ; i++) {
-                if (STREQ(guest_archs[i].model, model) &&
+                if ((guest_archs[i].arch == arch) &&
                     guest_archs[i].hvm == hvm) {
                     break;
                 }
@@ -330,7 +325,7 @@ libxlMakeCapabilitiesInternal(const char *hostmachine,
             if (i == nr_guest_archs)
                 nr_guest_archs++;
 
-            guest_archs[i].model = model;
+            guest_archs[i].arch = arch;
             guest_archs[i].bits = bits;
             guest_archs[i].hvm = hvm;
 
@@ -347,7 +342,7 @@ libxlMakeCapabilitiesInternal(const char *hostmachine,
         }
     }
 
-    if ((caps = libxlBuildCapabilities(hostmachine,
+    if ((caps = libxlBuildCapabilities(hostarch,
                                        host_pae,
                                        guest_archs,
                                        nr_guest_archs)) == NULL)
@@ -795,7 +790,6 @@ libxlMakeCapabilities(libxl_ctx *ctx)
 {
     libxl_physinfo phy_info;
     const libxl_version_info *ver_info;
-    struct utsname utsname;
 
     regcomp(&xen_cap_rec, xen_cap_re, REG_EXTENDED);
 
@@ -811,9 +805,7 @@ libxlMakeCapabilities(libxl_ctx *ctx)
         return NULL;
     }
 
-    uname(&utsname);
-
-    return libxlMakeCapabilitiesInternal(utsname.machine,
+    return libxlMakeCapabilitiesInternal(virArchFromHost(),
                                          &phy_info,
                                          ver_info->capabilities);
 }
diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c
index 302f81c..c02cb19 100644
--- a/src/libxl/libxl_driver.c
+++ b/src/libxl/libxl_driver.c
@@ -26,7 +26,6 @@
 
 #include <config.h>
 
-#include <sys/utsname.h>
 #include <math.h>
 #include <libxl.h>
 #include <fcntl.h>
@@ -320,7 +319,7 @@ libxlDoNodeGetInfo(libxlDriverPrivatePtr driver, virNodeInfoPtr info)
 {
     libxl_physinfo phy_info;
     const libxl_version_info* ver_info;
-    struct utsname utsname;
+    virArch hostarch = virArchFromHost();
 
     if (libxl_get_physinfo(driver->ctx, &phy_info)) {
         virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
@@ -334,14 +333,10 @@ libxlDoNodeGetInfo(libxlDriverPrivatePtr driver, virNodeInfoPtr info)
         return -1;
     }
 
-    uname(&utsname);
-    if (virStrncpy(info->model,
-                   utsname.machine,
-                   strlen(utsname.machine),
-                   sizeof(info->model)) == NULL) {
+    if (virStrcpyStatic(nodeinfo->model, virArchToString(hostarch)) == NULL) {
         virReportError(VIR_ERR_INTERNAL_ERROR,
                        _("machine type %s too big for destination"),
-                       utsname.machine);
+                       virArchToString(hostarch));
         return -1;
     }
 
diff --git a/src/lxc/lxc_conf.c b/src/lxc/lxc_conf.c
index e512b8f..9b89ceb 100644
--- a/src/lxc/lxc_conf.c
+++ b/src/lxc/lxc_conf.c
@@ -26,8 +26,6 @@
 /* includes */
 #include <config.h>
 
-#include <sys/utsname.h>
-
 #include "lxc_conf.h"
 #include "nodeinfo.h"
 #include "virterror_internal.h"
@@ -43,7 +41,7 @@
 #define VIR_FROM_THIS VIR_FROM_LXC
 
 static int lxcDefaultConsoleType(const char *ostype ATTRIBUTE_UNUSED,
-                                 const char *arch ATTRIBUTE_UNUSED)
+                                 virArch arch ATTRIBUTE_UNUSED)
 {
     return VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_LXC;
 }
@@ -52,14 +50,11 @@ static int lxcDefaultConsoleType(const char *ostype ATTRIBUTE_UNUSED,
 /* Functions */
 virCapsPtr lxcCapsInit(virLXCDriverPtr driver)
 {
-    struct utsname utsname;
     virCapsPtr caps;
     virCapsGuestPtr guest;
-    const char *altArch;
-
-    uname(&utsname);
+    virArch altArch;
 
-    if ((caps = virCapabilitiesNew(utsname.machine,
+    if ((caps = virCapabilitiesNew(virArchFromHost(),
                                    0, 0)) == NULL)
         goto error;
 
@@ -88,8 +83,7 @@ virCapsPtr lxcCapsInit(virLXCDriverPtr driver)
 
     if ((guest = virCapabilitiesAddGuest(caps,
                                          "exe",
-                                         utsname.machine,
-                                         sizeof(void*) == 4 ? 32 : 64,
+                                         caps->host.arch,
                                          LIBEXECDIR "/libvirt_lxc",
                                          NULL,
                                          0,
@@ -105,11 +99,10 @@ virCapsPtr lxcCapsInit(virLXCDriverPtr driver)
         goto error;
 
     /* On 64-bit hosts, we can use personality() to request a 32bit process */
-    if ((altArch = lxcContainerGetAlt32bitArch(utsname.machine)) != NULL) {
+    if ((altArch = lxcContainerGetAlt32bitArch(caps->host.arch)) != VIR_ARCH_NONE) {
         if ((guest = virCapabilitiesAddGuest(caps,
                                              "exe",
                                              altArch,
-                                             32,
                                              LIBEXECDIR "/libvirt_lxc",
                                              NULL,
                                              0,
diff --git a/src/lxc/lxc_container.c b/src/lxc/lxc_container.c
index 3014564..8875a92 100644
--- a/src/lxc/lxc_container.c
+++ b/src/lxc/lxc_container.c
@@ -1931,24 +1931,26 @@ static int userns_supported(void)
 #endif
 }
 
-const char *lxcContainerGetAlt32bitArch(const char *arch)
+virArch lxcContainerGetAlt32bitArch(virArch arch)
 {
     /* Any Linux 64bit arch which has a 32bit
      * personality available should be listed here */
-    if (STREQ(arch, "x86_64"))
-        return "i686";
-    if (STREQ(arch, "s390x"))
-        return "s390";
-    if (STREQ(arch, "ppc64"))
-        return "ppc";
-    if (STREQ(arch, "parisc64"))
-        return "parisc";
-    if (STREQ(arch, "sparc64"))
-        return "sparc";
-    if (STREQ(arch, "mips64"))
-        return "mips";
-
-    return NULL;
+    if (arch == VIR_ARCH_X86_64)
+        return VIR_ARCH_I686;
+    if (arch == VIR_ARCH_S390X)
+        return VIR_ARCH_S390;
+    if (arch == VIR_ARCH_PPC64)
+        return VIR_ARCH_PPC;
+    if (arch == VIR_ARCH_PARISC64)
+        return VIR_ARCH_PARISC;
+    if (arch == VIR_ARCH_SPARC64)
+        return VIR_ARCH_SPARC;
+    if (arch == VIR_ARCH_MIPS64)
+        return VIR_ARCH_MIPS;
+    if (arch == VIR_ARCH_MIPS64EL)
+        return VIR_ARCH_MIPSEL;
+
+    return VIR_ARCH_NONE;
 }
 
 
diff --git a/src/lxc/lxc_container.h b/src/lxc/lxc_container.h
index c8c70e0..ada72f7 100644
--- a/src/lxc/lxc_container.h
+++ b/src/lxc/lxc_container.h
@@ -63,6 +63,6 @@ int lxcContainerStart(virDomainDefPtr def,
 
 int lxcContainerAvailable(int features);
 
-const char *lxcContainerGetAlt32bitArch(const char *arch);
+virArch lxcContainerGetAlt32bitArch(virArch arch);
 
 #endif /* LXC_CONTAINER_H */
diff --git a/src/lxc/lxc_controller.c b/src/lxc/lxc_controller.c
index 5510b9a..34f38c8 100644
--- a/src/lxc/lxc_controller.c
+++ b/src/lxc/lxc_controller.c
@@ -29,7 +29,6 @@
 #include <sys/socket.h>
 #include <sys/types.h>
 #include <sys/un.h>
-#include <sys/utsname.h>
 #include <sys/personality.h>
 #include <unistd.h>
 #include <paths.h>
@@ -1077,17 +1076,15 @@ static int virLXCControllerDeleteInterfaces(virLXCControllerPtr ctrl)
 
 static int lxcSetPersonality(virDomainDefPtr def)
 {
-    struct utsname utsname;
-    const char *altArch;
+    virArch altArch;
 
-    uname(&utsname);
-
-    altArch = lxcContainerGetAlt32bitArch(utsname.machine);
+    altArch = lxcContainerGetAlt32bitArch(virArchFromHost());
     if (altArch &&
-        STREQ(def->os.arch, altArch)) {
+        (def->os.arch == altArch)) {
         if (personality(PER_LINUX32) < 0) {
             virReportSystemError(errno, _("Unable to request personality for %s on %s"),
-                                 altArch, utsname.machine);
+                                 virArchToString(altArch),
+                                 virArchToString(virArchFromHost()));
             return -1;
         }
     }
diff --git a/src/openvz/openvz_conf.c b/src/openvz/openvz_conf.c
index 2bd9caf..089f63b 100644
--- a/src/openvz/openvz_conf.c
+++ b/src/openvz/openvz_conf.c
@@ -40,7 +40,6 @@
 #include <limits.h>
 #include <errno.h>
 #include <string.h>
-#include <sys/utsname.h>
 #include <sys/wait.h>
 
 #include "virterror_internal.h"
@@ -170,20 +169,17 @@ error:
 
 
 static int openvzDefaultConsoleType(const char *ostype ATTRIBUTE_UNUSED,
-                                    const char *arch ATTRIBUTE_UNUSED)
+                                    virArch arch ATTRIBUTE_UNUSED)
 {
     return VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_OPENVZ;
 }
 
 virCapsPtr openvzCapsInit(void)
 {
-    struct utsname utsname;
     virCapsPtr caps;
     virCapsGuestPtr guest;
 
-    uname(&utsname);
-
-    if ((caps = virCapabilitiesNew(utsname.machine,
+    if ((caps = virCapabilitiesNew(virArchFromHost(),
                                    0, 0)) == NULL)
         goto no_memory;
 
@@ -194,8 +190,7 @@ virCapsPtr openvzCapsInit(void)
 
     if ((guest = virCapabilitiesAddGuest(caps,
                                          "exe",
-                                         utsname.machine,
-                                         sizeof(void*) == 4 ? 32 : 64,
+                                         caps->host.arch,
                                          NULL,
                                          NULL,
                                          0,
diff --git a/src/openvz/openvz_driver.c b/src/openvz/openvz_driver.c
index c5f5ca0..fd6ecf8 100644
--- a/src/openvz/openvz_driver.c
+++ b/src/openvz/openvz_driver.c
@@ -37,7 +37,6 @@
 #include <stdlib.h>
 #include <unistd.h>
 #include <errno.h>
-#include <sys/utsname.h>
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <paths.h>
diff --git a/src/parallels/parallels_driver.c b/src/parallels/parallels_driver.c
index 50efd1d..7dc59b9 100644
--- a/src/parallels/parallels_driver.c
+++ b/src/parallels/parallels_driver.c
@@ -31,7 +31,6 @@
 #include <stdlib.h>
 #include <unistd.h>
 #include <errno.h>
-#include <sys/utsname.h>
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <paths.h>
@@ -58,7 +57,6 @@
 
 #define PRLCTL                      "prlctl"
 #define PRLSRVCTL                   "prlsrvctl"
-#define PARALLELS_DEFAULT_ARCH      "x86_64"
 
 #define parallelsDomNotFoundError(domain)                                \
     do {                                                                 \
@@ -88,7 +86,7 @@ parallelsDriverUnlock(parallelsConnPtr driver)
 
 static int
 parallelsDefaultConsoleType(const char *ostype ATTRIBUTE_UNUSED,
-                            const char *arch ATTRIBUTE_UNUSED)
+                            virArch arch ATTRIBUTE_UNUSED)
 {
     return VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_SERIAL;
 }
@@ -110,10 +108,9 @@ parallelsBuildCapabilities(void)
 {
     virCapsPtr caps;
     virCapsGuestPtr guest;
-    struct utsname utsname;
-    uname(&utsname);
 
-    if ((caps = virCapabilitiesNew(utsname.machine, 0, 0)) == NULL)
+    if ((caps = virCapabilitiesNew(virArchFromHost(),
+                                   0, 0)) == NULL)
         goto no_memory;
 
     if (nodeCapsInitNUMA(caps) < 0)
@@ -122,8 +119,9 @@ parallelsBuildCapabilities(void)
     virCapabilitiesSetMacPrefix(caps, (unsigned char[]) {
                                 0x42, 0x1C, 0x00});
 
-    if ((guest = virCapabilitiesAddGuest(caps, "hvm", PARALLELS_DEFAULT_ARCH,
-                                         64, "parallels",
+    if ((guest = virCapabilitiesAddGuest(caps, "hvm",
+                                         VIR_ARCH_X86_64,
+                                         "parallels",
                                          NULL, 0, NULL)) == NULL)
         goto no_memory;
 
@@ -131,8 +129,9 @@ parallelsBuildCapabilities(void)
                                       "parallels", NULL, NULL, 0, NULL) == NULL)
         goto no_memory;
 
-    if ((guest = virCapabilitiesAddGuest(caps, "exe", PARALLELS_DEFAULT_ARCH,
-                                         64, "parallels",
+    if ((guest = virCapabilitiesAddGuest(caps, "exe",
+                                         VIR_ARCH_X86_64,
+                                         "parallels",
                                          NULL, 0, NULL)) == NULL)
         goto no_memory;
 
@@ -532,8 +531,7 @@ parallelsLoadDomain(parallelsConnPtr privconn, virJSONValuePtr jobj)
             goto no_memory;
     }
 
-    if (!(def->os.arch = strdup(PARALLELS_DEFAULT_ARCH)))
-        goto no_memory;
+    def->os.arch = VIR_ARCH_X86_64;
 
     if (VIR_ALLOC(pdom) < 0)
         goto no_memory;
@@ -1495,7 +1493,7 @@ parallelsApplyChanges(virDomainObjPtr dom, virDomainDefPtr new)
      * other paramenters are null and boot devices config is default */
 
     if (!STREQ_NULLABLE(old->os.type, new->os.type) ||
-        !STREQ_NULLABLE(old->os.arch, new->os.arch) ||
+        old->os.arch != new->os.arch ||
         new->os.machine != NULL || new->os.bootmenu != 0 ||
         new->os.kernel != NULL || new->os.initrd != NULL ||
         new->os.cmdline != NULL || new->os.root != NULL ||
diff --git a/src/phyp/phyp_driver.c b/src/phyp/phyp_driver.c
index 63017f4..c82acb6 100644
--- a/src/phyp/phyp_driver.c
+++ b/src/phyp/phyp_driver.c
@@ -40,7 +40,6 @@
 #include <sys/socket.h>
 #include <netdb.h>
 #include <fcntl.h>
-#include <sys/utsname.h>
 #include <domain_event.h>
 
 #include "internal.h"
@@ -289,7 +288,7 @@ phypGetVIOSPartitionID(virConnectPtr conn)
 
 
 static int phypDefaultConsoleType(const char *ostype ATTRIBUTE_UNUSED,
-                                  const char *arch ATTRIBUTE_UNUSED)
+                                  virArch arch ATTRIBUTE_UNUSED)
 {
     return VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_SERIAL;
 }
@@ -298,13 +297,11 @@ static int phypDefaultConsoleType(const char *ostype ATTRIBUTE_UNUSED,
 static virCapsPtr
 phypCapsInit(void)
 {
-    struct utsname utsname;
     virCapsPtr caps;
     virCapsGuestPtr guest;
 
-    uname(&utsname);
-
-    if ((caps = virCapabilitiesNew(utsname.machine, 0, 0)) == NULL)
+    if ((caps = virCapabilitiesNew(virArchFromHost(),
+                                   0, 0)) == NULL)
         goto no_memory;
 
     /* Some machines have problematic NUMA toplogy causing
@@ -323,8 +320,7 @@ phypCapsInit(void)
 
     if ((guest = virCapabilitiesAddGuest(caps,
                                          "linux",
-                                         utsname.machine,
-                                         sizeof(int) == 4 ? 32 : 8,
+                                         caps->host.arch,
                                          NULL, NULL, 0, NULL)) == NULL)
         goto no_memory;
 
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 01a1b98..c9146c4 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -576,17 +576,20 @@ cleanup:
 
 
 static char *
-qemuCapsFindBinaryForArch(const char *hostarch,
-                          const char *guestarch)
+qemuCapsFindBinaryForArch(virArch hostarch,
+                          virArch guestarch)
 {
     char *ret;
 
-    if (STREQ(guestarch, "i686")) {
+    /* Some special cases where libvirt's canonical
+     * guestarch string form can't match qemu's binary
+     */
+    if (guestarch == VIR_ARCH_I686) {
         ret = virFindFileInPath("qemu-system-i386");
         if (ret && !virFileIsExecutable(ret))
             VIR_FREE(ret);
 
-        if (!ret && STREQ(hostarch, "x86_64")) {
+        if (!ret && hostarch == VIR_ARCH_X86_64) {
             ret = virFindFileInPath("qemu-system-x86_64");
             if (ret && !virFileIsExecutable(ret))
                 VIR_FREE(ret);
@@ -594,11 +597,12 @@ qemuCapsFindBinaryForArch(const char *hostarch,
 
         if (!ret)
             ret = virFindFileInPath("qemu");
-    } else if (STREQ(guestarch, "itanium")) {
+    } else if (guestarch == VIR_ARCH_ITANIUM) {
         ret = virFindFileInPath("qemu-system-ia64");
     } else {
+        /* Default case we have matching arch strings */
         char *bin;
-        if (virAsprintf(&bin, "qemu-system-%s", guestarch) < 0) {
+        if (virAsprintf(&bin, "qemu-system-%s", virArchToString(guestarch)) < 0) {
             virReportOOMError();
             return NULL;
         }
@@ -610,26 +614,15 @@ qemuCapsFindBinaryForArch(const char *hostarch,
     return ret;
 }
 
-static int
-qemuCapsGetArchWordSize(const char *guestarch)
-{
-    if (STREQ(guestarch, "i686") ||
-        STREQ(guestarch, "ppc") ||
-        STREQ(guestarch, "sparc") ||
-        STREQ(guestarch, "mips") ||
-        STREQ(guestarch, "mipsel"))
-        return 32;
-    return 64;
-}
 
 static bool
-qemuCapsIsValidForKVM(const char *hostarch,
-                      const char *guestarch)
+qemuCapsIsValidForKVM(virArch hostarch,
+                      virArch guestarch)
 {
-    if (STREQ(hostarch, guestarch))
+    if (hostarch == guestarch)
         return true;
-    if (STREQ(hostarch, "x86_64") &&
-        STREQ(guestarch, "i686"))
+    if (hostarch == VIR_ARCH_X86_64 &&
+        guestarch == VIR_ARCH_I686)
         return true;
     return false;
 }
@@ -637,8 +630,8 @@ qemuCapsIsValidForKVM(const char *hostarch,
 static int
 qemuCapsInitGuest(virCapsPtr caps,
                   qemuCapsCachePtr cache,
-                  const char *hostarch,
-                  const char *guestarch)
+                  virArch hostarch,
+                  virArch guestarch)
 {
     virCapsGuestPtr guest;
     int i;
@@ -719,7 +712,6 @@ qemuCapsInitGuest(virCapsPtr caps,
     if ((guest = virCapabilitiesAddGuest(caps,
                                          "hvm",
                                          guestarch,
-                                         qemuCapsGetArchWordSize(guestarch),
                                          binary,
                                          NULL,
                                          nmachines,
@@ -777,13 +769,13 @@ qemuCapsInitGuest(virCapsPtr caps,
 
     }
 
-    if ((STREQ(guestarch, "i686") ||
-         STREQ(guestarch, "x86_64")) &&
+    if (((guestarch == VIR_ARCH_I686) ||
+         (guestarch == VIR_ARCH_X86_64)) &&
         (virCapabilitiesAddGuestFeature(guest, "acpi", 1, 1) == NULL ||
          virCapabilitiesAddGuestFeature(guest, "apic", 1, 0) == NULL))
         goto error;
 
-    if (STREQ(guestarch, "i686") &&
+    if ((guestarch == VIR_ARCH_I686) &&
         (virCapabilitiesAddGuestFeature(guest, "pae", 1, 0) == NULL ||
          virCapabilitiesAddGuestFeature(guest, "nonpae", 1, 0) == NULL))
         goto error;
@@ -807,15 +799,16 @@ error:
 
 static int
 qemuCapsInitCPU(virCapsPtr caps,
-                const char *arch)
+                virArch arch)
 {
     virCPUDefPtr cpu = NULL;
     union cpuData *data = NULL;
     virNodeInfo nodeinfo;
     int ret = -1;
+    const char *archstr = virArchToString(arch);
 
     if (VIR_ALLOC(cpu) < 0
-        || !(cpu->arch = strdup(arch))) {
+        || !(cpu->arch = strdup(archstr))) {
         virReportOOMError();
         goto error;
     }
@@ -829,14 +822,14 @@ qemuCapsInitCPU(virCapsPtr caps,
     cpu->threads = nodeinfo.threads;
     caps->host.cpu = cpu;
 
-    if (!(data = cpuNodeData(arch))
+    if (!(data = cpuNodeData(archstr))
         || cpuDecode(cpu, data, NULL, 0, NULL) < 0)
         goto cleanup;
 
     ret = 0;
 
 cleanup:
-    cpuDataFree(arch, data);
+    cpuDataFree(archstr, data);
 
     return ret;
 
@@ -847,9 +840,10 @@ error:
 
 
 static int qemuDefaultConsoleType(const char *ostype ATTRIBUTE_UNUSED,
-                                  const char *arch)
+                                  virArch arch)
 {
-    if (STRPREFIX(arch, "s390"))
+    if (arch == VIR_ARCH_S390 ||
+        arch == VIR_ARCH_S390X)
         return VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_VIRTIO;
     else
         return VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_SERIAL;
@@ -858,21 +852,10 @@ static int qemuDefaultConsoleType(const char *ostype ATTRIBUTE_UNUSED,
 
 virCapsPtr qemuCapsInit(qemuCapsCachePtr cache)
 {
-    struct utsname utsname;
     virCapsPtr caps;
     int i;
-    const char *const arches[] = {
-        "i686", "x86_64", "arm",
-        "microblaze", "microblazeel",
-        "mips", "mipsel", "sparc",
-        "ppc", "ppc64", "itanium",
-        "s390x"
-    };
-
-    /* Really, this never fails - look at the man-page. */
-    uname(&utsname);
-
-    if ((caps = virCapabilitiesNew(utsname.machine,
+
+    if ((caps = virCapabilitiesNew(virArchFromHost(),
                                    1, 1)) == NULL)
         goto error;
 
@@ -888,7 +871,7 @@ virCapsPtr qemuCapsInit(qemuCapsCachePtr cache)
         VIR_WARN("Failed to query host NUMA topology, disabling NUMA capabilities");
     }
 
-    if (qemuCapsInitCPU(caps, utsname.machine) < 0)
+    if (qemuCapsInitCPU(caps, virArchFromHost()) < 0)
         VIR_WARN("Failed to get host CPU");
 
     /* Add the power management features of the host */
@@ -899,11 +882,14 @@ virCapsPtr qemuCapsInit(qemuCapsCachePtr cache)
     virCapabilitiesAddHostMigrateTransport(caps,
                                            "tcp");
 
-    /* First the pure HVM guests */
-    for (i = 0 ; i < ARRAY_CARDINALITY(arches) ; i++)
+    /* QEMU can support pretty much every arch that exists,
+     * so just probe for them all - we gracefully fail
+     * if a qemu-system-$ARCH bvinary can't be found
+     */
+    for (i = 0 ; i < VIR_ARCH_LAST ; i++)
         if (qemuCapsInitGuest(caps, cache,
-                              utsname.machine,
-                              arches[i]) < 0)
+                              virArchFromHost(),
+                              i) < 0)
             goto error;
 
     /* QEMU Requires an emulator in the XML */
@@ -1610,7 +1596,6 @@ cleanup:
     return ret;
 }
 
-
 static void
 uname_normalize(struct utsname *ut)
 {
@@ -1625,24 +1610,24 @@ uname_normalize(struct utsname *ut)
         ut->machine[1] = '6';
 }
 
+
 int qemuCapsGetDefaultVersion(virCapsPtr caps,
                               qemuCapsCachePtr capsCache,
                               unsigned int *version)
 {
     const char *binary;
-    struct utsname ut;
     qemuCapsPtr qemucaps;
 
     if (*version > 0)
         return 0;
 
-    uname_normalize(&ut);
     if ((binary = virCapabilitiesDefaultGuestEmulator(caps,
                                                       "hvm",
-                                                      ut.machine,
+                                                      virArchFromHost(),
                                                       "qemu")) == NULL) {
         virReportError(VIR_ERR_INTERNAL_ERROR,
-                       _("Cannot find suitable emulator for %s"), ut.machine);
+                       _("Cannot find suitable emulator for %s"),
+                       virArchToString(virArchFromHost()));
         return -1;
     }
 
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 6968f74..267dce7 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -46,7 +46,6 @@
 #include "device_conf.h"
 #include "storage_file.h"
 
-#include <sys/utsname.h>
 #include <sys/stat.h>
 #include <fcntl.h>
 
@@ -506,7 +505,7 @@ qemuSetScsiControllerModel(virDomainDefPtr def,
             return -1;
         }
     } else {
-        if (STREQ(def->os.arch, "ppc64") &&
+        if ((def->os.arch == VIR_ARCH_PPC64) &&
             STREQ(def->os.machine, "pseries")) {
             *model = VIR_DOMAIN_CONTROLLER_MODEL_SCSI_IBMVSCSI;
         } else if (qemuCapsGet(caps, QEMU_CAPS_SCSI_LSI)) {
@@ -796,7 +795,8 @@ qemuDomainPrimeS390VirtioDevices(virDomainDefPtr def,
     }
 
     for (i = 0; i < def->nnets ; i++) {
-        if (STRPREFIX(def->os.arch, "s390") &&
+        if ((def->os.arch == VIR_ARCH_S390 ||
+             def->os.arch == VIR_ARCH_S390X) &&
             def->nets[i]->model == NULL) {
             def->nets[i]->model = strdup("virtio");
         }
@@ -913,7 +913,7 @@ int qemuDomainAssignSpaprVIOAddresses(virDomainDefPtr def,
     for (i = 0 ; i < def->nserials; i++) {
         if (def->serials[i]->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_SERIAL &&
             def->serials[i]->source.type == VIR_DOMAIN_CHR_TYPE_PTY &&
-            STREQ(def->os.arch, "ppc64") &&
+            (def->os.arch == VIR_ARCH_PPC64) &&
             STREQ(def->os.machine, "pseries"))
             def->serials[i]->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_SPAPRVIO;
         if (qemuAssignSpaprVIOAddress(def, &def->serials[i]->info,
@@ -2979,7 +2979,7 @@ qemuBuildUSBControllerDevStr(virDomainDefPtr domainDef,
     model = def->model;
 
     if (model == -1) {
-        if (STREQ(domainDef->os.arch, "ppc64"))
+        if (domainDef->os.arch == VIR_ARCH_PPC64)
             model = VIR_DOMAIN_CONTROLLER_MODEL_USB_PCI_OHCI;
         else
             model = VIR_DOMAIN_CONTROLLER_MODEL_USB_PIIX3_UHCI;
@@ -4287,7 +4287,7 @@ qemuBuildCpuArgStr(const virQEMUDriverPtr driver,
 
     *hasHwVirt = false;
 
-    if (STREQ(def->os.arch, "i686"))
+    if (def->os.arch == VIR_ARCH_I686)
         default_model = "qemu32";
     else
         default_model = "qemu64";
@@ -4399,7 +4399,7 @@ qemuBuildCpuArgStr(const virQEMUDriverPtr driver,
          *  1. guest OS is i686
          *  2. emulator is qemu-system-x86_64
          */
-        if (STREQ(def->os.arch, "i686") &&
+        if ((def->os.arch == VIR_ARCH_I686) &&
             (((hostarch == VIR_ARCH_X86_64) &&
               strstr(emulator, "kvm")) ||
              strstr(emulator, "x86_64"))) {
@@ -6885,13 +6885,13 @@ qemuBuildCommandLine(virConnectPtr conn,
  */
 char *
 qemuBuildChrDeviceStr(virDomainChrDefPtr serial,
-                       qemuCapsPtr caps,
-                       char *os_arch,
-                       char *machine)
+                      qemuCapsPtr caps,
+                      virArch arch,
+                      char *machine)
 {
     virBuffer cmd = VIR_BUFFER_INITIALIZER;
 
-    if (STREQ(os_arch, "ppc64") && STREQ(machine, "pseries")) {
+    if ((arch == VIR_ARCH_PPC64) && STREQ(machine, "pseries")) {
         if (serial->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_SERIAL &&
             serial->source.type == VIR_DOMAIN_CHR_TYPE_PTY &&
             serial->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_SPAPRVIO) {
@@ -8121,7 +8121,7 @@ qemuParseCommandLineCPU(virDomainDefPtr dom,
         }
     } while ((p = next));
 
-    if (STREQ(dom->os.arch, "x86_64")) {
+    if (dom->os.arch == VIR_ARCH_X86_64) {
         bool is_32bit = false;
         if (cpu) {
             union cpuData *cpuData = NULL;
@@ -8139,8 +8139,7 @@ qemuParseCommandLineCPU(virDomainDefPtr dom,
         }
 
         if (is_32bit) {
-            VIR_FREE(dom->os.arch);
-            dom->os.arch = strdup("i686");
+            dom->os.arch = VIR_ARCH_I686;
         }
     }
     VIR_FREE(model);
@@ -8338,16 +8337,17 @@ virDomainDefPtr qemuParseCommandLine(virCapsPtr caps,
     else
         path = strstr(def->emulator, "qemu");
     if (def->virtType == VIR_DOMAIN_VIRT_KVM)
-        def->os.arch = strdup(caps->host.cpu->arch);
+        def->os.arch = caps->host.arch;
     else if (path &&
-             STRPREFIX(path, "qemu-system-"))
-        def->os.arch = strdup(path + strlen("qemu-system-"));
-    else
-        def->os.arch = strdup("i686");
+             STRPREFIX(path, "qemu-system-")) {
+        def->os.arch = virArchFromString(path + strlen("qemu-system-"));
+    } else
+        def->os.arch = VIR_ARCH_I686;
     if (!def->os.arch)
         goto no_memory;
 
-    if (STREQ(def->os.arch, "i686")||STREQ(def->os.arch, "x86_64"))
+    if ((def->os.arch == VIR_ARCH_I686) ||
+        (def->os.arch == VIR_ARCH_X86_64))
         def->features |= (1 << VIR_DOMAIN_FEATURE_ACPI)
         /*| (1 << VIR_DOMAIN_FEATURE_APIC)*/;
 #define WANT_VALUE()                                                   \
diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h
index 6556e6e..59f32a6 100644
--- a/src/qemu/qemu_command.h
+++ b/src/qemu/qemu_command.h
@@ -65,7 +65,7 @@ virCommandPtr qemuBuildCommandLine(virConnectPtr conn,
 char *
 qemuBuildChrDeviceStr (virDomainChrDefPtr serial,
                        qemuCapsPtr caps,
-                       char *os_arch,
+                       virArch arch,
                        char *machine);
 
 /* With vlan == -1, use netdev syntax, else old hostnet */
diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c
index 8d380a1..04ae69f 100644
--- a/src/qemu/qemu_conf.c
+++ b/src/qemu/qemu_conf.c
@@ -33,7 +33,6 @@
 #include <fcntl.h>
 #include <sys/wait.h>
 #include <arpa/inet.h>
-#include <sys/utsname.h>
 #include <mntent.h>
 
 #include "virterror_internal.h"
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index e099c5c..60cf6c2 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -34,7 +34,6 @@
 #include <stdlib.h>
 #include <unistd.h>
 #include <errno.h>
-#include <sys/utsname.h>
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <signal.h>
diff --git a/src/security/virt-aa-helper.c b/src/security/virt-aa-helper.c
index e480b30..8f322fc 100644
--- a/src/security/virt-aa-helper.c
+++ b/src/security/virt-aa-helper.c
@@ -73,7 +73,6 @@ typedef struct {
     virCapsPtr caps;            /* VM capabilities */
     char *hvm;                  /* type of hypervisor (eg hvm, xen) */
     char *arch;                 /* machine architecture */
-    int bits;                   /* bits in the guest */
     char *newfile;              /* newly added file */
     bool append;                /* append to .files instead of rewrite */
 } vahControl;
@@ -640,7 +639,6 @@ verify_xpath_context(xmlXPathContextPtr ctxt)
  * Parse the xml we received to fill in the following:
  * ctl->hvm
  * ctl->arch
- * ctl->bits
  *
  * These are suitable for setting up a virCapsPtr
  */
@@ -650,6 +648,7 @@ caps_mockup(vahControl * ctl, const char *xmlStr)
     int rc = -1;
     xmlDocPtr xml = NULL;
     xmlXPathContextPtr ctxt = NULL;
+    char *arch;
 
     if (!(xml = virXMLParseStringCtxt(xmlStr, _("(domain_definition)"),
                                       &ctxt))) {
@@ -670,24 +669,13 @@ caps_mockup(vahControl * ctl, const char *xmlStr)
         vah_error(ctl, 0, _("os.type is not 'hvm'"));
         goto cleanup;
     }
-    ctl->arch = virXPathString("string(./os/type[1]/@arch)", ctxt);
-    if (!ctl->arch) {
-        /* The XML we are given should have an arch, but in case it doesn't,
-         * just use the host's arch.
-         */
-        struct utsname utsname;
-
-        /* Really, this never fails - look at the man-page. */
-        uname(&utsname);
-        if ((ctl->arch = strdup(utsname.machine)) == NULL) {
-            vah_error(ctl, 0, _("could not allocate memory"));
-            goto cleanup;
-        }
+    arch = virXPathString("string(./os/type[1]/@arch)", ctxt);
+    if (!arch) {
+        ctl->arch = virArchFromHost();
+    } else {
+        ctl->arch = virArchFromString(arch);
+        VIR_FREE(arch);
     }
-    if (STREQ(ctl->arch, "x86_64"))
-        ctl->bits = 64;
-    else
-        ctl->bits = 32;
 
     rc = 0;
 
@@ -699,7 +687,7 @@ caps_mockup(vahControl * ctl, const char *xmlStr)
 }
 
 static int aaDefaultConsoleType(const char *ostype ATTRIBUTE_UNUSED,
-                                const char *arch ATTRIBUTE_UNUSED)
+                                virArch arch ATTRIBUTE_UNUSED)
 {
     return VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_SERIAL;
 }
@@ -727,7 +715,6 @@ get_definition(vahControl * ctl, const char *xmlStr)
     if ((guest = virCapabilitiesAddGuest(ctl->caps,
                                          ctl->hvm,
                                          ctl->arch,
-                                         ctl->bits,
                                          NULL,
                                          NULL,
                                          0,
diff --git a/src/test/test_driver.c b/src/test/test_driver.c
index 6ca59e2..256be92 100644
--- a/src/test/test_driver.c
+++ b/src/test/test_driver.c
@@ -150,7 +150,7 @@ static void testDomainObjPrivateFree(void *data)
 
 
 static int testDefaultConsoleType(const char *ostype ATTRIBUTE_UNUSED,
-                                  const char *arch ATTRIBUTE_UNUSED)
+                                  virArch arch ATTRIBUTE_UNUSED)
 {
     return VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_SERIAL;
 }
@@ -163,7 +163,7 @@ testBuildCapabilities(virConnectPtr conn) {
     const char *const guest_types[] = { "hvm", "xen" };
     int i;
 
-    if ((caps = virCapabilitiesNew(TEST_MODEL, 0, 0)) == NULL)
+    if ((caps = virCapabilitiesNew(VIR_ARCH_I686, 0, 0)) == NULL)
         goto no_memory;
 
     caps->defaultConsoleTargetType = testDefaultConsoleType;
@@ -182,8 +182,7 @@ testBuildCapabilities(virConnectPtr conn) {
     for (i = 0; i < ARRAY_CARDINALITY(guest_types) ; i++) {
         if ((guest = virCapabilitiesAddGuest(caps,
                                              guest_types[i],
-                                             TEST_MODEL,
-                                             TEST_MODEL_WORDSIZE,
+                                             VIR_ARCH_I686,
                                              TEST_EMULATOR,
                                              NULL,
                                              0,
diff --git a/src/uml/uml_conf.c b/src/uml/uml_conf.c
index 6ef6de3..7414969 100644
--- a/src/uml/uml_conf.c
+++ b/src/uml/uml_conf.c
@@ -33,7 +33,6 @@
 #include <fcntl.h>
 #include <sys/wait.h>
 #include <arpa/inet.h>
-#include <sys/utsname.h>
 
 #include "uml_conf.h"
 #include "uuid.h"
@@ -54,21 +53,17 @@
 
 
 static int umlDefaultConsoleType(const char *ostype ATTRIBUTE_UNUSED,
-                                 const char *arch ATTRIBUTE_UNUSED)
+                                 virArch arch ATTRIBUTE_UNUSED)
 {
     return VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_UML;
 }
 
 
 virCapsPtr umlCapsInit(void) {
-    struct utsname utsname;
     virCapsPtr caps;
     virCapsGuestPtr guest;
 
-    /* Really, this never fails - look at the man-page. */
-    uname(&utsname);
-
-    if ((caps = virCapabilitiesNew(utsname.machine,
+    if ((caps = virCapabilitiesNew(virArchFromHost(),
                                    0, 0)) == NULL)
         goto error;
 
@@ -92,8 +87,7 @@ virCapsPtr umlCapsInit(void) {
 
     if ((guest = virCapabilitiesAddGuest(caps,
                                          "uml",
-                                         utsname.machine,
-                                         STREQ(utsname.machine, "x86_64") ? 64 : 32,
+                                         caps->host.arch,
                                          NULL,
                                          NULL,
                                          0,
@@ -412,11 +406,8 @@ virCommandPtr umlBuildCommandLine(virConnectPtr conn,
                                   virDomainObjPtr vm)
 {
     int i, j;
-    struct utsname ut;
     virCommandPtr cmd;
 
-    uname(&ut);
-
     cmd = virCommandNew(vm->def->os.kernel);
 
     virCommandAddEnvPassCommon(cmd);
diff --git a/src/vbox/vbox_tmpl.c b/src/vbox/vbox_tmpl.c
index f9fa442..f3b36f3 100644
--- a/src/vbox/vbox_tmpl.c
+++ b/src/vbox/vbox_tmpl.c
@@ -34,7 +34,6 @@
 
 #include <config.h>
 
-#include <sys/utsname.h>
 #include <unistd.h>
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -823,20 +822,18 @@ cleanup:
 
 
 static int vboxDefaultConsoleType(const char *ostype ATTRIBUTE_UNUSED,
-                                  const char *arch ATTRIBUTE_UNUSED)
+                                  virArch arch ATTRIBUTE_UNUSED)
 {
     return VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_SERIAL;
 }
 
 
-static virCapsPtr vboxCapsInit(void) {
-    struct utsname utsname;
+static virCapsPtr vboxCapsInit(void)
+{
     virCapsPtr caps;
     virCapsGuestPtr guest;
 
-    uname(&utsname);
-
-    if ((caps = virCapabilitiesNew(utsname.machine,
+    if ((caps = virCapabilitiesNew(virArchFromHost(),
                                    0, 0)) == NULL)
         goto no_memory;
 
@@ -847,8 +844,7 @@ static virCapsPtr vboxCapsInit(void) {
 
     if ((guest = virCapabilitiesAddGuest(caps,
                                          "hvm",
-                                         utsname.machine,
-                                         sizeof(void *) * CHAR_BIT,
+                                         caps->host.arch,
                                          NULL,
                                          NULL,
                                          0,
@@ -2230,7 +2226,6 @@ static char *vboxDomainGetXMLDesc(virDomainPtr dom, unsigned int flags) {
         machine->vtbl->GetAccessible(machine, &accessible);
         if (accessible) {
             int i = 0;
-            struct utsname utsname;
             PRBool PAEEnabled                   = PR_FALSE;
             PRBool ACPIEnabled                  = PR_FALSE;
             PRBool IOAPICEnabled                = PR_FALSE;
@@ -2312,8 +2307,7 @@ static char *vboxDomainGetXMLDesc(virDomainPtr dom, unsigned int flags) {
 
             def->os.type = strdup("hvm");
 
-            uname(&utsname);
-            def->os.arch = strdup(utsname.machine);
+            def->os.arch = virArchFromHost();
 
             def->os.nBootDevs = 0;
             for (i = 0; (i < VIR_DOMAIN_BOOT_LAST) && (i < maxBootPosition); i++) {
@@ -3785,7 +3779,7 @@ vboxSetBootDeviceOrder(virDomainDefPtr def, vboxGlobalData *data,
     int i = 0;
 
     VIR_DEBUG("def->os.type             %s", def->os.type);
-    VIR_DEBUG("def->os.arch             %s", def->os.arch);
+    VIR_DEBUG("def->os.arch             %s", virArchToString(def->os.arch));
     VIR_DEBUG("def->os.machine          %s", def->os.machine);
     VIR_DEBUG("def->os.nBootDevs        %zu", def->os.nBootDevs);
     VIR_DEBUG("def->os.bootDevs[0]      %d", def->os.bootDevs[0]);
diff --git a/src/vmware/vmware_conf.c b/src/vmware/vmware_conf.c
index 2eed4f8..33100fb 100644
--- a/src/vmware/vmware_conf.c
+++ b/src/vmware/vmware_conf.c
@@ -22,7 +22,6 @@
 #include <config.h>
 
 #include <string.h>
-#include <sys/utsname.h>
 
 #include "command.h"
 #include "cpu/cpu.h"
@@ -51,7 +50,7 @@ vmwareFreeDriver(struct vmware_driver *driver)
 
 
 static int vmwareDefaultConsoleType(const char *ostype ATTRIBUTE_UNUSED,
-                                    const char *arch ATTRIBUTE_UNUSED)
+                                    virArch arch ATTRIBUTE_UNUSED)
 {
     return VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_SERIAL;
 }
@@ -60,15 +59,14 @@ static int vmwareDefaultConsoleType(const char *ostype ATTRIBUTE_UNUSED,
 virCapsPtr
 vmwareCapsInit(void)
 {
-    struct utsname utsname;
     virCapsPtr caps = NULL;
     virCapsGuestPtr guest = NULL;
     virCPUDefPtr cpu = NULL;
     union cpuData *data = NULL;
+    const char *hostarch = NULL;
 
-    uname(&utsname);
-
-    if ((caps = virCapabilitiesNew(utsname.machine, 0, 0)) == NULL)
+    if ((caps = virCapabilitiesNew(virArchFromHost(),
+                                   0, 0)) == NULL)
         goto error;
 
     if (nodeCapsInitNUMA(caps) < 0)
@@ -79,8 +77,7 @@ vmwareCapsInit(void)
     /* i686 guests are always supported */
     if ((guest = virCapabilitiesAddGuest(caps,
                                          "hvm",
-                                         "i686",
-                                         32,
+                                         VIR_ARCH_I686,
                                          NULL, NULL, 0, NULL)) == NULL)
         goto error;
 
@@ -89,12 +86,16 @@ vmwareCapsInit(void)
                                       NULL, NULL, 0, NULL) == NULL)
         goto error;
 
-    if (VIR_ALLOC(cpu) < 0
-        || !(cpu->arch = strdup(utsname.machine))) {
+    if (VIR_ALLOC(cpu) < 0) {
         virReportOOMError();
         goto error;
     }
 
+    hostarch = virArchToString(caps->host.arch);
+    if (!(cpu->arch = strdup(hostarch))) {
+        virReportOOMError();
+        goto error;
+    }
     cpu->type = VIR_CPU_TYPE_HOST;
 
     if (!(data = cpuNodeData(cpu->arch))
@@ -107,15 +108,14 @@ vmwareCapsInit(void)
      * Or
      *  - Host CPU is x86_64 with virtualization extensions
      */
-    if (STREQ(utsname.machine, "x86_64") ||
-        (cpuHasFeature(utsname.machine, data, "lm") &&
-         (cpuHasFeature(utsname.machine, data, "vmx") ||
-          cpuHasFeature(utsname.machine, data, "svm")))) {
+    if (caps->host.arch == VIR_ARCH_X86_64 ||
+        (cpuHasFeature(hostarch, data, "lm") &&
+         (cpuHasFeature(hostarch, data, "vmx") ||
+          cpuHasFeature(hostarch, data, "svm")))) {
 
         if ((guest = virCapabilitiesAddGuest(caps,
                                              "hvm",
-                                             "x86_64",
-                                             64,
+                                             VIR_ARCH_X86_64,
                                              NULL, NULL, 0, NULL)) == NULL)
             goto error;
 
@@ -129,7 +129,7 @@ vmwareCapsInit(void)
 
 cleanup:
     virCPUDefFree(cpu);
-    cpuDataFree(utsname.machine, data);
+    cpuDataFree(hostarch, data);
 
     return caps;
 
diff --git a/src/vmx/vmx.c b/src/vmx/vmx.c
index e051de5..a4d1f2e 100644
--- a/src/vmx/vmx.c
+++ b/src/vmx/vmx.c
@@ -1522,14 +1522,9 @@ virVMXParseConfig(virVMXContext *ctx, virCapsPtr caps, const char *vmx)
     }
 
     if (guestOS != NULL && virFileHasSuffix(guestOS, "-64")) {
-        def->os.arch = strdup("x86_64");
+        def->os.arch = VIR_ARCH_X86_64;
     } else {
-        def->os.arch = strdup("i686");
-    }
-
-    if (def->os.arch == NULL) {
-        virReportOOMError();
-        goto cleanup;
+        def->os.arch = VIR_ARCH_I686;
     }
 
     /* vmx:smbios.reflecthost -> def:os.smbios_mode */
@@ -3069,14 +3064,15 @@ virVMXFormatConfig(virVMXContext *ctx, virCapsPtr caps, virDomainDefPtr def,
                       virtualHW_version);
 
     /* def:os.arch -> vmx:guestOS */
-    if (def->os.arch == NULL || STRCASEEQ(def->os.arch, "i686")) {
+    if (def->os.arch == VIR_ARCH_I686) {
         virBufferAddLit(&buffer, "guestOS = \"other\"\n");
-    } else if (STRCASEEQ(def->os.arch, "x86_64")) {
+    } else if (def->os.arch == VIR_ARCH_X86_64) {
         virBufferAddLit(&buffer, "guestOS = \"other-64\"\n");
     } else {
         virReportError(VIR_ERR_INTERNAL_ERROR,
                        _("Expecting domain XML attribute 'arch' of entry 'os/type' "
-                         "to be 'i686' or 'x86_64' but found '%s'"), def->os.arch);
+                         "to be 'i686' or 'x86_64' but found '%s'"),
+                       virArchToString(def->os.arch));
         goto cleanup;
     }
 
diff --git a/src/xen/xen_hypervisor.c b/src/xen/xen_hypervisor.c
index 237a6ab..1a959cd 100644
--- a/src/xen/xen_hypervisor.c
+++ b/src/xen/xen_hypervisor.c
@@ -36,7 +36,6 @@
 #include <stdint.h>
 #include <regex.h>
 #include <errno.h>
-#include <sys/utsname.h>
 
 #ifdef __sun
 # include <sys/systeminfo.h>
@@ -2292,8 +2291,7 @@ xenHypervisorGetVersion(virConnectPtr conn, unsigned long *hvVer)
 }
 
 struct guest_arch {
-    const char *model;
-    int bits;
+    virArch arch;
     int hvm;
     int pae;
     int nonpae;
@@ -2302,7 +2300,7 @@ struct guest_arch {
 
 
 static int xenDefaultConsoleType(const char *ostype,
-                                 const char *arch ATTRIBUTE_UNUSED)
+                                 virArch arch ATTRIBUTE_UNUSED)
 {
     if (STREQ(ostype, "hvm"))
         return VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_SERIAL;
@@ -2312,7 +2310,7 @@ static int xenDefaultConsoleType(const char *ostype,
 
 static virCapsPtr
 xenHypervisorBuildCapabilities(virConnectPtr conn,
-                               const char *hostmachine,
+                               virArch hostarch,
                                int host_pae,
                                const char *hvm_type,
                                struct guest_arch *guest_archs,
@@ -2322,7 +2320,7 @@ xenHypervisorBuildCapabilities(virConnectPtr conn,
     int hv_major = hv_versions.hv >> 16;
     int hv_minor = hv_versions.hv & 0xFFFF;
 
-    if ((caps = virCapabilitiesNew(hostmachine, 1, 1)) == NULL)
+    if ((caps = virCapabilitiesNew(hostarch, 1, 1)) == NULL)
         goto no_memory;
 
     virCapabilitiesSetMacPrefix(caps, (unsigned char[]){ 0x00, 0x16, 0x3e });
@@ -2357,9 +2355,8 @@ xenHypervisorBuildCapabilities(virConnectPtr conn,
 
         if ((guest = virCapabilitiesAddGuest(caps,
                                              guest_archs[i].hvm ? "hvm" : "xen",
-                                             guest_archs[i].model,
-                                             guest_archs[i].bits,
-                                             (STREQ(hostmachine, "x86_64") ?
+                                             guest_archs[i].arch,
+                                             (hostarch == VIR_ARCH_X86_64 ?
                                               "/usr/lib64/xen/bin/qemu-dm" :
                                               "/usr/lib/xen/bin/qemu-dm"),
                                              (guest_archs[i].hvm ?
@@ -2505,18 +2502,13 @@ xenHypervisorMakeCapabilitiesSunOS(virConnectPtr conn)
     struct guest_arch guest_arches[32];
     int i = 0;
     virCapsPtr caps = NULL;
-    struct utsname utsname;
     int pae, longmode;
     const char *hvm;
 
     if (!get_cpu_flags(conn, &hvm, &pae, &longmode))
         return NULL;
 
-    /* Really, this never fails - look at the man-page. */
-    uname(&utsname);
-
-    guest_arches[i].model = "i686";
-    guest_arches[i].bits = 32;
+    guest_arches[i].arch = VIR_ARCH_I686;
     guest_arches[i].hvm = 0;
     guest_arches[i].pae = pae;
     guest_arches[i].nonpae = !pae;
@@ -2524,8 +2516,7 @@ xenHypervisorMakeCapabilitiesSunOS(virConnectPtr conn)
     i++;
 
     if (longmode) {
-        guest_arches[i].model = "x86_64";
-        guest_arches[i].bits = 64;
+        guest_arches[i].arch = VIR_ARCH_X86_64;
         guest_arches[i].hvm = 0;
         guest_arches[i].pae = 0;
         guest_arches[i].nonpae = 0;
@@ -2534,8 +2525,7 @@ xenHypervisorMakeCapabilitiesSunOS(virConnectPtr conn)
     }
 
     if (hvm[0] != '\0') {
-        guest_arches[i].model = "i686";
-        guest_arches[i].bits = 32;
+        guest_arches[i].arch = VIR_ARCH_I686;
         guest_arches[i].hvm = 1;
         guest_arches[i].pae = pae;
         guest_arches[i].nonpae = 1;
@@ -2543,8 +2533,7 @@ xenHypervisorMakeCapabilitiesSunOS(virConnectPtr conn)
         i++;
 
         if (longmode) {
-            guest_arches[i].model = "x86_64";
-            guest_arches[i].bits = 64;
+            guest_arches[i].arch = VIR_ARCH_X86_64;
             guest_arches[i].hvm = 1;
             guest_arches[i].pae = 0;
             guest_arches[i].nonpae = 0;
@@ -2554,7 +2543,7 @@ xenHypervisorMakeCapabilitiesSunOS(virConnectPtr conn)
     }
 
     if ((caps = xenHypervisorBuildCapabilities(conn,
-                                               utsname.machine,
+                                               virArchFromHost(),
                                                pae, hvm,
                                                guest_arches, i)) == NULL)
         virReportOOMError();
@@ -2574,7 +2563,7 @@ xenHypervisorMakeCapabilitiesSunOS(virConnectPtr conn)
  */
 virCapsPtr
 xenHypervisorMakeCapabilitiesInternal(virConnectPtr conn,
-                                      const char *hostmachine,
+                                      virArch hostarch,
                                       FILE *cpuinfo, FILE *capabilities)
 {
     char line[1024], *str, *token;
@@ -2645,12 +2634,11 @@ xenHypervisorMakeCapabilitiesInternal(virConnectPtr conn,
             if (regexec(&xen_cap_rec, token, sizeof(subs) / sizeof(subs[0]),
                         subs, 0) == 0) {
                 int hvm = STRPREFIX(&token[subs[1].rm_so], "hvm");
-                const char *model;
-                int bits, pae = 0, nonpae = 0, ia64_be = 0;
+                int pae = 0, nonpae = 0, ia64_be = 0;
+                virArch arch;
 
                 if (STRPREFIX(&token[subs[2].rm_so], "x86_32")) {
-                    model = "i686";
-                    bits = 32;
+                    arch = VIR_ARCH_I686;
                     if (subs[3].rm_so != -1 &&
                         STRPREFIX(&token[subs[3].rm_so], "p"))
                         pae = 1;
@@ -2658,27 +2646,24 @@ xenHypervisorMakeCapabilitiesInternal(virConnectPtr conn,
                         nonpae = 1;
                 }
                 else if (STRPREFIX(&token[subs[2].rm_so], "x86_64")) {
-                    model = "x86_64";
-                    bits = 64;
+                    arch = VIR_ARCH_X86_64;
                 }
                 else if (STRPREFIX(&token[subs[2].rm_so], "ia64")) {
-                    model = "ia64";
-                    bits = 64;
+                    arch = VIR_ARCH_ITANIUM;
                     if (subs[3].rm_so != -1 &&
                         STRPREFIX(&token[subs[3].rm_so], "be"))
                         ia64_be = 1;
                 }
                 else if (STRPREFIX(&token[subs[2].rm_so], "powerpc64")) {
-                    model = "ppc64";
-                    bits = 64;
+                    arch = VIR_ARCH_PPC64;
                 } else {
-                    /* XXX surely no other Xen archs exist  */
+                    /* XXX surely no other Xen archs exist. Arrrrrrrrrm  */
                     continue;
                 }
 
                 /* Search for existing matching (model,hvm) tuple */
                 for (i = 0 ; i < nr_guest_archs ; i++) {
-                    if (STREQ(guest_archs[i].model, model) &&
+                    if (guest_archs[i].arch == arch &&
                         guest_archs[i].hvm == hvm) {
                         break;
                     }
@@ -2691,8 +2676,7 @@ xenHypervisorMakeCapabilitiesInternal(virConnectPtr conn,
                 if (i == nr_guest_archs)
                     nr_guest_archs++;
 
-                guest_archs[i].model = model;
-                guest_archs[i].bits = bits;
+                guest_archs[i].arch = arch;
                 guest_archs[i].hvm = hvm;
 
                 /* Careful not to overwrite a previous positive
@@ -2710,7 +2694,7 @@ xenHypervisorMakeCapabilitiesInternal(virConnectPtr conn,
     }
 
     if ((caps = xenHypervisorBuildCapabilities(conn,
-                                               hostmachine,
+                                               hostarch,
                                                host_pae,
                                                hvm_type,
                                                guest_archs,
@@ -2738,10 +2722,6 @@ xenHypervisorMakeCapabilities(virConnectPtr conn)
 #else
     virCapsPtr caps = NULL;
     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) {
@@ -2765,7 +2745,7 @@ xenHypervisorMakeCapabilities(virConnectPtr conn)
     }
 
     caps = xenHypervisorMakeCapabilitiesInternal(conn,
-                                                 utsname.machine,
+                                                 virArchFromHost(),
                                                  cpuinfo,
                                                  capabilities);
     if (caps == NULL)
diff --git a/src/xen/xen_hypervisor.h b/src/xen/xen_hypervisor.h
index fd23f38..786e301 100644
--- a/src/xen/xen_hypervisor.h
+++ b/src/xen/xen_hypervisor.h
@@ -62,7 +62,7 @@ int     xenHypervisorGetVersion         (virConnectPtr conn,
                                          unsigned long *hvVer);
 virCapsPtr
         xenHypervisorMakeCapabilitiesInternal(virConnectPtr conn,
-                                              const char *hostmachine,
+                                              virArch hostarch,
                                               FILE *cpuinfo,
                                               FILE *capabilities);
 char *
diff --git a/src/xenxs/xen_xm.c b/src/xenxs/xen_xm.c
index 23b3037..1b04b4c 100644
--- a/src/xenxs/xen_xm.c
+++ b/src/xenxs/xen_xm.c
@@ -263,7 +263,7 @@ xenParseXM(virConfPtr conf, int xendConfigVersion,
     virDomainGraphicsDefPtr graphics = NULL;
     virDomainHostdevDefPtr hostdev = NULL;
     int i;
-    const char *defaultArch, *defaultMachine;
+    const char *defaultMachine;
     int vmlocaltime = 0;
     unsigned long count;
     char *script = NULL;
@@ -290,15 +290,13 @@ xenParseXM(virConfPtr conf, int xendConfigVersion,
     if (!(def->os.type = strdup(hvm ? "hvm" : "xen")))
         goto no_memory;
 
-    defaultArch = virCapabilitiesDefaultGuestArch(caps, def->os.type, virDomainVirtTypeToString(def->virtType));
-    if (defaultArch == NULL) {
+    def->os.arch = virCapabilitiesDefaultGuestArch(caps, def->os.type, virDomainVirtTypeToString(def->virtType));
+    if (!def->os.arch) {
         virReportError(VIR_ERR_INTERNAL_ERROR,
                        _("no supported architecture for os type '%s'"),
                        def->os.type);
         goto cleanup;
     }
-    if (!(def->os.arch = strdup(defaultArch)))
-        goto no_memory;
 
     defaultMachine = virCapabilitiesDefaultGuestMachine(caps,
                                                         def->os.type,
-- 
1.7.11.7




More information about the libvir-list mailing list