* Don't delete active lock files.
This commit is contained in:
		
							parent
							
								
									1328aa3307
								
							
						
					
					
						commit
						33c5d23b81
					
				
					 5 changed files with 39 additions and 9 deletions
				
			
		|  | @ -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()); | ||||
|             } | ||||
|             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…
	
	Add table
		Add a link
		
	
		Reference in a new issue