grub-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: RFC: A partition for grubenv, etc.


From: Luiz Angelo Daros de Luca
Subject: Re: RFC: A partition for grubenv, etc.
Date: Thu, 27 May 2021 15:49:14 -0300

This was already discussed in this ML a couple of times.

It is not uncommon for some FS to have an unused header space. This
happens for btrfs and SUSE patches grub2 to use it:
https://build.opensuse.org/package/view_file/openSUSE:Factory/grub2/grub2-grubenv-in-btrfs-header.patch?expand=1.
It is a "workaround", specific for a single FS that needs to be
redesigned for each FS where grub cannot write to.
Its complexity grows with each new FS.

I think that grub should offer an alternative way to store grubenv
independently from FS in use. Grub already requires some spare space
for stage 1.5 and grub could use the remaining space after that for
grubenv. For BIOS with DOS partitions, it uses the blocks between
MBR and the first partition (sector 63 or 2048 for recent disks). For
BIOS with GPT, grub already requires a grub-bios partition (normally
way bigger than needed). And for UEFI, as it was already mentioned,
there is an EFI partition. I know I'm not considering anything
but x86 but it is where this issue happens. A new dedicated partition
might be overkill and only mostly only useful for GPT, where there
are already partitions dedicated for booting (grub bios boot or EFI).

My proposal would be an additional source for grubenv. SUSE still uses
the FS /boot/grub2/grubenv to store a
env_block variable (as well as other variables) that, if present, will
point to where an additional grubenv should be. My proposal is quite
the same,
but not limited to BTRFS.

grub2-mkconfig could be opportunistic, using only /boot/grub2/grubenv
when it is writable by grub, /boot/EFI when present, btrfs first
blocks or stage1.5 data when everything
else fails. Grub and userland tools would only need to check if the
"normal" grubenv does define a "$grubenv_device", "$grubenv_block" or
"$grubenv_include".

As it was mentioned, grubenv should be grub.cfg specific, not image
specific. As /boot/grub2/grubenv is still in use, each grub.conf would
still point to a different grubenv file that would include
a different grubenv_{device,block,include}. grubenv could contain an
uuid variable to help grub2-mkconfig and grub iteratively look for a
matching grub_block or allocate a new slot.
Something like this:

/boot/grub2/grubenv
grubenv_device=(hd0,msdos4)
grubenv_block=0 # for btrfs
grubenv_maxblock=64 # for btrfs 0x10000 (btrfs header location) /
0x400 (grubenv size)
# grubenv_block=1234 for stage1.5 area where 1234 is the stage1.5 size in blocks
grubenv_uuid=3dfd5d2a-7314-47dc-ba5a-e02aa2b00749

(hd0,msdos4)@0
grubenv_uuid=3dfd5d2a-7314-47dc-ba5a-e02aa2b00749
next_boot=2

With a simple grub.cfg scriptlet (using not valid syntax):

if [ "$grubenv_include" ]; then
   # for EFI
   load_env $grubenv_include
fi
if [ "$grubenv_device" ] && [ "$grubenv_block" ]; then
  for n in {1..$grubenv_maxblock}; do
     if [ "$grubenv_uuid" ]; then
       expected_uuid=$grubenv_uuid
       load_env -d $grubend_device -b $grubenv_block grubenv_uuid
       if [ "$grubenv_uuid" != "$expected_uuid" ]; then
         grubenv_uuid=$expected_uuid
         grubenv_block++
         continue
       fi
     fi
     # I hope it checks the header...
     if ! load_env -d $grubend_device -b $grubenv_block; then
       # not found or failed
       grubenv_device=
       grubenv_block=
     fi
     break
  fi
...
if [ "$grubenv_device" ] && [ "$grubenv_block" ]; then
   save_env -d $grubend_device -b $grubenv_block grubenv_uuid
fi

The problem is that the location of every single /boot/grub2/grubenv
is not deterministic. It would be hard to safely garbage-collect
unused grubenv blocks.
I think that whenever grub2-editenv writes a block, it should
rightshift the available area ($grubenv_maxblock) and add or move the
modified grubenv to position 0
(the hottest block). Eventually all unused grubenv blocks will be
dropped during the rightshift.

I'm not trying to solve every single corner case but I'm suggesting
changes that would empower the OS to solve the issue (requiring a
partition with writable FS for grubenv).
For most cases where grubenv is not writable today, it could
automatically solve the issue. For others where multiple complex
grub.conf/grubenv are in use,
it would give tools to the advanced user to manually solve the issue.
I'm not worried about advanced users because they can today create a
dedicated fat32 partition with
manually defined grubenv path. I'm thinking about distributions and
the general user that marginally knows what grub is.

Regards,

---
     Luiz Angelo Daros de Luca
            luizluca@gmail.com



reply via email to

[Prev in Thread] Current Thread [Next in Thread]