[libvirt] [PATCH 1/2] libxl: expose multiple emulators per guest in the capabilities XML

David Scott dave.scott at eu.citrix.com
Mon Apr 29 14:49:40 UTC 2013


libxl allows users to choose between two standard emulators:
1. (default in xen-4.2): qemu "traditional" (aka "qemu-dm")
2. (default in xen-4.3): qemu "upstream" (aka "qemu-system-i386")

The person who builds and packages xen gets to choose which
emulators are built. We examine the filesystem for the emulators
at runtime and expose them as separate "domains" within the same
"guest" architecture.

Signed-off-by: David Scott <dave.scott at eu.citrix.com>
---
 src/libxl/libxl_conf.c |   87 ++++++++++++++++++++++++++++++++++++-----------
 1 files changed, 66 insertions(+), 21 deletions(-)

diff --git a/src/libxl/libxl_conf.c b/src/libxl/libxl_conf.c
index 7e0753a..472d116 100644
--- a/src/libxl/libxl_conf.c
+++ b/src/libxl/libxl_conf.c
@@ -29,6 +29,8 @@
 #include <libxl.h>
 #include <sys/types.h>
 #include <sys/socket.h>
+#include <sys/stat.h>
+#include <unistd.h>
 
 #include "internal.h"
 #include "virlog.h"
@@ -50,6 +52,28 @@
 /* see xen-unstable.hg/xen/include/asm-x86/cpufeature.h */
 #define LIBXL_X86_FEATURE_PAE_MASK 0x40
 
+enum emulator_type {
+    emulator_traditional = 0,
+    emulator_upstream    = 1,
+    emulator_last        = 2,
+    /* extend with specific qemu versions later */
+};
+
+#define EMULATOR_LIB64 "/usr/lib64/xen/bin/"
+#define EMULATOR_LIB32 "/usr/lib/xen/bin/"
+
+#define EMULATOR_TRADITIONAL "qemu-dm"
+#define EMULATOR_UPSTREAM    "qemu-system-i386"
+
+static const char* emulator_lib64_path [] = {
+    EMULATOR_LIB64 EMULATOR_TRADITIONAL,
+    EMULATOR_LIB64 EMULATOR_UPSTREAM,
+};
+
+static const char* emulator_lib32_path [] = {
+    EMULATOR_LIB32 EMULATOR_TRADITIONAL,
+    EMULATOR_LIB32 EMULATOR_UPSTREAM,
+};
 
 struct guest_arch {
     virArch arch;
@@ -68,10 +92,11 @@ static virCapsPtr
 libxlBuildCapabilities(virArch hostarch,
                        int host_pae,
                        struct guest_arch *guest_archs,
-                       int nr_guest_archs)
+                       int nr_guest_archs,
+                       int emulators_found[])
 {
     virCapsPtr caps;
-    int i;
+    int i, j;
 
     if ((caps = virCapabilitiesNew(hostarch, 1, 1)) == NULL)
         goto no_memory;
@@ -91,12 +116,8 @@ libxlBuildCapabilities(virArch hostarch,
         if ((guest = virCapabilitiesAddGuest(caps,
                                              guest_archs[i].hvm ? "hvm" : "xen",
                                              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 ?
-                                              "/usr/lib/xen/boot/hvmloader" :
-                                              NULL),
+                                             NULL,
+                                             NULL,
                                              1,
                                              machines)) == NULL) {
             virCapabilitiesFreeMachines(machines, 1);
@@ -104,13 +125,21 @@ libxlBuildCapabilities(virArch hostarch,
         }
         machines = NULL;
 
-        if (virCapabilitiesAddGuestDomain(guest,
-                                          "xen",
-                                          NULL,
-                                          NULL,
-                                          0,
-                                          NULL) == NULL)
-            goto no_memory;
+        for (j = 0; j < emulator_last; ++j) {
+            if (emulators_found[j] == -1) /* failure from stat(2) */
+                continue;
+            if (virCapabilitiesAddGuestDomain(guest,
+                                              "xen",
+                                              ((hostarch == VIR_ARCH_X86_64) ?
+                                               emulator_lib64_path[j] :
+                                               emulator_lib32_path[j]),
+                                              (guest_archs[i].hvm ?
+                                               "/usr/lib/xen/boot/hvmloader" :
+                                               NULL),
+                                              0,
+                                              NULL) == NULL)
+                goto no_memory;
+        }
 
         if (guest_archs[i].pae &&
             virCapabilitiesAddGuestFeature(guest,
@@ -163,7 +192,8 @@ libxlBuildCapabilities(virArch hostarch,
 static virCapsPtr
 libxlMakeCapabilitiesInternal(virArch hostarch,
                               libxl_physinfo *phy_info,
-                              char *capabilities)
+                              char *capabilities,
+                              int emulators_found[])
 {
     char *str, *token;
     regmatch_t subs[4];
@@ -243,7 +273,7 @@ libxlMakeCapabilitiesInternal(virArch hostarch,
                 continue;
             }
 
-            /* Search for existing matching (model,hvm) tuple */
+            /* Search for existing matching (arch,hvm) tuple */
             for (i = 0 ; i < nr_guest_archs ; i++) {
                 if ((guest_archs[i].arch == arch) &&
                     guest_archs[i].hvm == hvm) {
@@ -277,7 +307,8 @@ libxlMakeCapabilitiesInternal(virArch hostarch,
     if ((caps = libxlBuildCapabilities(hostarch,
                                        host_pae,
                                        guest_archs,
-                                       nr_guest_archs)) == NULL)
+                                       nr_guest_archs,
+                                       emulators_found)) == NULL)
         goto no_memory;
 
     return caps;
@@ -756,9 +787,13 @@ error:
 virCapsPtr
 libxlMakeCapabilities(libxl_ctx *ctx)
 {
-    int err;
+    int i, err;
     libxl_physinfo phy_info;
     const libxl_version_info *ver_info;
+    struct stat sbuf;
+    const char *path;
+    virArch hostarch;
+    int emulators_found[emulator_last];
 
     err = regcomp(&xen_cap_rec, xen_cap_re, REG_EXTENDED);
     if (err != 0) {
@@ -782,9 +817,19 @@ libxlMakeCapabilities(libxl_ctx *ctx)
         return NULL;
     }
 
-    return libxlMakeCapabilitiesInternal(virArchFromHost(),
+    hostarch = virArchFromHost();
+
+    for (i = 0; i < emulator_last; i++){
+        path = (hostarch == VIR_ARCH_X86_64)?
+                emulator_lib64_path[i]:
+                emulator_lib32_path[i];
+        emulators_found[i] = stat(path, &sbuf);
+    }
+
+    return libxlMakeCapabilitiesInternal(hostarch,
                                          &phy_info,
-                                         ver_info->capabilities);
+                                         ver_info->capabilities,
+                                         emulators_found);
 }
 
 int
-- 
1.7.1




More information about the libvir-list mailing list