Utility that tries to figure how to update the FreeBSD loaders

loaders-update is intended for simple systems and, in some ways, inexperienced users.
Agreed.

Note that, as a fallback, it's simpler to keep an USB key with an appropriate version of FreeBSD inside. I mean if you have a physical access to the machine.

That said, I never experienced a boot problem after updating the loaders.
Unfortunately, I've experienced the situation before.
With the broken boot1.efi (at the moment, loader.efi must be kicked from boot1.efi), even when booted from USB memstick, FreeBSD which was in the first recognized hard drive by firmware was booted, thus cannot repair using memstick on UEFI boot.

But fortunately, at the moment, I had freebsd-boot partition for legacy boot (just using it when I started to test UEFI boot) and I could rescue myself to be able to boot with disabling UEFI boot on firmware config.

The top of thread on freebsd-current ML reporting the issue.

Review of the fix was D5108.
As I didn't registered (as I'm not sure I, not a FreeBSD committer is allowed to register there or not) at the moment, my reports are all via email (on or off list).
 
loaders-update is intended for simple systems and, in some ways, inexperienced users.

yes and no

It's really fast for an experienced users to forget a boot loader update after a zpool upgrade.

This check process part should be included in documentation and base script of freebsd-update.

Maybe it's already in.

But I my case, I miss the boot loader upgrade one or two time after a pool upgrade and it's not a fun case.
 
yes and no

It's really fast for an experienced users to forget a boot loader update after a zpool upgrade.

This check process part should be included in documentation and base script of freebsd-update.

Maybe it's already in.

But I my case, I miss the boot loader upgrade one or two time after a pool upgrade and it's not a fun case.
True. I don't consider myself as inexperienced and I use this software on all my machines. It's quicker and avoid typing errors.

At the base, I wrote this because of the recurrent problems/questions/disasters that we get here from people, often new users, but not only.

Of course, I was bitten as well by this, but in an uncommon way: https://forums.freebsd.org/threads/why-its-important-to-upgrade-efi-boot-bootx64-efi.79503

I agree, this should be part of freebsd-update with all the precautions needed by this delicate operation. I ported this software also in this idea, to attract the attention of the base committers.

From my point of view, it's one of the two main problems in using/installing/discovering FreeBSD and certainly a reason why some people fled this OS. The other is the kernel modules that remain unusable with the package system during the first three months of a minor release. This is incomprehensible to a standard user. On that point, I have no solution so far, but I'm thinking about it.
 
It's really fast for an experienced users to forget a boot loader update after a zpool upgrade.
It should be BEFORE zpool upgrade.

It would be best (but not sure it could be accepted upstream) if zpool upgrade forcibly invoke boot code update if any of the specified pool have bootfs and error out without upgrading if it doesn't finished successfully.
 
Well, upgrading boot code AFTER upgrading pool could be hazardous.

Imagine if the computer crashes just after upgrading the pool is finished, but before updating boot codes which support the newly enabled features with some reason (sudden AC line failures etc.).
It can easily cause unbootable computer.

And this also applies if you manually enable/activate any of the features that currently installed boot code doesn't support.
This case needs some more investigations before doing. You need to look for newer releases/stables and main (aka current) which its boot codes support the feature. You need to update your boot code of which you found.

Note that read compatible features are safe. Only read incompatible features matter.
 
I was saying that I think the bootcodes update should be done at system upgrade time (during freebsd-update). Because some problems may arise even if you didn't upgrade the pool as in the link I posted. So, it's before upgrading any pool and even if you don't upgrade your pool(s).
 
I was saying that I think the bootcodes update should be done at system upgrade time (during freebsd-update).
100% agreed for binary upgrade (freebsd-update) users.
But not all users do binary upgrade but source upgrade (mainly developers and early adopters). So forcible upgrade on freebsd-update time is insufficient (as human makes mistake).

Because some problems may arise even if you didn't upgrade the pool as in the link I posted. So, it's before upgrading any pool and even if you don't upgrade your pool(s).
Do you mean that you couldn't sanely boot / mountroot on some BEs?
After loader hands over to kernel, bootcodes does not matter anymore.
zfs.ko loaded by loader (before kernel starts, via /boot/loader.conf[.local]) and ZFS-related userland components like /sbin/zfs, /sbin/zpool, /lib/libzfs* must be in sync, at least zfs.ko should not be older than others.
Otherwise, syscalls from userland could fail. There could be other reason, but this is what I can think of for now.

For sane and safe upgrade of boot codes, it would be desirable that what read incompatible features are supported by boot codes can easily confirmed.

Fortunately, /usr/src/stand/libsa/zfs/zfsimpl.c has an array named features_for_read, but unfortunately, for example, string /boot/loader.efi does not list the array as a bulk.
If a file containing the array as text and hashes of boot codes in /boot as, for example, /boot/zfsfeatures.list is created on building boot codes, it would be helpful.
 
But not all users do binary upgrade but source upgrade (mainly developers and early adopters).
They don't use freebsd-update, so no automatic bootcodes update. It makes sense.

Do you mean that you couldn't sanely boot / mountroot on some BEs?
It was what I experienced. After updating the bootcodes, no problem anymore. That said, I didn't put the analysis deeper.
 
Emrion : Great utility, kudos. I have an OPNSense system running ZFS that is working OK, but I would like to preemptively update the bootloader(s) to prevent future issues. Before I do, I would like to understand what the recovery method would be in case I were left with an unbootable system after running the bootloader update. What steps should I take to prepare for a possible failure? I have physical access to the unit and can use a serial console connection if required.
 
Emrion : Great utility, kudos. I have an OPNSense system running ZFS that is working OK, but I would like to preemptively update the bootloader(s) to prevent future issues. Before I do, I would like to understand what the recovery method would be in case I were left with an unbootable system after running the bootloader update. What steps should I take to prepare for a possible failure? I have physical access to the unit and can use a serial console connection if required.
Preemptively you say? Just after the upgrade of the system or before, meaning you get the bootloaders of the next version and put them in a directory (and use the -s option)? I don't advise this last.

Anyway, the simplest method is to have a USB key with the current version of your OS. And when it concerns something that seats between internet and your local network, create this key before attempting any upgrade ;). If a problem arises, you boot on this key with the BIOS menu. Then, you can downgrade the loaders if necessary.

I never faced any trouble with the systematic update of the loaders, but I did it always after upgrade (including reboot for the new kernel takes place). It's better to reboot again immediatly to be sure that all is ok.
 
Hi Emrion,
I have couple of cases where the outputs of loaders-update confuse me. Let me start with this one.
question 1, since the system is UEFI boot, why not run gpart bootcode -p /boot/boot1.efi -i 2 nda1, as handbook says, https://docs.freebsd.org/en/books/handbook/zfs/#zfs-zpool-upgrade, (scroll down a few screenshots, see the "Warning" section.)
question 2, because the output reports a serious error, which i suppose refers to /dev/nda2p2, is it still safe to run loaders-update shoot-me?
Code:
root@AMD_STATION:[~] # gpart show
=>        34  1953525101  nda0  GPT  (932G)
          34        2014        - free -  (1.0M)
        2048      204800     1  efi  (100M)
      206848       32768     2  ms-reserved  (16M)
      239616  1131192599     3  ms-basic-data  (539G)
  1131432215        1769        - free -  (885K)
  1131433984     1736704     4  ms-recovery  (848M)
  1133170688        2048        - free -  (1.0M)
  1133172736   819200000     5  ms-basic-data  (391G)
  1952372736        2048        - free -  (1.0M)
  1952374784     1146880     6  ms-recovery  (560M)
  1953521664        3471        - free -  (1.7M)

=>        40  1953525095  nda1  GPT  (932G)
          40      532480     1  efi  (260M)
      532520        1024     2  freebsd-boot  (512K)
      533544         984        - free -  (492K)
      534528     4194304     3  freebsd-swap  (2.0G)
     4728832  1948794880     4  freebsd-zfs  (929G)
  1953523712        1423        - free -  (712K)

=>        34  2000409197  nda2  GPT  (954G)
          34           6        - free -  (3.0K)
          40      532480     1  efi  (260M)
      532520        1024     2  freebsd-boot  (512K)
      533544         984        - free -  (492K)
      534528     4194304     3  freebsd-swap  (2.0G)
     4728832  1948794880     4  freebsd-zfs  (929G)
  1953523712    46885519        - free -  (22G)

root@AMD_STATION:[~] # loaders-update show-me
loaders-update v1.2.2

One or more efi partition(s) have been found.

Examining nda2p1...
mount -t msdosfs /dev/nda2p1 /mnt
EFI loader /mnt/EFI/BOOT/BOOTX64.EFI is up-to-date.
Would run: cp /boot/loader.efi /mnt/EFI/BOOT/bootia32.efi
EFI loader /mnt/EFI/freebsd/loader.efi is up-to-date.
umount /mnt
Examining nda1p1...
Efi partition nda1p1 is already mounted in /boot/efi.
EFI loader /boot/efi/efi/freebsd/loader.efi is up-to-date.
Would run: cp /boot/loader.efi /boot/efi/efi/boot/bootia32.efi
EFI loader /boot/efi/efi/boot/bootx64.efi is up-to-date.
Examining nda0p1...
mount -t msdosfs /dev/nda0p1 /mnt
There is no FreeBSD loader in nda0p1
umount /mnt

One or more freebsd-boot partition(s) have been found.
The root file system is zfs.

Examining nda2...
There is currently no loader in /dev/nda2p2.
Cannot update without option -f.
Examining nda1...
Would run: gpart bootcode -b /boot/pmbr -p /boot/gptzfsboot -i 2 nda1

-------------------------------
Your current boot method is UEFI.
Boot device: /dev/nda1p1 File(\EFI\BOOT\BOOTX64.EFI)
Updatable EFI loader: 2
Updatable BIOS loader: 1
1 serious error(s) occured. See texts above.
 
(First of all, according to your partition layouts, I assume your nda0 to be of Windows, so completely ignore it.)

This should be because you have ESP as nda1p1 and freebsd-boot partition as nda1p2 (same for nda2, too).
ESP (uEfi System Partition) is not at all needed for legacy BIOS boots, while freebsd-boot is not at all needed for UEFI boots. Having both should be confusing you.

And more, ESP is mandated to be formatted as FAT{12|16|32}, while freebsd-boot partition is blindly read into memory as the whole partition to be memory image starting from fixed physical memory address by bootcode in (p)MBR.

Read Chapter 15 of the Handbok for details about legacy BIOS boots.
And this would help, too.
 
The method to update an EFI bootcode with gpart bootcode is not only outdated, but it will also destroy your ESP partition in a way you won't boot anymore (I think, not tested). So, stay away from that.

As T-Aoki says, you have an EFI partition that Windows uses in nda0p1. loaders-update saw it has no FreeBSD loader, therefore and fortunately, it won't do anything there. I programmed it for that: don't touch other loaders than the ones belonging to FreeBSD!

Concerning nda2p2, you don't have a bios bootcode inside. You can add one or not, that's not important since you boot on EFI. This is the thing that makes a "serious error".

Most of your EFI loaders are up-to-date.

What is worry me is that it wants to update two loaders named bootia32.efi. How these files came there? If I understand correctly, it's for 32-bits EFI. You have 64-bits EFI since your system boots on \EFI\BOOT\BOOTX64.EFI. If I was you, I'd delete these files.

Well, it's not really useful to run loaders-update shoot-me because it won't do anything gainful.
If you want to continue to use it without error or weird things, delete these bootia32.efi files and run it in shoot-me mode with the -f option. After that, it will be happy, saying all is up-to-date.
 
Thanks to T-Aoki and Emrion.
If I understand this right, in my case, gpart bootcode -b /boot/pmbr -p /boot/gptzfsboot -i 2 nda1 writes to freebsd-boot partition.
while cp /boot/loader.efi /boot/efi/efi/boot/bootx64.efi changes efi partition. gpart bootcode -p /boot/boot1.efi -i 1 nda1 writes to efi partition as well, but as Emrion explains, I shouldn't use it. Don't know what gpart bootcode -p /boot/boot1.efi -i 2 nda1 will do, but it's not correct command in this case.
Anyway, the handbook can be more clear.
 
I removed the 2 bootia32.efi files and run loaders-update shoot-me -f. All looks fine, only the gpart bootcode has different options for nda1p2 and nda2p2.
Code:
root@AMD_STATION:[~] # loaders-update shoot-me -f
loaders-update v1.2.2

One or more efi partition(s) have been found.

Examining nda2p1...
mount -t msdosfs /dev/nda2p1 /mnt
EFI loader /mnt/EFI/BOOT/BOOTX64.EFI is up-to-date.
EFI loader /mnt/EFI/freebsd/loader.efi is up-to-date.
umount /mnt
Examining nda1p1...
Efi partition nda1p1 is already mounted in /boot/efi.
EFI loader /boot/efi/efi/freebsd/loader.efi is up-to-date.
EFI loader /boot/efi/efi/boot/bootx64.efi is up-to-date.
Examining nda0p1...
mount -t msdosfs /dev/nda0p1 /mnt
There is no FreeBSD loader in nda0p1
umount /mnt

One or more freebsd-boot partition(s) have been found.
The content of the freebsd-boot partition(s) won't be analyzed.
The root file system is zfs.

Examining nda2...
The pmbr on this disk is up-to-date.
About to execute: gpart bootcode -p /boot/gptzfsboot -i 2 nda2
Are you sure (y/N)? y
partcode written to nda2p2
Examining nda1...
About to execute: gpart bootcode -b /boot/pmbr -p /boot/gptzfsboot -i 2 nda1
Are you sure (y/N)? y
partcode written to nda1p2
bootcode written to nda1

-------------------------------
Your current boot method is UEFI.
Boot device: /dev/nda1p1 File(\EFI\BOOT\BOOTX64.EFI)
Updated BIOS loader: 2
-------------------------------
 
That's ok, I think. Next times you run loaders-update, don't use anymore the -f option as its duty is done now.

I advise to run loaders-update after each freebsd-update upgrade (change of FreeBSD version). Conversely, it's useless after freebsd-update fetch install (simple update of the current version) as the loaders are likely to remain unchanged.
 
Back
Top