aq(4): interface lifecycle and link-state fixes
aq_if_init() programmed the address captured at attach, so an address set
with "ifconfig ether" or by lagg(4) enslavement was never written to
unicast filter slot 0: the interface transmitted with the new address but
the MAC still filtered on the old one, so it received nothing. Copy the
current if_getlladdr() the way the other iflib drivers do.
The link state could latch UP forever. aq_if_stop() cleared linkup
before calling aq_if_update_admin_status(), which suppressed the
LINK_STATE_DOWN transition the "link was UP" branch would have made.
Announce the down transition directly from aq_if_stop() instead, and do
not poll the admin status there at all: the MAC has just been reset, so a
stale link reading would re-announce the link as up.
The admin task itself had to stop reporting a link on a stopped
interface. iflib runs it while either IFF_DRV_RUNNING or IFF_DRV_OACTIVE
is set, and iflib_stop() sets OACTIVE, so the task kept polling after the
stop and re-announced LINK_STATE_UP behind the driver's back. Treat a
[22 lines not shown]
aq(4): mailbox, flow-control and firmware error-handling fixes
Fold the whole-driver-review correctness and hardening fixes for the
firmware and hardware layers.
Advance the firmware-mailbox address per word in aq_hw_fw_downld_dwords():
on B1 silicon each loop iteration waits for the mailbox address register
to differ from the expected address, but it was set once and never moved,
so after the first word every wait returned immediately and read stale
data. Advance it four bytes per word. B0 is unaffected (it polls the
busy bit). The same function also left err set to ETIMEDOUT after
successfully force-recovering the RAM CPU semaphore; the transfer loop is
guarded by "--cnt && !err", so it ran zero iterations and returned a
timeout with an untouched buffer, making the recovery path dead code.
aq_hw_get_mac_permanent() ignored the get_mac_addr() error and then
examined a buffer the firmware op never wrote on failure. A fresh softc
is zero, so the "invalid address" test fired, a random locally
administered MAC was substituted, and err was overwritten with 0 -- a
[46 lines not shown]
aq(4): clean up diagnostics and remove dead code
Non-functional cleanup, no change in behavior.
device_printf() already prefixes each line with the device name, so the
inline "atlantic:" token in the status and error messages produced a
doubled prefix and diverged from the trace macros; remove it so all
output carries one uniform "aqN:" prefix. Compile the RX/TX descriptor
tracers only when AQ_CFG_DEBUG_LVL > 2 and make them no-op macros
otherwise, so the default build no longer pays a cross-TU call plus
argument evaluation per descriptor.
Drop enum aq_dev_state, struct aq_rx_filters, and struct aq_vlan_tag,
which have no remaining references now that VLAN state lives in a
bitstr_t. Replace the four identical aq_sysctl_print_{tx,rx}_{head,tail}
handlers, each carrying a dead write path on a read-only oid, with one
aq_sysctl_print_ring_ptr that selects the accessor from arg2. Reduce the
thermal and PHY-recovery comments to single terse lines that keep the
load-bearing register numbers and the A1-vs-A2 recovery difference.
[5 lines not shown]
aq(4): PHY thermal-shutdown handling and correctness fixes
Fold the thermal-protection work and the correctness fixes that landed
alongside it.
Report and auto-recover from PHY thermal shutdown. The Atlantic PHYs can
autonomously shut down on over-temperature, latching global fault 0x8007
and dropping the link; Atlantic 2 ships this armed, Atlantic 1 disabled.
Arm it on Atlantic 1 at interface init (1E.C478.A via the MAC's MDIO
controller), and recover from a trip automatically: the admin-status poll
detects the fault, logs the shutdown limit and measured temperature, and
holds the link down until the PHY cools, then restores it -- Atlantic 1
needs a PHY reset (1E.2681.0) with the MAC firmware running plus a full
re-init, Atlantic 2 recovers on the re-init alone. New firmware ops
get_phy_fault, phy_reset, thermal_arm, and get_thermal_limit back the
state machine in aq_if_update_admin_status().
Make that Atlantic 1 thermal MDIO path address-correct and fail-safe.
The direct-MDIO helpers hardcoded the Clause-45 port address to 0, but it
[29 lines not shown]
aq(4): observability controls and sysctl/header hygiene
Fold the driver's observability and infrastructure work.
Make aq_device.h self-contained: it declares struct aq_dev in terms of
iflib, bitstring, socket, and ethernet types but included none of the
headers that define them, compiling only because every includer happened
to pull those first. Include what it uses. No functional change.
Make the debug controls per-instance. The debug and debug_categories
sysctls were registered per device but pointed at file-scope globals, so
writing dev.aq.1.debug also changed dev.aq.0.debug and a card could not
be traced in isolation. Move the level and category mask into struct
aq_dev, reach them through the aq_dev back-pointer in struct aq_hw (wired
up in attach_pre before the first firmware trace and guarded against a
NULL deref), emit through device_printf() so each line carries its unit,
and seed initial values from per-unit device hints so attach can be
traced.
[27 lines not shown]
Consolidate the internal dataset registries behind one module
## Problem
"Internal dataset" was defined in three separate places with three different membership sets and three different matching algorithms, which is how they drifted apart. `plugins/zfs/utils.py` matched the second path component and drove every mutation guard; `pool_/dataset_query_utils.py` matched an unanchored substring and drove `pool.dataset.query` filtering; `pool_/dataset.py` used a filter list whose `ix-applications` entry carried a trailing slash the other two did not. A fourth ad-hoc list lived in the unencrypted-dataset alert source. Nothing had unit coverage.
That divergence had real consequences. `pool.dataset.create` accepted `<pool>/ix-applications` and then hid the dataset it had just made. `.truenas_containers` was hidden from the dataset listing yet still offered by `pool.filesystem_choices` and still destroyable. Seven public mutators — `pool.dataset.rename`, `promote`, `set_quota`, `lock`, `change_key`, `inherit_parent_encryption_properties` and `zfs.tier.dataset_set_tier` — had no protection at all, so a caller could rename or promote the system dataset. Promote was the worst of them: internal children are frequently clones, so promoting one reparents its origin snapshot.
Separately, the `bypass` escape hatch was reachable from the public API. It was declared `SkipJsonSchema` on seven snapshot request models, but that annotation is only consulted when generating docs and JSON schema, never at dispatch, so any caller holding `SNAPSHOT_WRITE` could set it and defeat every guard.
## Solution
- **One registry.** `utils/zfs/internal.py` holds the table and the predicates. Membership is described on three independent axes — `visibility` (product listing), `path_scope` (raw ZFS listing) and `mutability` (mutation guards and name reservation) — because no two of them can express every dataset we own: the container dataset is hidden from the product listing yet present in the raw one and freely mutable. `path_scope` is scaffolding and retires once every entry is `INTERNAL`.
- **Shapes ported verbatim.** Each predicate reproduces the matching algorithm its callers used before, so consolidating the registries changes nothing about which datasets are listed. Converging the shapes would newly expose things like `tank/data/ix-apps` and flip four unrelated consumers, so that is deliberately left for later.
- **Guards moved up.** Protection now lives in the public `@api_method` bodies via `assert_mutable()`; the `*_impl` methods are unguarded owner-only mechanism, which is how sysdataset, docker, apps and container manage their own datasets. With nothing left to bypass, `bypass` is gone from the seven request models, from `destroy_impl`, and from every internal call site. `exclude_internal_paths` likewise leaves `ZFSResourceQuery` and survives only as a private keyword argument that JSON-RPC cannot reach, which is what keeps the usage census counting boot-pool and `.system`.
- **Gaps closed.** The seven unguarded mutators now refuse protected paths, `pool.dataset.delete` reports `EACCES` instead of a misleading "does not exist", and `<pool>/ix-applications` is reserved like every other entry.
- **Coverage.** A table-driven truth table pins all four predicates across every shape edge, and AST tests assert that each public mutator consults the registry, that no `*_impl` guards, and that only one module defines the table — so the next mutator cannot be added without a decision.
`container.create` now clones through `zfs.resource.snapshot.clone_impl` and mounts explicitly, rather than going out through the public `pool.snapshot.clone`, since its destination lives under a dataset the public endpoint is free to start refusing.
libm: make use of __builtin_cpu_supports() on i386
libm checks at runtime whether the CPU supports SSE. The compiler
runtime on x86 now provides a CPU feature array that we can test with
__builtin_cpu_supports().
[LAA][NFC] Refactor deref no-wrap check; expose broken reverse-loop bounds (#211960)
Split evaluatePtrAddRecAtMaxBTCWillNotWrap into two stages: compute
MaxOffset based on the step direction, then apply the shared
MaxOffset <= DerefBytes check.
Rename intermediate values to reflect what they actually represent.
This restructuring makes two long-standing off-by-EltSize issues in
the negative-step path explicit:
* The lower-bound check is over-conservative by EltSize.
* The upper-bound check under-counts by EltSize.
stat.2: enhance the description of st_blocks
Reviewed by: emaste, mckusick
Sponsored by: The FreeBSD Foundation
MFC after: 3 days
Differential revision: https://reviews.freebsd.org/D58592
audio/mpg123: udpate to 1.33.7
Lots of issues fixed.
1.33.7
------
- mpg123:
-- Fix heap buffer overflows in unicode path conversion on Windows (bug 388,
thanks to Alejandro Ramos).
-- Fix information disclosure of uninitialied memory for --auth-file without
line endings. (bug 390, thanks to Alejandro Ramos)
-- Fix out-of-bounds read/write when combining --continue --random --listentry <n>
where n is larger than the playlist size. (bug 391, thanks to Alejandro Ramos)
-- Fix a harmless valgrind memory leak report by not nulling playlist name.
-- Fix error handling of win32_net_writestring() (Windows only) by actually using
a signed type, also preventing a OOB read on failure.
(bug 392 by Alejandro Ramos)
-- Fix a mostly harmless OOB read of 1 byte when printing USLT lyrics.
(bug 392)
[54 lines not shown]
[AMDGPU] gfx1250 co-execution scheduler
Snapshot of the gfx1250 co-execution scheduling work, squashed into a
single commit on top of llvm/llvm-project e2a39f504fee.
Includes the co-execution window model (AMDGPUCoExecInfo.h), the
CoExecSchedStrategy window-slot-demand machinery, pre-RA and post-RA
co-execution hazard tracking in GCNHazardRecognizer, the gfx1250 static
simulator (AMDGPUStaticSimulator), expert-mode waitcnt work in
SIInsertWaitcnts, and the supporting lit and MIR tests.
Authored by, in no particular order:
Austin Kerbow, Jeffrey Byrnes, Alexey Sachkov, Lucas Ramirez,
Volkan Keles, Hideki Saito, Jay Foad, Brendon Cahoon,
Ilia Cherniavskii, Alexander Weinrauch, Vigneshwar, proaditya,
mssefat, Lei Zhang
[AMDGPU] gfx1250 co-execution scheduler
Snapshot of the gfx1250 co-execution scheduling work, squashed into a
single commit on top of llvm/llvm-project 7570d2daec56.
Includes the co-execution window model (AMDGPUCoExecInfo.h), the
CoExecSchedStrategy window-slot-demand machinery, pre-RA and post-RA
co-execution hazard tracking in GCNHazardRecognizer, the gfx1250 static
simulator (AMDGPUStaticSimulator), expert-mode waitcnt work in
SIInsertWaitcnts, and the supporting lit and MIR tests.
Authored by, in no particular order:
Austin Kerbow, Jeffrey Byrnes, Alexey Sachkov, Lucas Ramirez,
Volkan Keles, Hideki Saito, Jay Foad, Brendon Cahoon,
Ilia Cherniavskii, Alexander Weinrauch, Vigneshwar, proaditya,
mssefat, Lei Zhang
clang: Emit "long-double-type" module flag generically
Move emission of the "long-double-type" module flag out of PowerPC
and into generic code, so it describes the long double format for all
targets.
Co-authored-by: Claude (Claude-Opus-4.8) <noreply at anthropic.com>
Keep container records unless their pool was really destroyed
## Problem
The container FS attachment delegate was the only stateful-workload delegate whose `delete()` destroyed configuration: it undefined the libvirt domain and removed the `container_container` and `container_device` rows, while deliberately leaving the rootfs dataset alone. VMs and apps only stop. That made `pool.export(cascade=True, destroy=False)` — the flow that exists precisely because the pool is moving elsewhere intact — permanently orphan live storage. A container's definition, devices and idmap slice live only in SQLite, nothing on disk can rebuild them (unlike the migrated incus containers, we write no manifest), and a freed idmap slice can be reissued to another container while the surviving rootfs still carries its UID range.
`pool.dataset.delete` reached the same code with no cascade flag at all, so deleting a dataset that a container merely bind-mounted as a FILESYSTEM device destroyed the whole container. And since `query()` only reports containers in ACTIVE_STATES, the cleanup was not even coherent — it dropped the records of running containers and kept those of stopped ones.
## Solution
- **`delete()` is now stop-only**, matching the VM and apps delegates. Records are never removed from the delegate.
- **Record removal moved to a `pool.post_export` hook**, which is the only place that can see whether the data actually went away. It keys off a new `destroyed` flag from `pool.export` rather than `options['destroy']`: asking to destroy an OFFLINE pool leaves it untouched on its disks, so the requested option on its own would still have discarded records whose storage was intact. The hook matches on the dataset and ignores runtime state, so stopped containers are cleaned up too.
- **Containers are re-pointed at their storage when a pool is imported under a new name.** The dataset is always `<pool>/.truenas_containers/containers/<name>`, so the new location is derived rather than guessed. The remap is committed only when the old pool is genuinely gone, the derived dataset exists, and no other container claims it; each container is applied behind its own boundary so one failure cannot abort the import or block the rest.
- **`pool.reimport` no longer starts everything on the pool.** It walks the delegates in start-priority order (it was using registration order, quietly defeating the docker/apps ordering) and calls a new `start_on_import`, which containers and VMs override to honour `autostart`. Previously every stopped container and VM on the pool came up regardless.
Also documents why `storage_paths()` derives the container root from the dataset name rather than its real mountpoint — both consumers need the name-derived form, and switching to the mountpoint would silently stop matching containers on pool export and lock.