summary refs log tree commit diff
path: root/src/libstore
diff options
context:
space:
mode:
Diffstat (limited to 'src/libstore')
-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
6 files changed, 32 insertions, 6 deletions
diff --git a/src/libstore/gc.cc b/src/libstore/gc.cc
index 56e64369a7..ba59083cad 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 389be33a37..251f8922fa 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 da63765cdc..8dd87d046c 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 ad29305db7..4b69830456 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 67d230ca77..795488d17f 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 8b1d4e15db..ff47fdd67c 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;