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