From b7629778efcfeb9ea876616feb869457cd2bf071 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Sat, 29 Dec 2012 23:04:02 +0100 Subject: [PATCH] Allow mounting a path in a different location in the chroot Fixes #24. --- doc/manual/conf-file.xml | 65 ++++++++++++++++++---------------------- src/libstore/build.cc | 21 ++++++++----- src/libstore/globals.cc | 2 +- src/libstore/globals.hh | 4 +-- 4 files changed, 46 insertions(+), 46 deletions(-) diff --git a/doc/manual/conf-file.xml b/doc/manual/conf-file.xml index 70437686d8..588e152164 100644 --- a/doc/manual/conf-file.xml +++ b/doc/manual/conf-file.xml @@ -33,18 +33,18 @@ env-keep-derivations = false You can override settings using the flag, e.g. --option gc-keep-outputs false. -The following settings are currently available: +The following settings are currently available: - + gc-keep-outputs If true, the garbage collector will keep the outputs of non-garbage derivations. If false (default), outputs will be deleted unless they are GC roots themselves (or reachable from other roots). - + In general, outputs must be registered as roots separately. However, even if the output of a derivation is registered as a root, the collector will still delete store paths that are used @@ -53,7 +53,7 @@ flag, e.g. --option gc-keep-outputs false. this option to true. - + gc-keep-derivations @@ -71,7 +71,7 @@ flag, e.g. --option gc-keep-outputs false. - + env-keep-derivations If false (default), derivations @@ -95,7 +95,7 @@ flag, e.g. --option gc-keep-outputs false. - + build-max-jobs This option defines the maximum number of jobs @@ -234,7 +234,27 @@ flag, e.g. --option gc-keep-outputs false. - + + build-chroot-dirs + + When builds are performed in a chroot environment, + Nix will mount some directories from the normal file system + hierarchy inside the chroot. These are the Nix store, the + temporary build directory (usually + /tmp/nix-build-drvname-number), + the /proc filesystem, and the directories + listed here. The default is /dev /dev/pts, + since these contain files needed by many builds (such as + /dev/null). You can use the syntax + target=source + to mount a path in a different location in the chroot; for + instance, /bin=/nix-bin will mount the + directory /nix-bin as /bin + inside the chroot. + + + + build-use-substitutes If set to true (default), Nix @@ -243,7 +263,7 @@ flag, e.g. --option gc-keep-outputs false. - + build-fallback If set to true, Nix will fall @@ -253,34 +273,7 @@ flag, e.g. --option gc-keep-outputs false. - - build-chroot-dirs - When builds are performed in a chroot environment, - Nix will mount (using mount --bind on Linux) - some directories from the normal file system hierarchy inside the - chroot. These are the Nix store, the temporary build directory - (usually - /tmp/nix-pid-number) - and the directories listed here. The default is dev - /proc. Files in /dev (such as - /dev/null) are needed by many builds, and - some files in /proc may also be needed - occasionally. - - The value used on NixOS is - - -build-use-chroot = /dev /proc /bin - - to make the /bin/sh symlink available (which - is still needed by many builders). - - - - - - build-cache-failures If set to true, Nix will @@ -417,7 +410,7 @@ build-use-chroot = /dev /proc /bin - + auto-optimise-store If set to true (the default), diff --git a/src/libstore/build.cc b/src/libstore/build.cc index 08dfbd2840..c1cbf362a0 100644 --- a/src/libstore/build.cc +++ b/src/libstore/build.cc @@ -813,7 +813,8 @@ private: GoalState state; /* Stuff we need to pass to initChild(). */ - PathSet dirsInChroot; + typedef map DirsInChroot; // maps target path to source path + DirsInChroot dirsInChroot; typedef map Environment; Environment env; @@ -1863,8 +1864,14 @@ void DerivationGoal::startBuilder() /* Bind-mount a user-configurable set of directories from the host file system. */ - dirsInChroot = settings.dirsInChroot; - dirsInChroot.insert(tmpDir); + foreach (StringSet::iterator, i, settings.dirsInChroot) { + size_t p = i->find('='); + if (p == string::npos) + dirsInChroot[*i] = *i; + else + dirsInChroot[string(*i, 0, p)] = string(*i, p + 1); + } + dirsInChroot[tmpDir] = tmpDir; /* Make the closure of the inputs available in the chroot, rather than the whole Nix store. This prevents any access @@ -1881,7 +1888,7 @@ void DerivationGoal::startBuilder() if (lstat(i->c_str(), &st)) throw SysError(format("getting attributes of path `%1%'") % *i); if (S_ISDIR(st.st_mode)) - dirsInChroot.insert(*i); + dirsInChroot[*i] = *i; else { /* Creating a hard link to *i is impossible if its immutable bit is set. So clear it first. */ @@ -2056,9 +2063,9 @@ void DerivationGoal::initChild() /* Bind-mount all the directories from the "host" filesystem that we want in the chroot environment. */ - foreach (PathSet::iterator, i, dirsInChroot) { - Path source = *i; - Path target = chrootRootDir + source; + foreach (DirsInChroot::iterator, i, dirsInChroot) { + Path source = i->second; + Path target = chrootRootDir + i->first; if (source == "/proc") continue; // backwards compatibility debug(format("bind mounting `%1%' to `%2%'") % source % target); createDirs(target); diff --git a/src/libstore/globals.cc b/src/libstore/globals.cc index bb453a4519..596d4774ca 100644 --- a/src/libstore/globals.cc +++ b/src/libstore/globals.cc @@ -158,7 +158,7 @@ void Settings::get(bool & res, const string & name) } -void Settings::get(PathSet & res, const string & name) +void Settings::get(StringSet & res, const string & name) { SettingsMap::iterator i = settings.find(name); if (i == settings.end()) return; diff --git a/src/libstore/globals.hh b/src/libstore/globals.hh index 953eed9c36..be287698c6 100644 --- a/src/libstore/globals.hh +++ b/src/libstore/globals.hh @@ -139,7 +139,7 @@ struct Settings { /* The directories from the host filesystem to be included in the chroot. */ - PathSet dirsInChroot; + StringSet dirsInChroot; /* Whether to impersonate a Linux 2.6 machine on newer kernels. */ bool impersonateLinux26; @@ -181,7 +181,7 @@ private: void get(string & res, const string & name); void get(bool & res, const string & name); - void get(PathSet & res, const string & name); + void get(StringSet & res, const string & name); template void get(N & res, const string & name); };