Using the 'personality(2)' system call, we can make a container on an x86_64 host appear to be i686. Likewise for most other Linux 64bit arches. * src/lxc/lxc_conf.c: Fill in 32bit capabilities for x86_64 hosts * src/lxc/lxc_container.h, src/lxc/lxc_container.c: Add API to check if an arch has a 32bit alternative * src/lxc/lxc_controller.c: Set the process personality when starting guest --- src/lxc/lxc_conf.c | 25 ++++++++++++++++++++++++- src/lxc/lxc_container.c | 21 +++++++++++++++++++++ src/lxc/lxc_container.h | 2 ++ src/lxc/lxc_controller.c | 26 ++++++++++++++++++++++++-- 4 files changed, 71 insertions(+), 3 deletions(-) diff --git a/src/lxc/lxc_conf.c b/src/lxc/lxc_conf.c index 59d1161..226a57e 100644 --- a/src/lxc/lxc_conf.c +++ b/src/lxc/lxc_conf.c @@ -36,6 +36,7 @@ #include "logging.h" #include "uuid.h" #include "configmake.h" +#include "lxc_container.h" #define VIR_FROM_THIS VIR_FROM_LXC @@ -45,6 +46,7 @@ virCapsPtr lxcCapsInit(void) struct utsname utsname; virCapsPtr caps; virCapsGuestPtr guest; + const char *altArch; uname(&utsname); @@ -73,7 +75,7 @@ virCapsPtr lxcCapsInit(void) if ((guest = virCapabilitiesAddGuest(caps, "exe", utsname.machine, - sizeof(int) == 4 ? 32 : 8, + sizeof(void*) == 4 ? 32 : 64, LIBEXECDIR "/libvirt_lxc", NULL, 0, @@ -88,6 +90,27 @@ virCapsPtr lxcCapsInit(void) NULL) == NULL) goto error; + /* On 64-bit hosts, we can use personality() to request a 32bit process */ + if ((altArch = lxcContainerGetAlt32bitArch(utsname.machine)) != NULL) { + if ((guest = virCapabilitiesAddGuest(caps, + "exe", + altArch, + 32, + LIBEXECDIR "/libvirt_lxc", + NULL, + 0, + NULL)) == NULL) + goto error; + + if (virCapabilitiesAddGuestDomain(guest, + "lxc", + NULL, + NULL, + 0, + NULL) == NULL) + goto error; + } + /* LXC Requires an emulator in the XML */ virCapabilitiesSetEmulatorRequired(caps); diff --git a/src/lxc/lxc_container.c b/src/lxc/lxc_container.c index 269dc97..9830b71 100644 --- a/src/lxc/lxc_container.c +++ b/src/lxc/lxc_container.c @@ -837,6 +837,27 @@ static int userns_supported(void) #endif } +const char *lxcContainerGetAlt32bitArch(const char *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; +} + + /** * lxcContainerStart: * @def: pointer to virtual machine structure diff --git a/src/lxc/lxc_container.h b/src/lxc/lxc_container.h index 75c8836..5e08d45 100644 --- a/src/lxc/lxc_container.h +++ b/src/lxc/lxc_container.h @@ -55,4 +55,6 @@ int lxcContainerStart(virDomainDefPtr def, int lxcContainerAvailable(int features); +const char *lxcContainerGetAlt32bitArch(const char *arch); + #endif /* LXC_CONTAINER_H */ diff --git a/src/lxc/lxc_controller.c b/src/lxc/lxc_controller.c index 28cbe57..61e21c3 100644 --- a/src/lxc/lxc_controller.c +++ b/src/lxc/lxc_controller.c @@ -1,6 +1,5 @@ /* - * Copyright (C) 2010 Red Hat, Inc. - * Copyright IBM Corp. 2008 + * Copyright (C) 2010 Red Hat, Inc. Copyright IBM Corp. 2008 * * lxc_controller.c: linux container process controller * @@ -29,6 +28,8 @@ #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> #include <errno.h> @@ -565,6 +566,25 @@ static int lxcControllerCleanupInterfaces(unsigned int nveths, return 0; } +static int lxcSetPersonality(virDomainDefPtr def) +{ + struct utsname utsname; + const char *altArch; + + uname(&utsname); + + altArch = lxcContainerGetAlt32bitArch(utsname.machine); + if (altArch && + STREQ(def->os.arch, altArch)) { + if (personality(PER_LINUX32) < 0) { + virReportSystemError(errno, _("Unable to request personality for %s on %s"), + altArch, utsname.machine); + return -1; + } + } + return 0; +} + #ifndef MS_REC # define MS_REC 16384 #endif @@ -684,6 +704,8 @@ lxcControllerRun(virDomainDefPtr def, } } + if (lxcSetPersonality(def) < 0) + goto cleanup; if ((container = lxcContainerStart(def, nveths, -- 1.7.4 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list