GC roots cannot have a physical target #1036

Open
opened 2025-11-17 17:55:36 +00:00 by raito · 0 comments
Owner

Describe the bug

If you are using chroot stores for various separation objectives, you will run into the problem of managing the GC units for it.
Part of the job is also managing the direct roots for it.

A natural way to express GC roots is to simply symlink in the physical world and let Lix rebase the targets appropriately.

In practice, this doesn't work because GC root evaluation doesn't take place with physical vs. logical awareness, but always logical awareness.

As a consequence, it is necessary to have the symlink targets ALWAYS be logical ones, creating a skewed view outside the namespaces.

Steps To Reproduce

  1. Create a chroot store, let's say: /mnt (i.e. /mnt/nix/{store,var})
  2. Create some store paths and GC roots that symlinks /mnt/nix/var/nix/gcroots/some-path/mnt/nix/store/....)
  3. Run nix-collect-garbage --store /mnt
  4. See that some-path being GCed.

Expected behavior

some-path should not be GCed.

nix --version output

Lix 2.93.3.

Additional context

It's pretty obvious by reading the code in gc.c that isInStore uses config().storeDir which is logical awareness.
Question is what should be the fix? Should the GC code perform physical awareness or should isInStore perform physical awareness? Not obvious.

## Describe the bug If you are using chroot stores for various separation objectives, you will run into the problem of managing the GC units for it. Part of the job is also managing the direct roots for it. A natural way to express GC roots is to simply symlink in the physical world and let Lix rebase the targets appropriately. In practice, this doesn't work because GC root evaluation doesn't take place with physical vs. logical awareness, but always logical awareness. As a consequence, it is necessary to have the symlink targets *ALWAYS* be logical ones, creating a skewed view outside the namespaces. ## Steps To Reproduce 1. Create a chroot store, let's say: `/mnt` (i.e. `/mnt/nix/{store,var}`) 2. Create some store paths and GC roots that symlinks `/mnt/nix/var/nix/gcroots/some-path` → `/mnt/nix/store/....`) 3. Run `nix-collect-garbage --store /mnt` 4. See that `some-path` being GCed. ## Expected behavior `some-path` should not be GCed. ## `nix --version` output Lix 2.93.3. ## Additional context It's pretty obvious by reading the code in `gc.c` that `isInStore` uses `config().storeDir` which is logical awareness. Question is what should be the fix? Should the GC code perform physical awareness or should `isInStore` perform physical awareness? Not obvious.
raito self-assigned this 2025-11-17 17:55:36 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
lix-project/lix#1036
No description provided.