1
0
Fork 0
mirror of https://github.com/NixOS/nix synced 2024-09-20 11:11:03 -04:00

Preparatory refactor of LocalStore::verifyStore.

This commit is contained in:
Ben Radford 2023-07-28 10:11:45 +01:00 committed by Ben Radford
parent 31112fd26f
commit 50ce8d15eb
2 changed files with 33 additions and 24 deletions

View file

@ -1498,24 +1498,14 @@ bool LocalStore::verifyStore(bool checkContents, RepairFlag repair)
{ {
printInfo("reading the Nix store..."); printInfo("reading the Nix store...");
bool errors = false;
/* Acquire the global GC lock to get a consistent snapshot of /* Acquire the global GC lock to get a consistent snapshot of
existing and valid paths. */ existing and valid paths. */
auto fdGCLock = openGCLock(); auto fdGCLock = openGCLock();
FdLock gcLock(fdGCLock.get(), ltRead, true, "waiting for the big garbage collector lock..."); FdLock gcLock(fdGCLock.get(), ltRead, true, "waiting for the big garbage collector lock...");
StringSet store;
for (auto & i : readDirectory(realStoreDir)) store.insert(i.name);
/* Check whether all valid paths actually exist. */
printInfo("checking path existence...");
StorePathSet validPaths; StorePathSet validPaths;
PathSet done;
for (auto & i : queryAllValidPaths()) bool errors = verifyAllValidPaths(repair, validPaths);
verifyPath(printStorePath(i), store, done, validPaths, repair, errors);
/* Optionally, check the content hashes (slow). */ /* Optionally, check the content hashes (slow). */
if (checkContents) { if (checkContents) {
@ -1601,28 +1591,45 @@ bool LocalStore::verifyStore(bool checkContents, RepairFlag repair)
} }
void LocalStore::verifyPath(const Path & pathS, const StringSet & store, bool LocalStore::verifyAllValidPaths(RepairFlag repair, StorePathSet & validPaths)
PathSet & done, StorePathSet & validPaths, RepairFlag repair, bool & errors) {
StringSet store;
for (auto & i : readDirectory(realStoreDir)) store.insert(i.name);
/* Check whether all valid paths actually exist. */
printInfo("checking path existence...");
StorePathSet done;
bool errors = false;
auto existsInStoreDir = [&](const StorePath & storePath) {
return store.count(std::string(storePath.to_string()));
};
for (auto & i : queryAllValidPaths())
verifyPath(i, existsInStoreDir, done, validPaths, repair, errors);
return errors;
}
void LocalStore::verifyPath(const StorePath & path, std::function<bool(const StorePath &)> existsInStoreDir,
StorePathSet & done, StorePathSet & validPaths, RepairFlag repair, bool & errors)
{ {
checkInterrupt(); checkInterrupt();
if (!done.insert(pathS).second) return; if (!done.insert(path).second) return;
if (!isStorePath(pathS)) { auto pathS = printStorePath(path);
printError("path '%s' is not in the Nix store", pathS);
return;
}
auto path = parseStorePath(pathS); if (!existsInStoreDir(path)) {
if (!store.count(std::string(path.to_string()))) {
/* Check any referrers first. If we can invalidate them /* Check any referrers first. If we can invalidate them
first, then we can invalidate this path as well. */ first, then we can invalidate this path as well. */
bool canInvalidate = true; bool canInvalidate = true;
StorePathSet referrers; queryReferrers(path, referrers); StorePathSet referrers; queryReferrers(path, referrers);
for (auto & i : referrers) for (auto & i : referrers)
if (i != path) { if (i != path) {
verifyPath(printStorePath(i), store, done, validPaths, repair, errors); verifyPath(i, existsInStoreDir, done, validPaths, repair, errors);
if (validPaths.count(i)) if (validPaths.count(i))
canInvalidate = false; canInvalidate = false;
} }

View file

@ -265,6 +265,8 @@ public:
bool verifyStore(bool checkContents, RepairFlag repair) override; bool verifyStore(bool checkContents, RepairFlag repair) override;
virtual bool verifyAllValidPaths(RepairFlag repair, StorePathSet & validPaths);
/** /**
* Register the validity of a path, i.e., that `path` exists, that * Register the validity of a path, i.e., that `path` exists, that
* the paths referenced by it exists, and in the case of an output * the paths referenced by it exists, and in the case of an output
@ -333,8 +335,8 @@ private:
*/ */
void invalidatePathChecked(const StorePath & path); void invalidatePathChecked(const StorePath & path);
void verifyPath(const Path & path, const StringSet & store, void verifyPath(const StorePath & path, std::function<bool(const StorePath &)> existsInStoreDir,
PathSet & done, StorePathSet & validPaths, RepairFlag repair, bool & errors); StorePathSet & done, StorePathSet & validPaths, RepairFlag repair, bool & errors);
std::shared_ptr<const ValidPathInfo> queryPathInfoInternal(State & state, const StorePath & path); std::shared_ptr<const ValidPathInfo> queryPathInfoInternal(State & state, const StorePath & path);