diff options
author | Eelco Dolstra <e.dolstra@tudelft.nl> | 2006-09-14T22·30+0000 |
---|---|---|
committer | Eelco Dolstra <e.dolstra@tudelft.nl> | 2006-09-14T22·30+0000 |
commit | 5c38c863bdb6904f28a929b97e91d283e29aea70 (patch) | |
tree | 1a969c9afe7a55077e22002ff8bd8aee9e52fbb6 /src/libstore | |
parent | f00bc4c94ca4122d432ae516f8d1d7b405d5d05e (diff) |
* Fix a huge gaping hole in nix-env w.r.t. the garbage collector.
Nix-env failed to call addPermRoot(), which is necessary to safely add a new root. So if nix-env started after and finished before the garbage collector, the user environment (plus all other new stuff) it built might be garbage collected, leading to a dangling symlink chain in ~/.nix-profile... * Be more explicit if we block on the GC lock ("waiting for the big garbage collector lock..."). * Don't loop trying to create a new generation. It's not necessary anymore since profiles are locked nowadays.
Diffstat (limited to 'src/libstore')
-rw-r--r-- | src/libstore/gc.cc | 23 | ||||
-rw-r--r-- | src/libstore/gc.hh | 2 |
2 files changed, 15 insertions, 10 deletions
diff --git a/src/libstore/gc.cc b/src/libstore/gc.cc index 59e71daa0b46..ed1b1a84a44c 100644 --- a/src/libstore/gc.cc +++ b/src/libstore/gc.cc @@ -44,7 +44,10 @@ static int openGCLock(LockType lockType) if (fdGCLock == -1) throw SysError(format("opening global GC lock `%1%'") % fnGCLock); - lockFile(fdGCLock, lockType, true); + if (!lockFile(fdGCLock, lockType, false)) { + printMsg(lvlError, format("waiting for the big garbage collector lock...")); + lockFile(fdGCLock, lockType, true); + } /* !!! Restrict read permission on the GC root. Otherwise any process that can open the file for reading can DoS the @@ -74,7 +77,7 @@ void createSymlink(const Path & link, const Path & target, bool careful) Path addPermRoot(const Path & _storePath, const Path & _gcRoot, - bool indirect) + bool indirect, bool allowOutsideRootsDir) { Path storePath(canonPath(_storePath)); Path gcRoot(canonPath(_gcRoot)); @@ -97,14 +100,16 @@ Path addPermRoot(const Path & _storePath, const Path & _gcRoot, } else { - Path rootsDir = canonPath((format("%1%/%2%") % nixStateDir % gcRootsDir).str()); + if (!allowOutsideRootsDir) { + Path rootsDir = canonPath((format("%1%/%2%") % nixStateDir % gcRootsDir).str()); - if (string(gcRoot, 0, rootsDir.size() + 1) != rootsDir + "/") - throw Error(format( - "path `%1%' is not a valid garbage collector root; " - "it's not in the directory `%2%'") - % gcRoot % rootsDir); - + if (string(gcRoot, 0, rootsDir.size() + 1) != rootsDir + "/") + throw Error(format( + "path `%1%' is not a valid garbage collector root; " + "it's not in the directory `%2%'") + % gcRoot % rootsDir); + } + createSymlink(gcRoot, storePath, false); } diff --git a/src/libstore/gc.hh b/src/libstore/gc.hh index 54fc4dec4beb..3f7242884b59 100644 --- a/src/libstore/gc.hh +++ b/src/libstore/gc.hh @@ -39,7 +39,7 @@ void removeTempRoots(); /* Register a permanent GC root. */ Path addPermRoot(const Path & storePath, const Path & gcRoot, - bool indirect); + bool indirect, bool allowOutsideRootsDir = false); } |