Converting ext4 root to btrfs brings up grub error "sparse file not allowed"

I tested converting my ext4 root partition to btrfs in a virtual machine (Gnome Boxes with UEFI). What I did:

  • boot into a live image
  • use btrfs-convert to convert the root partition from ext4 to btrfs
  • chroot into the converted partition and reinstall grub³
  • adjust /etc/fstab
  • run mkinitcpio -P

The converted system works fine, but before booting there’s a weird error message saying “sparse file not allowed”. This seems to be caused by grub not being able to write to /boot/grub/grubenv on a btrfs partition for features like selecting the last booted system at startup¹.

I found workarounds to this problem, like disabling GRUB_SAVEDEFAULT¹ or placing the entire boot dir into a non-btrfs partition². Yet when letting the Manjaro installer manage the entire drive and specifying to use btrfs, the resulting installation won’t have the aforementioned issue and neither of the workarounds in place.

I’m left wondering what the installer does differently when stating upfront that you want to use a btrfs root partition?

¹=GRUB error: sparse file not allowed - #6 by linux-aarhus
²=Grub: sparse file not allowed - #5 by linux-aarhus
³=GRUB/Restore the GRUB Bootloader - Manjaro (UEFI steps)

It is about saving the boot choice for the next boot. That is not supported with grub on btrfs. Disable the save function:

GRUB_SAVEDEFAULT="false"

or use a ext4 boot partition.

1 Like

Yes, that’s what I wrote in my first post.

1 Like

I do not know of any other solution :man_shrugging:

1 Like

Well then everything is said? Will not work, won’t be fixed, grub cannot write to btrfs, only read.

This is what I’m curious about. Why am I not finding any of these workarounds (separate boot partition, disabled save function) when installing Manjaro with the btrfs option?

Because it is disabled anyway? Or was it enabled? Cannot remember exactly, but it was disabled when I installed Manjaro with btrfs last year about February.

Anyway, it doesn’t do any weird stuff when enabled. It gives you only an info message.

If you think it is worth to be mentioned, file a feature request on Issues · Applications / calamares · GitLab Which is the installer.

Dang, the option GRUB_SAVEDEFAULT is set to true but the line is commented out which I failed to spot at first. Now everything makes sense. Thanks for your help!

There’s really no hope that this option will ever work with btrfs?

Not in the near future !

(Ask the btrfs developers why) :rofl:
Or learn how btrfs works (balance & checksums & CoW)

You find good Information about Btrfs in the wiki

Take look here: btrfs/ZFS and file read hooks

In simple words: BTRFS/ZFS are too advanced for a simple write. Grub doesn’t use the linux module, instead it uses a “primitive module”.

Would it be possible to have /boot/grub on a dedicated ext4 partition instead of the entire /boot directory? This way, grub could still remember the last used option (I read it needs write access to /boot/grub/grubenv for that feature to work) and kernels would still be part of a btrfs snapshot.

Can you show

  1. fdisk -l
  2. /etc/fstab

Sure, but never tested it. I guess grub will not find the boot images then, but could be wrong. Needs testing.

Note that btrfs snapshots will not include boot images (initcpios) and when you do a rollback then /boot will be excluded since it is not btrfs and not the same partition. That would lead to an unbootable system until you recreate the boot images. Keep that in mind.

$ sudo fdisk -l
Disk /dev/vda: 32 GiB, 34359738368 bytes, 67108864 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: 3B97CDC5-F5A0-4DD2-84BA-F60E063D2599

Device Start End Sectors Size Type
/dev/vda1 2048 503807 501760 245M EFI System
/dev/vda2 1050624 33818623 32768000 15,6G Linux filesystem
/dev/vda3 33818624 67103471 33284848 15,9G Linux filesystem
/dev/vda4 503808 1050623 546816 267M Linux filesystem

Partition table entries are not in disk order.

UUID=AC66-B696 /boot/efi vfat umask=0077 0 2
UUID=96ba1349-26ec-4ec1-b4ac-0bf7c0b9cfdc /boot/grub ext4 defaults,noatime 0 2
UUID=e17a8462-e4bb-41ed-90c1-67fe6cb16fae / btrfs defaults,noatime 0 0
UUID=f7d377a9-17b9-4b39-a840-c82ad64d5565 /home ext4 defaults,noatime 0 2

After reinstalling grub, this seems to be working fine in a VM.

The idea was to have /boot/grub as dedicated ext4 partition. Why would the entire boot directory be excluded from snapshots and why would boot not be btrfs? (Subpartitioning /boot/grub should leave the /boot directory on the root partition so it should be btrfs.)

I dont´t think so. Because when installing grub this is hardcoded into grub. ( @/boot/grub ) .
You may be able to do so if you insist. But at some point in time it will break. :man_shrugging:

Alright. And a rollback after kernel upgrade?

Maybe using EFI instead? That way you can spare the additional partition.

sudo grub-install --target=x86_64-efi --efi-directory=/boot/efi --boot-directory=/boot/efi --bootloader-id=manjaro --recheck

That should work as well. But note, that update-grub will not work then, you need to run grub-mkconfig -o /boot/efi/grub/grub.cfg.

Will work because they are in /boot and not in /boot/grub/.
But reinstall-grub may fail, and there will not be any rollback for /boot/grub

Well, grub installation is standalone and has no system dependencies. So essentially, it would boot from EFI file, start grub from EFI partition and the grub.cfg has the path to linux images on /@/boot. So in theory, there wouldn’t be a problem. Even on an Upgrade at Patch Version so 6.6.8 → 6.6.9 there will be no problem, since the filename will remain the same.

Problem occour if you install a kernel and then rollback. grub.cfg will still have the menu entry, but the file will not be there. Updating grub.cfg would be needed then, but that’s it.

But where to find them ?

  • the “right” grub.cfg
  • grub modules that need to be loaded early ?

These may exist several times in different partitions with incompatible versions;

Look into the binary of “grub”.efi. The path seems to be inserted (hardcoded) on install into this file.

You are right. In case of a rollback, the kernel and the initrd will be rolled back, but grub.cfg will not . This will lead to a broken system.

How? Don’t understand?!

You are right. That is written on grub-install:

# strings /boot/efi/EFI/Manjaro/grubx64.efi | grep "boot/grub"
(,gpt6)/@/boot/grub

EFI and GRUB can still be on the same vfat efi partition. So you cannot just copy and paste it :smiley: