aboutsummaryrefslogtreecommitdiff
path: root/src/libstore
diff options
context:
space:
mode:
authorEelco Dolstra <eelco.dolstra@logicblox.com>2013-06-13 17:29:56 +0200
committerEelco Dolstra <eelco.dolstra@logicblox.com>2013-06-13 17:29:56 +0200
commit1b6ee8f4c7e74f75e1f49b43cf22be7730b30649 (patch)
treef5cad59175b0614105b72c29ae95148c31c15651 /src/libstore
parentcd49ee08970f0fa44053fb12cdf29668e8131a51 (diff)
Allow hard links between the outputs of a derivation
Diffstat (limited to 'src/libstore')
-rw-r--r--src/libstore/build.cc9
-rw-r--r--src/libstore/local-store.cc15
-rw-r--r--src/libstore/local-store.hh5
3 files changed, 20 insertions, 9 deletions
diff --git a/src/libstore/build.cc b/src/libstore/build.cc
index e49c66fc5..20ed2de39 100644
--- a/src/libstore/build.cc
+++ b/src/libstore/build.cc
@@ -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
diff --git a/src/libstore/local-store.cc b/src/libstore/local-store.cc
index 857d4cee0..13c70fbf5 100644
--- a/src/libstore/local-store.cc
+++ b/src/libstore/local-store.cc
@@ -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);
diff --git a/src/libstore/local-store.hh b/src/libstore/local-store.hh
index b1fde99cf..4b132972e 100644
--- a/src/libstore/local-store.hh
+++ b/src/libstore/local-store.hh
@@ -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);