diff --git a/src/libfetchers/fetch-to-store.cc b/src/libfetchers/fetch-to-store.cc index 7c5c5be1036f..8dfb74a9c5af 100644 --- a/src/libfetchers/fetch-to-store.cc +++ b/src/libfetchers/fetch-to-store.cc @@ -46,6 +46,12 @@ std::pair fetchToStore2( auto hash = Hash::parseSRI(fetchers::getStrAttr(*res, "hash")); auto storePath = store.makeFixedOutputPathFromCA(name, ContentAddressWithReferences::fromParts(method, hash, {})); + + /* Add a temproot before the call to isValidPath to prevent accidental GC in case the + input is cached. Note that this must be done before to avoid races. */ + if (mode != FetchMode::DryRun) + store.addTempRoot(storePath); + if (mode == FetchMode::DryRun || store.maybeQueryPathInfo(storePath)) { debug( "source path '%s' cache hit in '%s' (hash '%s')", diff --git a/src/libstore/async-path-writer.cc b/src/libstore/async-path-writer.cc index 925c52ea371a..dce38b526478 100644 --- a/src/libstore/async-path-writer.cc +++ b/src/libstore/async-path-writer.cc @@ -160,6 +160,7 @@ struct AsyncPathWriterImpl : AsyncPathWriter for (auto & item : items) { StringSource source(item.contents); + store->addTempRoot(item.storePath); auto storePath = store->addToStoreFromDump( source, item.storePath.name(), diff --git a/src/libstore/derivations.cc b/src/libstore/derivations.cc index 8dc185e45543..5994e7cb43eb 100644 --- a/src/libstore/derivations.cc +++ b/src/libstore/derivations.cc @@ -146,6 +146,12 @@ Store::writeDerivation(const Derivation & drv, RepairFlag repair, std::shared_pt { auto [suffix, contents, references, path] = infoForDerivation(*this, drv); + /* In case the derivation is already valid, we bail out early since that's + faster. But we need to make sure that the derivation has a corresponding + temproot. It is added by the remote in addToStoreFromDump, but we'd like + to avoid sending a lot of drv contents to the daemon. */ + addTempRoot(path); + if (isValidPath(path) && !repair) return path;