提交 4f2094a8 编写于 作者: D Daniel P. Berrange

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
上级 35416720
...@@ -36,6 +36,7 @@ ...@@ -36,6 +36,7 @@
#include "logging.h" #include "logging.h"
#include "uuid.h" #include "uuid.h"
#include "configmake.h" #include "configmake.h"
#include "lxc_container.h"
#define VIR_FROM_THIS VIR_FROM_LXC #define VIR_FROM_THIS VIR_FROM_LXC
...@@ -45,6 +46,7 @@ virCapsPtr lxcCapsInit(void) ...@@ -45,6 +46,7 @@ virCapsPtr lxcCapsInit(void)
struct utsname utsname; struct utsname utsname;
virCapsPtr caps; virCapsPtr caps;
virCapsGuestPtr guest; virCapsGuestPtr guest;
const char *altArch;
uname(&utsname); uname(&utsname);
...@@ -73,7 +75,7 @@ virCapsPtr lxcCapsInit(void) ...@@ -73,7 +75,7 @@ virCapsPtr lxcCapsInit(void)
if ((guest = virCapabilitiesAddGuest(caps, if ((guest = virCapabilitiesAddGuest(caps,
"exe", "exe",
utsname.machine, utsname.machine,
sizeof(int) == 4 ? 32 : 8, sizeof(void*) == 4 ? 32 : 64,
LIBEXECDIR "/libvirt_lxc", LIBEXECDIR "/libvirt_lxc",
NULL, NULL,
0, 0,
...@@ -88,6 +90,27 @@ virCapsPtr lxcCapsInit(void) ...@@ -88,6 +90,27 @@ virCapsPtr lxcCapsInit(void)
NULL) == NULL) NULL) == NULL)
goto error; 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 */ /* LXC Requires an emulator in the XML */
virCapabilitiesSetEmulatorRequired(caps); virCapabilitiesSetEmulatorRequired(caps);
......
...@@ -837,6 +837,27 @@ static int userns_supported(void) ...@@ -837,6 +837,27 @@ static int userns_supported(void)
#endif #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: * lxcContainerStart:
* @def: pointer to virtual machine structure * @def: pointer to virtual machine structure
......
...@@ -55,4 +55,6 @@ int lxcContainerStart(virDomainDefPtr def, ...@@ -55,4 +55,6 @@ int lxcContainerStart(virDomainDefPtr def,
int lxcContainerAvailable(int features); int lxcContainerAvailable(int features);
const char *lxcContainerGetAlt32bitArch(const char *arch);
#endif /* LXC_CONTAINER_H */ #endif /* LXC_CONTAINER_H */
/* /*
* Copyright (C) 2010 Red Hat, Inc. * Copyright (C) 2010 Red Hat, Inc. Copyright IBM Corp. 2008
* Copyright IBM Corp. 2008
* *
* lxc_controller.c: linux container process controller * lxc_controller.c: linux container process controller
* *
...@@ -29,6 +28,8 @@ ...@@ -29,6 +28,8 @@
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/un.h> #include <sys/un.h>
#include <sys/utsname.h>
#include <sys/personality.h>
#include <unistd.h> #include <unistd.h>
#include <paths.h> #include <paths.h>
#include <fcntl.h> #include <fcntl.h>
...@@ -545,6 +546,25 @@ static int lxcControllerCleanupInterfaces(unsigned int nveths, ...@@ -545,6 +546,25 @@ static int lxcControllerCleanupInterfaces(unsigned int nveths,
return 0; 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 #ifndef MS_REC
# define MS_REC 16384 # define MS_REC 16384
#endif #endif
...@@ -664,6 +684,8 @@ lxcControllerRun(virDomainDefPtr def, ...@@ -664,6 +684,8 @@ lxcControllerRun(virDomainDefPtr def,
} }
} }
if (lxcSetPersonality(def) < 0)
goto cleanup;
if ((container = lxcContainerStart(def, if ((container = lxcContainerStart(def,
nveths, nveths,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册