about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/libstore/gc.cc15
-rw-r--r--src/libstore/local-store.hh2
-rw-r--r--src/libstore/remote-store.cc9
-rw-r--r--src/libstore/remote-store.hh2
-rw-r--r--src/libstore/store-api.hh7
-rw-r--r--src/libstore/worker-protocol.hh3
-rw-r--r--src/nix-worker/main.cc10
7 files changed, 42 insertions, 6 deletions
diff --git a/src/libstore/gc.cc b/src/libstore/gc.cc
index 56e64369a741..ba59083cad74 100644
--- a/src/libstore/gc.cc
+++ b/src/libstore/gc.cc
@@ -82,6 +82,15 @@ void LocalStore::syncWithGC()
 }
 
 
+void LocalStore::addIndirectRoot(const Path & path)
+{
+    string hash = printHash32(hashString(htSHA1, path));
+    Path realRoot = canonPath((format("%1%/%2%/auto/%3%")
+        % nixStateDir % gcRootsDir % hash).str());
+    createSymlink(realRoot, path, false);
+}
+
+
 Path addPermRoot(const Path & _storePath, const Path & _gcRoot,
     bool indirect, bool allowOutsideRootsDir)
 {
@@ -90,12 +99,8 @@ Path addPermRoot(const Path & _storePath, const Path & _gcRoot,
     assertStorePath(storePath);
 
     if (indirect) {
-        string hash = printHash32(hashString(htSHA1, gcRoot));
-        Path realRoot = canonPath((format("%1%/%2%/auto/%3%")
-            % nixStateDir % gcRootsDir % hash).str());
-        
         createSymlink(gcRoot, storePath, true);
-        createSymlink(realRoot, gcRoot, false);
+        store->addIndirectRoot(gcRoot);
     }
 
     else {
diff --git a/src/libstore/local-store.hh b/src/libstore/local-store.hh
index 389be33a37db..251f8922fa45 100644
--- a/src/libstore/local-store.hh
+++ b/src/libstore/local-store.hh
@@ -61,6 +61,8 @@ public:
 
     void addTempRoot(const Path & path);
 
+    void addIndirectRoot(const Path & path);
+    
     void syncWithGC();
 };
 
diff --git a/src/libstore/remote-store.cc b/src/libstore/remote-store.cc
index da63765cdcf7..8dd87d046c2f 100644
--- a/src/libstore/remote-store.cc
+++ b/src/libstore/remote-store.cc
@@ -253,6 +253,15 @@ void RemoteStore::addTempRoot(const Path & path)
 }
 
 
+void RemoteStore::addIndirectRoot(const Path & path)
+{
+    writeInt(wopAddIndirectRoot, to);
+    writeString(path, to);
+    processStderr();
+    readInt(from);
+}
+
+
 void RemoteStore::syncWithGC()
 {
     writeInt(wopSyncWithGC, to);
diff --git a/src/libstore/remote-store.hh b/src/libstore/remote-store.hh
index ad29305db76b..4b698304562c 100644
--- a/src/libstore/remote-store.hh
+++ b/src/libstore/remote-store.hh
@@ -49,6 +49,8 @@ public:
 
     void addTempRoot(const Path & path);
 
+    void addIndirectRoot(const Path & path);
+    
     void syncWithGC();
     
 private:
diff --git a/src/libstore/store-api.hh b/src/libstore/store-api.hh
index 67d230ca7725..795488d17f2c 100644
--- a/src/libstore/store-api.hh
+++ b/src/libstore/store-api.hh
@@ -91,6 +91,13 @@ public:
        The root disappears as soon as we exit. */
     virtual void addTempRoot(const Path & path) = 0;
 
+    /* Add an indirect root, which is merely a symlink to `path' from
+       /nix/var/nix/gcroots/auto/<hash of `path'>.  `path' is supposed
+       to be a symlink to a store path.  The garbage collector will
+       automatically remove the indirect root when it finds that
+       `path' has disappeared. */
+    virtual void addIndirectRoot(const Path & path) = 0;
+
     /* Acquire the global GC lock, then immediately release it.  This
        function must be called after registering a new permanent root,
        but before exiting.  Otherwise, it is possible that a running
diff --git a/src/libstore/worker-protocol.hh b/src/libstore/worker-protocol.hh
index 8b1d4e15dbdc..ff47fdd67c1a 100644
--- a/src/libstore/worker-protocol.hh
+++ b/src/libstore/worker-protocol.hh
@@ -19,7 +19,8 @@ typedef enum {
     wopBuildDerivations,
     wopEnsurePath,
     wopAddTempRoot,
-    wopSyncWithGC
+    wopAddIndirectRoot,
+    wopSyncWithGC,
 } WorkerOp;
 
 
diff --git a/src/nix-worker/main.cc b/src/nix-worker/main.cc
index c8abe14299cd..80db782e90ba 100644
--- a/src/nix-worker/main.cc
+++ b/src/nix-worker/main.cc
@@ -269,6 +269,15 @@ static void performOp(Source & from, Sink & to, unsigned int op)
         break;
     }
 
+    case wopAddIndirectRoot: {
+        Path path = absPath(readString(from));
+        startWork();
+        store->addIndirectRoot(path);
+        stopWork();
+        writeInt(1, to);
+        break;
+    }
+
     case wopSyncWithGC: {
         startWork();
         store->syncWithGC();
@@ -473,6 +482,7 @@ void run(Strings args)
     else if (daemon) {
         if (setuidMode)
             throw Error("daemon cannot be started in setuid mode");
+        chdir("/");
         daemonLoop();
     }