1
0
Fork 0
mirror of https://github.com/NixOS/nix synced 2025-07-06 21:41:48 +02:00

* nix-store, nix-instantiate: added an option `--add-root' to

immediately add the result as a permanent GC root.  This is the only
  way to prevent a race with the garbage collector.  For instance, the
  old style

    ln -s $(nix-store -r $(nix-instantiate foo.nix)) \
      /nix/var/nix/gcroots/result

  has two time windows in which the garbage collector can interfere
  (by GC'ing the derivation and the output, respectively).  On the
  other hand,

    nix-store --add-root /nix/var/nix/gcroots/result -r \
      $(nix-instantiate --add-root /nix/var/nix/gcroots/drv \
        foo.nix)

  is safe.

* nix-build: use `--add-root' to prevent GC races.
This commit is contained in:
Eelco Dolstra 2005-02-01 12:36:25 +00:00
parent a6b65fd5e1
commit dcc37c236c
11 changed files with 165 additions and 17 deletions

View file

@ -42,3 +42,5 @@ Options:
--verbose / -v: verbose operation (may be repeated)
--keep-failed / -K: keep temporary directories of failed builds
--add-root: add garbage collector roots for the result

View file

@ -1,5 +1,9 @@
#include <iostream>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include "globals.hh"
#include "build.hh"
#include "gc.hh"
@ -18,6 +22,10 @@ void printHelp()
}
static Path gcRoot;
static int rootNr = 0;
static Path findOutput(const Derivation & drv, string id)
{
for (DerivationOutputs::const_iterator i = drv.outputs.begin();
@ -27,6 +35,22 @@ static Path findOutput(const Derivation & drv, string id)
}
static Path followSymlinks(Path & path)
{
while (!isStorePath(path)) {
struct stat st;
if (lstat(path.c_str(), &st))
throw SysError(format("getting status of `%1%'") % path);
if (!S_ISLNK(st.st_mode)) return path;
string target = readLink(path);
path = canonPath(string(target, 0, 1) == "/"
? target
: path + "/" + target);
}
return path;
}
/* Realisation the given path. For a derivation that means build it;
for other paths it means ensure their validity. */
static Path realisePath(const Path & path)
@ -35,7 +59,14 @@ static Path realisePath(const Path & path)
PathSet paths;
paths.insert(path);
buildDerivations(paths);
return findOutput(derivationFromPath(path), "out");
Path outPath = findOutput(derivationFromPath(path), "out");
if (gcRoot == "")
printGCWarning();
else
outPath = addPermRoot(outPath, makeRootName(gcRoot, rootNr));
return outPath;
} else {
ensurePath(path);
return path;
@ -48,6 +79,10 @@ static void opRealise(Strings opFlags, Strings opArgs)
{
if (!opFlags.empty()) throw UsageError("unknown flag");
for (Strings::iterator i = opArgs.begin();
i != opArgs.end(); i++)
*i = followSymlinks(*i);
if (opArgs.size() > 1) {
PathSet drvPaths;
for (Strings::iterator i = opArgs.begin();
@ -374,8 +409,8 @@ void run(Strings args)
Strings opFlags, opArgs;
Operation op = 0;
for (Strings::iterator i = args.begin(); i != args.end(); ++i) {
string arg = *i;
for (Strings::iterator i = args.begin(); i != args.end(); ) {
string arg = *i++;
Operation oldOp = op;
@ -403,6 +438,11 @@ void run(Strings args)
op = opInit;
else if (arg == "--verify")
op = opVerify;
else if (arg == "--add-root") {
if (i == args.end())
throw UsageError("`--add-root requires an argument");
gcRoot = *i++;
}
else if (arg[0] == '-')
opFlags.push_back(arg);
else