Return ENODEV from vdev_prop_get/set for a missing vdev
Return ENODEV instead of ENOENT when a vdev guid lookup
fails so zpool commands report a vdev that disappeared as
"no such device in pool" rather than "no such pool or dataset".
Reviewed-by: Alexander Motin <alexander.motin at TrueNAS.com>
Signed-off-by: Mark Maybee <mark.maybee at delphix.com>
Assisted-by: Claude Sonnet 5.5
Closes #19594
Build the vdev config in place instead of copying it.
vdev_config_generate() built each child's nvlist on its own, copied it
into the parent and then freed it. The extended stats and the vdev
tree in spa_config_generate() were added the same way. In a config
with stats, the stats of a leaf under a raidz vdev were copied four
times.
Each nested nvlist is now added empty and filled where it lives. The
output is the same. vdev_config_generate() keeps its interface and
calls the new vdev_config_generate_impl().
On a pool with 1200 disks, building the config that
ZFS_IOC_POOL_STATS returns took about 287 ms before and about 80 ms
after. This was measured in userland with libzpool. In a perf profile
of that ioctl the copies were about 55% of the samples.
Signed-off-by: Caleb St. John <yocalebo at gmail.com>
Reviewed-by: Ameer Hamza <ameer.hamza at truenas.com>
Reviewed-by: Alexander Motin <alexander.motin at TrueNAS.com>
Closes #19355
ZTS: isolate the legacy mount option test dataset
Use a separate dataset for legacy mount option checks so properties left
by an earlier test do not affect the result. Destroy only that dataset
on exit, and skip its destruction if creation failed.
Match complete option names and compare against the paired inverse, so a
positive option cannot match the corresponding negative spelling.
Assisted-by: OpenAI Codex
Reviewed-by: Alexander Motin <alexander.motin at TrueNAS.com>
Signed-off-by: ooonea <35407790+ooonea at users.noreply.github.com>
Co-authored-by: ooonea <ooonea at noreply.codeberg.org>
Closes #19586
Release the upgrade hold before clearing os_upgrade_id
dmu_objset_upgrade_task_cb() clears os_upgrade_id under
os_upgrade_lock and only then, after dropping the lock, releases its
long hold on the dataset. dmu_objset_upgrade_stop() waits for the
task only if it finds os_upgrade_id set, so in that window it returns
at once, dmu_objset_disown() can drop the last hold, and the async
eviction finds the long hold still counted:
VERIFY3U(rc->rc_count, ==, number) failed (1 == 0)
PANIC at refcount.c:91:zfs_refcount_destroy_many()
dsl_dataset_evict_async+0x151/0x290 [zfs]
The task's own release then touches a dataset that may be freed.
dmu_objset_own() starts a userspace upgrade task on every writable
mount, so a pool destroyed right after it is created can hit this:
zpool_create_024_pos did once in CI.
Release the hold while os_upgrade_lock is still held, before clearing
[4 lines not shown]
vdev: avoid null member access in statistics updates
Initialize the statistics pointers only in the successful non-root I/O
path, where they are used. Remove the early sanitizer-specific
initializations without adding a null check.
Assisted-by: OpenAI Codex
Reviewed-by: Alexander Motin <alexander.motin at TrueNAS.com>
Signed-off-by: ooonea <ooonea at noreply.codeberg.org>
Closes #19578
Linux: read the change cookie under z_lock
The change cookie was read after zfs_getattr_fast() dropped z_lock, so
a concurrent setattr could bump it after the attributes were read, and
getattr returned the old owner, group or mode with the new cookie.
knfsd hands that pair to NFSv4 clients, which cache attributes by
change attribute and kept the stale values until the next change.
setattr, ACL changes and link/unlink update the attributes and bump
z_seq under z_lock, so read the cookie there, with the attributes.
Reviewed-by: Tony Hutter <hutter2 at llnl.gov>
Reviewed-by: Alexander Motin <alexander.motin at TrueNAS.com>
Signed-off-by: Ameer Hamza <ameer.hamza at truenas.com>
Closes #19589
ZTS: sync checksum test data before fault injection
Ensure that the checksum configuration test reads persisted blocks.
mkfile does not sync its writes, and flushing the ARC with zinject -a
does not make dirty dbufs evictable. Cached reads can miss the injected
checksum errors needed to reach the configured threshold.
Reviewed-by: Brian Behlendorf <behlendorf1 at llnl.gov>
Reviewed-by: Alexander Motin <alexander.motin at TrueNAS.com>
Signed-off-by: ooonea <35407790+ooonea at users.noreply.github.com>
Assisted-by: OpenAI Codex
Closes #19545
ZTS: allow ctypes library discovery
Include the loader discovery tools used by Python ctypes in the
constrained Linux test path.
Reviewed-by: Brian Behlendorf <behlendorf1 at llnl.gov>
Signed-off-by: ooonea <35407790+ooonea at users.noreply.github.com>
Assisted-by: OpenAI Codex
Closes #19576
Add tests for stale mmap pages after rollback and recv -F
A file that has been mapped with mmap() keeps its pages in the Linux
page cache. If the dataset is then rolled back, or receives an
incremental stream with "zfs receive -F", and the file keeps its
object number, generation and size but has different data, reads
and new mappings kept returning the pre-rollback data until the
cache was dropped or the dataset remounted (#10931). The on-disk
data was always correct.
Add mmap_cached_rollback and mmap_cached_receive to the mmap group.
Both fault the file in through a read-only mapping, change the
dataset underneath it, and check that read() and a fresh mapping
see the new contents. The mmap_stale_check helper does the mapping
and checksumming.
Both tests fail on Linux without the zfs_rezget() page cache fix
and pass with it. They also pass on FreeBSD.
[3 lines not shown]
Linux 7.3 compat: META
Update the META file to reflect compatibility with the 7.3
kernel.
Assisted-by: OpenAI Codex
Reviewed-by: Brian Behlendorf <behlendorf1 at llnl.gov>
Signed-off-by: ooonea <35407790+ooonea at users.noreply.github.com>
Closes #19553
libzutil: keep the latest label when two vdevs claim one id
When it builds a pool's config from the labels found by a scan,
get_configs() puts each top-level vdev at the id its label gives,
replacing whatever was there, and leaking it. A device can keep the
label of a top-level vdev that the pool no longer has, such as one
added after a checkpoint that the pool was then rewound to, while a
vdev added since has the same id. Whichever comes last wins, so the
stale vdev can replace the current one in the config. The import, or
"zdb -e", then fails with an I/O error when the pool's metadata has
blocks on that vdev. When it has none there, the import falls back
on the config stored in the pool, which works only while the paths
recorded there still lead to the devices.
For each id, keep the top-level vdev whose label has the latest txg,
and free the one it replaces.
Reviewed-by: Brian Behlendorf <behlendorf1 at llnl.gov>
Reviewed-by: Will Rouesnel <wrouesnel at wrouesnel.com>
Signed-off-by: Tigerblue77 <37409593+tigerblue77 at users.noreply.github.com>
Closes #19496
abi: update for libspl kthread changes
Sponsored-by: TrueNAS
Reviewed-by: Kamil Monicz <kamil at monicz.dev>
Reviewed-by: Brian Behlendorf <behlendorf1 at llnl.gov>
Signed-off-by: Rob Norris <rob.norris at truenas.com>
Closes 19508
libspl: updated "owned" primitives to track curthread
kmutex_t and krwlock_t both have an owner field, tracking the owner.
These can now use a kthread_t* and the curthread pointer like everything
else.
Sponsored-by: TrueNAS
Reviewed-by: Kamil Monicz <kamil at monicz.dev>
Reviewed-by: Brian Behlendorf <behlendorf1 at llnl.gov>
Signed-off-by: Rob Norris <rob.norris at truenas.com>
Closes 19508
libspl/thread: rewrite for kthread semantics and to hide pthread
The libspl kthread implementation was previously a simple wrapper around
POSIX threads. This was subtly wrong in a handful of ways, mostly in
that a pthread does not have exactly the same lifetime as a kthread, and
pthread_t neither represents exactly the same thing as kthread_t*, nor
is it guaranteed to be the same size and shape.
This commit properly implements the kthread semantics and API on top of
pthreads, while largely hiding the pthread use inside as an
implementation detail.
Sponsored-by: TrueNAS
Reviewed-by: Kamil Monicz <kamil at monicz.dev>
Reviewed-by: Brian Behlendorf <behlendorf1 at llnl.gov>
Signed-off-by: Rob Norris <rob.norris at truenas.com>
Closes 19508
spa: extend HAVE_SPA_THREAD gate to all uses of spa_did
thread_join(spa->spa_did) was always compiled in, which was ok while
thread_join() is either a no-op or takes a type trivially convertible to
a uintptr_t. Next commit will change the latter for userspace, breaking
the build.
Since this is all part of the currently-unused "SPA thread" mechanism,
it should go behind the same compilation gate.
Sponsored-by: TrueNAS
Reviewed-by: Kamil Monicz <kamil at monicz.dev>
Reviewed-by: Brian Behlendorf <behlendorf1 at llnl.gov>
Signed-off-by: Rob Norris <rob.norris at truenas.com>
Closes 19508
raidz: don't lose the expansion wakeup when a resilver ends early
When a pass of a RAID-Z expansion fails, because a child cannot be
read or its DTL_MISSING is not empty, spa_raidz_expand_thread() waits
for the txgs of that pass to sync, and only then sets
vre_waiting_for_resilver. raidz_dtl_reassessed() resumes the
expansion only if that flag is already set. A DTL reassessment that
lands in between is lost, and the expansion stays paused with every
child healthy, until something else reassesses the DTLs.
This is what happens after "zpool online" of a child that was offline
during an expansion. The online wakes the thread, the next pass fails
again because the child's DTL_MISSING is not empty yet, and the
resilver of a short outage ends, and reassesses the DTLs, while the
thread is still in txg_wait_synced().
Count the reassessments in vre_dtl_gen, and do not set
vre_waiting_for_resilver if the count has moved since the pass
started: the zthr then runs the next pass at once, as a wakeup would
[13 lines not shown]
zarcsummary: handle reset output pipes
A reader closing the output early can raise ConnectionResetError rather
than BrokenPipeError. Handle both with the existing successful exit path
and preserve the handling of other exceptions.
Assisted-by: OpenAI Codex
Reviewed-by: Brian Behlendorf <behlendorf1 at llnl.gov>
Signed-off-by: ooonea <35407790+ooonea at users.noreply.github.com>
Closes #19547
Linux: fix zfs_sha256_available() on ARM CPUs that also have SHA-512
ID_AA64ISAR0_EL1.SHA2 is 0b0001 when SHA-256 is implemented and 0b0010
when SHA-256 and SHA-512 both are. zfs_sha256_available() tested bit 0
of the field, so on every CPU that also implements SHA-512, which
includes Apple silicon and recent Cortex and Neoverse cores, it reported
SHA-256 as absent. The sha256 armv8-ce implementation was then never
listed and the slower NEON variant was the fastest available, while
zfs_sha512_impl correctly offered armv8-ce on the same CPU.
Treat any nonzero field value as SHA-256 present, matching the kernel's
HWCAP_SHA2 logic. FreeBSD and userspace use HWCAP and were already
correct.
Reviewed-by: Tino Reichardt <milky-zfs at mcmilk.de>
Reviewed-by: Rob Norris <rob.norris at truenas.com>
Reviewed-by: Alexander Motin <alexander.motin at TrueNAS.com>
Signed-off-by: Walter McKelvie <walt at mckelvie.org>
Closes #19536
ZTS: preserve failures across repeated test executions
The reporter keeps only the last result for each test pathname. A pass
from another runfile group or a later iteration can overwrite an
earlier failure and make zfs-tests.sh report success.
Keep each result record and apply the existing pathname-based known
and intermittent failure policies. Cover duplicate groups and repeated
iterations with logs emitted by the test runner.
Reviewed-by: Brian Behlendorf <behlendorf1 at llnl.gov>
Reviewed-by: Tigerblue77 <37409593+tigerblue77 at users.noreply.github.com>
Signed-off-by: Kamil Monicz <kamil at monicz.dev>
Closes #19438
ZTS: age MRU buffers before checking MFU promotion
A repeated read only promotes MRU buffers after ARC_MINTIME has elapsed.
Wait one second before the second read so the test establishes that
precondition without changing ARC behavior or its assertions.
Update the strategy to describe the operations the test performs.
Assisted-by: OpenAI Codex
Reviewed-by: Alexander Motin <alexander.motin at TrueNAS.com>
Reviewed-by: Brian Behlendorf <behlendorf1 at llnl.gov>
Signed-off-by: ooonea <35407790+ooonea at users.noreply.github.com>
Closes #19544
unit/nvpair: verify complete copied results
Read the copied string from the destination list rather than the source.
Require both pair iterators to reach the end when comparing a duplicate.
The current loop accepts a copy truncated after its first pair.
Check that duplication preserves the list's uniqueness flags as well as
its entries. Distinct input names otherwise hide a changed list mode.
Reviewed-by: Brian Behlendorf <behlendorf1 at llnl.gov>
Signed-off-by: Kamil Monicz <kamil at monicz.dev>
Closes #19455
unit: exercise the selected nvlist and normalization modes
The byte and uint8 cases ignore their uniqueness parameters, and the
pair-lookup case always constructs an NV_UNIQUE_NAME list. Use the
selected fixtures and check ENOTSUP for pair lookup in the other modes.
Select NFKD in the compatibility-decomposition test, which currently
passes NFKC and repeats the composition mode instead.
Reviewed-by: Brian Behlendorf <behlendorf1 at llnl.gov>
Signed-off-by: Kamil Monicz <kamil at monicz.dev>
Closes #19455
unit: check fixture setup and output cleanup results
Check the fat-ZAP upgrade operations and memory-stream closes directly,
so their failures cannot be hidden by later assertions on the contents.
Reject a failure to disable core dumps in the btree death-test child
with a nonzero exit. An assertion there would produce the same SIGABRT
that the test expects from the btree operation.
Reviewed-by: Brian Behlendorf <behlendorf1 at llnl.gov>
Reviewed-by: Rob Norris <rob.norris at truenas.com>
Signed-off-by: Kamil Monicz <kamil at monicz.dev>
Closes #19467
libspl: keep native backtraces usable under Valgrind
Native unwinding inspects register snapshots and probes process memory.
Memcheck can report these operations while handling an assertion,
obscuring the failure that triggered the backtrace.
Disable Valgrind error reporting on the calling thread while generating
the native backtrace, then restore the previous reporting state. Keep
the native registers, symbolization and caller-selected descriptor,
including stderr redirected after Valgrind starts. Detect the optional
client-request headers during userspace configuration.
This scope also hides genuine errors encountered while unwinding.
Add destination tests for redirected stderr and custom descriptors.
Reviewed-by: Brian Behlendorf <behlendorf1 at llnl.gov>
Signed-off-by: Kamil Monicz <kamil at monicz.dev>
Closes #19459
build: generate zfs_gitrev.h before building the kernel modules
module/Makefile lists modules and gitrev as two prerequisites of all,
with nothing that orders them. Under make -j the kernel build can then
compile spa_history.c or spl-proc.c before zfs_gitrev.h exists. Seen
with make -j24 -l25:
spa_history.c:32:10: fatal error: 'zfs_gitrev.h' file not found
Make modules-Linux and modules-FreeBSD depend on gitrev instead.
Reviewed-by: Brian Behlendorf <behlendorf1 at llnl.gov>
Signed-off-by: Alexander Moch <mail at alexmoch.com>
Closes #19535
test-runner: write the kmemleak report into the log
When kmemleak reports objects after a test, the test runner marks the
test as failed and writes the report to a kmemleak file in the test's
output directory, but not to the log. The CI's Test Summary and job
summary take a failed test's output from the log, so the report only
shows up in the downloaded archive.
Also write the report into the log, after the test's own output, with
each line prefixed "kmemleak:". The kmemleak file is unchanged.
Reviewed-by: Brian Behlendorf <behlendorf1 at llnl.gov>
Signed-off-by: Alexander Moch <mail at alexmoch.com>
Closes #19472
ZTS: select failed tests from current runner logs
The rerun filters only recognize unprefixed, unlabelled result lines.
Current timestamps and platform identifiers prevent failures from
being selected, so automatic retries can report success without
rerunning a failed test.
Parse the emitted result headers and retain group identifiers when
matching failures. Match resolved directories first, with relative
runfile group paths allowing reruns after the suite moves. Absolute
groups and standalone tests keep exact path matching.
Let the runner parse retry records after the wrapper filters eligible
test names, retaining older log support.
Reviewed-by: Brian Behlendorf <behlendorf1 at llnl.gov>
Reviewed-by: Tigerblue77 <37409593+tigerblue77 at users.noreply.github.com>
Signed-off-by: Kamil Monicz <kamil at monicz.dev>
Closes #19437
zio_crypt_os: add Linux kernel crypto API backend
Implement the zio_crypt_os platform interface using the Linux kernel
crypto API. This provides hardware-accelerated encryption on platforms
where the ICP has none, most notably ARM.
The kernel exports these symbols GPL-only by default, so configure
selects this backend only when the kernel exports them with a license
compatible with the module's and the AEAD and hash cores (CRYPTO_AEAD2
and CRYPTO_HASH2) are enabled. A builtin build is not subject to export
licensing, but then needs those cores to be builtin as well. Otherwise
the ICP backend is used. Only the selected backend is compiled.
The backend looks up its algorithms by name at key load time, so it
declares a soft dependency on the modules providing them for initrd
builders to include.
Finally, since crypto accelerators may DMA write to keydata and
hmac_keydata, dsl_crypto_key_sync() will now put these on the heap
[6 lines not shown]
zstream: read BLKSSZGET into an int in zstream raw
The BLKSSZGET ioctl stores an int, but zstream raw passed a pointer to
the uint64_t volume.sectorsize. On little-endian systems this happens
to work because the upper half was already zero, but on big-endian
systems the sector size ends up in the upper 32 bits (512 << 32, or
2 TiB). free_blocks() then rounds the start of a freed range up to
2 TiB and writes zeros from the start of the range towards it. On any
smaller device that write fails with ENOSPC at the end of the device,
so zstream raw exits at the first FREE record with a nonzero offset,
after zeroing from that offset to the end of the device. Every zvol
stream has such a record before its data (the free past the end of the
volume), so zstream raw could not apply a zvol stream to a block
device on big-endian systems at all.
Read the value into an int and assign it.
Reviewed-by: Brian Behlendorf <behlendorf1 at llnl.gov>
Signed-off-by: Will Rouesnel <wrouesnel at wrouesnel.com>
Closes #19324
zpool: compare special and dedup vdevs only with normal vdevs
Since 1d9c32c16 a special or dedup vdev may be more redundant than the
normal vdevs, but get_replication() still compared each special or dedup
vdev with the previous special or dedup vdev. A pool with a 3-way
special mirror and a 2-way dedup mirror on 2-way mirror normal vdevs,
each of which is individually acceptable, was therefore reported as
inconsistent. check_replication() skips all checks for an inconsistent
pool, so a later non-redundant addition was accepted without -f:
zpool create tank mirror f1 f2 special mirror f3 f4 f5
zpool add tank dedup mirror f6 f7 # accepted
zpool add tank f8 # accepted without -f
At the same time, creating the same layout in one step was rejected:
zpool create tank mirror f1 f2 special mirror f3 f4 f5 \
dedup mirror f6 f7 # rejected
[14 lines not shown]