libstore: asyncify Store::verifyStore
Change-Id: I12d5f348aa5a253d409b45db8a6bbb18754450c0
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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()};
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user