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