Skip to content

Add temproots in copyPaths, plus all the associated stuff#15719

Open
dramforever wants to merge 8 commits into
NixOS:masterfrom
dramforever:batch-addtemproots
Open

Add temproots in copyPaths, plus all the associated stuff#15719
dramforever wants to merge 8 commits into
NixOS:masterfrom
dramforever:batch-addtemproots

Conversation

@dramforever
Copy link
Copy Markdown
Contributor

Motivation

GC "race" whack-a-mole.

Context

Fixes, hopefully, #1970. Supersedes #15613. Originally discussed in #15616 but split out.

Make copyPaths add the copied paths as temproots, but hopefully in a better manner than individually rooting every single path:

  • Change the Store::addTempRoot virtual method to a batched Store::addTempRoots method, with the original one remaining as a non-virtual helper. Implement LocalStore::addTempRoots as writing out temproots in a batch. Also add an LRU cache for LocalStore::addTempRoots. RemoteStore::addTempRoots is just a loop.
  • Add AddTempRootsFlag to Store::queryValidPaths
  • In copyPaths, set AddTempRootsFlag while calling queryValidPaths
  • Finally, add a AddTempRootsFlag flag worker protocol operation QueryValidPaths, and use that in RemoteStore::queryValidPaths. This requires a new daemon on the remote side, in exchange for (hopefully) better performance.

Adding a flag to worker protocol QueryValidPaths is somewhat unorthogonal, but it was how it's done in the legacy SSH store, and I do think it still makes sense to do in QueryValidPaths in the worker protocol since it closes a TOCTOU for the result of list of valid paths, if needed by the caller. I haven't added a batch AddTempRoots worker protocol operation since it doesn't seem to be needed.

Also note that

  • The first commit "libstore: gc: Write temproot before trying the GC lock" is theoretically a standalone fix, but it's included here since the code is changed later by the batch LocalStore::addTempRoots code. Including it makes the later commit make more sense.

Add 👍 to pull requests you find important.

The Nix maintainer team uses a GitHub project board to schedule and track reviews.

@github-actions github-actions Bot added new-cli Relating to the "nix" command store Issues and pull requests concerning the Nix store labels Apr 21, 2026
@dramforever dramforever requested a review from xokdvium April 21, 2026 06:28
Move the writing of the temproots file to before checking the GC lock.
This closes a race, however unlikely, where yet another GC may start
again after we sent the temproots to the old running GC, but before
writing the temproots file.
Introduce LocalStore::addTempRoots, which adds all temproots in a batch
for LocalStore.

Make this available from the base class Store by making a virtual method
Store::addTempRoots, overriding it in LocalStore and RemoteStore (it is
just a loop for each path because the benefit of having this be batched
is unclear), and making the single-path Store::addTempRoot a wrapper
around that.
This avoids some system calls in case of duplicate temproots.
Use the new batched addTempRoots for both convenience and better
performance for LocalStore.
Use the new batched addTempRoots for both convenience and better
performance for LocalStore.
Add AddTempRootsFlag for optionally adding all queried paths as
temproots. This will be used to close a GC race in copyPaths.

The existing LegacySSHStore::queryValidPaths subclass overload with the
lock parameter is absorbed. LegacySSHStore::Connection::queryValidPaths
(i.e. ServeProto::BasicClientConnection::queryValidPaths) remains
unchanged.
This closes a race where paths in the result of queryValidPaths can
become invalid if a GC happens later that deletes the path, leaving
paths invalid after return from copyPaths.
This asks the QueryValidPaths operation to add temproots on the remote,
saving roundtrips in RemoteStore::queryValidPaths.
@dramforever dramforever force-pushed the batch-addtemproots branch from 67d061f to 3a2bd29 Compare May 14, 2026 06:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

new-cli Relating to the "nix" command store Issues and pull requests concerning the Nix store

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant