1
1
Fork 0
mirror of https://github.com/NixOS/nix.git synced 2025-11-15 23:12:44 +01:00

Merge remote-tracking branch 'origin/master' into flakes

This commit is contained in:
Eelco Dolstra 2019-12-11 14:53:30 +01:00
commit ecb3a1afa2
119 changed files with 3905 additions and 2250 deletions

View file

@ -534,42 +534,36 @@ void canonicalisePathMetaData(const Path & path, uid_t fromUid)
}
void LocalStore::checkDerivationOutputs(const Path & drvPath, const Derivation & drv)
void LocalStore::checkDerivationOutputs(const StorePath & drvPath, const Derivation & drv)
{
string drvName = storePathToName(drvPath);
assert(isDerivation(drvName));
assert(drvPath.isDerivation());
std::string drvName(drvPath.name());
drvName = string(drvName, 0, drvName.size() - drvExtension.size());
if (drv.isFixedOutput()) {
DerivationOutputs::const_iterator out = drv.outputs.find("out");
if (out == drv.outputs.end())
throw Error(format("derivation '%1%' does not have an output named 'out'") % drvPath);
throw Error("derivation '%s' does not have an output named 'out'", printStorePath(drvPath));
bool recursive; Hash h;
out->second.parseHashInfo(recursive, h);
Path outPath = makeFixedOutputPath(recursive, h, drvName);
auto outPath = makeFixedOutputPath(recursive, h, drvName);
StringPairs::const_iterator j = drv.env.find("out");
if (out->second.path != outPath || j == drv.env.end() || j->second != outPath)
throw Error(format("derivation '%1%' has incorrect output '%2%', should be '%3%'")
% drvPath % out->second.path % outPath);
if (out->second.path != outPath || j == drv.env.end() || parseStorePath(j->second) != outPath)
throw Error("derivation '%s' has incorrect output '%s', should be '%s'",
printStorePath(drvPath), printStorePath(out->second.path), printStorePath(outPath));
}
else {
Derivation drvCopy(drv);
for (auto & i : drvCopy.outputs) {
i.second.path = "";
drvCopy.env[i.first] = "";
}
Hash h = hashDerivationModulo(*this, drvCopy);
Hash h = hashDerivationModulo(*this, drv, true);
for (auto & i : drv.outputs) {
Path outPath = makeOutputPath(i.first, h, drvName);
auto outPath = makeOutputPath(i.first, h, drvName);
StringPairs::const_iterator j = drv.env.find(i.first);
if (i.second.path != outPath || j == drv.env.end() || j->second != outPath)
throw Error(format("derivation '%1%' has incorrect output '%2%', should be '%3%'")
% drvPath % i.second.path % outPath);
if (i.second.path != outPath || j == drv.env.end() || parseStorePath(j->second) != outPath)
throw Error("derivation '%s' has incorrect output '%s', should be '%s'",
printStorePath(drvPath), printStorePath(i.second.path), printStorePath(outPath));
}
}
}
@ -578,16 +572,15 @@ void LocalStore::checkDerivationOutputs(const Path & drvPath, const Derivation &
uint64_t LocalStore::addValidPath(State & state,
const ValidPathInfo & info, bool checkOutputs)
{
checkStoreName(storePathToName(info.path));
if (info.ca != "" && !info.isContentAddressed(*this))
throw Error("cannot add path '%s' to the Nix store because it claims to be content-addressed but isn't", info.path);
throw Error("cannot add path '%s' to the Nix store because it claims to be content-addressed but isn't",
printStorePath(info.path));
state.stmtRegisterValidPath.use()
(info.path)
(printStorePath(info.path))
(info.narHash.to_string(Base16))
(info.registrationTime == 0 ? time(0) : info.registrationTime)
(info.deriver, info.deriver != "")
(info.deriver ? printStorePath(*info.deriver) : "", (bool) info.deriver)
(info.narSize, info.narSize != 0)
(info.ultimate ? 1 : 0, info.ultimate)
(concatStringsSep(" ", info.sigs), !info.sigs.empty())
@ -599,8 +592,8 @@ uint64_t LocalStore::addValidPath(State & state,
the database. This is useful for the garbage collector: it can
efficiently query whether a path is an output of some
derivation. */
if (isDerivation(info.path)) {
Derivation drv = readDerivation(realStoreDir + "/" + baseNameOf(info.path));
if (info.path.isDerivation()) {
auto drv = readDerivation(*this, realStoreDir + "/" + std::string(info.path.to_string()));
/* Verify that the output paths in the derivation are correct
(i.e., follow the scheme for computing output paths from
@ -613,34 +606,31 @@ uint64_t LocalStore::addValidPath(State & state,
state.stmtAddDerivationOutput.use()
(id)
(i.first)
(i.second.path)
(printStorePath(i.second.path))
.exec();
}
}
{
auto state_(Store::state.lock());
state_->pathInfoCache.upsert(storePathToHash(info.path), std::make_shared<ValidPathInfo>(info));
state_->pathInfoCache.upsert(storePathToHash(printStorePath(info.path)), std::make_shared<ValidPathInfo>(info));
}
return id;
}
void LocalStore::queryPathInfoUncached(const Path & path,
void LocalStore::queryPathInfoUncached(const StorePath & path,
Callback<std::shared_ptr<const ValidPathInfo>> callback) noexcept
{
try {
auto info = std::make_shared<ValidPathInfo>();
info->path = path;
assertStorePath(path);
auto info = std::make_shared<ValidPathInfo>(path.clone());
callback(retrySQLite<std::shared_ptr<ValidPathInfo>>([&]() {
auto state(_state.lock());
/* Get the path info. */
auto useQueryPathInfo(state->stmtQueryPathInfo.use()(path));
auto useQueryPathInfo(state->stmtQueryPathInfo.use()(printStorePath(info->path)));
if (!useQueryPathInfo.next())
return std::shared_ptr<ValidPathInfo>();
@ -650,13 +640,13 @@ void LocalStore::queryPathInfoUncached(const Path & path,
try {
info->narHash = Hash(useQueryPathInfo.getStr(1));
} catch (BadHash & e) {
throw Error("in valid-path entry for '%s': %s", path, e.what());
throw Error("in valid-path entry for '%s': %s", printStorePath(path), e.what());
}
info->registrationTime = useQueryPathInfo.getInt(2);
auto s = (const char *) sqlite3_column_text(state->stmtQueryPathInfo, 3);
if (s) info->deriver = s;
if (s) info->deriver = parseStorePath(s);
/* Note that narSize = NULL yields 0. */
info->narSize = useQueryPathInfo.getInt(4);
@ -673,7 +663,7 @@ void LocalStore::queryPathInfoUncached(const Path & path,
auto useQueryReferences(state->stmtQueryReferences.use()(info->id));
while (useQueryReferences.next())
info->references.insert(useQueryReferences.getStr(0));
info->references.insert(parseStorePath(useQueryReferences.getStr(0)));
return info;
}));
@ -691,27 +681,27 @@ void LocalStore::updatePathInfo(State & state, const ValidPathInfo & info)
(info.ultimate ? 1 : 0, info.ultimate)
(concatStringsSep(" ", info.sigs), !info.sigs.empty())
(info.ca, !info.ca.empty())
(info.path)
(printStorePath(info.path))
.exec();
}
uint64_t LocalStore::queryValidPathId(State & state, const Path & path)
uint64_t LocalStore::queryValidPathId(State & state, const StorePath & path)
{
auto use(state.stmtQueryPathInfo.use()(path));
auto use(state.stmtQueryPathInfo.use()(printStorePath(path)));
if (!use.next())
throw Error(format("path '%1%' is not valid") % path);
throw Error("path '%s' is not valid", printStorePath(path));
return use.getInt(0);
}
bool LocalStore::isValidPath_(State & state, const Path & path)
bool LocalStore::isValidPath_(State & state, const StorePath & path)
{
return state.stmtQueryPathInfo.use()(path).next();
return state.stmtQueryPathInfo.use()(printStorePath(path)).next();
}
bool LocalStore::isValidPathUncached(const Path & path)
bool LocalStore::isValidPathUncached(const StorePath & path)
{
return retrySQLite<bool>([&]() {
auto state(_state.lock());
@ -720,39 +710,38 @@ bool LocalStore::isValidPathUncached(const Path & path)
}
PathSet LocalStore::queryValidPaths(const PathSet & paths, SubstituteFlag maybeSubstitute)
StorePathSet LocalStore::queryValidPaths(const StorePathSet & paths, SubstituteFlag maybeSubstitute)
{
PathSet res;
StorePathSet res;
for (auto & i : paths)
if (isValidPath(i)) res.insert(i);
if (isValidPath(i)) res.insert(i.clone());
return res;
}
PathSet LocalStore::queryAllValidPaths()
StorePathSet LocalStore::queryAllValidPaths()
{
return retrySQLite<PathSet>([&]() {
return retrySQLite<StorePathSet>([&]() {
auto state(_state.lock());
auto use(state->stmtQueryValidPaths.use());
PathSet res;
while (use.next()) res.insert(use.getStr(0));
StorePathSet res;
while (use.next()) res.insert(parseStorePath(use.getStr(0)));
return res;
});
}
void LocalStore::queryReferrers(State & state, const Path & path, PathSet & referrers)
void LocalStore::queryReferrers(State & state, const StorePath & path, StorePathSet & referrers)
{
auto useQueryReferrers(state.stmtQueryReferrers.use()(path));
auto useQueryReferrers(state.stmtQueryReferrers.use()(printStorePath(path)));
while (useQueryReferrers.next())
referrers.insert(useQueryReferrers.getStr(0));
referrers.insert(parseStorePath(useQueryReferrers.getStr(0)));
}
void LocalStore::queryReferrers(const Path & path, PathSet & referrers)
void LocalStore::queryReferrers(const StorePath & path, StorePathSet & referrers)
{
assertStorePath(path);
return retrySQLite<void>([&]() {
auto state(_state.lock());
queryReferrers(*state, path, referrers);
@ -760,42 +749,40 @@ void LocalStore::queryReferrers(const Path & path, PathSet & referrers)
}
PathSet LocalStore::queryValidDerivers(const Path & path)
StorePathSet LocalStore::queryValidDerivers(const StorePath & path)
{
assertStorePath(path);
return retrySQLite<PathSet>([&]() {
return retrySQLite<StorePathSet>([&]() {
auto state(_state.lock());
auto useQueryValidDerivers(state->stmtQueryValidDerivers.use()(path));
auto useQueryValidDerivers(state->stmtQueryValidDerivers.use()(printStorePath(path)));
PathSet derivers;
StorePathSet derivers;
while (useQueryValidDerivers.next())
derivers.insert(useQueryValidDerivers.getStr(1));
derivers.insert(parseStorePath(useQueryValidDerivers.getStr(1)));
return derivers;
});
}
PathSet LocalStore::queryDerivationOutputs(const Path & path)
StorePathSet LocalStore::queryDerivationOutputs(const StorePath & path)
{
return retrySQLite<PathSet>([&]() {
return retrySQLite<StorePathSet>([&]() {
auto state(_state.lock());
auto useQueryDerivationOutputs(state->stmtQueryDerivationOutputs.use()
(queryValidPathId(*state, path)));
PathSet outputs;
StorePathSet outputs;
while (useQueryDerivationOutputs.next())
outputs.insert(useQueryDerivationOutputs.getStr(1));
outputs.insert(parseStorePath(useQueryDerivationOutputs.getStr(1)));
return outputs;
});
}
StringSet LocalStore::queryDerivationOutputNames(const Path & path)
StringSet LocalStore::queryDerivationOutputNames(const StorePath & path)
{
return retrySQLite<StringSet>([&]() {
auto state(_state.lock());
@ -812,31 +799,36 @@ StringSet LocalStore::queryDerivationOutputNames(const Path & path)
}
Path LocalStore::queryPathFromHashPart(const string & hashPart)
std::optional<StorePath> LocalStore::queryPathFromHashPart(const std::string & hashPart)
{
if (hashPart.size() != storePathHashLen) throw Error("invalid hash part");
Path prefix = storeDir + "/" + hashPart;
return retrySQLite<Path>([&]() -> std::string {
return retrySQLite<std::optional<StorePath>>([&]() -> std::optional<StorePath> {
auto state(_state.lock());
auto useQueryPathFromHashPart(state->stmtQueryPathFromHashPart.use()(prefix));
if (!useQueryPathFromHashPart.next()) return "";
if (!useQueryPathFromHashPart.next()) return {};
const char * s = (const char *) sqlite3_column_text(state->stmtQueryPathFromHashPart, 0);
return s && prefix.compare(0, prefix.size(), s, prefix.size()) == 0 ? s : "";
if (s && prefix.compare(0, prefix.size(), s, prefix.size()) == 0)
return parseStorePath(s);
return {};
});
}
PathSet LocalStore::querySubstitutablePaths(const PathSet & paths)
StorePathSet LocalStore::querySubstitutablePaths(const StorePathSet & paths)
{
if (!settings.useSubstitutes) return PathSet();
if (!settings.useSubstitutes) return StorePathSet();
auto remaining = paths;
PathSet res;
StorePathSet remaining;
for (auto & i : paths)
remaining.insert(i.clone());
StorePathSet res;
for (auto & sub : getDefaultSubstituters()) {
if (remaining.empty()) break;
@ -845,12 +837,12 @@ PathSet LocalStore::querySubstitutablePaths(const PathSet & paths)
auto valid = sub->queryValidPaths(remaining);
PathSet remaining2;
StorePathSet remaining2;
for (auto & path : remaining)
if (valid.count(path))
res.insert(path);
res.insert(path.clone());
else
remaining2.insert(path);
remaining2.insert(path.clone());
std::swap(remaining, remaining2);
}
@ -859,7 +851,7 @@ PathSet LocalStore::querySubstitutablePaths(const PathSet & paths)
}
void LocalStore::querySubstitutablePathInfos(const PathSet & paths,
void LocalStore::querySubstitutablePathInfos(const StorePathSet & paths,
SubstitutablePathInfos & infos)
{
if (!settings.useSubstitutes) return;
@ -867,17 +859,16 @@ void LocalStore::querySubstitutablePathInfos(const PathSet & paths,
if (sub->storeDir != storeDir) continue;
for (auto & path : paths) {
if (infos.count(path)) continue;
debug(format("checking substituter '%s' for path '%s'")
% sub->getUri() % path);
debug("checking substituter '%s' for path '%s'", sub->getUri(), printStorePath(path));
try {
auto info = sub->queryPathInfo(path);
auto narInfo = std::dynamic_pointer_cast<const NarInfo>(
std::shared_ptr<const ValidPathInfo>(info));
infos[path] = SubstitutablePathInfo{
info->deriver,
info->references,
infos.insert_or_assign(path.clone(), SubstitutablePathInfo{
info->deriver ? info->deriver->clone() : std::optional<StorePath>(),
cloneStorePathSet(info->references),
narInfo ? narInfo->fileSize : 0,
info->narSize};
info->narSize});
} catch (InvalidPath &) {
} catch (SubstituterDisabled &) {
} catch (Error & e) {
@ -911,7 +902,7 @@ void LocalStore::registerValidPaths(const ValidPathInfos & infos)
auto state(_state.lock());
SQLiteTxn txn(state->db);
PathSet paths;
StorePathSet paths;
for (auto & i : infos) {
assert(i.narHash.type == htSHA256);
@ -919,7 +910,7 @@ void LocalStore::registerValidPaths(const ValidPathInfos & infos)
updatePathInfo(*state, i);
else
addValidPath(*state, i, false);
paths.insert(i.path);
paths.insert(i.path.clone());
}
for (auto & i : infos) {
@ -932,10 +923,10 @@ void LocalStore::registerValidPaths(const ValidPathInfos & infos)
this in addValidPath() above, because the references might
not be valid yet. */
for (auto & i : infos)
if (isDerivation(i.path)) {
if (i.path.isDerivation()) {
// FIXME: inefficient; we already loaded the derivation in addValidPath().
Derivation drv = readDerivation(realStoreDir + "/" + baseNameOf(i.path));
checkDerivationOutputs(i.path, drv);
checkDerivationOutputs(i.path,
readDerivation(*this, realStoreDir + "/" + std::string(i.path.to_string())));
}
/* Do a topological sort of the paths. This will throw an
@ -951,18 +942,18 @@ void LocalStore::registerValidPaths(const ValidPathInfos & infos)
/* Invalidate a path. The caller is responsible for checking that
there are no referrers. */
void LocalStore::invalidatePath(State & state, const Path & path)
void LocalStore::invalidatePath(State & state, const StorePath & path)
{
debug(format("invalidating path '%1%'") % path);
debug("invalidating path '%s'", printStorePath(path));
state.stmtInvalidatePath.use()(path).exec();
state.stmtInvalidatePath.use()(printStorePath(path)).exec();
/* Note that the foreign key constraints on the Refs table take
care of deleting the references entries for `path'. */
{
auto state_(Store::state.lock());
state_->pathInfoCache.erase(storePathToHash(path));
state_->pathInfoCache.erase(storePathToHash(printStorePath(path)));
}
}
@ -980,10 +971,10 @@ void LocalStore::addToStore(const ValidPathInfo & info, Source & source,
RepairFlag repair, CheckSigsFlag checkSigs, std::shared_ptr<FSAccessor> accessor)
{
if (!info.narHash)
throw Error("cannot add path '%s' because it lacks a hash", info.path);
throw Error("cannot add path '%s' because it lacks a hash", printStorePath(info.path));
if (requireSigs && checkSigs && !info.checkSignatures(*this, getPublicKeys()))
throw Error("cannot add path '%s' because it lacks a valid signature", info.path);
throw Error("cannot add path '%s' because it lacks a valid signature", printStorePath(info.path));
addTempRoot(info.path);
@ -991,12 +982,12 @@ void LocalStore::addToStore(const ValidPathInfo & info, Source & source,
PathLocks outputLock;
Path realPath = realStoreDir + "/" + baseNameOf(info.path);
Path realPath = realStoreDir + "/" + std::string(info.path.to_string());
/* Lock the output path. But don't lock if we're being called
from a build hook (whose parent process already acquired a
lock on this path). */
if (!locksHeld.count(info.path))
if (!locksHeld.count(printStorePath(info.path)))
outputLock.lockPaths({realPath});
if (repair || !isValidPath(info.path)) {
@ -1011,7 +1002,7 @@ void LocalStore::addToStore(const ValidPathInfo & info, Source & source,
else {
if (!info.references.empty())
settings.requireExperimentalFeature("ca-references");
hashSink = std::make_unique<HashModuloSink>(htSHA256, storePathToHash(info.path));
hashSink = std::make_unique<HashModuloSink>(htSHA256, storePathToHash(printStorePath(info.path)));
}
LambdaSource wrapperSource([&](unsigned char * data, size_t len) -> size_t {
@ -1026,11 +1017,11 @@ void LocalStore::addToStore(const ValidPathInfo & info, Source & source,
if (hashResult.first != info.narHash)
throw Error("hash mismatch importing path '%s';\n wanted: %s\n got: %s",
info.path, info.narHash.to_string(), hashResult.first.to_string());
printStorePath(info.path), info.narHash.to_string(), hashResult.first.to_string());
if (hashResult.second != info.narSize)
throw Error("size mismatch importing path '%s';\n wanted: %s\n got: %s",
info.path, info.narSize, hashResult.second);
printStorePath(info.path), info.narSize, hashResult.second);
autoGC();
@ -1046,12 +1037,12 @@ void LocalStore::addToStore(const ValidPathInfo & info, Source & source,
}
Path LocalStore::addToStoreFromDump(const string & dump, const string & name,
StorePath LocalStore::addToStoreFromDump(const string & dump, const string & name,
bool recursive, HashType hashAlgo, RepairFlag repair)
{
Hash h = hashString(hashAlgo, dump);
Path dstPath = makeFixedOutputPath(recursive, h, name);
auto dstPath = makeFixedOutputPath(recursive, h, name);
addTempRoot(dstPath);
@ -1060,7 +1051,8 @@ Path LocalStore::addToStoreFromDump(const string & dump, const string & name,
/* The first check above is an optimisation to prevent
unnecessary lock acquisition. */
Path realPath = realStoreDir + "/" + baseNameOf(dstPath);
Path realPath = realStoreDir + "/";
realPath += dstPath.to_string();
PathLocks outputLock({realPath});
@ -1091,8 +1083,7 @@ Path LocalStore::addToStoreFromDump(const string & dump, const string & name,
optimisePath(realPath); // FIXME: combine with hashPath()
ValidPathInfo info;
info.path = dstPath;
ValidPathInfo info(dstPath.clone());
info.narHash = hash.first;
info.narSize = hash.second;
info.ca = makeFixedOutputCA(recursive, h);
@ -1106,7 +1097,7 @@ Path LocalStore::addToStoreFromDump(const string & dump, const string & name,
}
Path LocalStore::addToStore(const string & name, const Path & _srcPath,
StorePath LocalStore::addToStore(const string & name, const Path & _srcPath,
bool recursive, HashType hashAlgo, PathFilter & filter, RepairFlag repair)
{
Path srcPath(absPath(_srcPath));
@ -1124,8 +1115,8 @@ Path LocalStore::addToStore(const string & name, const Path & _srcPath,
}
Path LocalStore::addTextToStore(const string & name, const string & s,
const PathSet & references, RepairFlag repair)
StorePath LocalStore::addTextToStore(const string & name, const string & s,
const StorePathSet & references, RepairFlag repair)
{
auto hash = hashString(htSHA256, s);
auto dstPath = makeTextPath(name, hash, references);
@ -1134,7 +1125,8 @@ Path LocalStore::addTextToStore(const string & name, const string & s,
if (repair || !isValidPath(dstPath)) {
Path realPath = realStoreDir + "/" + baseNameOf(dstPath);
Path realPath = realStoreDir + "/";
realPath += dstPath.to_string();
PathLocks outputLock({realPath});
@ -1154,11 +1146,10 @@ Path LocalStore::addTextToStore(const string & name, const string & s,
optimisePath(realPath);
ValidPathInfo info;
info.path = dstPath;
ValidPathInfo info(dstPath.clone());
info.narHash = narHash;
info.narSize = sink.s->size();
info.references = references;
info.references = cloneStorePathSet(references);
info.ca = "text:" + hash.to_string();
registerValidPath(info);
}
@ -1180,27 +1171,25 @@ Path LocalStore::createTempDirInStore()
the GC between createTempDir() and addTempRoot(), so repeat
until `tmpDir' exists. */
tmpDir = createTempDir(realStoreDir);
addTempRoot(tmpDir);
addTempRoot(parseStorePath(tmpDir));
} while (!pathExists(tmpDir));
return tmpDir;
}
void LocalStore::invalidatePathChecked(const Path & path)
void LocalStore::invalidatePathChecked(const StorePath & path)
{
assertStorePath(path);
retrySQLite<void>([&]() {
auto state(_state.lock());
SQLiteTxn txn(state->db);
if (isValidPath_(*state, path)) {
PathSet referrers; queryReferrers(*state, path, referrers);
StorePathSet referrers; queryReferrers(*state, path, referrers);
referrers.erase(path); /* ignore self-references */
if (!referrers.empty())
throw PathInUse(format("cannot delete path '%1%' because it is in use by %2%")
% path % showPaths(referrers));
throw PathInUse("cannot delete path '%s' because it is in use by %s",
printStorePath(path), showPaths(referrers));
invalidatePath(*state, path);
}
@ -1219,18 +1208,19 @@ bool LocalStore::verifyStore(bool checkContents, RepairFlag repair)
existing and valid paths. */
AutoCloseFD fdGCLock = openGCLock(ltWrite);
PathSet store;
StringSet store;
for (auto & i : readDirectory(realStoreDir)) store.insert(i.name);
/* Check whether all valid paths actually exist. */
printInfo("checking path existence...");
PathSet validPaths2 = queryAllValidPaths(), validPaths, done;
StorePathSet validPaths;
PathSet done;
fdGCLock = -1;
for (auto & i : validPaths2)
verifyPath(i, store, done, validPaths, repair, errors);
for (auto & i : queryAllValidPaths())
verifyPath(printStorePath(i), store, done, validPaths, repair, errors);
/* Optionally, check the content hashes (slow). */
if (checkContents) {
@ -1265,21 +1255,20 @@ bool LocalStore::verifyStore(bool checkContents, RepairFlag repair)
auto info = std::const_pointer_cast<ValidPathInfo>(std::shared_ptr<const ValidPathInfo>(queryPathInfo(i)));
/* Check the content hash (optionally - slow). */
printMsg(lvlTalkative, format("checking contents of '%1%'") % i);
printMsg(lvlTalkative, "checking contents of '%s'", printStorePath(i));
std::unique_ptr<AbstractHashSink> hashSink;
if (info->ca == "")
hashSink = std::make_unique<HashSink>(info->narHash.type);
else
hashSink = std::make_unique<HashModuloSink>(info->narHash.type, storePathToHash(info->path));
hashSink = std::make_unique<HashModuloSink>(info->narHash.type, storePathToHash(printStorePath(info->path)));
dumpPath(toRealPath(i), *hashSink);
dumpPath(toRealPath(printStorePath(i)), *hashSink);
auto current = hashSink->finish();
if (info->narHash != nullHash && info->narHash != current.first) {
printError(format("path '%1%' was modified! "
"expected hash '%2%', got '%3%'")
% i % info->narHash.to_string() % current.first.to_string());
printError("path '%s' was modified! expected hash '%s', got '%s'",
printStorePath(i), info->narHash.to_string(), current.first.to_string());
if (repair) repairPath(i); else errors = true;
} else {
@ -1287,14 +1276,14 @@ bool LocalStore::verifyStore(bool checkContents, RepairFlag repair)
/* Fill in missing hashes. */
if (info->narHash == nullHash) {
printError(format("fixing missing hash on '%1%'") % i);
printError("fixing missing hash on '%s'", printStorePath(i));
info->narHash = current.first;
update = true;
}
/* Fill in missing narSize fields (from old stores). */
if (info->narSize == 0) {
printError(format("updating size field on '%1%' to %2%") % i % current.second);
printError("updating size field on '%s' to %s", printStorePath(i), current.second);
info->narSize = current.second;
update = true;
}
@ -1310,9 +1299,9 @@ bool LocalStore::verifyStore(bool checkContents, RepairFlag repair)
/* It's possible that the path got GC'ed, so ignore
errors on invalid paths. */
if (isValidPath(i))
printError(format("error: %1%") % e.msg());
printError("error: %s", e.msg());
else
printError(format("warning: %1%") % e.msg());
warn(e.msg());
errors = true;
}
}
@ -1322,43 +1311,43 @@ bool LocalStore::verifyStore(bool checkContents, RepairFlag repair)
}
void LocalStore::verifyPath(const Path & path, const PathSet & store,
PathSet & done, PathSet & validPaths, RepairFlag repair, bool & errors)
void LocalStore::verifyPath(const Path & pathS, const StringSet & store,
PathSet & done, StorePathSet & validPaths, RepairFlag repair, bool & errors)
{
checkInterrupt();
if (!done.insert(path).second) return;
if (!done.insert(pathS).second) return;
if (!isStorePath(path)) {
printError(format("path '%1%' is not in the Nix store") % path);
auto state(_state.lock());
invalidatePath(*state, path);
if (!isStorePath(pathS)) {
printError("path '%s' is not in the Nix store", pathS);
return;
}
if (store.find(baseNameOf(path)) == store.end()) {
auto path = parseStorePath(pathS);
if (!store.count(std::string(path.to_string()))) {
/* Check any referrers first. If we can invalidate them
first, then we can invalidate this path as well. */
bool canInvalidate = true;
PathSet referrers; queryReferrers(path, referrers);
StorePathSet referrers; queryReferrers(path, referrers);
for (auto & i : referrers)
if (i != path) {
verifyPath(i, store, done, validPaths, repair, errors);
if (validPaths.find(i) != validPaths.end())
verifyPath(printStorePath(i), store, done, validPaths, repair, errors);
if (validPaths.count(i))
canInvalidate = false;
}
if (canInvalidate) {
printError(format("path '%1%' disappeared, removing from database...") % path);
printError("path '%s' disappeared, removing from database...", pathS);
auto state(_state.lock());
invalidatePath(*state, path);
} else {
printError(format("path '%1%' disappeared, but it still has valid referrers!") % path);
printError("path '%s' disappeared, but it still has valid referrers!", pathS);
if (repair)
try {
repairPath(path);
} catch (Error & e) {
printError(format("warning: %1%") % e.msg());
warn(e.msg());
errors = true;
}
else errors = true;
@ -1367,7 +1356,7 @@ void LocalStore::verifyPath(const Path & path, const PathSet & store,
return;
}
validPaths.insert(path);
validPaths.insert(std::move(path));
}
@ -1436,7 +1425,7 @@ void LocalStore::vacuumDB()
}
void LocalStore::addSignatures(const Path & storePath, const StringSet & sigs)
void LocalStore::addSignatures(const StorePath & storePath, const StringSet & sigs)
{
retrySQLite<void>([&]() {
auto state(_state.lock());
@ -1462,7 +1451,7 @@ void LocalStore::signPathInfo(ValidPathInfo & info)
for (auto & secretKeyFile : secretKeyFiles.get()) {
SecretKey secretKey(readFile(secretKeyFile));
info.sign(secretKey);
info.sign(*this, secretKey);
}
}