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: Michael Chang
Subject: Re: RFC: A partition for grubenv, etc.
Date: Fri, 28 May 2021 11:42:58 +0800
User-agent: Mutt/1.10.1 (2018-07-13)

On Thu, May 27, 2021 at 03:49:14PM -0300, Luiz Angelo Daros de Luca wrote:
> 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.

This looks good to me, and the best thing to have is that this opens the
possibility to do in place upgrade and then you will have the writable
grubenv. :)

However I'd like to add one thing to the list. As long as this will have
to deal with very sensible block areas. The tool (grub-editenv?) should
be enhanced to understand the usable blocks of the filesystem or
partition table in use, and therefore prohitbiting those who tries to
set out any settings of writing out of bound. It is important to make
sure no data corruptio will happen before usability.

Thanks,
Michael

> 
> Regards,
> 
> ---
>      Luiz Angelo Daros de Luca
>             luizluca@gmail.com
> 




reply via email to

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