From 74033a844fe57e3e91c71ae37f9a65f6b2f22aa9 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 4 Dec 2006 23:29:16 +0000 Subject: * Add indirect root registration to the protocol so that unprivileged processes can register indirect roots. Of course, there is still the problem that the garbage collector can only read the targets of the indirect roots when it's running as root... --- src/libstore/gc.cc | 15 ++++++++++----- src/libstore/local-store.hh | 2 ++ src/libstore/remote-store.cc | 9 +++++++++ src/libstore/remote-store.hh | 2 ++ src/libstore/store-api.hh | 7 +++++++ src/libstore/worker-protocol.hh | 3 ++- src/nix-worker/main.cc | 10 ++++++++++ 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/. `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(); } -- cgit 1.4.1