1
1
Fork 0
mirror of https://github.com/NixOS/nix.git synced 2025-11-09 03:56:01 +01:00

Merge pull request #13784 from NixOS/queryPathInfo-dont-disconnect

Fix client disconnect when queryPathInfo() returns a negative result
This commit is contained in:
Jörg Thalheim 2025-08-19 17:16:47 +02:00 committed by GitHub
commit 5c0eff24d5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 22 additions and 11 deletions

View file

@ -311,6 +311,8 @@ protected:
LRUCache<std::string, PathInfoCacheValue> pathInfoCache; LRUCache<std::string, PathInfoCacheValue> pathInfoCache;
}; };
void invalidatePathInfoCacheFor(const StorePath & path);
SharedSync<State> state; SharedSync<State> state;
std::shared_ptr<NarInfoDiskCache> diskCache; std::shared_ptr<NarInfoDiskCache> diskCache;

View file

@ -109,7 +109,8 @@ struct WorkerProto::BasicClientConnection : WorkerProto::BasicConnection
const StorePathSet & paths, const StorePathSet & paths,
SubstituteFlag maybeSubstitute); SubstituteFlag maybeSubstitute);
UnkeyedValidPathInfo queryPathInfo(const StoreDirConfig & store, bool * daemonException, const StorePath & path); std::optional<UnkeyedValidPathInfo>
queryPathInfo(const StoreDirConfig & store, bool * daemonException, const StorePath & path);
void putBuildDerivationRequest( void putBuildDerivationRequest(
const StoreDirConfig & store, const StoreDirConfig & store,

View file

@ -259,13 +259,14 @@ void RemoteStore::queryPathInfoUncached(
const StorePath & path, Callback<std::shared_ptr<const ValidPathInfo>> callback) noexcept const StorePath & path, Callback<std::shared_ptr<const ValidPathInfo>> callback) noexcept
{ {
try { try {
std::shared_ptr<const ValidPathInfo> info; auto info = ({
{
auto conn(getConnection()); auto conn(getConnection());
info = std::make_shared<ValidPathInfo>( conn->queryPathInfo(*this, &conn.daemonException, path);
StorePath{path}, conn->queryPathInfo(*this, &conn.daemonException, path)); });
} if (!info)
callback(std::move(info)); callback(nullptr);
else
callback(std::make_shared<ValidPathInfo>(StorePath{path}, *info));
} catch (...) { } catch (...) {
callback.rethrow(); callback.rethrow();
} }
@ -456,7 +457,9 @@ StorePath RemoteStore::addToStoreFromDump(
} }
if (fsm != dumpMethod) if (fsm != dumpMethod)
unsupported("RemoteStore::addToStoreFromDump doesn't support this `dumpMethod` `hashMethod` combination"); unsupported("RemoteStore::addToStoreFromDump doesn't support this `dumpMethod` `hashMethod` combination");
return addCAToStore(dump, name, hashMethod, hashAlgo, references, repair)->path; auto storePath = addCAToStore(dump, name, hashMethod, hashAlgo, references, repair)->path;
invalidatePathInfoCacheFor(storePath);
return storePath;
} }
void RemoteStore::addToStore(const ValidPathInfo & info, Source & source, RepairFlag repair, CheckSigsFlag checkSigs) void RemoteStore::addToStore(const ValidPathInfo & info, Source & source, RepairFlag repair, CheckSigsFlag checkSigs)

View file

@ -319,6 +319,11 @@ bool Store::PathInfoCacheValue::isKnownNow()
return std::chrono::steady_clock::now() < time_point + ttl; return std::chrono::steady_clock::now() < time_point + ttl;
} }
void Store::invalidatePathInfoCacheFor(const StorePath & path)
{
state.lock()->pathInfoCache.erase(path.to_string());
}
std::map<std::string, std::optional<StorePath>> Store::queryStaticPartialDerivationOutputMap(const StorePath & path) std::map<std::string, std::optional<StorePath>> Store::queryStaticPartialDerivationOutputMap(const StorePath & path)
{ {
std::map<std::string, std::optional<StorePath>> outputs; std::map<std::string, std::optional<StorePath>> outputs;

View file

@ -244,7 +244,7 @@ void WorkerProto::BasicServerConnection::postHandshake(const StoreDirConfig & st
WorkerProto::write(store, *this, info); WorkerProto::write(store, *this, info);
} }
UnkeyedValidPathInfo WorkerProto::BasicClientConnection::queryPathInfo( std::optional<UnkeyedValidPathInfo> WorkerProto::BasicClientConnection::queryPathInfo(
const StoreDirConfig & store, bool * daemonException, const StorePath & path) const StoreDirConfig & store, bool * daemonException, const StorePath & path)
{ {
to << WorkerProto::Op::QueryPathInfo << store.printStorePath(path); to << WorkerProto::Op::QueryPathInfo << store.printStorePath(path);
@ -253,14 +253,14 @@ UnkeyedValidPathInfo WorkerProto::BasicClientConnection::queryPathInfo(
} catch (Error & e) { } catch (Error & e) {
// Ugly backwards compatibility hack. // Ugly backwards compatibility hack.
if (e.msg().find("is not valid") != std::string::npos) if (e.msg().find("is not valid") != std::string::npos)
throw InvalidPath(std::move(e.info())); return std::nullopt;
throw; throw;
} }
if (GET_PROTOCOL_MINOR(protoVersion) >= 17) { if (GET_PROTOCOL_MINOR(protoVersion) >= 17) {
bool valid; bool valid;
from >> valid; from >> valid;
if (!valid) if (!valid)
throw InvalidPath("path '%s' is not valid", store.printStorePath(path)); return std::nullopt;
} }
return WorkerProto::Serialise<UnkeyedValidPathInfo>::read(store, *this); return WorkerProto::Serialise<UnkeyedValidPathInfo>::read(store, *this);
} }