about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEelco Dolstra <eelco.dolstra@logicblox.com>2012-12-29T22·04+0100
committerEelco Dolstra <eelco.dolstra@logicblox.com>2012-12-29T22·04+0100
commitb7629778efcfeb9ea876616feb869457cd2bf071 (patch)
tree665d5232ede4907a11e2a6cb2a2f5e548af216b6
parent68dcbb187e540034e85b5b77d1b37cec1759a587 (diff)
Allow mounting a path in a different location in the chroot
Fixes #24.
-rw-r--r--doc/manual/conf-file.xml65
-rw-r--r--src/libstore/build.cc21
-rw-r--r--src/libstore/globals.cc2
-rw-r--r--src/libstore/globals.hh4
4 files changed, 46 insertions, 46 deletions
diff --git a/doc/manual/conf-file.xml b/doc/manual/conf-file.xml
index 70437686d8bd..588e15216491 100644
--- a/doc/manual/conf-file.xml
+++ b/doc/manual/conf-file.xml
@@ -33,18 +33,18 @@ env-keep-derivations = false
 <para>You can override settings using the <option>--option</option>
 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>
 
-  
+
   <varlistentry xml:id="conf-gc-keep-outputs"><term><literal>gc-keep-outputs</literal></term>
 
     <listitem><para>If <literal>true</literal>, the garbage collector
     will keep the outputs of non-garbage derivations.  If
     <literal>false</literal> (default), outputs will be deleted unless
     they are GC roots themselves (or reachable from other roots).</para>
- 
+
     <para>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. <literal>--option gc-keep-outputs false</literal>.</para>
     this option to <literal>true</literal>.</para></listitem>
 
   </varlistentry>
-  
+
 
   <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><term><literal>env-keep-derivations</literal></term>
 
     <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 xml:id="conf-build-max-jobs"><term><literal>build-max-jobs</literal></term>
 
     <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 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>
 
     <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><term><literal>build-fallback</literal></term>
 
     <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 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>
 
     <listitem><para>If set to <literal>true</literal>, Nix will
@@ -417,7 +410,7 @@ build-use-chroot = /dev /proc /bin</programlisting>
 
   </varlistentry>
 
-  
+
   <varlistentry><term><literal>auto-optimise-store</literal></term>
 
     <listitem><para>If set to <literal>true</literal> (the default),
diff --git a/src/libstore/build.cc b/src/libstore/build.cc
index 08dfbd2840e6..c1cbf362a0c5 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<Path, Path> DirsInChroot; // maps target path to source path
+    DirsInChroot dirsInChroot;
     typedef map<string, string> 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 bb453a45199e..596d4774ca4d 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 953eed9c36a2..be287698c6c8 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<class N> void get(N & res, const string & name);
 };