David Scott wrote: > 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@xxxxxxxxxxxxx> > --- > 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 */ > +}; > Do you think this will need to be extended in the future? As 'qemu-traditional' goes by way of the Dodo, this won't be needed right? > + > +#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" > I think this could be made quite a bit simpler with something like #define LIBXL_EMULATOR_TRADITIONAL_PATH LIBDIR "/xen/bin/qemu-dm" #define LIBXL_EMULATOR_UPSTREAM_PATH LIBDIR "/xen/bin/qemu-sytstem-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; > + } > and then just add the emulators here. E.g. if (virFileExists(LIBXL_EMULATOR_TRADITIONAL_PATH) { if (virCapabilitiesAddGuestDomain(guest, "xen", LIBXL_EMULATOR_TRADITIONAL_PATH (guest_archs[i].hvm ? "/usr/lib/xen/boot/hvmloader" : NULL), 0, NULL) == NULL) goto no_memory; } if (virFileExists(LIBXL_EMULATOR_UPSTREAM_PATH) { if (virCapabilitiesAddGuestDomain(guest, "xen", LIBXL_EMULATOR_UPSTREAM_PATH (guest_archs[i].hvm ? "/usr/lib/xen/boot/hvmloader" : NULL), 0, NULL) == NULL) goto no_memory; } Regards, Jim > > 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 > -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list