Nix goes into lengths to try to not garbage collect store paths that are in use. It goes through the processes and finds store paths from their /proc/$pid/environ, fds, maps, lsof
output, etc:
This is obviously not, and cannot be, entirely perfect. For example, one issue I’m running into is with nix-locate
’s command-not-found
hook: /etc/bashrc
sources command-not-found.sh
from nix-index-with-db
, which defines a bash function command_not_found_handle
that has a hardcoded path to /nix/store/s8pf5...-nix-index-with-db-0.1.8/bin/nix-locate
.
None of this appears in anything that Nix would find GC roots in , so nix-index-with-db
can get garbage collected. A bash environment variable also doesn’t help since /proc/$pid/environ
contains the initial environment of the bash.
Now I consider this exact issue minor and probably not worth going into great lengths to avoid, but perhaps there are other similar issues that could be solved in a similar fashion?
So I’m wondering if it would be possible to define a way to declare that a certain process depends on a certain store path.
Obviously a process opening a file would be enough, but that’s perhaps a bit annoying; getting bash to open and keep open /etc/bashrc
open would be sufficient, but feels like it might require modifying bash, and it would consume a file descriptor (or it could map it).
Instead I’m thinking maybe it would be possible to develop a mechanism to attach such information to a specific process from outside, so we could have something like
nix-register-gc-roots --pid $pid /nix/store/...
This could use something like (pid, start_time)
as a unique identifier for that process so that reused pids won’t prevent GC.
Would something like this be desirable? Overly complex for the benefits?