about summary refs log tree commit diff
path: root/src/libstore
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 /src/libstore
parent68dcbb187e540034e85b5b77d1b37cec1759a587 (diff)
Allow mounting a path in a different location in the chroot
Fixes #24.
Diffstat (limited to 'src/libstore')
-rw-r--r--src/libstore/build.cc21
-rw-r--r--src/libstore/globals.cc2
-rw-r--r--src/libstore/globals.hh4
3 files changed, 17 insertions, 10 deletions
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);
 };