* Don't delete active lock files.
This commit is contained in:
parent
1328aa3307
commit
33c5d23b81
|
@ -194,9 +194,35 @@ void collectGarbage(const PathSet & roots, GCAction action,
|
|||
debug(format("dead path `%1%'") % path);
|
||||
result.insert(path);
|
||||
|
||||
AutoCloseFD fdLock;
|
||||
|
||||
if (action == gcDeleteDead) {
|
||||
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);
|
||||
|
||||
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
|
||||
|
|
|
@ -16,7 +16,9 @@ void collectGarbage(const PathSet & roots, GCAction action,
|
|||
PathSet & result);
|
||||
|
||||
/* 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);
|
||||
|
||||
|
||||
|
|
|
@ -127,9 +127,8 @@ PathLocks::~PathLocks()
|
|||
/* Write a (meaningless) token to the file to indicate to
|
||||
other processes waiting on this lock that the lock is
|
||||
stale (deleted). */
|
||||
if (write(i->first, "d", 1) == 1) {
|
||||
unlink(i->second.c_str());
|
||||
}
|
||||
writeFull(i->first, (const unsigned char *) "d", 1);
|
||||
/* Note that the result of unlink() is ignored; removing
|
||||
the lock file is an optimisation, not a necessity. */
|
||||
}
|
||||
|
|
|
@ -36,10 +36,10 @@ nix-pull.sh: dependencies.nix
|
|||
gc.sh: dependencies.nix
|
||||
gc-concurrent.sh: gc-concurrent.nix
|
||||
|
||||
#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 \
|
||||
# gc-concurrent.sh verify.sh nix-pull.sh
|
||||
TESTS = init.sh gc-concurrent.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 \
|
||||
gc-concurrent.sh verify.sh nix-pull.sh
|
||||
#TESTS = init.sh gc-concurrent.sh
|
||||
|
||||
XFAIL_TESTS =
|
||||
|
||||
|
|
|
@ -6,4 +6,7 @@ echo $(cat $input1/foo)$(cat $input2/bar) > $out/foobar
|
|||
sleep 5
|
||||
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
|
Loading…
Reference in a new issue