Allow hard links between the outputs of a derivation
This commit is contained in:
		
							parent
							
								
									cd49ee0897
								
							
						
					
					
						commit
						1b6ee8f4c7
					
				
					 3 changed files with 20 additions and 9 deletions
				
			
		| 
						 | 
				
			
			@ -844,6 +844,11 @@ private:
 | 
			
		|||
    bool repair;
 | 
			
		||||
    map<Path, Path> redirectedBadOutputs;
 | 
			
		||||
 | 
			
		||||
    /* Set of inodes seen during calls to canonicalisePathMetaData()
 | 
			
		||||
       for this build's outputs.  This needs to be shared between
 | 
			
		||||
       outputs to allow hard links between outputs. */
 | 
			
		||||
    InodesSeen inodesSeen;
 | 
			
		||||
 | 
			
		||||
    /* Magic exit code denoting that setting up the child environment
 | 
			
		||||
       failed.  (It's possible that the child actually returns the
 | 
			
		||||
       exit code, but ah well.) */
 | 
			
		||||
| 
						 | 
				
			
			@ -1493,7 +1498,7 @@ void DerivationGoal::buildDone()
 | 
			
		|||
                /* Canonicalise first.  This ensures that the path
 | 
			
		||||
                   we're rewriting doesn't contain a hard link to
 | 
			
		||||
                   /etc/shadow or something like that. */
 | 
			
		||||
                canonicalisePathMetaData(path, buildUser.enabled() ? buildUser.getUID() : -1);
 | 
			
		||||
                canonicalisePathMetaData(path, buildUser.enabled() ? buildUser.getUID() : -1, inodesSeen);
 | 
			
		||||
 | 
			
		||||
                /* FIXME: this is in-memory. */
 | 
			
		||||
                StringSink sink;
 | 
			
		||||
| 
						 | 
				
			
			@ -2307,7 +2312,7 @@ void DerivationGoal::computeClosure()
 | 
			
		|||
        /* Get rid of all weird permissions.  This also checks that
 | 
			
		||||
           all files are owned by the build user, if applicable. */
 | 
			
		||||
        canonicalisePathMetaData(path,
 | 
			
		||||
            buildUser.enabled() && rewrittenPaths.find(path) == rewrittenPaths.end() ? buildUser.getUID() : -1);
 | 
			
		||||
            buildUser.enabled() && rewrittenPaths.find(path) == rewrittenPaths.end() ? buildUser.getUID() : -1, inodesSeen);
 | 
			
		||||
 | 
			
		||||
        /* For this output path, find the references to other paths
 | 
			
		||||
           contained in it.  Compute the SHA-256 NAR hash at the same
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -500,10 +500,6 @@ void canonicaliseTimestampAndPermissions(const Path & path)
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
typedef std::pair<dev_t, ino_t> Inode;
 | 
			
		||||
typedef set<Inode> InodesSeen;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void canonicalisePathMetaData_(const Path & path, uid_t fromUid, InodesSeen & inodesSeen)
 | 
			
		||||
{
 | 
			
		||||
    checkInterrupt();
 | 
			
		||||
| 
						 | 
				
			
			@ -561,10 +557,8 @@ static void canonicalisePathMetaData_(const Path & path, uid_t fromUid, InodesSe
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void canonicalisePathMetaData(const Path & path, uid_t fromUid)
 | 
			
		||||
void canonicalisePathMetaData(const Path & path, uid_t fromUid, InodesSeen & inodesSeen)
 | 
			
		||||
{
 | 
			
		||||
    InodesSeen inodesSeen;
 | 
			
		||||
 | 
			
		||||
    canonicalisePathMetaData_(path, fromUid, inodesSeen);
 | 
			
		||||
 | 
			
		||||
    /* On platforms that don't have lchown(), the top-level path can't
 | 
			
		||||
| 
						 | 
				
			
			@ -580,6 +574,13 @@ void canonicalisePathMetaData(const Path & path, uid_t fromUid)
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void canonicalisePathMetaData(const Path & path, uid_t fromUid)
 | 
			
		||||
{
 | 
			
		||||
    InodesSeen inodesSeen;
 | 
			
		||||
    canonicalisePathMetaData(path, fromUid, inodesSeen);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void LocalStore::checkDerivationOutputs(const Path & drvPath, const Derivation & drv)
 | 
			
		||||
{
 | 
			
		||||
    string drvName = storePathToName(drvPath);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -305,6 +305,10 @@ private:
 | 
			
		|||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
typedef std::pair<dev_t, ino_t> Inode;
 | 
			
		||||
typedef set<Inode> InodesSeen;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* "Fix", or canonicalise, the meta-data of the files in a store path
 | 
			
		||||
   after it has been built.  In particular:
 | 
			
		||||
   - the last modification date on each file is set to 1 (i.e.,
 | 
			
		||||
| 
						 | 
				
			
			@ -313,6 +317,7 @@ private:
 | 
			
		|||
     without execute permission; setuid bits etc. are cleared)
 | 
			
		||||
   - the owner and group are set to the Nix user and group, if we're
 | 
			
		||||
     in a setuid Nix installation. */
 | 
			
		||||
void canonicalisePathMetaData(const Path & path, uid_t fromUid, InodesSeen & inodesSeen);
 | 
			
		||||
void canonicalisePathMetaData(const Path & path, uid_t fromUid);
 | 
			
		||||
 | 
			
		||||
void canonicaliseTimestampAndPermissions(const Path & path);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue