aboutsummaryrefslogtreecommitdiff
path: root/src/nix-env/profiles.cc
diff options
context:
space:
mode:
authorEelco Dolstra <e.dolstra@tudelft.nl>2006-09-14 22:30:33 +0000
committerEelco Dolstra <e.dolstra@tudelft.nl>2006-09-14 22:30:33 +0000
commit5c38c863bdb6904f28a929b97e91d283e29aea70 (patch)
tree1a969c9afe7a55077e22002ff8bd8aee9e52fbb6 /src/nix-env/profiles.cc
parentf00bc4c94ca4122d432ae516f8d1d7b405d5d05e (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/nix-env/profiles.cc')
-rw-r--r--src/nix-env/profiles.cc23
1 files changed, 11 insertions, 12 deletions
diff --git a/src/nix-env/profiles.cc b/src/nix-env/profiles.cc
index 0db5bda5e..b99024d07 100644
--- a/src/nix-env/profiles.cc
+++ b/src/nix-env/profiles.cc
@@ -1,5 +1,6 @@
#include "profiles.hh"
#include "util.hh"
+#include "gc.hh"
#include <sys/types.h>
#include <sys/stat.h>
@@ -82,19 +83,17 @@ Path createGeneration(Path profile, Path outPath)
Generations gens = findGenerations(profile, dummy);
unsigned int num = gens.size() > 0 ? gens.front().number : 0;
- /* Create the new generation. */
- Path outLink;
-
- while (1) {
- makeName(profile, num, outLink);
- if (symlink(outPath.c_str(), outLink.c_str()) == 0) break;
- if (errno != EEXIST)
- throw SysError(format("creating symlink `%1%'") % outLink);
- /* Somebody beat us to it, retry with a higher number. */
- num++;
- }
+ /* Create the new generation. Note that addPermRoot() blocks if
+ the garbage collector is running to prevent the stuff we've
+ build from moving from the temporary roots (which the GC knows)
+ to the permanent roots (of which the GC would have a stale
+ view). If we didn't do it this way, the GC might remove the
+ user environment etc. we've just built. */
+ Path generation;
+ makeName(profile, num + 1, generation);
+ addPermRoot(outPath, generation, false, true);
- return outLink;
+ return generation;
}