From 4f2094a8a61682c81b3b5412ac1f3d9564a8b544 Mon Sep 17 00:00:00 2001 From: "Daniel P. Berrange" Date: Wed, 23 Feb 2011 17:17:53 +0000 Subject: [PATCH] Allow 32-on-64 execution for LXC guests 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 59d1161916..226a57e119 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 269dc9784a..9830b71c2a 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 75c88367c0..5e08d45181 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 fa46977afe..d2b113ce15 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 #include #include +#include +#include #include #include #include @@ -545,6 +546,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 @@ -664,6 +684,8 @@ lxcControllerRun(virDomainDefPtr def, } } + if (lxcSetPersonality(def) < 0) + goto cleanup; if ((container = lxcContainerStart(def, nveths, -- GitLab