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
This commit is contained in:
parent
35416720c2
commit
4f2094a8a6
@ -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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
#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,
|
|||||||
|
|
||||||
int lxcContainerAvailable(int features);
|
int lxcContainerAvailable(int features);
|
||||||
|
|
||||||
|
const char *lxcContainerGetAlt32bitArch(const char *arch);
|
||||||
|
|
||||||
#endif /* LXC_CONTAINER_H */
|
#endif /* LXC_CONTAINER_H */
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* 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 @@
|
|||||||
#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,
|
|||||||
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,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (lxcSetPersonality(def) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
if ((container = lxcContainerStart(def,
|
if ((container = lxcContainerStart(def,
|
||||||
nveths,
|
nveths,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user