-
-
Notifications
You must be signed in to change notification settings - Fork 14.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
nixos: Support systemd-gpt-auto-root #282022
Conversation
I had to run `sudo sgdisk --typecode=2:4F68BCE3-E8CD-4DB1-96E7-FBCAF984B709 /dev/nvme3n1` in order to cause the right partition type code to be applied to the correct partition, so that `systemd-gpt-auto-generator` would detect it at boot time.
philiptaron/flock.nix@58dfcb6 is me testing this out on my real machine; it works great. I had to do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I really like having systemd-gpt-auto-generator
(and the other generators) find and detect partitions.
I'd love to see this committed -- what's outstanding, do you think, @ElvishJerricco? |
The only thing that gives me pause is the handling of
so that it can be extended with the other options that systemd supports in the future, rather than having this |
That makes sense. It would default to fstab, you think? Or to something else? |
I agree here. There are various methods of how systemd can setup the mounts, and I think rather than having one or another (i.e. |
nixos/modules/tasks/filesystems.nix
Outdated
{ | ||
assertion = config.boot.initrd.gptAutoRoot.enable -> config.boot.loader.systemd-boot.enable; | ||
message = '' | ||
'boot.initrd.gptAutoRoot.enable' requires systemd-boot. | ||
''; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not the case if booting from a UKI with systemd-stub, where it will take care of setting up the EFI variables for the root disk: https://www.freedesktop.org/software/systemd/man/latest/systemd-stub.html#LoaderDevicePartUUID
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, we don't include ways of using systemd-stub at this time.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, we have a builder for ukify? We maybe can't properly check if a UKI is used, but then this assertion should be removed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah I agree with @msanft we should not assert on that. Booting without enabling sd-boot via the module system is an actual use-case we have for appliance images.
This doesn't work. the I personally use |
@arianvp But we don't support other things in |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is really cool! The assertion in filesystems.nix on whether the user explicitly includes the rootfs has been bugging me for a while now!
nixos/modules/tasks/filesystems.nix
Outdated
{ | ||
assertion = config.boot.initrd.gptAutoRoot.enable -> config.boot.loader.systemd-boot.enable; | ||
message = '' | ||
'boot.initrd.gptAutoRoot.enable' requires systemd-boot. | ||
''; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah I agree with @msanft we should not assert on that. Booting without enabling sd-boot via the module system is an actual use-case we have for appliance images.
b972fc6
to
b50070e
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A couple notes.
- If
boot.initrd.supportedFilesystems = ["ext4"];
(for example) is not set,systemd-gpt-auto-generator
will fail to find the root file system. That's a sharp edge, and one that almost made me believe that the thing didn't work. - I had to edit the disk earlier in order to set the correct GUID (
sgdisk --typecode=2:4F68BCE3-E8CD-4DB1-96E7-FBCAF984B709 /dev/nvme3n1
) as the type of the partition wasn't right at my initial format time. That's a sharp edge. - I note this in the logs from this boot:
Mar 03 14:46:35 zebul systemd-gpt-auto-generator[577]: Failed to chase block device, ignoring: No such file or directory
Mar 03 14:46:35 zebul systemd-gpt-auto-generator[577]: Probed fstype 'ext4' on partition /dev/disk/by-diskseq/1-part2.
Mar 03 14:46:35 zebul systemd-gpt-auto-generator[577]: Reading EFI variable /sys/firmware/efi/efivars/LoaderDevicePartUUID-4a67b082-0a4c-41cf-b6c7-440b29bb8c4f.
Mar 03 14:46:35 zebul systemd-gpt-auto-generator[577]: Root partition not marked for growing the file system in the GPT partition table, not generating drop-in for systemd-growfs-root.service.
I don't think any of those logs are a problem, just noting them as "expected output" from the tool.
@@ -688,7 +688,7 @@ in | |||
|
|||
config = mkIf config.boot.initrd.enable { | |||
assertions = [ | |||
{ assertion = any (fs: fs.mountPoint == "/") fileSystems; | |||
{ assertion = !config.boot.initrd.systemd.enable -> any (fs: fs.mountPoint == "/") fileSystems; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If config.boot.initrd.systemd.enable
is set, there is no assertion. If config.boot.initrd.systemd.enable
is not set, there is an assertion when no "/" mountpoint is set.
assertion = cfg.root == "fstab" -> any (fs: fs.mountPoint == "/") (builtins.attrValues config.fileSystems); | ||
message = "The ‘fileSystems’ option does not specify your root file system."; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, and here's the other assertion.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! I think this is a good solution that can also serve as a ground for future additions, e.g. using systemd-veritysetup-generator
.
I actually think this should work with all other systemd generators that are capable of setting up the root mounts, as even if some have other options (e.g. roothash
for systemd-veritysetup-generator
), all that I have looked at seem to be fine with additionally having root
.
Yes, might not hurt to additionally document the requirement for DDI-conformance when using this, either in the release notes or the module documentation. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's fix the merge conflict and this is good to go on my end.
b50070e
to
f1731f2
Compare
This also happens to fix #276374. It's easy to modify the |
So that resumeDevice isn't needed to make systemd stage 1 work.
@ofborg test hibernate hibernate-systemd-stage-1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tested this on my systems that are all running impermanence with a tmpfs as root to make sure that that use case still works, and I haven't encountered any issues.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for getting this in!
@@ -371,7 +389,12 @@ in { | |||
"autofs" | |||
# systemd-cryptenroll | |||
] ++ lib.optional cfg.enableTpm2 "tpm-tis" | |||
++ lib.optional (cfg.enableTpm2 && !(pkgs.stdenv.hostPlatform.isRiscV64 || pkgs.stdenv.hostPlatform.isArmv7)) "tpm-crb"; | |||
++ lib.optional (cfg.enableTpm2 && !(pkgs.stdenv.hostPlatform.isRiscV64 || pkgs.stdenv.hostPlatform.isArmv7)) "tpm-crb" | |||
++ lib.optional cfg.package.withEfi "efivarfs"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't this be conditional on cfg.root == "gpt-auto"
? I don't see why this feature should add kernel modules for users who don't enable it. Adding it is problematic for me because it doesn't exist on armv6l.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@lopsided98 efivarfs
is useful for a few features, notably including hibernation. I'd rather disable it on platforms that don't support it than require it to be explicitly enabled.
If efivarfs
doesn't exist on a platform, then I'm surprised we build systemd with withEfi = true
. Maybe that's the change we should make?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
withEfi
defaults to stdenv.hostPlatform.isEfi
. In practice, isEfi
means "platforms where systemd EFI support can be built". There are unlikely to be any armv6l systems that use EFI, so it would be fine to remove it from isEfi
, but I'm still not super happy with tying efivarfs
in the initrd to systemd EFI support.
There is no way to override boot.initrd.availableKernelModules
to remove an item, so we should be careful about what is added unconditionally. If someone wants to disable EFI support in their kernel for whatever reason, they also have to override systemd and rebuild the world. If hibernation needs efivarsfs
, it should be automatically enabled in that module as well. I actually have a similar objection to autofs
, but it has never caused enough problems for me to try fixing it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- You don't have to rebuild the world to override systemd. You can just set
systemd.package = pkgs.systemd.override { withEfi = false; };
- Hibernation isn't really something we have a module for. It's just something systemd is able to do. So simply having
systemctl
means a user is able to attempt to hibernate.
We could have an option like boot.initrd.systemd.efiSupport
with a default of cfg.package.withEfi
so that it can be reasonably overridden. I still think this is wrong, however. Ideally, a system that doesn't have EFI should have systemd.package
set to a systemd override with EFI disabled.
Alternatively, we could have a new option like boot.initrd.optionalKernelModules
which lists modules that should be included if the kernel build has them. This would be helpful in other situations as well. Like the all-hardware.nix
profile breaks when you build with the RPi kernel, since it disables many of the modules that all-hardware.nix
has in availableKernelModules
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I actually have a similar objection to autofs, but it has never caused enough problems for me to try fixing it.
autofs
is required for systemd to boot as far as I am aware. as systemd ships with some required .automount
units
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I actually have a similar objection to autofs, but it has never caused enough problems for me to try fixing it.
autofs
is required for systemd to boot as far as I am aware. as systemd ships with some required.automount
units
From the docs on CONFIG_AUTOFS_FS:
The automounter is a tool to automatically mount remote file systems on demand. This implementation is partially kernel-based to reduce overhead in the already-mounted case; this is unlike the BSD automounter (amd), which is a pure user space daemon.
To use the automounter you need the user-space tools from https://www.kernel.org/pub/linux/daemons/autofs/; you also want to answer Y to "NFS file system support", below.
To compile this support as a module, choose M here: the module will be called autofs.
If you are not a part of a fairly large, distributed network or don't have a laptop which needs to dynamically reconfigure to the local network, you probably do not need an automounter, and can say N here.
I only see one .automount
unit that ships with systemd and it looks trivially replaceable.
…for the forseeable." This reverts commit 4b2c89e. Testing to see if it's what's causing my activation woes.
It brings me no pleasure to report that setting
|
… for the forseeable." This reverts commit d3bb46c. Per Matrix discussion, we're going to add in `rw` to the kernel arguments.
Description of changes
Rather than removing the broken generator in #277703, why not just support it?
Note: You must add your desired file system type to
boot.initrd.supportedFilesystems
.Fixes #293586, #276374
Things done
nix.conf
? (See Nix manual)sandbox = relaxed
sandbox = true
nix-shell -p nixpkgs-review --run "nixpkgs-review rev HEAD"
. Note: all changes have to be committed, also see nixpkgs-review usage./result/bin/
)