* 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.
This commit is contained in:
Eelco Dolstra 2006-09-14 22:30:33 +00:00
parent f00bc4c94c
commit 5c38c863bd
3 changed files with 26 additions and 22 deletions

View file

@ -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;
/* 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);
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++;
}
return outLink;
return generation;
}