Skip to content

nixos-init: init at 0.1.0#433154

Merged
misuzu merged 4 commits intoNixOS:masterfrom
nikstur:nixos-init
Sep 23, 2025
Merged

nixos-init: init at 0.1.0#433154
misuzu merged 4 commits intoNixOS:masterfrom
nikstur:nixos-init

Conversation

@nikstur
Copy link
Contributor

@nikstur nikstur commented Aug 12, 2025

This is the core of #428908

It adds a Rust binary called nixos-init that initializes NixOS. It basically replaces prepare-root (which is stage-2-init.sh (which contains the activationScripts)) and some other scripts.

Please see the README in the nixos-init package for more documenation and reasoning.

Things done

  • Built on platform:
    • x86_64-linux
    • aarch64-linux
    • x86_64-darwin
    • aarch64-darwin
  • Tested, as applicable:
  • Ran nixpkgs-review on this PR. See nixpkgs-review usage.
  • Tested basic functionality of all binary files, usually in ./result/bin/.
  • Nixpkgs Release Notes
    • Package update: when the change is major or breaking.
  • NixOS Release Notes
    • Module addition: when adding a new NixOS module.
    • Module update: when the change is significant.
  • Fits CONTRIBUTING.md, pkgs/README.md, maintainers/README.md and other READMEs.

Add a 👍 reaction to pull requests you find important.

@nix-owners nix-owners bot requested review from aanderse and flokli August 12, 2025 18:06
@nixpkgs-ci nixpkgs-ci bot added 10.rebuild-linux: 1-10 This PR causes between 1 and 10 packages to rebuild on Linux. 10.rebuild-darwin: 1-10 This PR causes between 1 and 10 packages to rebuild on Darwin. 10.rebuild-darwin: 1 This PR causes 1 package to rebuild on Darwin. 6.topic: nixos Issues or PRs affecting NixOS modules, or package usability issues specific to NixOS 8.has: module (update) This PR changes an existing module in `nixos/` 6.topic: systemd Software suite that provides an array of system components for Linux operating systems. labels Aug 12, 2025
@r-vdp
Copy link
Contributor

r-vdp commented Aug 12, 2025

I noticed that you drop the chroot-realpath package already in the first commit, but then only convert the usage sites to nix-init in the third. Maybe you should delete the package as part of the third commit then?

I'll try it out and give a more thorough review later, as I'm on mobile currently.

Great work in any case, looking forward to getting this merged!

@nikstur
Copy link
Contributor Author

nikstur commented Aug 12, 2025

Maybe you should delete the package as part of the third commit then?

That got lost in the wrong commit during rebasing. Thanks for catching it!

Fixed now.

@boomshroom
Copy link
Contributor

I'm guessing the reason most of this couldn't be handled by initrd-systemd directly is because doing so would require a new initrd every generation?

If that's the case, what would be the actual requirements for systemd to load? I'm fairly certain it refuses to boot without /usr/bin/env, but it seems perfectly fine without /bin/sh, and that should be safe to generate with systemd-tmpfiles. tmpfiles also supports being given literal text to write directly to a target file, which could potentially work for modprobe and the firmware if they aren't needed immediately when switching root.

Copy link
Member

@getchoo getchoo left a comment

Choose a reason for hiding this comment

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

This is probably the least important review I've made in Nixpkgs, but here are a couple typos I found while skimming the code

Thanks for all the work in documentation here, though. It made it so much easier to understand as someone not super familiar with our init stuff. The project structure is also great 👍

Copy link
Member

@flokli flokli left a comment

Choose a reason for hiding this comment

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

Didn't take look at the rust code yet, but did a pass on the text.

@r-vdp
Copy link
Contributor

r-vdp commented Aug 14, 2025

I booted my laptop with this patch included and everything looks fine. One weird thing is that none of the log::info! calls from the switch-root service made it into the system journal. I do see a log line from the find-etc service though. I didn't yet figure out the difference between the two services.

@emilazy
Copy link
Member

emilazy commented Aug 14, 2025

(Thanks for the ping and for the great work, hoping to take a look at this soon!)

@nikstur
Copy link
Contributor Author

nikstur commented Aug 18, 2025

I'm guessing the reason most of this couldn't be handled by initrd-systemd directly is because doing so would require a new initrd every generation?

That's one of the reasons.

If that's the case, what would be the actual requirements for systemd to load? I'm fairly certain it refuses to boot without /usr/bin/env, but it seems perfectly fine without /bin/sh

The hard hard requirements are (1) setting up /run/current-system, (2) setting up /etc and (3) setting up /usr/bin/env.

that should be safe to generate with systemd-tmpfiles

We've had discussions about this in the community. The issue is that the system() call from libc relies on /bin/sh and this could be called by any binary very very early in the boot process. Indeed we had this in kbd which called system() in systemd-vconsole-setup.service. Now solved by #434001. However, I haven't observed any more of these cases in my testing. I'm open to eventually do this, but for this PR I don't want to change the scope anymore.

tmpfiles also supports being given literal text to write directly to a target file, which could potentially work for modprobe and the firmware if they aren't needed immediately when switching root.

Here again, timing is the issue. You want to set these variables very very early but also not too earyl in the initrd. You only want to set them to their stage 2 paths just right before switching root.

@r-vdp
Copy link
Contributor

r-vdp commented Aug 19, 2025

I booted my laptop with this patch included and everything looks fine. One weird thing is that none of the log::info! calls from the switch-root service made it into the system journal. I do see a log line from the find-etc service though. I didn't yet figure out the difference between the two services.

Turns out that I was confused, because with this patch, nixos-init will be used to find the etc overlay image even if system.nixos-init.enable is set to false. So when building my system, I saw nixos-init being compiled and included, and I assumed that it was also used for the rest of the initrd stuff, but that wasn't the case.

I now enabled the option and booted again, and I do see the expected log messages. Everything looks fine, except that my nix store is not getting bind mounted. With the current code, when the nix store is not already a mount point, it does not get remounted. On my system /nix is a mount point but not /nix/store.

This patch fixes it, by also bind mounting the store if it wasn't a mount point: r-vdp@8463445 r-vdp@55ffd4c

@nikstur
Copy link
Contributor Author

nikstur commented Aug 19, 2025

So when building my system, I saw nixos-init being compiled and included, and I assumed that it was also used for the rest of the initrd stuff, but that wasn't the case.

That's still an important test case. You tested that everything works fine even when not enabling nixos-init.

This patch fixes it, by also bind mounting the store if it wasn't a mount point: r-vdp@8463445 r-vdp@55ffd4c

Thank you! Implemented the fix now.

@nixpkgs-ci nixpkgs-ci bot added 10.rebuild-darwin: 0 This PR does not cause any packages to rebuild on Darwin. and removed 10.rebuild-darwin: 1-10 This PR causes between 1 and 10 packages to rebuild on Darwin. 10.rebuild-darwin: 1 This PR causes 1 package to rebuild on Darwin. labels Sep 22, 2025
@nixpkgs-ci nixpkgs-ci bot added 10.rebuild-darwin: 1-10 This PR causes between 1 and 10 packages to rebuild on Darwin. 10.rebuild-darwin: 1 This PR causes 1 package to rebuild on Darwin. 8.has: changelog This PR adds or changes release notes 8.has: documentation This PR adds or changes documentation and removed 10.rebuild-darwin: 0 This PR does not cause any packages to rebuild on Darwin. labels Sep 22, 2025
Copy link
Contributor

@LordGrimmauld LordGrimmauld left a comment

Choose a reason for hiding this comment

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

My complaints were all addressed. I didn't run it on my system, but there is a nixos test and the changes look reasonable. Thank you :)

@nixpkgs-ci nixpkgs-ci bot added the 12.approvals: 2 This PR was reviewed and approved by two persons. label Sep 23, 2025
@nixpkgs-ci nixpkgs-ci bot added 12.approvals: 3+ This PR was reviewed and approved by three or more persons. and removed 12.approvals: 2 This PR was reviewed and approved by two persons. labels Sep 23, 2025
@nikstur
Copy link
Contributor Author

nikstur commented Sep 23, 2025

The merge queue seems to be stuck. However, I see nothing wrong. Any objections to bypassing the merge queue rules?

@LordGrimmauld
Copy link
Contributor

doesn't look stuck to me?

@nikstur
Copy link
Contributor Author

nikstur commented Sep 23, 2025

doesn't look stuck to me?

I can only merge by bypassing the rules. It seems to be waiting for ofborg (which might never finish).

image

@misuzu misuzu added this pull request to the merge queue Sep 23, 2025
@LordGrimmauld
Copy link
Contributor

You can press "merge when ready", which adds it to the merge queue. It won't wait on ofborg, it just will never say anything different than "merge when ready" since enabling merge queues.

Merged via the queue into NixOS:master with commit e7fa9ff Sep 23, 2025
34 of 37 checks passed
@nikstur
Copy link
Contributor Author

nikstur commented Sep 23, 2025

You can press "merge when ready", which adds it to the merge queue. It won't wait on ofborg, it just will never say anything different than "merge when ready" since enabling merge queues.

Ah Ok, I didn't know that thank you!

and newer series. However, embedded chips without LSX (Loongson SIMD eXtension), such as 2K0300 SoC, are not
supported. `pkgsCross.loongarch64-linux-embedded` can be used to build software and systems for these platforms.
- The official Nix formatter `nixfmt` is now stable and available as `pkgs.nixfmt`, deprecating the temporary `pkgs.nixfmt-rfc-style` attribute. The classic `nixfmt` will stay available for some more time as `pkgs.nixfmt-classic`.
- Added `nixos-init`, a Rust-based bashless initialization system for systemd initrd. This allows to build NixOS systems without any interpreter. Enable via `system.nixos-init.enable = true;`.
Copy link
Member

Choose a reason for hiding this comment

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

This entry belongs in the NixOS release notes, not the Nixpkgs release notes!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done: #446997

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

6.topic: nixos Issues or PRs affecting NixOS modules, or package usability issues specific to NixOS 6.topic: systemd Software suite that provides an array of system components for Linux operating systems. 8.has: changelog This PR adds or changes release notes 8.has: documentation This PR adds or changes documentation 8.has: module (new) This PR adds a module in `nixos/` 8.has: module (update) This PR changes an existing module in `nixos/` 8.has: tests This PR has tests 10.rebuild-darwin: 1-10 This PR causes between 1 and 10 packages to rebuild on Darwin. 10.rebuild-darwin: 1 This PR causes 1 package to rebuild on Darwin. 10.rebuild-linux: 1-10 This PR causes between 1 and 10 packages to rebuild on Linux. 12.approvals: 3+ This PR was reviewed and approved by three or more persons.

Projects

None yet

Development

Successfully merging this pull request may close these issues.