[libvirt] [PATCH v3 08/20] Refactor guest init to support qemu-system-i386 binary too

Daniel P. Berrange berrange at redhat.com
Tue Sep 25 18:00:01 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 | 163 +++++++++++++++++++++++--------------------
 1 file changed, 89 insertions(+), 74 deletions(-)

diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 0a203c5..c173286 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -227,53 +227,6 @@ static int qemuCapsOnceInit(void)
 
 VIR_ONCE_GLOBAL_INIT(qemuCaps)
 
-struct qemu_feature_flags {
-    const char *name;
-    const int default_on;
-    const int toggle;
-};
-
-struct qemu_arch_info {
-    const char *arch;
-    int wordsize;
-    const char *binary;
-    const char *altbinary;
-    const struct qemu_feature_flags *flags;
-    int nflags;
-};
-
-/* Feature flags for the architecture info */
-static const struct qemu_feature_flags const arch_info_i686_flags [] = {
-    { "pae",  1, 0 },
-    { "nonpae",  1, 0 },
-    { "acpi", 1, 1 },
-    { "apic", 1, 0 },
-};
-
-static const struct qemu_feature_flags const arch_info_x86_64_flags [] = {
-    { "acpi", 1, 1 },
-    { "apic", 1, 0 },
-};
-
-/* The archicture tables for supported QEMU archs */
-static const struct qemu_arch_info const arch_info_hvm[] = {
-    {  "i686",   32, "qemu",
-       "qemu-system-x86_64", arch_info_i686_flags, 4 },
-    {  "x86_64", 64, "qemu-system-x86_64",
-       NULL, arch_info_x86_64_flags, 2 },
-    {  "arm",    32, "qemu-system-arm",    NULL, NULL, 0 },
-    {  "microblaze", 32, "qemu-system-microblaze",   NULL, NULL, 0 },
-    {  "microblazeel", 32, "qemu-system-microblazeel",   NULL, NULL, 0 },
-    {  "mips",   32, "qemu-system-mips",   NULL, NULL, 0 },
-    {  "mipsel", 32, "qemu-system-mipsel", NULL, NULL, 0 },
-    {  "sparc",  32, "qemu-system-sparc",  NULL, NULL, 0 },
-    {  "ppc",    32, "qemu-system-ppc",    NULL, NULL, 0 },
-    {  "ppc64",    64, "qemu-system-ppc64",    NULL, NULL, 0 },
-    {  "itanium", 64, "qemu-system-ia64",  NULL, NULL, 0 },
-    {  "s390x",  64, "qemu-system-s390x",  NULL, NULL, 0 },
-};
-
-
 static virCommandPtr
 qemuCapsProbeCommand(const char *qemu,
                      qemuCapsPtr caps)
@@ -348,6 +301,7 @@ qemuCapsParseMachineTypesStr(const char *output,
             caps->machineAliases[caps->nmachineTypes-1] = name;
         } else {
             caps->machineTypes[caps->nmachineTypes-1] = name;
+            caps->machineAliases[caps->nmachineTypes-1] = NULL;
         }
     } while ((p = next));
 
@@ -367,7 +321,7 @@ qemuCapsParseMachineTypesStr(const char *output,
 
     return 0;
 
-  no_memory:
+no_memory:
     virReportOOMError();
     return -1;
 }
@@ -567,11 +521,70 @@ cleanup:
 }
 
 
+static char *
+qemuCapsFindBinaryForArch(const char *hostarch,
+                          const char *guestarch)
+{
+    char *ret;
+
+    if (STREQ(guestarch, "i686")) {
+        ret = virFindFileInPath("qemu-system-i386");
+        if (ret && !virFileIsExecutable(ret))
+            VIR_FREE(ret);
+
+        if (!ret && STREQ(hostarch, "x86_64")) {
+            ret = virFindFileInPath("qemu-system-x86_64");
+            if (ret && !virFileIsExecutable(ret))
+                VIR_FREE(ret);
+        }
+
+        if (!ret)
+            ret = virFindFileInPath("qemu");
+    } else if (STREQ(guestarch, "itanium")) {
+        ret = virFindFileInPath("qemu-system-ia64");
+    } else {
+        char *bin;
+        if (virAsprintf(&bin, "qemu-system-%s", guestarch) < 0) {
+            virReportOOMError();
+            return NULL;
+        }
+        ret = virFindFileInPath(bin);
+        VIR_FREE(bin);
+    }
+    if (ret && !virFileIsExecutable(ret))
+        VIR_FREE(ret);
+    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)
+{
+    if (STREQ(hostarch, guestarch))
+        return true;
+    if (STREQ(hostarch, "x86_64") &&
+        STREQ(guestarch, "i686"))
+        return true;
+    return false;
+}
+
 static int
 qemuCapsInitGuest(virCapsPtr caps,
                   qemuCapsCachePtr cache,
-                  const char *hostmachine,
-                  const struct qemu_arch_info *info)
+                  const char *hostarch,
+                  const char *guestarch)
 {
     virCapsGuestPtr guest;
     int i;
@@ -588,12 +601,7 @@ qemuCapsInitGuest(virCapsPtr caps,
     /* Check for existance of base emulator, or alternate base
      * which can be used with magic cpu choice
      */
-    binary = virFindFileInPath(info->binary);
-
-    if (binary == NULL || !virFileIsExecutable(binary)) {
-        VIR_FREE(binary);
-        binary = virFindFileInPath(info->altbinary);
-    }
+    binary = qemuCapsFindBinaryForArch(hostarch, guestarch);
 
     /* Ignore binary if extracting version info fails */
     if (binary) {
@@ -609,8 +617,7 @@ qemuCapsInitGuest(virCapsPtr caps,
      *  - hostarch is x86_64 and guest arch is i686
      * The latter simply needs "-cpu qemu32"
      */
-    if (STREQ(info->arch, hostmachine) ||
-        (STREQ(hostmachine, "x86_64") && STREQ(info->arch, "i686"))) {
+    if (qemuCapsIsValidForKVM(hostarch, guestarch)) {
         const char *const kvmbins[] = { "/usr/libexec/qemu-kvm", /* RHEL */
                                         "qemu-kvm", /* Fedora */
                                         "kvm" }; /* Upstream .spec */
@@ -657,8 +664,8 @@ qemuCapsInitGuest(virCapsPtr caps,
      * just give -no-kvm to disable acceleration if required */
     if ((guest = virCapabilitiesAddGuest(caps,
                                          "hvm",
-                                         info->arch,
-                                         info->wordsize,
+                                         guestarch,
+                                         qemuCapsGetArchWordSize(guestarch),
                                          binary,
                                          NULL,
                                          nmachines,
@@ -715,15 +722,16 @@ qemuCapsInitGuest(virCapsPtr caps,
 
     }
 
-    if (info->nflags) {
-        for (i = 0 ; i < info->nflags ; i++) {
-            if (virCapabilitiesAddGuestFeature(guest,
-                                               info->flags[i].name,
-                                               info->flags[i].default_on,
-                                               info->flags[i].toggle) == NULL)
-                goto error;
-        }
-    }
+    if ((STREQ(guestarch, "i686") ||
+         STREQ(guestarch, "x86_64")) &&
+        (virCapabilitiesAddGuestFeature(guest, "acpi", 1, 1) == NULL ||
+         virCapabilitiesAddGuestFeature(guest, "apic", 1, 0) == NULL))
+        goto error;
+
+    if (STREQ(guestarch, "i686") &&
+        (virCapabilitiesAddGuestFeature(guest, "pae", 1, 0) == NULL ||
+         virCapabilitiesAddGuestFeature(guest, "nonpae", 1, 0) == NULL))
+        goto error;
 
     ret = 0;
 
@@ -795,13 +803,20 @@ 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,
                                    1, 1)) == NULL)
-        goto no_memory;
+        goto error;
 
     /* Using KVM's mac prefix for QEMU too */
     virCapabilitiesSetMacPrefix(caps, (unsigned char[]){ 0x52, 0x54, 0x00 });
@@ -827,11 +842,11 @@ virCapsPtr qemuCapsInit(qemuCapsCachePtr cache)
                                            "tcp");
 
     /* First the pure HVM guests */
-    for (i = 0 ; i < ARRAY_CARDINALITY(arch_info_hvm) ; i++)
+    for (i = 0 ; i < ARRAY_CARDINALITY(arches) ; i++)
         if (qemuCapsInitGuest(caps, cache,
                               utsname.machine,
-                              &arch_info_hvm[i]) < 0)
-            goto no_memory;
+                              arches[i]) < 0)
+            goto error;
 
     /* QEMU Requires an emulator in the XML */
     virCapabilitiesSetEmulatorRequired(caps);
@@ -840,7 +855,7 @@ virCapsPtr qemuCapsInit(qemuCapsCachePtr cache)
 
     return caps;
 
- no_memory:
+error:
     virCapabilitiesFree(caps);
     return NULL;
 }
-- 
1.7.11.4




More information about the libvir-list mailing list