about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/libstore/local-store.hh4
-rw-r--r--src/nix/run.cc22
2 files changed, 25 insertions, 1 deletions
diff --git a/src/libstore/local-store.hh b/src/libstore/local-store.hh
index 3a2568ec9479..0c2766f667ec 100644
--- a/src/libstore/local-store.hh
+++ b/src/libstore/local-store.hh
@@ -73,6 +73,8 @@ private:
 
     Sync<State, std::recursive_mutex> _state;
 
+public:
+
     const Path realStoreDir;
     const Path dbDir;
     const Path linksDir;
@@ -80,6 +82,8 @@ private:
     const Path schemaPath;
     const Path trashDir;
 
+private:
+
     bool requireSigs;
 
     PublicKeys publicKeys;
diff --git a/src/nix/run.cc b/src/nix/run.cc
index ba1efb63b472..ed1c2650cb3f 100644
--- a/src/nix/run.cc
+++ b/src/nix/run.cc
@@ -4,6 +4,11 @@
 #include "shared.hh"
 #include "store-api.hh"
 #include "derivations.hh"
+#include "local-store.hh"
+
+#if __linux__
+#include <sys/mount.h>
+#endif
 
 using namespace nix;
 
@@ -40,6 +45,20 @@ struct CmdRun : StoreCommand, MixInstallables
 
         store->buildPaths(pathsToBuild);
 
+        auto store2 = store.dynamic_pointer_cast<LocalStore>();
+
+        if (store2 && store->storeDir != store2->realStoreDir) {
+#if __linux__
+            if (unshare(CLONE_NEWUSER | CLONE_NEWNS) == -1)
+                throw SysError("setting up a private mount namespace");
+
+            if (mount(store2->realStoreDir.c_str(), store->storeDir.c_str(), "", MS_BIND, 0) == -1)
+                throw SysError(format("mounting ‘%s’ on ‘%s’") % store2->realStoreDir % store->storeDir);
+#else
+            throw Error(format("mounting the Nix store on ‘%s’ is not supported on this platform") % store->storeDir);
+#endif
+        }
+
         PathSet outPaths;
         for (auto & path : pathsToBuild)
             if (isDerivation(path)) {
@@ -55,7 +74,8 @@ struct CmdRun : StoreCommand, MixInstallables
                 unixPath.push_front(path + "/bin");
         setenv("PATH", concatStringsSep(":", unixPath).c_str(), 1);
 
-        execlp("bash", "bash", nullptr);
+        if (execlp("bash", "bash", nullptr) == -1)
+            throw SysError("unable to exec ‘bash’");
     }
 };