Comment 75 for bug 1396379

Revision history for this message
Lord Enum (lordenum) wrote :

So, I thought I'd take a quick look at this bug and why it's not been fixed yet:

There's 3 parts to explore, Ubiquity itself, it's script to handle installing grub (grub-installer) and grub-install itself.

Starting with grub-install itself, it does do something a little unexpected (to me at least) when installing to efi. When running grub-install /dev/sdb the variable that stores /dev/sdb internally is called install_device and when installing efi, that is ignored - as you can see in this code:
https://github.com/phil-opp/x86_64-grub/blob/54ad4ba67db8fd1e38068e49d3d94b88138046f8/util/grub-install.c#L1007 (<--- just the first version that came up in a search, but I assume it's the same in all grub-install.c versions)

So, grub-install relies on /boot or /boot/efi having the fat32 esp partition mounted to it. Looking through the grub-installer it does not do the mounting of /boot/efi itself - but it is correctly parsing the grub partition selected in Ubiquity to grub-install (which grub-install will not use (as explained above)). Ubiquity does the mounting - (it creates /target when installing and then mounts the esp partition to /target/boot/efi)

From a quick look I believe Ubiquity creates the /boot/efi mount via writing a fstab into /target/etc as part of the install process. Long story short, I believe this is handled by
https://git.launchpad.net/ubuntu/+source/ubiquity/tree/d-i/source/partman-efi/fstab.d/efi?h=applied/ubuntu/jammy
^ as you can see, this just searches for the first esp partition it can find, writes the fstab to mount it to /boot/efi and then finishes. Hence we get our problem that it's always the first esp partition that gets written to.

Because this is so convoluted, a fix is not immediately obvious. My own fix is to modify grub-installer so that, just before running grub-install, it checks if the destination is removable (i.e. a USB stick or similar) and, if it is, adds the --removable + --no-nvram flag, unmounts the /target/boot/efi Ubiquity set up and remounts it based on the boot device that will be passed to grub-install. The modification to the grub-installer script (located at /usr/shar/grub-installer) looks like:

if [ -n "$bootremovable" ]; then
   grub_install_params="$grub_install_params --removable --no-nvram"
   umount "$ROOT/boot/efi"
   bootdev_actual="$(fdisk -l | grep "$bootdev" | grep "EFI System" | cut -d' ' -f1)"
   mount "$bootdev_actual" "$ROOT/boot/efi"
fi

As this is my first ever attempt at writing anything in a shell script, this is probably highly naive, but does work, should not have a negative impact to other normal installs (as it only affects installing to removables) and would stop anyone else from screwing up their Windows partition when newbies think about trying out a Ubuntu based distribution on a USB stick and find out, when they next reboot, that instead of booting to Windows they get a grub prompt (typing exit in that prompt does at least allow them to boot Windows - but still, not a pleasant experience).

Attached is a diff that adds this against the version at: https://git.launchpad.net/ubuntu/+source/ubiquity/plain/d-i/source/grub-installer/grub-installer?h=applied/ubuntu/jammy