Skip to content
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

kexec is broken with lanzaboote #143

Open
jpdisco opened this issue Apr 8, 2023 · 10 comments
Open

kexec is broken with lanzaboote #143

jpdisco opened this issue Apr 8, 2023 · 10 comments
Labels
dependency Issues related to our dependencies
Milestone

Comments

@jpdisco
Copy link

jpdisco commented Apr 8, 2023

I am trying to reboot via kexec my computer using systemdctl kexec. This used to work just fine with normal nixos, but I am trying out lanzaboote (very cool btw :)) and it is not working at all anymore.

I now get this error.

Running /nix/store/pjp3v7ni274d1hh7cn4m5yhslgggzbrl-kexec-tools-2.0.25/bin/kexec --load "/boot/EFI/Linux/nixos-generation-294.efi" --append "init=/nix/store/h4mjlcgl479ll843nv43slmaqzr62wd8-nixos-system-poopbox-23.05.20230406.0e19daa/init loglevel=4"(null)
Cannot determine the file type of /boot/EFI/Linux/nixos-generation-294.efi
(kexec) failed with exit status 255.

Is there something I can do to fix this, or is kexec just something that is broken right now?

@blitz
Copy link
Member

blitz commented Apr 9, 2023

Can you show the command line that used to work for you before?

Cannot determine the file type of /boot/EFI/Linux/nixos-generation-294.efi

I'm pretty sure kexec doesn't support UEFI binaries. You need to specify the kernel directly for --load. It's one of the bzImage files in EFI/nixos.

@jpdisco
Copy link
Author

jpdisco commented Apr 9, 2023

It looks like you are right about the UEFI binaries, when I disable lanzaboote, it runs load with one of those bzImage files and it works well.

Running /nix/store/pjp3v7ni274d1hh7cn4m5yhslgggzbrl-kexec-tools-2.0.25/bin/kexec --load "/boot/EFI/nixos/zk1jnsj87zc6rl0klly6534sj5q5vzj8-linux-6.9.2-bzImage.efi" --append "init=/nix/store/h4mjlcgl479ll843nv43slmaqzr62wd8-nixos-system-poopbox-23.05.20230406.0e19daa/init loglevel=4(null)

So it seems like when lanzaboote is enabled it tries to load a UEFI binary for some reason.

@Myaats
Copy link
Contributor

Myaats commented Apr 9, 2023

Looked into it and it seems like kexec has yet to add support for Unified Kernel Images1. As lanzaboote only emits UKI's onto your ESP that one won't work, as a workaround try to use the kernel and init path provided by /nix/var/nix/profiles/system/boot.json or the other systems/generations.

Footnotes

  1. https://www.spinics.net/lists/kexec/msg30939.html

@MatthewCash
Copy link

I ran into this same problem a few weeks ago. If no kernel is manually loaded for kexec, systemd will try to load the one in the default boot loader entry. Run bootctl status | grep linux:, and it will show which kernel systemd will try to kexec into.

The solution seems to be to enable/run the prepare-kexec.service service, which will run a NixOS provided script to correctly setup kexec.

@lilyinstarlight
Copy link
Member

lilyinstarlight commented Apr 9, 2023

It looks like systemd can either parse the systemd-boot conf to determine the linux kernel to kexec or it just looks in $esp/EFI/Linux, which is where it is getting the lanzaboote image from

I did look into the systemd source code though and noticed there is a functionality to allow other bootloaders to specify this sort of information:

https://github.com/systemd/systemd/blob/v253/src/shared/bootspec.c#L1154-L1159

/* This function is similar to boot_entries_load_config(), however we automatically search for the
 * ESP and the XBOOTLDR partition unless it is explicitly specified. Also, if the user did not pass
 * an ESP or XBOOTLDR path directly, let's see if /run/boot-loader-entries/ exists. If so, let's
 * read data from there, as if it was an ESP (i.e. loading both entries and loader.conf data from
 * it). This allows other boot loaders to pass boot loader entry information to our tools if they
 * want to. */

So we could just synthesize a /run/boot-loader-entries with fake systemd-boot config for the correct kernels/initrds and then systemctl kexec would also work as expected

@alois31
Copy link
Contributor

alois31 commented Apr 10, 2023

The solution seems to be to enable/run the prepare-kexec.service service, which will run a NixOS provided script to correctly setup kexec.

This service is already enabled, but for some reason it doesn't get run automatically.

@MatthewCash
Copy link

The solution seems to be to enable/run the prepare-kexec.service service, which will run a NixOS provided script to correctly setup kexec.

This service is already enabled, but for some reason it doesn't get run automatically.

I meant enable as in run on startup, like the systemctl enable command, so on NixOS you would set

systemd.services."prepare-kexec".wantedBy = [ "multi-user.target" ];

@jpdisco
Copy link
Author

jpdisco commented Apr 11, 2023

systemd.services."prepare-kexec".wantedBy = [ "multi-user.target" ];

I added to my configuration and the problems are fixed!

@RaitoBezarius
Copy link
Member

This seems like something that should be sent to NixOS upstream by pinging the @NixOS/systemd team.

@RaitoBezarius
Copy link
Member

If someone can retest kexec on master, let me know. I will try to write test for it before.

@blitz blitz added the dependency Issues related to our dependencies label Oct 20, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
dependency Issues related to our dependencies
Projects
None yet
Development

No branches or pull requests

7 participants