Skip to content

nix-env: remove lockProfile() when calling --list-generations - #16523

Merged
xokdvium merged 1 commit into
NixOS:masterfrom
thiagokokada:fix-5144
Sep 26, 2026
Merged

xokdvium merged 1 commit into
NixOS:masterfrom
thiagokokada:fix-5144

Conversation

@thiagokokada

@thiagokokada thiagokokada commented Sep 26, 2026 •

Copy link
Copy Markdown
Contributor

--list-generations is a read-only call, so it shouldn't need root.

Fix #5144.

Motivation

nix-env --list-generations need a profile lock, that in multi-user installs means it needs root to succeed. However nix-env --list-generations is a read-only operation, so it should not need root.

Context

This is a long standing issue for nixos-rebuild-ng, since users want to run nixos-rebuild list-generations without needing root. Right now we have 2 different code paths to list generations, one where we manually scrap the /nix/store for the data we need (used by nixos-rebuild list-generations) and another using nix-env --list-generations (used for nixos-rebuild switch --rollback, since this needs root anyway).

Getting this PR merged would mean we can unify both code paths and also means we could avoid unholy hacks like this one, that reimplements the nix-env --list-profiles as a shell script to get both non-root+remote usage at the cost of my sanity: NixOS/nixpkgs#560972.

I am not a specialist in C++ or CppNix codebase, but the removal of this lock seems safe: opListGenerations is only called when nix-env --list-generations is used.

As part of the Automation/AI policy, I used Codex with gpt-5.6-terra model to understand the issue, but the coding part was done for me.


Add 👍 to pull requests you find important.

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

`--list-generations` is a read-only call, so it shouldn't need root.

Fix NixOS#5144.
@github-actions github-actions Bot added the new-cli Relating to the "nix" command label Sep 26, 2026

@xokdvium xokdvium left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like this originates from 2006! 86cbd93

The only potential issue I see is trying to list generations while the profile is being modified.

There's probably pre-existing issues with us using std::filesystem for directory iterator:

[Note 4 : If a file is removed from or added to a directory after the construction of a directory_iterator for the
directory, it is unspecified whether or not subsequently incrementing the iterator will ever result in an iterator
referencing the removed or added directory entry. See POSIX readdir. — end note]

And findGenerations could stand to tolerate disappearing files instead barfing on lstat but it doesn't seem all that bad IMO compared to failing outright. Lemme push an update for that.

@xokdvium

Copy link
Copy Markdown
Contributor

Hm, alternatively: maybe behavior of findGenerations should stay unspecified if the profile is being concurrently modified - that's what is effectively already is in CmdProfileDiffClosures and CmdProfileHistory. It might be a bit too hard to make it behave sanely and consistently with concurrent modifications (and even harder to test).

@xokdvium xokdvium left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll approve optimistically here seeing that probably the racy listing isn't that big of a deal, but it would be nice if someone could think of a way to check how we'd behave when racing the same profile dir.

@thiagokokada

thiagokokada commented Sep 26, 2026 •

Copy link
Copy Markdown
Contributor Author

Just one more argument in favor of this change: nix profile history (that I imagine it is the equivalent command in the new nix CLI and does the same call for findGenerations()) doesn't lock/need root.

Sadly we can't use nix profile history in nixos-rebuild-ng because it doesn't expose enough information.

@xokdvium

Copy link
Copy Markdown
Contributor

Indeed that's what I meant by:

modified - that's what is effectively already is in CmdProfileDiffClosures and CmdProfileHistory

@xokdvium

Copy link
Copy Markdown
Contributor

Filed #16524. Let's proceed here.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

nix-env --list-generations shouldn't require root

2 participants