GRUBENV error when using BTRFS

1 System description

Hello! I am running Manjaro KDE on BTRFS with the default configurations from Architect.

1.1 Partitioning

  • 100MB EFI
  • some partitions for Windows
  • 20GB swap
  • 670GB btrfs partition:
    • @ subvolume for /root
    • @home subvolume for /home
    • @cache subvolume for /var/cache

2 Issue

When I installed Manjaro I chose kernel 5.10, however this one hangs on reboot/shutdown and I wish to downgrade to 5.9, but keep it easy to switch back to upcoming updates of 5.10 .

2.1 Try to solve this

I manage to choose the kernel I want from grub, but the choice is not saved and the next boot will load the default 5.10. In order to allow grub to save the default I set the following in /etc/default/grub:

GRUB_DEFAULT=saved
...
GRUB_SAVEDEFAULT=true

and then sudo update-grub.

2.2 What didn’t work

When I am rebooting and choosing kernel 5.9 I get the error:

error: sparse file not allowed

The system boots afterwards with kernel 5.9, but the choice is still not saved. After some googling I found out that this is because GRUB does not want to write to BTRFS due to possibility of corruption.

3 My next resolve

I am thinking that if I get /boot to be mounted as ext4, then grub will be able to carry on with writing the new default kernel choice.

3.1 What keeps me from doing that?

3.1.1 BTRFS shrink

I don’t have anymore unalocated space on my SSD, so I need to shrink the BTRFS partition. However, I found very few resources about shrinking a btrfs partition and I do not know if there is any caveat to doing so.

btrfs filesystem resize -1g /mybtrfs

3.1.2 Grub using the new /boot

I am afraid whether grub will know where the new /boot is. Linux will sure mount it as fstab dictates and I assume there will not be a problem there. But how does grub know about that? Is it enough to update-grub and it will reconfigure itself?

4 My questions for you

Does anyone have any advices on how I should proceed with shrinking the btrfs partition? In addition, does anyone know how to make sure that grub will behave properly after this change?
If you have another idea how to solve this problem, I am eager to hear it.

I would be happy with your speculations as well. You don’t need to be 100% precise. I am just trying to convince myself whether I can perform this action without breaking my Manjaro.

I am also thinking that previous snapshots will not be valid after this, since /boot should not be part of the snapshots anymore, but I am still a newby in terms of btrfs so I don’t know how the protocol would interpret this change.

1 Resume

So after an entire day of frustration, I got it working. I thought to record this in order for other people to avoid making the mistakes I did.

2 Describing the need for this solution

As described here, grubenv refuses to write to btrfs because the filesystem will interpret this as corruption. Therefore, you cannot make use of GRUB_SAVEDEFAULT and you will need to manually describe the default kernel you want to use. See first post for what happend when you set GRUB_SAVEDEFAULT=true.

3 My go at solving this

3.1 /boot subvolume

Before trying to shrink my btrfs partition and make a separate partition for /boot I have tried to make a dedicated subvolume. I described the mounting of this in \etc\fstab with settings like compress=no, nodatacow hopping that grubenv will be aware there is no risk of corruption anymore. But that didn’t work since I assume that grub raises this condition just from the fact that \boot is on btrfs.

3.2 Breaking GRUB

  1. I made a @boot subvolume, copied everything from previous \boot to it and made the new entry for mounting of it in \etc\fstab.
  2. sudo update-grub and then I thought that everything was setup, but oh my I was wrong. You need to reinstall grub to get it right!

4 Actual solution

As I have said thus far, I chose to make a separate partition for \boot on ext4 just as Fedora chose to do.

4.1 Make dedicated \boot partition on ext*

Since (3) didn’t work I got use to idea of having an extra partition for \boot on ext*.

  1. Shrink the btrfs partition by 1GB. I haven’'t figure out how to make use of btrfs resize since I was able to shrink it, but the available space would not show as unallocated. In exchange I have use gparted which provides resize for btrfs. I believe KDE Partition Manager should work as well, but I haven’t tried.
  2. Make 1GB partition of ext* from the new unallocated space.
  3. Mount this partition to \new_boot
  4. Copy everything but \boot\efi from \boot to \new_boot
  5. umount \boot\efi && umount \new_boot and rm -r \boot\*
  6. Make entry in \etc\fstab for you new boot partition to mount at \boot and mount \boot

4.2 Reinstall GRUB

In my initial go with the btrfs subvolume I haven’t reinstalled grub and that costed me half of my day (follow up in section 5).

  1. Make your settings for grub in \etc\default\grub
  2. update-grub
  3. grub-install --recheck
  4. You might want to repeat 1) and 2) if \etc\default\grub doesn’t resemble your configurations anymore

5 What else can go wrong

After I messed up first time, I have tried to reinstall grub in chroot while inside a live Manjaro. I was keep getting the next error whether I tried to install grub or make a manual boot entry with efibootmgr:

Could not prepare boot variable: No space left on device

Manjaro has cached previous boots configurations from efi and that gives the false warning of the lack of space. Get rid of this error and useless log with:

rm /sys/firmware/efi/efivars/dump-*

Disclamer: This last solution seemed to work for me, but do it on your own discretion. I don’t have enough information about it to recommend it.

Manjaro-architect and calamares intentionally disable default saving for btrfs to avoid the sparse files error. It is an unfortunate grub feature.

I would rather not default to a separate /boot partition as it complicates the partitioning scheme. You can still get this feature by mounting esp to /boot.

@hydra,

Did you try to do this also?
This approach will use your existing ESP and thus you won’t need a separate /boot partition…

  1. Unmount /boot/efi

  2. Mount your ESP at /efi and create a subdir for manjaro at /efi/Manjaro

  3. Recursively copy the contents of /boot to /efi/Manjaro using sudo cp -var /boot/* /efi/Manjaro.

  4. Bind-mount the /efi/Manjaro directory as /boot eg:
    systemd-mount -o bind /efi/Manjaro /boot
    And this in fstab:

    /efi/Manjaro   /boot   none    bind
    

    Or use: [root tip] systemd mount unit samples
    (Ofcourse don’t forget to adjust your entry for your ESP to mount it at /efi before this)

  5. If you still have a directory /boot/efi (which should be empty now), you can remove that dir because it won’t be used/needed anymore.

  6. Re-install grub with the ESP at /efi:
    sudo grub-install --target=x86_64-efi --efi-directory=/efi --bootloader-id=Manjaro --recheck --verbose

4 Likes

@Chrysostomus,

That is a bit of a bummer since one nice feature I found about Manjaro is the easiness to manage and jump between kernels.

@TriMoon
Thank you very much for your solution! I wasn’t aware you can have this layout.

One handicap I have however, is that the ESP is 100MB (Windows installation scheme) and the current boot won’t fit on it. But I assume that I can resize the Windows main partition, move MBR (16MB) down and then resize the ESP as described in this post.

My current partition scheme is the following:

2 Likes

It is what i use myself on HD…
Although i use a different name for /efi/Manjaro and i use sd-boot as bootloader in my current setup.

That is not the/a MBR, it is a M$ partition. I have no idea what it is used for…

But yes you need a larger ESP /dev/nvme0n1p1 ofcourse, and can get rid of the /boot partition because the data will be in /efi/Manjaro :wink:
PS: The ESP does not need to be the first partition :wink:

1 Like

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