diff options
author | Jake Waksbaum <jake.waksbaum@gmail.com> | 2020-11-16 02:35:50 -0500 |
---|---|---|
committer | Jake Waksbaum <jake.waksbaum@gmail.com> | 2020-11-16 02:35:50 -0500 |
commit | 01db455733899728947a15f8d50942f10432d61e (patch) | |
tree | bd95ffea1ea38a0c4e61f5d4991c1b8ec7b0a251 /src/libstore/remote-store.cc | |
parent | 258e5338d68c5d98090748bbbd49bd33a37c7954 (diff) |
Fix deadlock in nix-store when max-connections=1
This fixes a bug I encountered where `nix-store -qR` will deadlock when
the `--include-outputs` flag is passed and `max-connections=1`.
The deadlock occurs because `RemoteStore::queryDerivationOutputs` takes
the only connection from the connection pool and uses it to check the
daemon version. If the version is new enough, it calls
`Store::queryDerivationOutputs`, which eventually calls
`RemoteStore::queryPartialDerivationOutputMap`, where we take another
connection from the connection pool to check the version again. Because
we still haven't released the connection from the caller, this waits for
a connection to be available, causing a deadlock.
This diff solves the issue by using `getProtocol` to check the protocol
version in the caller `RemoteStore::queryDerivationOutputs`, which
immediately frees the connection back to the pool before returning the
protocol version. That way we've already freed the connection by the
time we call `RemoteStore::queryPartialDerivationOutputMap`.
Diffstat (limited to 'src/libstore/remote-store.cc')
-rw-r--r-- | src/libstore/remote-store.cc | 4 |
1 files changed, 2 insertions, 2 deletions
diff --git a/src/libstore/remote-store.cc b/src/libstore/remote-store.cc index b6f70057d..a392f3b8c 100644 --- a/src/libstore/remote-store.cc +++ b/src/libstore/remote-store.cc @@ -409,10 +409,10 @@ StorePathSet RemoteStore::queryValidDerivers(const StorePath & path) StorePathSet RemoteStore::queryDerivationOutputs(const StorePath & path) { - auto conn(getConnection()); - if (GET_PROTOCOL_MINOR(conn->daemonVersion) >= 0x16) { + if (GET_PROTOCOL_MINOR(getProtocol()) >= 0x16) { return Store::queryDerivationOutputs(path); } + auto conn(getConnection()); conn->to << wopQueryDerivationOutputs << printStorePath(path); conn.processStderr(); return worker_proto::read(*this, conn->from, Phantom<StorePathSet> {}); |