[libvirt] [PATCH 6/6 v2] Convert QEMU capabilities code to use virArch

Daniel P. Berrange berrange at redhat.com
Tue Dec 18 14:09:16 UTC 2012


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

Signed-off-by: Daniel P. Berrange <berrange at redhat.com>
---
 src/qemu/qemu_capabilities.c | 155 +++++++++++++++++++++----------------------
 src/qemu/qemu_capabilities.h |   2 +-
 2 files changed, 76 insertions(+), 81 deletions(-)

diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 6a02161..ae75bc6 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -42,7 +42,6 @@
 #include <sys/stat.h>
 #include <unistd.h>
 #include <sys/wait.h>
-#include <sys/utsname.h>
 #include <stdarg.h>
 
 #define VIR_FROM_THIS VIR_FROM_QEMU
@@ -215,7 +214,7 @@ struct _qemuCaps {
     unsigned int version;
     unsigned int kvmVersion;
 
-    char *arch;
+    virArch arch;
 
     size_t ncpuDefinitions;
     char **cpuDefinitions;
@@ -250,6 +249,32 @@ static int qemuCapsOnceInit(void)
 
 VIR_ONCE_GLOBAL_INIT(qemuCaps)
 
+static virArch qemuCapsArchFromString(const char *arch)
+{
+    if (STREQ(arch, "ia64"))
+        return VIR_ARCH_ITANIUM;
+    if (STREQ(arch, "i386"))
+        return VIR_ARCH_I686;
+    if (STREQ(arch, "arm"))
+        return VIR_ARCH_ARMV7L;
+
+    return virArchFromString(arch);
+}
+
+
+static const char *qemuCapsArchToString(virArch arch)
+{
+    if (arch == VIR_ARCH_I686)
+        return "i386";
+    else if (arch == VIR_ARCH_ITANIUM)
+        return "ia64";
+    else if (arch == VIR_ARCH_ARMV7L)
+        return "arm";
+
+    return virArchToString(arch);
+}
+
+
 struct _qemuCapsHookData {
     uid_t runUid;
     gid_t runGid;
@@ -550,14 +575,14 @@ qemuCapsProbeCPUModels(qemuCapsPtr caps, qemuCapsHookDataPtr hookData)
     qemuCapsParseCPUModels parse;
     virCommandPtr cmd;
 
-    if (STREQ(caps->arch, "i686") ||
-        STREQ(caps->arch, "x86_64"))
+    if (caps->arch == VIR_ARCH_I686 ||
+        caps->arch == VIR_ARCH_X86_64)
         parse = qemuCapsParseX86Models;
-    else if (STREQ(caps->arch, "ppc64"))
+    else if (caps->arch == VIR_ARCH_PPC64)
         parse = qemuCapsParsePPCModels;
     else {
         VIR_DEBUG("don't know how to parse %s CPU models",
-                  caps->arch);
+                  virArchToString(caps->arch));
         return 0;
     }
 
@@ -586,37 +611,34 @@ qemuCapsFindBinaryForArch(virArch hostarch,
                           virArch guestarch)
 {
     char *ret;
+    const char *archstr = qemuCapsArchToString(guestarch);
+    char *binary;
 
-    /* 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 (virAsprintf(&binary, "qemu-system-%s", archstr) < 0) {
+        virReportOOMError();
+        return NULL;
+    }
+
+    ret = virFindFileInPath(binary);
+    VIR_FREE(binary);
+    if (ret && !virFileIsExecutable(ret))
+        VIR_FREE(ret);
+
+    if (guestarch == VIR_ARCH_I686 &&
+        !ret &&
+        hostarch == VIR_ARCH_X86_64) {
+        ret = virFindFileInPath("qemu-system-x86_64");
         if (ret && !virFileIsExecutable(ret))
             VIR_FREE(ret);
+    }
 
-        if (!ret && hostarch == VIR_ARCH_X86_64) {
-            ret = virFindFileInPath("qemu-system-x86_64");
-            if (ret && !virFileIsExecutable(ret))
-                VIR_FREE(ret);
-        }
-
-        if (!ret)
-            ret = virFindFileInPath("qemu");
-    } 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", virArchToString(guestarch)) < 0) {
-            virReportOOMError();
-            return NULL;
-        }
-        ret = virFindFileInPath(bin);
-        VIR_FREE(bin);
+    if (guestarch == VIR_ARCH_I686 &&
+        !ret) {
+        ret = virFindFileInPath("qemu");
+        if (ret && !virFileIsExecutable(ret))
+            VIR_FREE(ret);
     }
-    if (ret && !virFileIsExecutable(ret))
-        VIR_FREE(ret);
+
     return ret;
 }
 
@@ -1608,20 +1630,6 @@ cleanup:
     return ret;
 }
 
-static void
-uname_normalize(struct utsname *ut)
-{
-    uname(ut);
-
-    /* Map i386, i486, i586 to i686.  */
-    if (ut->machine[0] == 'i' &&
-        ut->machine[1] != '\0' &&
-        ut->machine[2] == '8' &&
-        ut->machine[3] == '6' &&
-        ut->machine[4] == '\0')
-        ut->machine[1] = '6';
-}
-
 
 int qemuCapsGetDefaultVersion(virCapsPtr caps,
                               qemuCapsCachePtr capsCache,
@@ -1689,10 +1697,7 @@ qemuCapsPtr qemuCapsNewCopy(qemuCapsPtr caps)
 
     ret->version = caps->version;
     ret->kvmVersion = caps->kvmVersion;
-
-    if (caps->arch &&
-        !(ret->arch = strdup(caps->arch)))
-        goto no_memory;
+    ret->arch = caps->arch;
 
     if (VIR_ALLOC_N(ret->cpuDefinitions, caps->ncpuDefinitions) < 0)
         goto no_memory;
@@ -1729,8 +1734,6 @@ void qemuCapsDispose(void *obj)
     qemuCapsPtr caps = obj;
     size_t i;
 
-    VIR_FREE(caps->arch);
-
     for (i = 0 ; i < caps->nmachineTypes ; i++) {
         VIR_FREE(caps->machineTypes[i]);
         VIR_FREE(caps->machineAliases[i]);
@@ -1801,7 +1804,7 @@ const char *qemuCapsGetBinary(qemuCapsPtr caps)
     return caps->binary;
 }
 
-const char *qemuCapsGetArch(qemuCapsPtr caps)
+virArch qemuCapsGetArch(qemuCapsPtr caps)
 {
     return caps->arch;
 }
@@ -2142,7 +2145,6 @@ qemuCapsInitHelp(qemuCapsPtr caps, uid_t runUid, gid_t runGid)
     char *help = NULL;
     int ret = -1;
     const char *tmp;
-    struct utsname ut;
     qemuCapsHookData hookData;
 
     VIR_DEBUG("caps=%p", caps);
@@ -2151,18 +2153,9 @@ qemuCapsInitHelp(qemuCapsPtr caps, uid_t runUid, gid_t runGid)
     if (tmp) {
         tmp += strlen(QEMU_SYSTEM_PREFIX);
 
-        /* For historical compat we use 'itanium' as arch name */
-        if (STREQ(tmp, "ia64"))
-            tmp = "itanium";
-        else if (STREQ(tmp, "i386"))
-            tmp = "i686";
+        caps->arch = qemuCapsArchFromString(tmp);
     } else {
-        uname_normalize(&ut);
-        tmp = ut.machine;
-    }
-    if (!(caps->arch = strdup(tmp))) {
-        virReportOOMError();
-        goto cleanup;
+        caps->arch = virArchFromHost();
     }
 
     hookData.runUid = runUid;
@@ -2183,14 +2176,15 @@ qemuCapsInitHelp(qemuCapsPtr caps, uid_t runUid, gid_t runGid)
         goto cleanup;
 
     /* Currently only x86_64 and i686 support PCI-multibus. */
-    if (STREQLEN(caps->arch, "x86_64", 6) ||
-        STREQLEN(caps->arch, "i686", 4)) {
+    if (caps->arch == VIR_ARCH_X86_64 ||
+        caps->arch == VIR_ARCH_I686) {
         qemuCapsSet(caps, QEMU_CAPS_PCI_MULTIBUS);
     }
 
     /* S390 and probably other archs do not support no-acpi -
        maybe the qemu option parsing should be re-thought. */
-    if (STRPREFIX(caps->arch, "s390"))
+    if (caps->arch == VIR_ARCH_S390 ||
+        caps->arch == VIR_ARCH_S390X)
         qemuCapsClear(caps, QEMU_CAPS_NO_ACPI);
 
     /* qemuCapsExtractDeviceStr will only set additional caps if qemu
@@ -2302,6 +2296,7 @@ qemuCapsInitQMP(qemuCapsPtr caps,
     char *monpath = NULL;
     char *pidfile = NULL;
     qemuCapsHookData hookData;
+    char *archstr;
 
     /* the ".sock" sufix is important to avoid a possible clash with a qemu
      * domain called "capabilities"
@@ -2394,26 +2389,26 @@ qemuCapsInitQMP(qemuCapsPtr caps,
 
     qemuCapsInitQMPBasic(caps);
 
-    if (!(caps->arch = qemuMonitorGetTargetArch(mon)))
+    if (!(archstr = qemuMonitorGetTargetArch(mon)))
         goto cleanup;
 
-    /* Map i386, i486, i586 to i686.  */
-    if (caps->arch[0] == 'i' &&
-        caps->arch[1] != '\0' &&
-        caps->arch[2] == '8' &&
-        caps->arch[3] == '6' &&
-        caps->arch[4] == '\0')
-        caps->arch[1] = '6';
+    if ((caps->arch = qemuCapsArchFromString(archstr)) == VIR_ARCH_NONE) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("Unknown QEMU arch %s"), archstr);
+        VIR_FREE(archstr);
+        goto cleanup;
+    }
+    VIR_FREE(archstr);
 
     /* Currently only x86_64 and i686 support PCI-multibus. */
-    if (STREQLEN(caps->arch, "x86_64", 6) ||
-        STREQLEN(caps->arch, "i686", 4)) {
+    if (caps->arch == VIR_ARCH_X86_64 ||
+        caps->arch == VIR_ARCH_I686)
         qemuCapsSet(caps, QEMU_CAPS_PCI_MULTIBUS);
-    }
 
     /* S390 and probably other archs do not support no-acpi -
        maybe the qemu option parsing should be re-thought. */
-    if (STRPREFIX(caps->arch, "s390"))
+    if (caps->arch == VIR_ARCH_S390 ||
+        caps->arch == VIR_ARCH_S390X)
         qemuCapsClear(caps, QEMU_CAPS_NO_ACPI);
 
     if (qemuCapsProbeQMPCommands(caps, mon) < 0)
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
index bf4eef8..700b0ac 100644
--- a/src/qemu/qemu_capabilities.h
+++ b/src/qemu/qemu_capabilities.h
@@ -197,7 +197,7 @@ bool qemuCapsGet(qemuCapsPtr caps,
 char *qemuCapsFlagsString(qemuCapsPtr caps);
 
 const char *qemuCapsGetBinary(qemuCapsPtr caps);
-const char *qemuCapsGetArch(qemuCapsPtr caps);
+virArch qemuCapsGetArch(qemuCapsPtr caps);
 unsigned int qemuCapsGetVersion(qemuCapsPtr caps);
 unsigned int qemuCapsGetKVMVersion(qemuCapsPtr caps);
 int qemuCapsAddCPUDefinition(qemuCapsPtr caps,
-- 
1.7.11.7




More information about the libvir-list mailing list