Systemd-boot for non-btrfs root

Hi

I try to follow this wiki, but it is incomplete for non-btrfs systems.

After # booctl install we need to populate the EFI partition with at least one kernel.

kernel-install working fine for that.

Example:

# kernel-install add 6.5.4-1-default /lib/modules/6.5.4-1-default/vmlinuz

# kernel-install add 6.5.3-1-default /lib/modules/6.5.3-1-default/vmlinuz

After that we have two bootable kernels in the EFI partition (I already deleted grub).

$ tree /boot/efi/
/boot/efi/
├── 13fa2da157c34b99a1b2d5d6e8eec38e
│   ├── 6.5.3-1-default
│   │   ├── initrd
│   │   └── linux
│   └── 6.5.4-1-default
│       ├── initrd
│       └── linux
├── EFI
│   ├── BOOT
│   │   └── BOOTX64.EFI
│   ├── Linux
│   └── systemd
│       └── systemd-bootx64.efi
└── loader
    ├── entries
    │   ├── 13fa2da157c34b99a1b2d5d6e8eec38e-6.5.3-1-default.conf
    │   └── 13fa2da157c34b99a1b2d5d6e8eec38e-6.5.4-1-default.conf
    ├── entries.srel
    ├── loader.conf
    └── random-seed
$ bootctl list 
         type: Boot Loader Specification Type #1 (.conf)
        title: openSUSE Tumbleweed (6.5.4-1-default) (default) (selected)
           id: 13fa2da157c34b99a1b2d5d6e8eec38e-6.5.4-1-default.conf
       source: /boot/efi//loader/entries/13fa2da157c34b99a1b2d5d6e8eec38e-6.5.4-1-default.conf
     sort-key: opensuse-tumbleweed
      version: 6.5.4-1-default
   machine-id: 13fa2da157c34b99a1b2d5d6e8eec38e
        linux: /boot/efi//13fa2da157c34b99a1b2d5d6e8eec38e/6.5.4-1-default/linux
       initrd: /boot/efi//13fa2da157c34b99a1b2d5d6e8eec38e/6.5.4-1-default/initrd
      options: root=UUID=52ec0975-e16c-4880-9fe6-c0dc4751c9c0 splash=silent mitigations=auto q>

         type: Boot Loader Specification Type #1 (.conf)
        title: openSUSE Tumbleweed (6.5.3-1-default)
           id: 13fa2da157c34b99a1b2d5d6e8eec38e-6.5.3-1-default.conf
       source: /boot/efi//loader/entries/13fa2da157c34b99a1b2d5d6e8eec38e-6.5.3-1-default.conf
     sort-key: opensuse-tumbleweed
      version: 6.5.3-1-default
   machine-id: 13fa2da157c34b99a1b2d5d6e8eec38e
        linux: /boot/efi//13fa2da157c34b99a1b2d5d6e8eec38e/6.5.3-1-default/linux
       initrd: /boot/efi//13fa2da157c34b99a1b2d5d6e8eec38e/6.5.3-1-default/initrd
      options: root=UUID=52ec0975-e16c-4880-9fe6-c0dc4751c9c0 splash=silent mitigations=auto q>

         type: Automatic
        title: Reboot Into Firmware Interface
           id: auto-reboot-to-firmware-setup
       source: /sys/firmware/efi/efivars/LoaderEntries-4a67b082-0a4c-41cf-b6c7-440b29bb8c4f

If you know a good solution for running kernel-install after a kernel update, please let me know.
Back in Ubuntu I have /etc/kernel/postinst.d for sripts like that, but I don’t know the OpenSUSE way.

After briefly looking at sdbootutil, it does seem to expect btrfs with snapshots. It should not be too hard to check whether both are used and skip if not, but someone has to implement it. If you are interested in this functionality, you can contribute to

GitHub - openSUSE/sdbootutil

Then existing sdbootutil-rpm-scriptlets should just work (it simply calls sdbooutil during kernel installation/removal).

To the original poster, maker sure you have the folder /usr/lib/bootloader/systemd-boot, it’s provided by perl-Bootloader. Then just change the boot loader in /etc/sysconfig/bootloader to:

LOADER_TYPE="systemd-boot"

There is one small problem that I will report as an issue, but for now, you get two copies of the initrd in the efi partition.

Gene

1 Like

I forgot to mention, to use the upstream systemd-boot scripts, you must keep the suse-module-tools-scriptlets package. This means you don’t install the sdbootutil-rpm-scriptlets package. If you have set LOADER_TYPE=“systemd-boot”, the following happens:

When a new kernel is installed or removed, the post section of /usr/lib/module-init-tools/kernel-scriptlets/rpm-script calls /usr/lib/bootloader/bootloader_entry, which is linked to /usr/bin/pbl.

The script /usr/bin/pbl (perl_Bootloader) calls the appropriate script in /usr/lib/bootloader/systemd-boot to add or remove kernels from the efi partition with kernel-install.

I’m pretty sure this is the mechanism used by the other rpm based distributions that aren’t using snapshots.

If you don’t like the extra initrd that is copied by the existing scripts, I can share my work around for the three issues that cause the problem. However, I’m currently trying to get them resolved with upstream, so they should go away in a while.

Gene

Thank you for your help Gene!

I’ve tested LOADER_TYPE=“systemd-boot” and I see what you mentioned.
After a kernel install, now there are two different initrds for a kernel. Both are in the kernel command line.
As far I can see the initrds differ only in the arguments.

I have a big enough EFI partition, so it’s not really a probem for me, but I’m curious about your workaround, and maybe others too.

While fixing this issue, I came across two other issues. I was planning on opening them one at a time to avoid confusion. However, the first issue, kernel-install version 254 regression, looks like it won’t be resolved until systemd version 255. So I’m going to open the other two issues, one of which is the two initrd issue, today or tomorrow. In the mean time, here is how I resolved all three issues.

As root, do the following:

1) If you don't have the patch package installed, run:
   # zypper install patch

2) # cd /usr/lib/bootloader

3) # mkdir systemd-boot-mod

4) # cp systemd-boot/* systemd-boot-mod

5) # cd systemd-boot-mod

6) In systemd-boot-mod, create the file add-kernel.patch containing the following text:
13a14,17
> # Modified by DGS to call kernel-install with only $version and $kernel.
> # Let override script, /etc/kernel/install.d/50-dracut.install, select
> # correct version of initrd or generate a new one if necessary.
>
53c57,58
<   ( set -x ; kernel-install add $version $kernel $initrd ) || err=1
---
> # Mod by DGS.
>   ( set -x ; kernel-install add $version $kernel ) || err=1
7) # patch -i add-kernel.patch add-kernel

8) Set LOADER_TYPE="systemd-boot-mod" in /etc/sysconfig/bootloader.

If you want to verify the patch before you change directories, run “diff …/systemd-boot/add-kernel add-kernel” and you should see the same text as you placed in the file add-kernel.patch. You can safely delete add-kernel.patch when you’re done.

To address the other two issues, do the following as root:

1) # mkdir -p /etc/kernel/install.d

2) # cd /etc/kernel/install.d

3) # cp /usr/lib/kernel/install.d/50-dracut.install .

4) In /etc/kernel/install.d, create the file 50-dracut.install.patch containing the following text:
6a7,8
> # Needed in later mod by DGS for regression in kernel-install version 254.
> KERNAL_IMAGE_DIRNAME="/boot"
41c43,46
<             IMAGE_PREGENERATED=${KERNEL_IMAGE%/*}/initrd
---
> # Mod by DGS, fix for KERNEL_IMAGE being resolved to /usr/lib/modules/... in version 254.
> # Also use KERNEL_VERSION to avoid grabbing newer initrd when adding an old kernel to /efi.
> #             IMAGE_PREGENERATED=${KERNEL_IMAGE%/*}/initrd
>             IMAGE_PREGENERATED="${KERNAL_IMAGE_DIRNAME}/initrd-${KERNEL_VERSION}"
5) # patch -i 50-dracut.install.patch 50-dracut.install

Again, if you want to verify the patch, run “diff /usr/lib/kernel/install.d/50-dracut.install 50-dracut.install” and you should see the same text as you placed in the file 50-dracut.install. You can safely delete 50-dracut.install when you’re done.

If you use kernel-install to remove and add back your kernels, you should see a similar tree to this:

# tree /efi/2ebf7cdd6cdb4335b16f89f43f467a48/
/efi/2ebf7cdd6cdb4335b16f89f43f467a48/
├── 6.4.12-1-default
│   ├── initrd
│   └── linux
├── 6.5.4-1-default
│   ├── initrd
│   └── linux
└── 6.5.6-1-default
    ├── initrd
    └── linux

I hope this works as well for you as it does for me.

Gene

Thank you for sharing it.

Somehow add-kernel.patch doesn’t want to apply, but it’s a one line change, I did it manually.

Apparently the forum deletes trailing white space in preformatted text blocks. That changes line 5 of the patch from "> " in my terminal to “>” in the post. And patch doesn’t like that… So here’s a new version that works:

13a14,17
> # Modified by DGS to call kernel-install with only $version and $kernel.
> # Let override script, /etc/kernel/install.d/50-dracut.install, select
> # correct version of initrd or generate a new one if necessary.
> #
53c57,58
<   ( set -x ; kernel-install add $version $kernel $initrd ) || err=1
---
> # Mod by DGS.
>   ( set -x ; kernel-install add $version $kernel ) || err=1

I cut and pasted it back to a terminal, and it works now.

Thanks for the heads up.

Gene

Just for noting.
The above mentioned workaround is no longer needed.

I spoke too soon.
It is still needed.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.