Allow mounting a path in a different location in the chroot

Fixes #24.
This commit is contained in:
Eelco Dolstra 2012-12-29 23:04:02 +01:00
parent 68dcbb187e
commit b7629778ef
4 changed files with 46 additions and 46 deletions

View file

@ -33,18 +33,18 @@ env-keep-derivations = false
<para>You can override settings using the <option>--option</option> <para>You can override settings using the <option>--option</option>
flag, e.g. <literal>--option gc-keep-outputs false</literal>.</para> flag, e.g. <literal>--option gc-keep-outputs false</literal>.</para>
<para>The following settings are currently available: <para>The following settings are currently available:
<variablelist> <variablelist>
<varlistentry xml:id="conf-gc-keep-outputs"><term><literal>gc-keep-outputs</literal></term> <varlistentry xml:id="conf-gc-keep-outputs"><term><literal>gc-keep-outputs</literal></term>
<listitem><para>If <literal>true</literal>, the garbage collector <listitem><para>If <literal>true</literal>, the garbage collector
will keep the outputs of non-garbage derivations. If will keep the outputs of non-garbage derivations. If
<literal>false</literal> (default), outputs will be deleted unless <literal>false</literal> (default), outputs will be deleted unless
they are GC roots themselves (or reachable from other roots).</para> they are GC roots themselves (or reachable from other roots).</para>
<para>In general, outputs must be registered as roots separately. <para>In general, outputs must be registered as roots separately.
However, even if the output of a derivation is registered as a However, even if the output of a derivation is registered as a
root, the collector will still delete store paths that are used root, the collector will still delete store paths that are used
@ -53,7 +53,7 @@ flag, e.g. <literal>--option gc-keep-outputs false</literal>.</para>
this option to <literal>true</literal>.</para></listitem> this option to <literal>true</literal>.</para></listitem>
</varlistentry> </varlistentry>
<varlistentry xml:id="conf-gc-keep-derivations"><term><literal>gc-keep-derivations</literal></term> <varlistentry xml:id="conf-gc-keep-derivations"><term><literal>gc-keep-derivations</literal></term>
@ -71,7 +71,7 @@ flag, e.g. <literal>--option gc-keep-outputs false</literal>.</para>
</varlistentry> </varlistentry>
<varlistentry><term><literal>env-keep-derivations</literal></term> <varlistentry><term><literal>env-keep-derivations</literal></term>
<listitem><para>If <literal>false</literal> (default), derivations <listitem><para>If <literal>false</literal> (default), derivations
@ -95,7 +95,7 @@ flag, e.g. <literal>--option gc-keep-outputs false</literal>.</para>
</varlistentry> </varlistentry>
<varlistentry xml:id="conf-build-max-jobs"><term><literal>build-max-jobs</literal></term> <varlistentry xml:id="conf-build-max-jobs"><term><literal>build-max-jobs</literal></term>
<listitem><para>This option defines the maximum number of jobs <listitem><para>This option defines the maximum number of jobs
@ -234,7 +234,27 @@ flag, e.g. <literal>--option gc-keep-outputs false</literal>.</para>
</varlistentry> </varlistentry>
<varlistentry xml:id="conf-build-chroot-dirs"><term><literal>build-chroot-dirs</literal></term>
<listitem><para>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
<filename>/tmp/nix-build-<replaceable>drvname</replaceable>-<replaceable>number</replaceable></filename>),
the <literal>/proc</literal> filesystem, and the directories
listed here. The default is <literal>/dev /dev/pts</literal>,
since these contain files needed by many builds (such as
<filename>/dev/null</filename>). You can use the syntax
<literal><replaceable>target</replaceable>=<replaceable>source</replaceable></literal>
to mount a path in a different location in the chroot; for
instance, <literal>/bin=/nix-bin</literal> will mount the
directory <literal>/nix-bin</literal> as <literal>/bin</literal>
inside the chroot.</para></listitem>
</varlistentry>
<varlistentry><term><literal>build-use-substitutes</literal></term> <varlistentry><term><literal>build-use-substitutes</literal></term>
<listitem><para>If set to <literal>true</literal> (default), Nix <listitem><para>If set to <literal>true</literal> (default), Nix
@ -243,7 +263,7 @@ flag, e.g. <literal>--option gc-keep-outputs false</literal>.</para>
</varlistentry> </varlistentry>
<varlistentry><term><literal>build-fallback</literal></term> <varlistentry><term><literal>build-fallback</literal></term>
<listitem><para>If set to <literal>true</literal>, Nix will fall <listitem><para>If set to <literal>true</literal>, Nix will fall
@ -253,34 +273,7 @@ flag, e.g. <literal>--option gc-keep-outputs false</literal>.</para>
</varlistentry> </varlistentry>
<varlistentry xml:id="conf-build-chroot-dirs"><term><literal>build-chroot-dirs</literal></term>
<listitem><para>When builds are performed in a chroot environment,
Nix will mount (using <command>mount --bind</command> on Linux)
some directories from the normal file system hierarchy inside the
chroot. These are the Nix store, the temporary build directory
(usually
<filename>/tmp/nix-<replaceable>pid</replaceable>-<replaceable>number</replaceable></filename>)
and the directories listed here. The default is <literal>dev
/proc</literal>. Files in <filename>/dev</filename> (such as
<filename>/dev/null</filename>) are needed by many builds, and
some files in <filename>/proc</filename> may also be needed
occasionally.</para>
<para>The value used on NixOS is
<programlisting>
build-use-chroot = /dev /proc /bin</programlisting>
to make the <filename>/bin/sh</filename> symlink available (which
is still needed by many builders).</para>
</listitem>
</varlistentry>
<varlistentry><term><literal>build-cache-failures</literal></term> <varlistentry><term><literal>build-cache-failures</literal></term>
<listitem><para>If set to <literal>true</literal>, Nix will <listitem><para>If set to <literal>true</literal>, Nix will
@ -417,7 +410,7 @@ build-use-chroot = /dev /proc /bin</programlisting>
</varlistentry> </varlistentry>
<varlistentry><term><literal>auto-optimise-store</literal></term> <varlistentry><term><literal>auto-optimise-store</literal></term>
<listitem><para>If set to <literal>true</literal> (the default), <listitem><para>If set to <literal>true</literal> (the default),

View file

@ -813,7 +813,8 @@ private:
GoalState state; GoalState state;
/* Stuff we need to pass to initChild(). */ /* Stuff we need to pass to initChild(). */
PathSet dirsInChroot; typedef map<Path, Path> DirsInChroot; // maps target path to source path
DirsInChroot dirsInChroot;
typedef map<string, string> Environment; typedef map<string, string> Environment;
Environment env; Environment env;
@ -1863,8 +1864,14 @@ void DerivationGoal::startBuilder()
/* Bind-mount a user-configurable set of directories from the /* Bind-mount a user-configurable set of directories from the
host file system. */ host file system. */
dirsInChroot = settings.dirsInChroot; foreach (StringSet::iterator, i, settings.dirsInChroot) {
dirsInChroot.insert(tmpDir); 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, /* Make the closure of the inputs available in the chroot,
rather than the whole Nix store. This prevents any access rather than the whole Nix store. This prevents any access
@ -1881,7 +1888,7 @@ void DerivationGoal::startBuilder()
if (lstat(i->c_str(), &st)) if (lstat(i->c_str(), &st))
throw SysError(format("getting attributes of path `%1%'") % *i); throw SysError(format("getting attributes of path `%1%'") % *i);
if (S_ISDIR(st.st_mode)) if (S_ISDIR(st.st_mode))
dirsInChroot.insert(*i); dirsInChroot[*i] = *i;
else { else {
/* Creating a hard link to *i is impossible if its /* Creating a hard link to *i is impossible if its
immutable bit is set. So clear it first. */ immutable bit is set. So clear it first. */
@ -2056,9 +2063,9 @@ void DerivationGoal::initChild()
/* Bind-mount all the directories from the "host" /* Bind-mount all the directories from the "host"
filesystem that we want in the chroot filesystem that we want in the chroot
environment. */ environment. */
foreach (PathSet::iterator, i, dirsInChroot) { foreach (DirsInChroot::iterator, i, dirsInChroot) {
Path source = *i; Path source = i->second;
Path target = chrootRootDir + source; Path target = chrootRootDir + i->first;
if (source == "/proc") continue; // backwards compatibility if (source == "/proc") continue; // backwards compatibility
debug(format("bind mounting `%1%' to `%2%'") % source % target); debug(format("bind mounting `%1%' to `%2%'") % source % target);
createDirs(target); createDirs(target);

View file

@ -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); SettingsMap::iterator i = settings.find(name);
if (i == settings.end()) return; if (i == settings.end()) return;

View file

@ -139,7 +139,7 @@ struct Settings {
/* The directories from the host filesystem to be included in the /* The directories from the host filesystem to be included in the
chroot. */ chroot. */
PathSet dirsInChroot; StringSet dirsInChroot;
/* Whether to impersonate a Linux 2.6 machine on newer kernels. */ /* Whether to impersonate a Linux 2.6 machine on newer kernels. */
bool impersonateLinux26; bool impersonateLinux26;
@ -181,7 +181,7 @@ private:
void get(string & res, const string & name); void get(string & res, const string & name);
void get(bool & 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<class N> void get(N & res, const string & name); template<class N> void get(N & res, const string & name);
}; };