* Detect whether chroot / bind-mount support is available.

This commit is contained in:
Eelco Dolstra 2007-10-27 16:51:55 +00:00
parent dc6f373842
commit d91cd30563
2 changed files with 26 additions and 4 deletions

View file

@ -99,6 +99,11 @@ static char buf[1024];]],
AC_LANG_POP(C++) AC_LANG_POP(C++)
# Check for chroot support (requires chroot() and bind mounts).
AC_CHECK_FUNCS([chroot])
AC_CHECK_HEADERS([sys/mount.h])
# Check for <locale> # Check for <locale>
AC_LANG_PUSH(C++) AC_LANG_PUSH(C++)
AC_CHECK_HEADERS([locale]) AC_CHECK_HEADERS([locale])

View file

@ -24,6 +24,15 @@
#include <pwd.h> #include <pwd.h>
#include <grp.h> #include <grp.h>
#include "config.h"
#if HAVE_SYS_MOUNT_H
#include <sys/mount.h>
#endif
#define CHROOT_ENABLED HAVE_CHROOT && HAVE_SYS_MOUNT_H && defined(MS_BIND)
namespace nix { namespace nix {
@ -583,9 +592,6 @@ void deletePathWrapped(const Path & path)
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
#include <sys/mount.h>
/* Helper RAII class for automatically unmounting bind-mounts in /* Helper RAII class for automatically unmounting bind-mounts in
chroots. */ chroots. */
struct BindMount struct BindMount
@ -613,6 +619,7 @@ struct BindMount
void bind(const Path & source, const Path & target) void bind(const Path & source, const Path & target)
{ {
#if CHROOT_ENABLED
debug(format("bind mounting `%1%' to `%2%'") % source % target); debug(format("bind mounting `%1%' to `%2%'") % source % target);
this->source = source; this->source = source;
@ -622,10 +629,12 @@ struct BindMount
if (mount(source.c_str(), target.c_str(), "", MS_BIND, 0) == -1) if (mount(source.c_str(), target.c_str(), "", MS_BIND, 0) == -1)
throw SysError(format("bind mount from `%1%' to `%2%' failed") % source % target); throw SysError(format("bind mount from `%1%' to `%2%' failed") % source % target);
#endif
} }
void unbind() void unbind()
{ {
#if CHROOT_ENABLED
if (source == "") return; if (source == "") return;
debug(format("unmount bind-mount `%1%'") % target); debug(format("unmount bind-mount `%1%'") % target);
@ -658,6 +667,7 @@ struct BindMount
} }
source = ""; source = "";
#endif
} }
}; };
@ -1644,8 +1654,9 @@ void DerivationGoal::startBuilder()
/* Are we doing a chroot build? */ /* Are we doing a chroot build? */
useChroot = queryBoolSetting("build-use-chroot", false); useChroot = queryBoolSetting("build-use-chroot", false);
Path tmpRootDir; Path tmpRootDir;
if (useChroot) { if (useChroot) {
#if CHROOT_ENABLED
/* Create a temporary directory in which we set up the chroot /* Create a temporary directory in which we set up the chroot
environment using bind-mounts. environment using bind-mounts.
@ -1683,6 +1694,10 @@ void DerivationGoal::startBuilder()
guarantee that list elements are destroyed in order?) */ guarantee that list elements are destroyed in order?) */
for (Paths::iterator i = dirsInChroot.begin(); i != dirsInChroot.end(); ++i) for (Paths::iterator i = dirsInChroot.begin(); i != dirsInChroot.end(); ++i)
bindMounts.push_front(boost::shared_ptr<BindMount>(new BindMount(*i, tmpRootDir + *i))); bindMounts.push_front(boost::shared_ptr<BindMount>(new BindMount(*i, tmpRootDir + *i)));
#else
throw Error("chroot builds are not supported on this platform");
#endif
} }
@ -1710,6 +1725,7 @@ void DerivationGoal::startBuilder()
try { /* child */ try { /* child */
#if CHROOT_ENABLED
/* If building in a chroot, do the chroot right away. /* If building in a chroot, do the chroot right away.
initChild() will do a chdir() to the temporary build initChild() will do a chdir() to the temporary build
directory to make sure the current directory is in the directory to make sure the current directory is in the
@ -1718,6 +1734,7 @@ void DerivationGoal::startBuilder()
same directories.) */ same directories.) */
if (useChroot && chroot(tmpRootDir.c_str()) == -1) if (useChroot && chroot(tmpRootDir.c_str()) == -1)
throw SysError(format("cannot change root directory to `%1%'") % tmpRootDir); throw SysError(format("cannot change root directory to `%1%'") % tmpRootDir);
#endif
initChild(); initChild();