* In `nix-env -i|-u|-e', lock the profile to prevent races between
concurrent nix-env operations on the same profile. Fixes NIX-7.
This commit is contained in:
		
							parent
							
								
									49de87132f
								
							
						
					
					
						commit
						588cb0eade
					
				
					 3 changed files with 26 additions and 6 deletions
				
			
		|  | @ -51,14 +51,14 @@ PathLocks::PathLocks() | |||
| } | ||||
| 
 | ||||
| 
 | ||||
| PathLocks::PathLocks(const PathSet & paths) | ||||
| PathLocks::PathLocks(const PathSet & paths, const string & waitMsg) | ||||
|     : deletePaths(false) | ||||
| { | ||||
|     lockPaths(paths); | ||||
|     lockPaths(paths, waitMsg); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| void PathLocks::lockPaths(const PathSet & _paths) | ||||
| void PathLocks::lockPaths(const PathSet & _paths, const string & waitMsg) | ||||
| { | ||||
|     /* May be called only once! */ | ||||
|     assert(fds.empty()); | ||||
|  | @ -94,7 +94,10 @@ void PathLocks::lockPaths(const PathSet & _paths) | |||
|                 throw SysError(format("opening lock file `%1%'") % lockPath); | ||||
| 
 | ||||
|             /* Acquire an exclusive lock. */ | ||||
|             if (!lockFile(fd, ltWrite, false)) { | ||||
|                 if (waitMsg != "") printMsg(lvlError, waitMsg); | ||||
|                 lockFile(fd, ltWrite, true); | ||||
|             } | ||||
| 
 | ||||
|             debug(format("lock acquired on `%1%'") % lockPath); | ||||
| 
 | ||||
|  |  | |||
|  | @ -18,8 +18,10 @@ private: | |||
| 
 | ||||
| public: | ||||
|     PathLocks(); | ||||
|     PathLocks(const PathSet & paths); | ||||
|     void lockPaths(const PathSet & _paths); | ||||
|     PathLocks(const PathSet & paths, | ||||
|         const string & waitMsg = ""); | ||||
|     void lockPaths(const PathSet & _paths, | ||||
|         const string & waitMsg = ""); | ||||
|     ~PathLocks(); | ||||
|     void setDeletion(bool deletePaths); | ||||
| }; | ||||
|  |  | |||
|  | @ -10,6 +10,7 @@ | |||
| #include "help.txt.hh" | ||||
| #include "nixexpr-ast.hh" | ||||
| #include "get-drvs.hh" | ||||
| #include "pathlocks.hh" | ||||
| 
 | ||||
| #include <cerrno> | ||||
| #include <ctime> | ||||
|  | @ -411,6 +412,14 @@ static void printMissing(EvalState & state, const DrvInfos & elems) | |||
| } | ||||
| 
 | ||||
| 
 | ||||
| static void lockProfile(PathLocks & lock, const Path & profile) | ||||
| { | ||||
|     lock.lockPaths(singleton<PathSet>(profile), | ||||
|         (format("waiting for lock on profile `%1%'") % profile).str()); | ||||
|     lock.setDeletion(true); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| static void installDerivations(Globals & globals, | ||||
|     const Strings & args, const Path & profile) | ||||
| { | ||||
|  | @ -426,6 +435,8 @@ static void installDerivations(Globals & globals, | |||
| 
 | ||||
|     /* Add in the already installed derivations, unless they have the
 | ||||
|        same name as a to-be-installed element. */ | ||||
|     PathLocks lock; | ||||
|     lockProfile(lock, profile); | ||||
|     DrvInfos installedElems = queryInstalled(globals.state, profile); | ||||
| 
 | ||||
|     DrvInfos allElems(newElems); | ||||
|  | @ -480,6 +491,8 @@ static void upgradeDerivations(Globals & globals, | |||
|        name and a higher version number. */ | ||||
| 
 | ||||
|     /* Load the currently installed derivations. */ | ||||
|     PathLocks lock; | ||||
|     lockProfile(lock, profile); | ||||
|     DrvInfos installedElems = queryInstalled(globals.state, profile); | ||||
| 
 | ||||
|     /* Fetch all derivations from the input file. */ | ||||
|  | @ -559,6 +572,8 @@ static void opUpgrade(Globals & globals, | |||
| static void uninstallDerivations(Globals & globals, DrvNames & selectors, | ||||
|     Path & profile) | ||||
| { | ||||
|     PathLocks lock; | ||||
|     lockProfile(lock, profile); | ||||
|     DrvInfos installedElems = queryInstalled(globals.state, profile); | ||||
|     DrvInfos newElems; | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue