diff --git a/lix/legacy/nix-store.cc b/lix/legacy/nix-store.cc index 69e7ef178..917cd3e2b 100644 --- a/lix/legacy/nix-store.cc +++ b/lix/legacy/nix-store.cc @@ -791,7 +791,7 @@ static void opVerifyPath(AsyncIoRoot & aio, Strings opFlags, Strings opArgs) printMsg(lvlTalkative, "checking path '%s'...", store->printStorePath(path)); auto info = store->queryPathInfo(path); HashSink sink(info->narHash.type); - store->narFromPath(path)->drainInto(sink); + aio.blockOn(store->narFromPath(path))->drainInto(sink); auto current = sink.finish(); if (current.first != info->narHash) { printError("path '%s' was modified! expected hash '%s', got '%s'", @@ -928,7 +928,8 @@ static void opServe(AsyncIoRoot & aio, Strings opFlags, Strings opArgs) } case ServeProto::Command::DumpStorePath: - store->narFromPath(store->parseStorePath(readString(in)))->drainInto(out); + aio.blockOn(store->narFromPath(store->parseStorePath(readString(in)))) + ->drainInto(out); break; case ServeProto::Command::ImportPaths: { diff --git a/lix/libstore/binary-cache-store.cc b/lix/libstore/binary-cache-store.cc index 1505416c4..526a635a7 100644 --- a/lix/libstore/binary-cache-store.cc +++ b/lix/libstore/binary-cache-store.cc @@ -350,33 +350,37 @@ try { co_return result::current_exception(); } -box_ptr BinaryCacheStore::narFromPath(const StorePath & storePath) -{ +kj::Promise>> BinaryCacheStore::narFromPath(const StorePath & storePath) +try { auto info = queryPathInfo(storePath).cast(); try { auto file = getFile(info->url); - return make_box_ptr([](auto info, auto file, auto & stats) -> WireFormatGenerator { - constexpr size_t buflen = 65536; - auto buf = std::make_unique(buflen); - size_t total = 0; - auto decompressor = makeDecompressionSource(info->compression, *file); - try { - while (true) { - const auto len = decompressor->read(buf.get(), buflen); - co_yield std::span{buf.get(), len}; - total += len; + co_return make_box_ptr( + [](auto info, auto file, auto & stats) -> WireFormatGenerator { + constexpr size_t buflen = 65536; + auto buf = std::make_unique(buflen); + size_t total = 0; + auto decompressor = makeDecompressionSource(info->compression, *file); + try { + while (true) { + const auto len = decompressor->read(buf.get(), buflen); + co_yield std::span{buf.get(), len}; + total += len; + } + } catch (EndOfFile &) { } - } catch (EndOfFile &) { - } - stats.narRead++; - //stats.narReadCompressedBytes += nar->size(); // FIXME - stats.narReadBytes += total; - }(std::move(info), std::move(file), stats)); + stats.narRead++; + // stats.narReadCompressedBytes += nar->size(); // FIXME + stats.narReadBytes += total; + }(std::move(info), std::move(file), stats) + ); } catch (NoSuchBinaryCacheFile & e) { throw SubstituteGone(std::move(e.info())); } +} catch (...) { + co_return result::current_exception(); } std::shared_ptr BinaryCacheStore::queryPathInfoUncached(const StorePath & storePath) diff --git a/lix/libstore/binary-cache-store.hh b/lix/libstore/binary-cache-store.hh index 15ab4485c..8418baf1e 100644 --- a/lix/libstore/binary-cache-store.hh +++ b/lix/libstore/binary-cache-store.hh @@ -150,7 +150,7 @@ public: kj::Promise>> queryRealisationUncached(const DrvOutput &) override; - box_ptr narFromPath(const StorePath & path) override; + kj::Promise>> narFromPath(const StorePath & path) override; ref getFSAccessor() override; diff --git a/lix/libstore/build/local-derivation-goal.cc b/lix/libstore/build/local-derivation-goal.cc index c2776805d..76ed4300c 100644 --- a/lix/libstore/build/local-derivation-goal.cc +++ b/lix/libstore/build/local-derivation-goal.cc @@ -1142,11 +1142,13 @@ struct RestrictedStore : public virtual IndirectRootStore, public virtual GcStor co_return result::current_exception(); } - box_ptr narFromPath(const StorePath & path) override - { + kj::Promise>> narFromPath(const StorePath & path) override + try { if (!goal.isAllowed(path)) throw InvalidPath("cannot dump unknown path '%s' in recursive Nix", printStorePath(path)); - return LocalFSStore::narFromPath(path); + co_return TRY_AWAIT(LocalFSStore::narFromPath(path)); + } catch (...) { + co_return result::current_exception(); } kj::Promise> ensurePath(const StorePath & path) override diff --git a/lix/libstore/dummy-store.cc b/lix/libstore/dummy-store.cc index bb55328e3..aa2f11d5a 100644 --- a/lix/libstore/dummy-store.cc +++ b/lix/libstore/dummy-store.cc @@ -70,8 +70,8 @@ struct DummyStore final : public Store RepairFlag repair) override try { unsupported("addTextToStore"); } catch (...) { return {result::current_exception()}; } - box_ptr narFromPath(const StorePath & path) override - { unsupported("narFromPath"); } + kj::Promise>> narFromPath(const StorePath & path) override + try { unsupported("narFromPath"); } catch (...) { return {result::current_exception()}; } kj::Promise>> queryRealisationUncached(const DrvOutput &) override diff --git a/lix/libstore/export-import.cc b/lix/libstore/export-import.cc index 40d9017f3..356073e84 100644 --- a/lix/libstore/export-import.cc +++ b/lix/libstore/export-import.cc @@ -32,7 +32,7 @@ try { HashSink hashSink(HashType::SHA256); TeeSink teeSink(sink, hashSink); - narFromPath(path)->drainInto(teeSink); + TRY_AWAIT(narFromPath(path))->drainInto(teeSink); /* Refuse to export paths that have changed. This prevents filesystem corruption from spreading to other machines. diff --git a/lix/libstore/legacy-ssh-store.cc b/lix/libstore/legacy-ssh-store.cc index 6fb0df07b..ffb727f7d 100644 --- a/lix/libstore/legacy-ssh-store.cc +++ b/lix/libstore/legacy-ssh-store.cc @@ -248,15 +248,17 @@ struct LegacySSHStore final : public Store co_return result::current_exception(); } - box_ptr narFromPath(const StorePath & path) override - { + kj::Promise>> narFromPath(const StorePath & path) override + try { auto conn(connections->get()); conn->to << ServeProto::Command::DumpStorePath << printStorePath(path); conn->to.flush(); - return make_box_ptr([] (auto conn) -> WireFormatGenerator { + co_return make_box_ptr([] (auto conn) -> WireFormatGenerator { co_yield copyNAR(conn->from); }(std::move(conn))); + } catch (...) { + co_return result::current_exception(); } kj::Promise>> diff --git a/lix/libstore/local-fs-store.cc b/lix/libstore/local-fs-store.cc index e8df9e0ea..2c824f159 100644 --- a/lix/libstore/local-fs-store.cc +++ b/lix/libstore/local-fs-store.cc @@ -84,11 +84,15 @@ ref LocalFSStore::getFSAccessor() std::dynamic_pointer_cast(shared_from_this()))); } -box_ptr LocalFSStore::narFromPath(const StorePath & path) -{ +kj::Promise>> LocalFSStore::narFromPath(const StorePath & path) +try { if (!isValidPath(path)) throw Error("path '%s' does not exist in store", printStorePath(path)); - return make_box_ptr(dumpPath(getRealStoreDir() + std::string(printStorePath(path), config().storeDir.size()))); + co_return make_box_ptr( + dumpPath(getRealStoreDir() + std::string(printStorePath(path), config().storeDir.size())) + ); +} catch (...) { + co_return result::current_exception(); } const std::string LocalFSStore::drvsLogDir = "drvs"; diff --git a/lix/libstore/local-fs-store.hh b/lix/libstore/local-fs-store.hh index d469f8011..7f4668b45 100644 --- a/lix/libstore/local-fs-store.hh +++ b/lix/libstore/local-fs-store.hh @@ -42,7 +42,7 @@ public: LocalFSStoreConfig & config() override = 0; const LocalFSStoreConfig & config() const override = 0; - box_ptr narFromPath(const StorePath & path) override; + kj::Promise>> narFromPath(const StorePath & path) override; ref getFSAccessor() override; /** diff --git a/lix/libstore/make-content-addressed.cc b/lix/libstore/make-content-addressed.cc index dd21a51cc..7a41f538a 100644 --- a/lix/libstore/make-content-addressed.cc +++ b/lix/libstore/make-content-addressed.cc @@ -26,7 +26,7 @@ try { std::string oldHashPart(path.hashPart()); StringSink sink; - srcStore.narFromPath(path)->drainInto(sink); + TRY_AWAIT(srcStore.narFromPath(path))->drainInto(sink); StringMap rewrites; diff --git a/lix/libstore/remote-fs-accessor.cc b/lix/libstore/remote-fs-accessor.cc index 9da86795b..24450ad7b 100644 --- a/lix/libstore/remote-fs-accessor.cc +++ b/lix/libstore/remote-fs-accessor.cc @@ -101,7 +101,7 @@ try { } StringSink sink; - store->narFromPath(storePath)->drainInto(sink); + TRY_AWAIT(store->narFromPath(storePath))->drainInto(sink); co_return {TRY_AWAIT(addToCache(storePath.hashPart(), std::move(sink.s))), restPath}; } catch (...) { co_return result::current_exception(); diff --git a/lix/libstore/remote-store.cc b/lix/libstore/remote-store.cc index 95eda7c56..8b2c138fc 100644 --- a/lix/libstore/remote-store.cc +++ b/lix/libstore/remote-store.cc @@ -999,15 +999,17 @@ RemoteStore::Connection::~Connection() } } -box_ptr RemoteStore::narFromPath(const StorePath & path) -{ +kj::Promise>> RemoteStore::narFromPath(const StorePath & path) +try { auto conn(connections->get()); conn->to << WorkerProto::Op::NarFromPath << printStorePath(path); conn->processStderr(); - return make_box_ptr([](auto conn) -> WireFormatGenerator { + co_return make_box_ptr([](auto conn) -> WireFormatGenerator { co_yield copyNAR(conn->from); }(std::move(conn))); -} +} catch (...) { + co_return result::current_exception();} + ref RemoteStore::getFSAccessor() { diff --git a/lix/libstore/remote-store.hh b/lix/libstore/remote-store.hh index 6b08f1f00..a095dd5cc 100644 --- a/lix/libstore/remote-store.hh +++ b/lix/libstore/remote-store.hh @@ -199,7 +199,7 @@ protected: virtual ref getFSAccessor() override; - virtual box_ptr narFromPath(const StorePath & path) override; + virtual kj::Promise>> narFromPath(const StorePath & path) override; private: diff --git a/lix/libstore/store-api.cc b/lix/libstore/store-api.cc index b78147f00..e9364f63d 100644 --- a/lix/libstore/store-api.cc +++ b/lix/libstore/store-api.cc @@ -1126,7 +1126,7 @@ try { CopyPathStream source{ act, info->narSize, - make_box_ptr(srcStore.narFromPath(storePath)) + make_box_ptr(TRY_AWAIT(srcStore.narFromPath(storePath))) }; TRY_AWAIT(dstStore.addToStore(*info, source, repair, checkSigs)); co_return result::success(); @@ -1275,7 +1275,7 @@ try { makeCopyPathMessage(srcUri, dstUri, storePathS), Logger::Fields{storePathS, srcUri, dstUri}, info->narSize, - make_box_ptr(srcStore.narFromPath(missingPath)) + make_box_ptr(TRY_AWAIT(srcStore.narFromPath(missingPath))) ); } catch (...) { co_return result::current_exception(); diff --git a/lix/libstore/store-api.hh b/lix/libstore/store-api.hh index 2448005eb..164716151 100644 --- a/lix/libstore/store-api.hh +++ b/lix/libstore/store-api.hh @@ -606,7 +606,7 @@ public: /** * Generate a NAR dump of a store path. */ - virtual box_ptr narFromPath(const StorePath & path) = 0; + virtual kj::Promise>> narFromPath(const StorePath & path) = 0; /** * For each path, if it's a derivation, build it. Building a diff --git a/lix/libstore/uds-remote-store.hh b/lix/libstore/uds-remote-store.hh index a3e05474f..a28e6b2b3 100644 --- a/lix/libstore/uds-remote-store.hh +++ b/lix/libstore/uds-remote-store.hh @@ -42,7 +42,7 @@ public: ref getFSAccessor() override { return LocalFSStore::getFSAccessor(); } - box_ptr narFromPath(const StorePath & path) override + kj::Promise>> narFromPath(const StorePath & path) override { return LocalFSStore::narFromPath(path); } /** diff --git a/lix/nix/dump-path.cc b/lix/nix/dump-path.cc index de3e8f302..33baef36e 100644 --- a/lix/nix/dump-path.cc +++ b/lix/nix/dump-path.cc @@ -22,7 +22,7 @@ struct CmdDumpPath : StorePathCommand { logger->pause(); FdSink sink(STDOUT_FILENO); - store->narFromPath(storePath)->drainInto(sink); + aio().blockOn(store->narFromPath(storePath))->drainInto(sink); sink.flush(); } }; diff --git a/lix/nix/verify.cc b/lix/nix/verify.cc index fcad4ac85..4f233297d 100644 --- a/lix/nix/verify.cc +++ b/lix/nix/verify.cc @@ -1,11 +1,13 @@ #include "lix/libcmd/command.hh" #include "lix/libmain/shared.hh" #include "lix/libstore/store-api.hh" +#include "lix/libutil/async.hh" #include "lix/libutil/thread-pool.hh" #include "lix/libutil/signals.hh" #include "lix/libutil/exit.hh" #include +#include using namespace nix; @@ -81,7 +83,7 @@ struct CmdVerify : StorePathsCommand ThreadPool pool{"Verify pool"}; - auto doPath = [&](const StorePath & storePath) { + auto doPath = [&](AsyncIoRoot & aio, const StorePath & storePath) { try { checkInterrupt(); @@ -99,7 +101,7 @@ struct CmdVerify : StorePathsCommand auto hashSink = HashSink(info->narHash.type); - store->narFromPath(info->path)->drainInto(hashSink); + aio.blockOn(store->narFromPath(info->path))->drainInto(hashSink); auto hash = hashSink.finish(); @@ -173,7 +175,7 @@ struct CmdVerify : StorePathsCommand }; for (auto & storePath : storePaths) - pool.enqueue(std::bind(doPath, storePath)); + pool.enqueueWithAio(std::bind(doPath, std::placeholders::_1, storePath)); pool.process();