-
-
Notifications
You must be signed in to change notification settings - Fork 40
Description
Running nix-eval-jobs without specifying --gc-roots-dir creates a temporary folder, where a permanent GC root for each evaluated derivation is created. But since this folder is removed before nix-eval-jobs terminates, those GC roots are not really permanent and become dangling immediately.
Doing this against a large package set, like nixpkgs, will create around 100k GC roots per run, which can quickly grow into the millions when executed multiple times and exhaust the available filesystem inodes.
The temporary folder creation was introduced by #342, sadly without an explanation why it's necessary.
nix-eval-jobs/src/nix-eval-jobs.cc
Lines 468 to 471 in 4b392b2
| if (myArgs.gcRootsDir.empty()) { | |
| const nix::Path tmpDir = nix::createTempDir(); | |
| gcRootsDir.emplace(tmpDir, true); | |
| myArgs.gcRootsDir = tmpDir; |
There are currently two places where the --gc-roots-dir value is used:
Lines 237 to 249 in 4b392b2
| if (!args.gcRootsDir.empty()) { | |
| const nix::Path root = | |
| args.gcRootsDir + "/" + | |
| std::string(nix::baseNameOf(drv.drvPath)); | |
| if (!nix::pathExists(root)) { | |
| auto localStore = | |
| state->store | |
| .dynamic_pointer_cast<nix::LocalFSStore>(); | |
| auto storePath = | |
| localStore->parseStorePath(drv.drvPath); | |
| localStore->addPermRoot(storePath, root); | |
| } | |
| } |
nix-eval-jobs/src/nix-eval-jobs.cc
Lines 573 to 576 in 4b392b2
| assert(!myArgs.gcRootsDir.empty()); | |
| const nix::Path root = | |
| myArgs.gcRootsDir + "/" + | |
| std::string(nix::baseNameOf(newDrvPathS)); |
The first one checks if a value is present, which is currently always true. The second place asserts that a value is present.
But both just create dangling GC roots in the end.
Could the temporary folder creation be disabled again?
If it's necessary for --constituents processing, could it be changed, that it only happens when --constituents is given?