* Start move towards SHA-256 hashes instead of MD5.

* Start cleaning up unique store path generation (they weren't always
  unique; in particular the suffix ("-aterm-2.2", "-builder.sh") was
  not part of the hash, therefore changes to the suffix would cause
  multiple store objects with the same hash).
This commit is contained in:
Eelco Dolstra 2005-01-14 13:51:38 +00:00
parent a7b94e87d7
commit 9530cc3170
9 changed files with 63 additions and 34 deletions

View file

@ -59,7 +59,7 @@ static Path copyAtom(EvalState & state, const Path & srcPath)
ne.closure.elems[dstPath] = elem;
Hash drvHash = hashDerivation(state, ne);
Path drvPath = writeTerm(unparseStoreExpr(ne), "");
Path drvPath = writeTerm(unparseStoreExpr(ne), "c");
state.drvHashes.insert(make_pair(drvPath, drvHash));
state.drvRoots[drvPath] = ne.closure.roots;
@ -250,21 +250,32 @@ static Expr primDerivation(EvalState & state, const ATermVector & _args)
throw Error(format("invalid character `%1%' in derivation name `%2%'")
% *i % drvName);
}
/* Construct the "masked" derivation store expression, which is
the final one except that the list of output paths is set to
the set of output names, and the corresponding environment
variables have an empty value. This ensures that changes in
the set of output names do get reflected in the hash. */
ne.derivation.env["out"] = "";
ne.derivation.outputs.insert("out");
/* Determine the output path by hashing the Nix expression with no
outputs to produce a unique but deterministic path name for
this derivation. */
if (!outHashGiven) outHash = hashDerivation(state, ne);
Path outPath = canonPath(nixStore + "/" +
((string) outHash).c_str() + "-" + drvName);
Path outPath = makeStorePath("output:out",
outHash, drvName);
/* Construct the final derivation store expression. */
ne.derivation.env["out"] = outPath;
ne.derivation.outputs.clear();
ne.derivation.outputs.insert(outPath);
/* Write the resulting term into the Nix store directory. */
Hash drvHash = outHashGiven
? hashString((string) outHash + outPath, htMD5)
: hashDerivation(state, ne);
Path drvPath = writeTerm(unparseStoreExpr(ne), "-d-" + drvName);
Path drvPath = writeTerm(unparseStoreExpr(ne), "d-" + drvName);
printMsg(lvlChatty, format("instantiated `%1%' -> `%2%'")
% drvName % drvPath);

View file

@ -69,10 +69,10 @@ static void initAndRun(int argc, char * * argv)
}
/* Setup Nix paths. */
nixStore = getEnv("NIX_STORE_DIR", canonPath(NIX_STORE_DIR));
nixDataDir = getEnv("NIX_DATA_DIR", canonPath(NIX_DATA_DIR));
nixLogDir = getEnv("NIX_LOG_DIR", canonPath(NIX_LOG_DIR));
nixStateDir = getEnv("NIX_STATE_DIR", canonPath(NIX_STATE_DIR));
nixStore = canonPath(getEnv("NIX_STORE_DIR", NIX_STORE_DIR));
nixDataDir = canonPath(getEnv("NIX_DATA_DIR", NIX_DATA_DIR));
nixLogDir = canonPath(getEnv("NIX_LOG_DIR", NIX_LOG_DIR));
nixStateDir = canonPath(getEnv("NIX_STATE_DIR", NIX_STATE_DIR));
nixDBPath = getEnv("NIX_DB_DIR", nixStateDir + "/db");
/* Check that the store directory and its parent are not

View file

@ -1137,7 +1137,7 @@ void NormalisationGoal::createClosure()
/* Write the normal form. This does not have to occur in the
transaction below because writing terms is idem-potent. */
ATerm nfTerm = unparseStoreExpr(nf);
Path nfPath = writeTerm(nfTerm, "-s");
Path nfPath = writeTerm(nfTerm, "s");
/* Register each output path, and register the normal form. This
is wrapped in one database transaction to ensure that if we

View file

@ -411,19 +411,34 @@ static void invalidatePath(const Path & path, Transaction & txn)
}
Path makeStorePath(const string & type,
Hash & hash, const string & suffix)
{
/* e.g., "source:sha256:1abc...:/nix/store:foo.tar.gz" */
string s = type + ":sha256:" + (string) hash + ":"
+ nixStore + ":" + suffix;
Hash nameHash = hashString(s, htSHA256);
printMsg(lvlError, format("name input: %1% -> %2%") % s % (string) nameHash);
return nixStore + "/" + (string) nameHash + "-" + suffix;
}
Path addToStore(const Path & _srcPath)
{
Path srcPath(absPath(_srcPath));
debug(format("adding `%1%' to the store") % srcPath);
Hash h(htMD5);
Hash h(htSHA256);
{
SwitchToOriginalUser sw;
h = hashPath(srcPath, htMD5);
h = hashPath(srcPath, htSHA256);
}
string baseName = baseNameOf(srcPath);
Path dstPath = canonPath(nixStore + "/" + (string) h + "-" + baseName);
Path dstPath = makeStorePath("source", h, baseName);
if (!readOnlyMode && !isValidPath(dstPath)) {
@ -443,6 +458,11 @@ Path addToStore(const Path & _srcPath)
copyPath(srcPath, dstPath);
Hash h2 = hashPath(dstPath, htSHA256);
if (h != h2)
throw Error(format("contents of `%1%' changed while copying it to `%2%' (%3% -> %4%)")
% srcPath % dstPath % (string) h % (string) h2);
makePathReadOnly(dstPath);
Transaction txn(nixDB);
@ -457,11 +477,13 @@ Path addToStore(const Path & _srcPath)
}
void addTextToStore(const Path & dstPath, const string & s)
Path addTextToStore(const string & suffix, const string & s)
{
assertStorePath(dstPath);
Hash hash = hashString(s, htSHA256);
Path dstPath = makeStorePath("text", hash, suffix);
if (!isValidPath(dstPath)) {
if (!readOnlyMode && !isValidPath(dstPath)) {
PathSet lockPaths;
lockPaths.insert(dstPath);
@ -482,6 +504,8 @@ void addTextToStore(const Path & dstPath, const string & s)
outputLock.setDeletion(true);
}
return dstPath;
}

View file

@ -81,14 +81,17 @@ void assertStorePath(const Path & path);
/* Checks whether a path is valid. */
bool isValidPath(const Path & path);
/* Constructs a unique store path name. */
Path makeStorePath(const string & type,
Hash & hash, const string & suffix);
/* Copy the contents of a path to the store and register the validity
the resulting path. The resulting path is returned. */
Path addToStore(const Path & srcPath);
/* Like addToStore, but the path of the output is given, and the
contents written to the output path is a regular file containing
the given string. */
void addTextToStore(const Path & dstPath, const string & s);
/* Like addToStore, but the contents written to the output path is a
regular file containing the given string. */
Path addTextToStore(const string & suffix, const string & s);
/* Delete a value from the nixStore directory. */
void deleteFromStore(const Path & path);

View file

@ -14,19 +14,9 @@ Hash hashTerm(ATerm t)
Path writeTerm(ATerm t, const string & suffix)
{
/* The id of a term is its hash. */
Hash h = hashTerm(t);
Path path = canonPath(nixStore + "/" +
(string) h + suffix + ".store");
if (!readOnlyMode && !isValidPath(path)) {
char * s = ATwriteToString(t);
if (!s) throw Error(format("cannot write aterm to `%1%'") % path);
addTextToStore(path, string(s));
}
return path;
char * s = ATwriteToString(t);
if (!s) throw Error("cannot print aterm");
return addTextToStore(suffix + ".store", string(s));
}

View file

@ -22,6 +22,7 @@ Hash::Hash(HashType type)
else if (type == htSHA1) hashSize = sha1HashSize;
else if (type == htSHA256) hashSize = sha256HashSize;
else throw Error("unknown hash type");
assert(hashSize <= maxHashSize);
memset(hash, 0, hashSize);
}

View file

@ -18,7 +18,7 @@ const int sha256HashSize = 32;
struct Hash
{
static const unsigned int maxHashSize = 20;
static const unsigned int maxHashSize = 32;
unsigned int hashSize;
unsigned char hash[maxHashSize];

View file

@ -216,7 +216,7 @@ void createUserEnv(EvalState & state, const DrvInfos & drvs,
/* Also write a copy of the list of inputs to the store; we need
it for future modifications of the environment. */
Path inputsFile = writeTerm(inputs2, "-env-inputs");
Path inputsFile = writeTerm(inputs2, "env-inputs");
Expr topLevel = makeCall(envBuilder, makeAttrs(ATmakeList3(
makeBind(toATerm("system"),