From b7629778efcfeb9ea876616feb869457cd2bf071 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Sat, 29 Dec 2012 23:04:02 +0100 Subject: Allow mounting a path in a different location in the chroot Fixes #24. --- src/libstore/build.cc | 21 ++++++++++++++------- src/libstore/globals.cc | 2 +- src/libstore/globals.hh | 4 ++-- 3 files changed, 17 insertions(+), 10 deletions(-) (limited to 'src') 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 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 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 void get(N & res, const string & name); }; -- cgit 1.4.1