libstore: asyncify Store::verifyStore

Change-Id: I12d5f348aa5a253d409b45db8a6bbb18754450c0
This commit is contained in:
eldritch horrors
2025-02-04 14:10:16 +00:00
parent a400394454
commit de66d7b2b4
7 changed files with 37 additions and 20 deletions
+1 -1
View File
@@ -748,7 +748,7 @@ static void opVerify(AsyncIoRoot & aio, Strings opFlags, Strings opArgs)
else if (i == "--repair") repair = Repair;
else throw UsageError("unknown flag '%1%'", i);
if (store->verifyStore(checkContents, repair)) {
if (aio.blockOn(store->verifyStore(checkContents, repair))) {
warn("not all store errors were fixed");
throw Exit(1);
}
+1 -1
View File
@@ -854,7 +854,7 @@ static void performOp(AsyncIoRoot & aio, TunnelLogger * logger, ref<Store> store
logger->startWork();
if (repair && !trusted)
throw Error("you are not privileged to repair paths");
bool errors = store->verifyStore(checkContents, (RepairFlag) repair);
bool errors = aio.blockOn(store->verifyStore(checkContents, (RepairFlag) repair));
logger->stopWork();
to << errors;
break;
+23 -11
View File
@@ -8,6 +8,7 @@
#include "lix/libstore/nar-info.hh"
#include "lix/libutil/async.hh"
#include "lix/libutil/references.hh"
#include "lix/libutil/result.hh"
#include "lix/libutil/topo-sort.hh"
#include "lix/libutil/signals.hh"
#include "lix/libutil/finally.hh"
@@ -1517,8 +1518,8 @@ void LocalStore::invalidatePathChecked(const StorePath & path)
}
bool LocalStore::verifyStore(bool checkContents, RepairFlag repair)
{
kj::Promise<Result<bool>> LocalStore::verifyStore(bool checkContents, RepairFlag repair)
try {
printInfo("reading the Nix store...");
bool errors = false;
@@ -1553,7 +1554,7 @@ bool LocalStore::verifyStore(bool checkContents, RepairFlag repair)
StorePathSet done;
for (auto & i : queryAllValidPaths())
verifyPath(i, storePathsInStoreDir, done, validPaths, repair, errors);
TRY_AWAIT(verifyPath(i, storePathsInStoreDir, done, validPaths, repair, errors));
}
/* Optionally, check the content hashes (slow). */
@@ -1598,7 +1599,7 @@ bool LocalStore::verifyStore(bool checkContents, RepairFlag repair)
if (info->narHash != nullHash && info->narHash != current.first) {
printError("path '%s' was modified! expected hash '%s', got '%s'",
printStorePath(i), info->narHash.to_string(Base::Base32, true), current.first.to_string(Base::Base32, true));
if (repair) RUN_ASYNC_IN_NEW_THREAD(repairPath(i)); else errors = true;
if (repair) TRY_AWAIT(repairPath(i)); else errors = true;
} else {
bool update = false;
@@ -1636,16 +1637,24 @@ bool LocalStore::verifyStore(bool checkContents, RepairFlag repair)
}
}
return errors;
co_return errors;
} catch (...) {
co_return result::current_exception();
}
void LocalStore::verifyPath(const StorePath & path, const StorePathSet & storePathsInStoreDir,
StorePathSet & done, StorePathSet & validPaths, RepairFlag repair, bool & errors)
{
kj::Promise<Result<void>> LocalStore::verifyPath(
const StorePath & path,
const StorePathSet & storePathsInStoreDir,
StorePathSet & done,
StorePathSet & validPaths,
RepairFlag repair,
bool & errors
)
try {
checkInterrupt();
if (!done.insert(path).second) return;
if (!done.insert(path).second) co_return result::success();
if (!storePathsInStoreDir.count(path)) {
/* Check any referrers first. If we can invalidate them
@@ -1669,7 +1678,7 @@ void LocalStore::verifyPath(const StorePath & path, const StorePathSet & storePa
printError("path '%s' disappeared, but it still has valid referrers!", pathS);
if (repair)
try {
RUN_ASYNC_IN_NEW_THREAD(repairPath(path));
TRY_AWAIT(repairPath(path));
} catch (Error & e) {
logWarning(e.info());
errors = true;
@@ -1677,10 +1686,13 @@ void LocalStore::verifyPath(const StorePath & path, const StorePathSet & storePa
else errors = true;
}
return;
co_return result::success();
}
validPaths.insert(std::move(path));
co_return result::success();
} catch (...) {
co_return result::current_exception();
}
+2 -2
View File
@@ -273,7 +273,7 @@ public:
*/
void optimisePath(const Path & path, RepairFlag repair);
bool verifyStore(bool checkContents, RepairFlag repair) override;
kj::Promise<Result<bool>> verifyStore(bool checkContents, RepairFlag repair) override;
/**
* Register the validity of a path, i.e., that `path` exists, that
@@ -340,7 +340,7 @@ private:
*/
void invalidatePathChecked(const StorePath & path);
void verifyPath(const StorePath & path, const StorePathSet & store,
kj::Promise<Result<void>> verifyPath(const StorePath & path, const StorePathSet & store,
StorePathSet & done, StorePathSet & validPaths, RepairFlag repair, bool & errors);
std::shared_ptr<const ValidPathInfo> queryPathInfoInternal(DBState & state, const StorePath & path);
+5 -3
View File
@@ -795,12 +795,14 @@ void RemoteStore::optimiseStore()
}
bool RemoteStore::verifyStore(bool checkContents, RepairFlag repair)
{
kj::Promise<Result<bool>> RemoteStore::verifyStore(bool checkContents, RepairFlag repair)
try {
auto conn(getConnection());
conn->to << WorkerProto::Op::VerifyStore << checkContents << repair;
conn.processStderr();
return readInt(conn->from);
return {readInt(conn->from)};
} catch (...) {
return {result::current_exception()};
}
+1 -1
View File
@@ -137,7 +137,7 @@ public:
void optimiseStore() override;
bool verifyStore(bool checkContents, RepairFlag repair) override;
kj::Promise<Result<bool>> verifyStore(bool checkContents, RepairFlag repair) override;
/**
* The default instance would schedule the work on the client side, but
+4 -1
View File
@@ -706,7 +706,10 @@ public:
*
* @return true if errors remain.
*/
virtual bool verifyStore(bool checkContents, RepairFlag repair = NoRepair) { return false; };
virtual kj::Promise<Result<bool>> verifyStore(bool checkContents, RepairFlag repair = NoRepair)
{
return {false};
}
/**
* @return An object to access files in the Nix store.