* Don't delete active lock files.

This commit is contained in:
Eelco Dolstra 2005-01-31 12:19:53 +00:00
parent 1328aa3307
commit 33c5d23b81
5 changed files with 39 additions and 9 deletions

View file

@ -194,9 +194,35 @@ void collectGarbage(const PathSet & roots, GCAction action,
debug(format("dead path `%1%'") % path); debug(format("dead path `%1%'") % path);
result.insert(path); result.insert(path);
AutoCloseFD fdLock;
if (action == gcDeleteDead) { if (action == gcDeleteDead) {
printMsg(lvlInfo, format("deleting `%1%'") % path); printMsg(lvlInfo, format("deleting `%1%'") % path);
/* Only delete a lock file if we can acquire a write lock
on it. That means that it's either stale, or the
process that created it hasn't locked it yet. In the
latter case the other process will detect that we
deleted the lock, and retry (see pathlocks.cc). */
if (path.size() >= 5 && string(path, path.size() - 5) == ".lock") {
fdLock = open(path.c_str(), O_RDWR);
if (fdLock == -1) {
if (errno == ENOENT) continue;
throw SysError(format("opening lock file `%1%'") % path);
}
if (!lockFile(fdLock, ltWrite, false)) {
debug(format("skipping active lock `%1%'") % path);
continue;
}
}
deleteFromStore(path); deleteFromStore(path);
if (fdLock != -1)
/* Write token to stale (deleted) lock file. */
writeFull(fdLock, (const unsigned char *) "d", 1);
} }
/* Only delete lock files if the path is belongs to doesn't /* Only delete lock files if the path is belongs to doesn't

View file

@ -16,7 +16,9 @@ void collectGarbage(const PathSet & roots, GCAction action,
PathSet & result); PathSet & result);
/* Register a temporary GC root. This root will automatically /* Register a temporary GC root. This root will automatically
disappear when this process exits. */ disappear when this process exits. WARNING: this function should
not be called inside a BDB transaction, otherwise we can
deadlock. */
void addTempRoot(const Path & path); void addTempRoot(const Path & path);

View file

@ -127,9 +127,8 @@ PathLocks::~PathLocks()
/* Write a (meaningless) token to the file to indicate to /* Write a (meaningless) token to the file to indicate to
other processes waiting on this lock that the lock is other processes waiting on this lock that the lock is
stale (deleted). */ stale (deleted). */
if (write(i->first, "d", 1) == 1) {
unlink(i->second.c_str()); unlink(i->second.c_str());
} writeFull(i->first, (const unsigned char *) "d", 1);
/* Note that the result of unlink() is ignored; removing /* Note that the result of unlink() is ignored; removing
the lock file is an optimisation, not a necessity. */ the lock file is an optimisation, not a necessity. */
} }

View file

@ -36,10 +36,10 @@ nix-pull.sh: dependencies.nix
gc.sh: dependencies.nix gc.sh: dependencies.nix
gc-concurrent.sh: gc-concurrent.nix gc-concurrent.sh: gc-concurrent.nix
#TESTS = init.sh hash.sh lang.sh simple.sh dependencies.sh locking.sh parallel.sh \ TESTS = init.sh hash.sh lang.sh simple.sh dependencies.sh locking.sh parallel.sh \
# build-hook.sh substitutes.sh substitutes2.sh fallback.sh nix-push.sh gc.sh \ build-hook.sh substitutes.sh substitutes2.sh fallback.sh nix-push.sh gc.sh \
# gc-concurrent.sh verify.sh nix-pull.sh gc-concurrent.sh verify.sh nix-pull.sh
TESTS = init.sh gc-concurrent.sh #TESTS = init.sh gc-concurrent.sh
XFAIL_TESTS = XFAIL_TESTS =

View file

@ -6,4 +6,7 @@ echo $(cat $input1/foo)$(cat $input2/bar) > $out/foobar
sleep 5 sleep 5
mkdir $out || true mkdir $out || true
# Check that the GC hasn't deleted the lock on our output.
test -e "$out.lock"
ln -s $input2 $out/input-2 ln -s $input2 $out/input-2