Get the link offset using the zfs_dnode_sa_lookup helper now.
Recently, the symbolic links we rely on in the boot loader have stopped
working.
Prior to OpenZFS commit e90badec11 ("Inherit the project ID for every
object type", Matt Turner, 2026-08-14), symbolic link information was
written at a fixed offset in the SA data. Since that commit, the
inherited PROJIDs mean that all pools with quota enabled have started
writing symbolic links with a new, non-fixed offset. Old symbolic links
remained unchanged, but new ones were written with a different
offset. At work, we have all these things: rewritten BEs, quotas, and a
dependence on symbolic links in our boot path.
This came in on 2026-08-24 OpenZFS merge (22649d4dba). This was 12
hours after stab week for August, so we didn't hit this until the
September stab week. Since the new kernel has to write links at the new
offset, the initial tests worked, but the second ones didn't.
Sponsored by: Netflix
Differential Revision: https://reviews.freebsd.org/D60268
Find the SA values with the zfs_dnode_sa_lookup and read out the
relevant bits for the stat buffer.
Sponsored by: Netflix
Differential Revision: https://reviews.freebsd.org/D60267
zfs_dnode_sa_lookup will look in the bonus part of the dnode for the
requested SA values, and fall back to the spill as if it's not there.
Sponsored by: Netflix
Differential Revision: https://reviews.freebsd.org/D60266
Compute the offset for the data for this bundle and the requested data
type.
Sponsored by: Netflix
Differential Revision: https://reviews.freebsd.org/D60265
zfs_sa_load looks up all the system attribute offsets and stores them in
the mountpoint.
Sponsored by: Netflix
Differential Revision: https://reviews.freebsd.org/D60264
For the dynamic system attributes, we'll need the mount argument. Adjust
zfs_dnode_readlink to take that argument.
Sponsored by: Netflix
Differential Revision: https://reviews.freebsd.org/D60262
When reading dynamic system attributes, we'll need the mount argument
since we can no longer hard-code the offsets. Adjust zfs_dnode_stat to
take it.
Sponsored by: Netflix
Differential Revision: https://reviews.freebsd.org/D60261
Dynamic system attribute layout can require modifications to the mount
structure on lookup. Drop the const to allow that.
Sponsored by: Netflix
Differential Revision: https://reviews.freebsd.org/D60260
Remove semi-transparent pixels around the orb. These become more
pronounced when the orb is used as the spash screen image.
While here also strip metadata.
MFC after: 3 days
Reviewed by: tsoome
Differential Revision: https://reviews.freebsd.org/D60163
DHCP initmd discovery used net_configure() to open and configure SNP,
then immediately closed the socket and released the protocol.
Selecting net0 as currdev subsequently required another exclusive
SNP attach, which may hang on some EDK II firmware.
Keep the configured socket available for ordinary network consumers
so NFS boot can reuse it. Add an explicit deconfiguration operation
and invoke it only when an initmd URL requires handing SNP back
to the firmware network stack.
Signed-off-by: Krzysztof Galazka <[email protected]>
Reviewed by: imp
Assisted by: Github Copilot (GPT-5.6 Sol)
Sponsored by: Intel Corporation
Differential Revision: https://reviews.freebsd.org/D59999
Ability to override DHCP options with command-line arguments
was affected by intoduction of initmd support. Initmd discovery
configures the network before loader arguments
were parsed, so a dhcp.root-path override was unavailable
during the first network configuration. Move parsing
arguments earlier and apply dhcp.root-path even if DHCP response
does not contain option 17. This allows providing a dynamic NFS
root e.g. by chain loading loader.efi from iPXE.
Signed-off-by: Krzysztof Galazka <[email protected]>
Reviewed by: imp
Assisted by: Github Copilot (GPT-5.6 Sol)
Sponsored by: Intel Corporation
Differential Revision: https://reviews.freebsd.org/D59998
When the OpenFirmware loader flattens the firmware device tree into the
FDT it hands to the kernel (usefdt=1, i.e. on every real-mode OF system
such as pSeries LPARs and QEMU pseries guests), add_node_to_fdt() clamps
every property value to 1024 bytes. Any larger property reaches the
kernel truncated.
On QEMU pseries the PCI host bridge's "interrupt-map" is 3584 bytes
(32 slots x 4 pins x 7 cells), so only the entries for slots 0-8 survive
and the entry for slot 9 is cut in the middle. A PCI device in slot 9
or above therefore gets no INTx routing (irq 0), and with INVARIANTS the
partial trailing entry trips the "ofw_bus_search_intrmap: truncated map"
assertion in ofw_bus_search_intrmap() during PCI attach, panicking the
kernel as soon as such a device is present. "ibm,drc-indexes",
"ibm,drc-names" and "ibm,drc-power-domains" are cut the same way.
Drop the clamp. fdt_setprop() already reports a property that does not
fit into the FDT buffer, so no separate limit is needed.
Fixes: 5ecf8e3852 ("Clean up some FDT-related code in the PowerPC bootloader, improving error checking and robustness. Prevents errors and crashes in FDT commands on PowerMac G5 systems.")
Differential Revision: https://reviews.freebsd.org/D60086
BSDRP images are built with "poudriere image -t firmware", which puts
gptboot.efi on the ESP instead of loader.efi. gptboot.efi reads the GPT
bootme attribute, picks the active system partition (BSDRP1 or BSDRP2),
chainloads /boot/loader.efi from it and hands loader.efi that partition
in LoadedImage->DeviceHandle (stand/efi/boot1/boot1.c:try_boot).
Since ce9bfd7816 ("loader.efi: Refactor try_boot_device_partitions"),
find_currdev() no longer tries that device: try_boot_device_partitions()
walks the parent disk while explicitly skipping dp->pd_handle, on the
assumption that the boot image always comes from an ESP holding no root
filesystem. When chainloaded, the partition gptboot.efi selected is
therefore the one partition never considered, and loader.efi falls
through to the first other UFS partition on the disk - the previous
system. Every A/B upgrade silently boots the old slice.
Commit 1c85c5eea0, which introduced try_boot_device_partitions(), did
try dp itself before its siblings; the refactor dropped it. Restore it,
keeping the sibling walk as the fallback for the normal ESP case.
Fixes: ce9bfd7816
Assisted-by: Claude Code (Fable 5, Opus 5)
Sponsored by: Netflix
When we're searching for the EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID (GOPs) to
use, skip any whose Mode or Mode->Info pointers are NULL. The spec
requires these to be non-null, however, some firmwares seem to fail to
populate the Info when, for example, a monitor is not present. Work
around these bugs by skipping any GOPs with bad pointers.
PR: 288900
Sponsored by: Netflix
Differential Revision: https://reviews.freebsd.org/D59830
For the images we read into the memory, use EfiLoaderData memory type
instead of EfiReservedMemoryType. The kernel handles the former properly
and won't reallocate it. While the latter isn't necessarily mapped,
which can cause ram disks to fault when loaded. memdisk_uefi.efi
used the latter type, but also registered the device as an ACPI
RAM disk, which we don't do.
Fixes: afee781523
Sponsored by: Netflix
The only possible time we could download the initmd that the dhcp server
told us about is if we're netbooting. So only attempt to do that if the
load device for loader.efi is a network. IF you are booting off disk and
then need to snag an initmd off the network, that's a different path,
and wouldn't need to necessarily do a dhcp exchange, except to get the
IP address.
Sponsored by: Netflix
When we can't find root, we give the user a chance to drop to the boot
loader OK prompt. We should eat the character that's pressed to not
interfere with the interactive session.
Sponsored by: Netflix
When we haven't downloaded an image via mem{disk,cd} and ipxe, try any
image specified by the FreeBSD-specific initmd dhcp option. This allows
direct booting of loader.efi with a detached root ramdisk filesystem.
Sponsored by: Netflix
Differential Revision: https://reviews.freebsd.org/D59433
Configure net0, read the DHCP-provided initmd URL, and download it
through the file API so directly booted loader.efi can construct its
root memory disk.
Sponsored by: Netflix
Differential Revision: https://reviews.freebsd.org/D59432
Feed the existing decompressor from loader file descriptors as well as
iPXE callbacks, allowing arbitrary HTTP filesystem URLs to become
kernel-exportable memory disks.
Sponsored by: Netflix
Differential Revision: https://reviews.freebsd.org/D59431
Close the exclusively opened SNP protocol after loader networking
finishes so the firmware network stack can reconnect the controller and
service a subsequent HTTP request.
Sponsored by: Netflix
Differential Revision: https://reviews.freebsd.org/D59430
Allow callers to obtain DHCP configuration without opening a network
file, enabling loader.efi to discover an initmd URL before handing the
interface back to firmware HTTP.
Differential Revision: https://reviews.freebsd.org/D59429
Sponsored by: Netflix
Request FreeBSD RFC 3925 PEM 2238 DHCP 125 option. Use suboption 1 to
specify a ramdisk image to load and use to load the kernel and as the
root file system.
Differential Revision: https://reviews.freebsd.org/D59428
Sponsored by: Netflix
Until now, the "http" device only worked when firmware itself booted
loader.efi via EFI HTTP Boot: efihttp_dev_init() required a URI node on
the loader's own boot device path, and every fetch went to that same
server. Add a second form, using the parse_uri() helper from libsa/dev.c,
that works anywhere: http[N]://host[:port]/path (N is a network interface
unit, defaulting to 0). This lets a devspec like this be used as rootdev,
in loader.conf, or interactively, independent of how loader.efi itself
was booted.
Network configuration is shared, loader-wide state (the myip/netmask/
gateip/nameip globals from net.h): if something has already configured
them (e.g. tftp/nfs via net_open()), the http device just reuses those
values, applying them to EFI_IP4_CONFIG2_PROTOCOL as a static address. If
nothing has, it drives IP4Config2's own DHCP directly instead of calling
netdev's net_open(): net_open() opens the NIC's SNP
EFI_OPEN_PROTOCOL_EXCLUSIVE, which would disconnect the Mnp/Ip4/.../
HttpDxe driver chain this code depends on. That chain is also commonly
disconnected already by whatever chained us here (e.g. iPXE excludes and
exclusively opens SNP for its own raw I/O), so reconnect it explicitly
with ConnectController() before giving up.
The legacy EFI HTTP Boot path is untouched.
Sponsored by: Netflix
Differential Revision: https://reviews.freebsd.org/D59423
Add parse_uri(), a helper for devices whose devspec can take a
"[N]://host[:port][/path]" form in addition to the traditional "N:path"
form. It returns EINVAL when devspec doesn't match that pattern, so a
caller's own dv_parsedev can fall back to the traditional form.
Un-static default_parsedev() so it can serve as that fallback.
Sponsored by: Netflix
Differential Revision: https://reviews.freebsd.org/D59422
Some UEFI firmwares do not contain the RamDisk protocol. When this
happens, load the file into a md disk instead. This is less desireable
than the RamDisk (since that allows better chain-booting options), but
sufficient to boot an image as a md device for FreeBSD. While most
severs have the RamDisk protocol enabled in their builds, I have two
IoT class boards from different manufacturers that do not. Since it
works just fine with this fallback, that's preferable.
Sponsored by: Netflix
Differential Revision: https://reviews.freebsd.org/D59421
When someone has loaded a ram disk, that's a stronger hint about what to
boot than the UEFI boot manager. Prefer it and rework a little the #ifdefs
to reduce their number.
Sponsored by: Netflix
Differential Revision: https://reviews.freebsd.org/D59419
Augment the md device to allow creation of md devices. This is useful
when UEFI doesn't support RamDisk and in other cases where we have a
handy initrd-like image we want to use.
Sponsored by: Netflix
Differential Revision: https://reviews.freebsd.org/D59418
Only the EFI loader supports the md devices (as the moment). Create
LOADER_MD_SUPPORT and only try to compile md when that's true. For the
moment, also allow it when only MD_IMAGE_SIZE is defined, but that
will be dropped since LOADER_MD_SUPPORT is a superset.
Sponsored by: Netflix
Reviewed by: tsoome
Differential Revision: https://reviews.freebsd.org/D59416
Use the field names from the Arm Documentation for the CTR_EL0
register. These will later be generated from a BSD Licensed JSON file
so to reduce the diff for that rename now.
Reviewed by: Kajetan Puchalski <[email protected]>
Sponsored by: Arm Ltd
Differential Revision: https://reviews.freebsd.org/D59173
- consistently use Mt request within Aq. This makes author
e-mail addresses clickable in many frontends.
- @freebsd.org -> @FreeBSD.org
- ([email protected]) -> Aq Mt [email protected]
Event: Berlin Hackathon 202609
MFC after: 3 days
Reviewed by: ziaee
Differential Revision: https://reviews.freebsd.org/D59410
If an explicit loader wasn't requested, then bhyveload(8) maintains a
/boot handle that it can use for swapping to a different flavor. This
means that we expose all of the host /boot to the sandbox for the
duration of script execution.
Add a callback to ack that we're OK with the interpreter so that
bhyveload(8) can release the bootfd. This is worth doing because it's
prior to guest script execution, so we're still running a reasonably
untainted process.
Reviewed by: imp, jhb
Differential Revision: https://reviews.freebsd.org/D58771
To avoid any sort of POLA violation, this commit restores old
guards and defines the C23 feature test macros in addition to
them. This is to close off whole class of possible breakage,
rather than patching it case by case.
Reported by: dim
Reviewed by: dim, dteske, fuz
Approved by: dim, dteske (mentor), fuz (mentor)
MFC after: 1 month
Differential Revision: https://reviews.freebsd.org/D58911
The loader's ZFS implementation never set st_dev or st_ino in
zfs_dnode_stat(). With an uninitialized struct stat, veriexec's device
comparison in lib/libsecureboot/veopen.c read stack garbage and skipped
the matching manifest entry, failing with a spurious "no entry" on ZFS
root under UEFI Secure Boot.
Rather than zeroing the device (which would break veriexec's ability to
tell apart the same path on different datasets), populate st_dev and
st_ino with the same intrinsic identifiers the kernel uses:
- st_dev = the dataset's ds_fsid_guid (as the kernel does via
dmu_objset_fsid_guid()/dsl_dataset_fsid_guid()), already read in
zfs_mount_dataset() and now propagated through struct zfsmount.
- st_ino = the object number resolved in zfs_lookup(), propagated
through struct file (the loader's equivalent of the kernel's z_id).
dev_t and ino_t are 64-bit on FreeBSD, so both are assigned directly
with no hashing. A memset() at the top of zfs_dnode_stat() zeroes the
remaining fields so they no longer hold stack garbage.
Tested on 16.0-CURRENT (amd64), ZFS-on-GELI root: rebuilt and re-signed
the EFI loader; the system boots under UEFI Secure Boot with
mac_veriexec active.
(boot1 segment was modified by kevans)
PR: 295935
Sponsored by: Defenso
Reviewed-by: kevans
Pull-Request: https://github.com/freebsd/freebsd-src/pull/2271
Define the __STDC_VERSION_STDIO_H__ feature test macro now that
the header fully conforms to C23.
Reviewed by: fuz
Approved by: fuz (mentor)
MFC after: 1 month
Differential Revision: https://reviews.freebsd.org/D58842