* 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...
This commit is contained in:
parent
0d40f6d7bb
commit
74033a844f
7 changed files with 42 additions and 6 deletions
|
@ -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 {
|
||||
|
|
|
@ -61,6 +61,8 @@ public:
|
|||
|
||||
void addTempRoot(const Path & path);
|
||||
|
||||
void addIndirectRoot(const Path & path);
|
||||
|
||||
void syncWithGC();
|
||||
};
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -49,6 +49,8 @@ public:
|
|||
|
||||
void addTempRoot(const Path & path);
|
||||
|
||||
void addIndirectRoot(const Path & path);
|
||||
|
||||
void syncWithGC();
|
||||
|
||||
private:
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -19,7 +19,8 @@ typedef enum {
|
|||
wopBuildDerivations,
|
||||
wopEnsurePath,
|
||||
wopAddTempRoot,
|
||||
wopSyncWithGC
|
||||
wopAddIndirectRoot,
|
||||
wopSyncWithGC,
|
||||
} WorkerOp;
|
||||
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue