Subject: [bug#41011] [PATCH] gnu: grub: Support for network boot via tftp/nfs.

From: Stefan <[email-masked]>
Date: Fri, 12 Jun 2020 16:41:07 +0200

Hi Danny!

> (canonicalize-device-spec seems to expect a nfs share reference to be a
> string, too.  Is that on purpose?  No <nfs-share> record?  That's kinda
> weird when we even have records for device labels and uuids--but we don't
> have them for something that's actually complicated to specify? [1] :) )

I think you are already able today to specify a (file-system (type "nfs") (device "my-server:/srv/nfs/music") …). It is just not sufficient yet for an NFS root file system. And using this style is still possible.

Therefore I started to use a simple string for an NFS share, too. That canonicalize-device-spec expects a string is due to an older patch from me in (boot-system), which Maxim moved from there.

Actually I see a difference between an NFS share and a file system label and an UUID, and this is (file-system (type …) …). If you specify for example "ext4" or "btrfs" the ‘device’ field can still have multiple representations, whereas for the type "nfs" the device field can only have one representation.

>> When booting
>> from NFS using the nfsroot Linux option, it's possible to specify a
>> '/dev/nfs' as the root kernel parameter.  /dev/nfs is not a real block
>> device, it's just a stub hinting the kernel that its root file system is
>> on NFS.  Perhaps that can be used?
> 
> Hmm maybe.  @Stefan?

As explained in another e-mail, no, that’s not an option.

> Also, could we have a system test testing this stuff?  I can write the
> actual test--but could you tell me how to use the functionality introduced
> in this patch?

A system test would be great!

You need a TFTP server serving the content of some /boot… folder as its root, which gets filled by the new grub-efi-net bootloader. This folder name is specified by (bootloader-configuration (target …) …). So lets assume you will use /boot-tftp for this.

The bootloader installer will create a link /boot-tftp/gnu pointing to ../gnu, and a link /boot-tftp/efi/boot/grub.cfg pointing to ../../../boot/grub/grub.cfg. So the TFTP server needs to have access to the store and the grub.cfg through these links as well.

You need a DHCP server pointing the guix machine to the TFTP server and to the file to boot. I use dnsmasq for this. My relevant configuration lines are the “TFTP server name” option number 66 and the “Bootfile name” option 67:

dhcp-option-force=66,10.10.10.10
dhcp-option-force=67,efi/boot/bootaa64.efi

The dnsmasq program can be configured with 

enable-tftp
tftp-root=/srv/tftp/

to act as a TFTP server, too. This is probably preferable.

You need an NFS server serving the root file system.

And you need a guix machine, capable to boot via network. Possibly any UEFI system could work, I think using qemu is possible as well.

I’m using a Raspberry Pi 3b. It is not PXE compliant, but capable to boot via network. For example it can only handle an IP address but no hostname inside the “TFTP server name” option. After specific firmware blobs have been loaded, it is loading the U-Boot, which then acts as an UEFI implementation and uses PXE. However, I do not use special PXE functionality, but finally the U-Boot will try to load /efi/boot/bootaa64.efi via TFTP, which in fact is GRUB.

GRUB then loads more files via TFTP from /efi/boot, most interestingly /efi/boot/grub.cfg, which is a link to ../../../boot/grub/grub.cfg. And that file points GRUB to the store.

Up to here no NFS is involved at all. GRUB will load the initrd and start Linux. Then the guix system is running and will mount its root file system via NFS.

If it is possible to start qemu with just an initrd, a kernel, and kernel arguments, then it would be possible to avoid DHCP, TFTP, and GRUB. This might be a much simpler first step for a test, only requiring an NFS server.

Bye

Stefan