Subject: Re: bug#44353: guix system disk-image -t raw fails with grub-efi-bootloader

From: Maxim Cournoyer <[email-masked]>
Date: Sat, 07 Nov 2020 15:32:49 -0500

Hello Mathieu!

Mathieu Othacehe <[email-masked]> writes:

> Hello Maxim,
>
> Thanks for your patch! It's hard to provide a reliable abstraction on
> top of all the exotic bootloader installation methods existing.
>
> Currently, each bootloader implements two methods:
>
> * bootloader-installer
> * bootloader-disk-image-installer
>
> The first one is dedicated to the installation of the bootloader on a
> mounted directory, while the second one is meant to work on a disk
> device such as "/dev/sda" or directly on a disk-image.
>
> When producing a disk-image with the "raw" type, we are always creating
> and populating an ESP partition (see raw-image-type), regardless of the
> selected bootloader. In fact, "raw" should be renamed to "hybrid-efi".
>
> The produced image can work on machines with legacy mbr boot or with EFI
> boot. Hence, calling "install-grub-efi" like it's done while building
> the lightweight-desktop operating-system is useless and fails. The
> attached patch fixes it.

Thank you for the clarifications!

> You can test it with:
>
> qemu-system-x86_64 -m 1024 -bios $(guix build
> ovmf)/share/firmware/ovmf_x64.bin -hda disk.img

Thank you!  I hadn't realized that the default SeaBIOS BIOS used by QEMU
wasn't EFI-capable!  The image now boots, but fails bringing up its file
systems for some reason.  Perhaps I'm supposed to edit the file system
definitions of the template before use?

Here's how I tested it:

$ time ./pre-inst-env guix system disk-image
gnu/system/examples/lightweight-desktop.tmpl --verbosity=2 --no-offload

That took 38 minutes on my system and produced /gnu/store/...-disk-image.

$ cp /gnu/store/...-disk-image /tmp/lightweight-desktop.img

$ chmod +rw /tmp/lightweight-desktop.img

Then I tried running it with the suggested command:

$ qemu-system-x86_64 -m 1024 -bios $(guix build
ovmf)/share/firmware/ovmf_x64.bin -hda /tmp/lightweight-desktop.img

>> +                              ;; Special case: most bootloaders can be copied
>> +                              ;; directly at some fixed location on the image
>> +                              ;; disk, but when installed to the master boot
>> +                              ;; record (MBR), GRUB requires support files
>> +                              ;; present under /boot/grub, which is handled by
>> +                              ;; its 'installer' procedure.
>>                                #:bootloader-installer
>> -                              #+(bootloader-installer bootloader)
>> +                              #+(if (eq? 'grub (bootloader-name bootloader))
>> +                                    (bootloader-installer bootloader)
>> +                                    #f)
>
> That would prevent other bootloaders relying on this procedure to work,
> such as extlinux.

I pondered about such solution, but when I verified the bootloaders
under gnu/bootloaders, it appeared that *only* the install-grub
procedure supported being passed #f as its mount point; the others would
fail because of the unexpected #f boolean value.

For example, the install-extlinux procedure from (gnu bootloaders
extlinux):

--8<---------------cut here---------------start------------->8---
(define (install-extlinux mbr)
  #~(lambda (bootloader device mount-point)
      (let ((extlinux (string-append bootloader "/sbin/extlinux"))
            (install-dir (string-append mount-point "/boot/extlinux"))
            (syslinux-dir (string-append bootloader "/share/syslinux")))
        (for-each (lambda (file)
                    (install-file file install-dir))
                  (find-files syslinux-dir "\\.c32$"))
        (invoke/quiet extlinux "--install" install-dir)
        (write-file-on-device (string-append syslinux-dir "/" #$mbr)
                              440 device 0))))
--8<---------------cut here---------------end--------------->8---

Would break if device was set to #f, as is done in (guix build image)'s
initialize-efi-partition:

--8<---------------cut here---------------start------------->8---
  (when bootloader-installer
    (display "installing bootloader...\n")
    (bootloader-installer bootloader-package #f root))
--8<---------------cut here---------------end--------------->8---

Is my analysis correct?  If so, the patch I sent yesterday would fix the
problem more thoroughly.

Thank you,

Maxim