libstore: asyncify Store::addTempRoot

Change-Id: Ie3ef2a637d54b22f0bf9c8aba14d2f7546c6cd9a
This commit is contained in:
eldritch horrors
2025-02-14 15:28:50 +00:00
parent 84dd5864f3
commit 81275c9ad7
17 changed files with 47 additions and 33 deletions
+1 -1
View File
@@ -888,7 +888,7 @@ static void opServe(AsyncIoRoot & aio, Strings opFlags, Strings opArgs)
auto paths = ServeProto::Serialise<StorePathSet>::read(*store, rconn);
if (lock && writeAllowed)
for (auto & path : paths)
store->addTempRoot(path);
aio.blockOn(store->addTempRoot(path));
if (substitute && writeAllowed) {
aio.blockOn(store->substitutePaths(paths));
+1 -1
View File
@@ -66,7 +66,7 @@ bool createUserEnv(EvalState & state, DrvInfos & elems,
/* This is only necessary when installing store paths, e.g.,
`nix-env -i /nix/store/abcd...-foo'. */
state.ctx.store->addTempRoot(*j.second);
state.aio.blockOn(state.ctx.store->addTempRoot(*j.second));
state.aio.blockOn(state.ctx.store->ensurePath(*j.second));
references.insert(*j.second);
+1 -1
View File
@@ -108,7 +108,7 @@ struct CacheImpl : Cache
auto locked = stmt.getInt(2) != 0;
auto timestamp = stmt.getInt(3);
store->addTempRoot(storePath);
TRY_AWAIT(store->addTempRoot(storePath));
if (!store->isValidPath(storePath)) {
// FIXME: we could try to substitute 'storePath'.
debug("ignoring disappeared cache entry '%s'", inAttrsJSON);
+1 -1
View File
@@ -127,7 +127,7 @@ struct PathInputScheme : InputScheme
auto storePath = store->maybeParseStorePath(absPath);
if (storePath)
store->addTempRoot(*storePath);
TRY_AWAIT(store->addTempRoot(*storePath));
time_t mtime = 0;
if (!storePath || storePath->name() != "source" || !store->isValidPath(*storePath)) {
+6 -6
View File
@@ -185,17 +185,17 @@ try {
trace("loading derivation");
if (nrFailed != 0) {
return {done(
co_return done(
BuildResult::MiscFailure,
{},
Error("cannot build missing derivation '%s'", worker.store.printStorePath(drvPath))
)};
);
}
/* `drvPath' should already be a root, but let's be on the safe
side: if the user forgot to make it a root, we wouldn't want
things being garbage collected while we're busy. */
worker.evalStore.addTempRoot(drvPath);
TRY_AWAIT(worker.evalStore.addTempRoot(drvPath));
/* Get the derivation. It is probably in the eval store, but it might be inthe main store:
@@ -211,9 +211,9 @@ try {
}
assert(drv);
return haveDerivation();
co_return TRY_AWAIT(haveDerivation());
} catch (...) {
return {result::current_exception()};
co_return result::current_exception();
}
@@ -250,7 +250,7 @@ try {
for (auto & i : drv->outputsAndOptPaths(worker.store))
if (i.second.second)
worker.store.addTempRoot(*i.second.second);
TRY_AWAIT(worker.store.addTempRoot(*i.second.second));
auto outputHashes = staticOutputHashes(worker.evalStore, *drv);
for (auto & [outputName, outputHash] : outputHashes)
+2 -2
View File
@@ -1185,8 +1185,8 @@ struct RestrictedStore : public virtual IndirectRootStore, public virtual GcStor
) override
try { unsupported("buildDerivation"); } catch (...) { return {result::current_exception()}; }
void addTempRoot(const StorePath & path) override
{ }
kj::Promise<Result<void>> addTempRoot(const StorePath & path) override
{ return {result::success()}; }
void addIndirectRoot(const Path & path) override
{ }
+1 -1
View File
@@ -52,7 +52,7 @@ kj::Promise<Result<Goal::WorkResult>> PathSubstitutionGoal::workImpl() noexcept
try {
trace("init");
worker.store.addTempRoot(storePath);
TRY_AWAIT(worker.store.addTempRoot(storePath));
/* If the path already exists we're done. */
if (!repair && worker.store.isValidPath(storePath)) {
+2 -1
View File
@@ -1,3 +1,4 @@
#include "build/derivation-goal.hh"
#include "lix/libutil/async-collect.hh"
#include "lix/libutil/charptr-cast.hh"
#include "lix/libstore/build/worker.hh"
@@ -146,7 +147,7 @@ Worker::makeBasicDerivationGoal(
try {
/* Prevent the .chroot directory from being
garbage-collected. (See isActiveTempFile() in gc.cc.) */
store.addTempRoot(drvPath);
TRY_AWAIT(store.addTempRoot(drvPath));
co_return makeGoalCommon(
derivationGoals,
+1 -1
View File
@@ -666,7 +666,7 @@ static void performOp(AsyncIoRoot & aio, TunnelLogger * logger, ref<Store> store
case WorkerProto::Op::AddTempRoot: {
auto path = store->parseStorePath(readString(from));
logger->startWork();
store->addTempRoot(path);
aio.blockOn(store->addTempRoot(path));
logger->stopWork();
to << 1;
break;
+12 -7
View File
@@ -2,6 +2,7 @@
#include "lix/libstore/local-store.hh"
#include "lix/libstore/pathlocks.hh"
#include "lix/libutil/processes.hh"
#include "lix/libutil/result.hh"
#include "lix/libutil/signals.hh"
#include "lix/libutil/finally.hh"
#include "lix/libutil/unix-domain-socket.hh"
@@ -65,7 +66,7 @@ try {
running. This should be superfluous since the caller should
have registered this root yet, but let's be on the safe
side. */
addTempRoot(storePath);
TRY_AWAIT(addTempRoot(storePath));
/* Don't clobber the link if it already exists and doesn't
point to the Nix store. */
@@ -116,27 +117,28 @@ void LocalStore::createTempRootsFile()
}
void LocalStore::addTempRoot(const StorePath & path)
{
kj::Promise<Result<void>> LocalStore::addTempRoot(const StorePath & path)
try {
if (config().readOnly) {
debug("Read-only store doesn't support creating lock files for temp roots, but nothing can be deleted anyways.");
return;
co_return result::success();
}
createTempRootsFile();
/* Open/create the global GC lock file. */
{
auto & fdGCLock = [&]() -> auto & {
auto fdGCLock(_fdGCLock.lock());
if (!*fdGCLock)
*fdGCLock = openGCLock();
}
return *fdGCLock;
}();
restart:
/* Try to acquire a shared global GC lock (non-blocking). This
only succeeds if the garbage collector is not currently
running. */
FdLock gcLock(*_fdGCLock.lock(), ltRead, FdLock::dont_wait);
FdLock gcLock(fdGCLock, ltRead, FdLock::dont_wait);
if (!gcLock.valid()) {
/* We couldn't get a shared global GC lock, so the garbage
@@ -190,6 +192,9 @@ void LocalStore::addTempRoot(const StorePath & path)
seen by a future run of the garbage collector. */
auto s = printStorePath(path) + '\0';
writeFull(_fdTempRoots.lock()->get(), s);
co_return result::success();
} catch (...) {
co_return result::current_exception();
}
+3 -3
View File
@@ -1214,7 +1214,7 @@ try {
}
};
addTempRoot(info.path);
TRY_AWAIT(addTempRoot(info.path));
if (repair || !isValidPath(info.path)) {
@@ -1366,7 +1366,7 @@ try {
auto dstPath = makeFixedOutputPathFromCA(name, desc);
addTempRoot(dstPath);
TRY_AWAIT(addTempRoot(dstPath));
if (repair || !isValidPath(dstPath)) {
@@ -1436,7 +1436,7 @@ try {
.references = references,
});
addTempRoot(dstPath);
TRY_AWAIT(addTempRoot(dstPath));
if (repair || !isValidPath(dstPath)) {
+1 -1
View File
@@ -218,7 +218,7 @@ public:
const StorePathSet & references,
RepairFlag repair) override;
void addTempRoot(const StorePath & path) override;
kj::Promise<Result<void>> addTempRoot(const StorePath & path) override;
private:
+1 -1
View File
@@ -269,7 +269,7 @@ try {
uint64_t done = 0;
for (auto & i : paths) {
addTempRoot(i);
TRY_AWAIT(addTempRoot(i));
if (!isValidPath(i)) continue; /* path was GC'ed, probably */
{
Activity act(*logger, lvlTalkative, actUnknown, fmt("optimising path '%s'", printStorePath(i)));
+5 -2
View File
@@ -758,12 +758,15 @@ try {
}
void RemoteStore::addTempRoot(const StorePath & path)
{
kj::Promise<Result<void>> RemoteStore::addTempRoot(const StorePath & path)
try {
auto conn(getConnection());
conn->to << WorkerProto::Op::AddTempRoot << printStorePath(path);
conn.processStderr();
readInt(conn->from);
return {result::success()};
} catch (...) {
return {result::current_exception()};
}
+1 -1
View File
@@ -129,7 +129,7 @@ public:
kj::Promise<Result<void>> ensurePath(const StorePath & path) override;
void addTempRoot(const StorePath & path) override;
kj::Promise<Result<void>> addTempRoot(const StorePath & path) override;
Roots findRoots(bool censor) override;
+7 -2
View File
@@ -666,8 +666,13 @@ public:
* Add a store path as a temporary root of the garbage collector.
* The root disappears as soon as we exit.
*/
virtual void addTempRoot(const StorePath & path)
{ debug("not creating temporary root, store doesn't support GC"); }
virtual kj::Promise<Result<void>> addTempRoot(const StorePath & path)
try {
debug("not creating temporary root, store doesn't support GC");
return {result::success()};
} catch (...) {
return {result::current_exception()};
}
/**
* @return a string representing information about the path that
+1 -1
View File
@@ -368,7 +368,7 @@ SV * derivationFromPath(char * drvPath)
void addTempRoot(char * storePath)
PPCODE:
try {
store()->addTempRoot(store()->parseStorePath(storePath));
aio().blockOn(store()->addTempRoot(store()->parseStorePath(storePath)));
} catch (Error & e) {
croak("%s", e.what());
}