ZTS/zfs_mount: test that ro/rw mount methods remain consistent

Whether a mount ends up as read-only or read-write depends on a
combination of platform, readonly= filesystem property, mount method
(system mount(8) or zfs-mount(8)) and mount option provided (ro, rw or
none).

This tests all combinations, and ensures they match what has
traditionally been expected on this platform, so we'll know if we
accidentally changed it.

Sponsored-by: TrueNAS
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Rob Norris <rob.norris@truenas.com>
Closes #18557
Closes #18563
This commit is contained in:
Rob Norris
2026-05-19 14:27:12 +10:00
committed by Brian Behlendorf
parent b394b8742e
commit 20437d856c
4 changed files with 134 additions and 3 deletions
+2 -2
View File
@@ -271,8 +271,8 @@ tests = ['zfs_mount_001_pos', 'zfs_mount_002_pos', 'zfs_mount_003_pos',
'zfs_mount_004_pos', 'zfs_mount_005_pos', 'zfs_mount_007_pos',
'zfs_mount_009_neg', 'zfs_mount_010_neg', 'zfs_mount_011_neg',
'zfs_mount_012_pos', 'zfs_mount_all_001_pos', 'zfs_mount_encrypted',
'zfs_mount_remount', 'zfs_mount_all_fail', 'zfs_mount_all_mountpoints',
'zfs_mount_test_race', 'zfs_mount_recursive']
'zfs_mount_remount', 'zfs_mount_ro_rw', 'zfs_mount_all_fail',
'zfs_mount_all_mountpoints', 'zfs_mount_test_race', 'zfs_mount_recursive']
tags = ['functional', 'cli_root', 'zfs_mount']
[tests/functional/cli_root/zfs_program]
+1 -1
View File
@@ -156,7 +156,7 @@ tests = ['zfs_mount_001_pos', 'zfs_mount_002_pos', 'zfs_mount_003_pos',
'zfs_mount_004_pos', 'zfs_mount_005_pos', 'zfs_mount_007_pos',
'zfs_mount_009_neg', 'zfs_mount_010_neg', 'zfs_mount_011_neg',
'zfs_mount_012_pos', 'zfs_mount_encrypted', 'zfs_mount_remount',
'zfs_mount_all_fail', 'zfs_mount_all_mountpoints',
'zfs_mount_ro_rw', 'zfs_mount_all_fail', 'zfs_mount_all_mountpoints',
'zfs_mount_test_race', 'zfs_mount_recursive']
tags = ['functional', 'cli_root', 'zfs_mount']
+1
View File
@@ -814,6 +814,7 @@ nobase_dist_datadir_zfs_tests_tests_SCRIPTS += \
functional/cli_root/zfs_mount/zfs_mount_encrypted.ksh \
functional/cli_root/zfs_mount/zfs_mount_recursive.ksh \
functional/cli_root/zfs_mount/zfs_mount_remount.ksh \
functional/cli_root/zfs_mount/zfs_mount_ro_rw.ksh \
functional/cli_root/zfs_mount/zfs_mount_test_race.ksh \
functional/cli_root/zfs_mount/zfs_multi_mount.ksh \
functional/cli_root/zfs_program/cleanup.ksh \
@@ -0,0 +1,130 @@
#!/bin/ksh -p
# SPDX-License-Identifier: CDDL-1.0
#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License (the "License").
# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or https://opensource.org/licenses/CDDL-1.0.
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
# If applicable, add the following below this CDDL HEADER, with the
# fields enclosed by brackets "[]" replaced with your own identifying
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#
#
# Copyright (c) 2026, TrueNAS.
#
. $STF_SUITE/include/libtest.shlib
. $STF_SUITE/tests/functional/cli_root/zfs_mount/zfs_mount.kshlib
#
# we set up and mount multiple times, with these combinations:
# - readonly property: on, off
# - mount method: mount(8) (mountpoint=legacy), zfs-mount(8) (mountpoint=path)
# - mount option: [none], ro, rw
#
# after each mount, we check whether we ended up mounting read-only or
# read-write, and note the result. once we've done them all, we compare the
# result set to the "correct" set for this platform (by observation). the
# test passes if they match, fail if they don't
#
# readonly | on | off |
# mount method | legacy | path | legacy | path |
# mount option | -- ro rw | -- ro rw | -- ro rw | -- ro rw |
typeset -a rs_linux=( rw ro rw ro ro rw rw ro rw rw ro rw )
typeset -a rs_freebsd=( ro ro ro ro ro rw rw ro rw rw ro rw )
if is_linux ; then
typeset -n rs_wanted=rs_linux
elif is_freebsd ; then
typeset -n rs_wanted=rs_freebsd
else
log_unsupported "no result set defined for this platform"
fi
verify_runnable "both"
testfs=$TESTPOOL/$TESTFS
testmnt=$TESTDIR/mountpoint
function cleanup
{
log_must zfs inherit -S canmount $testfs
log_must zfs inherit readonly $testfs
log_must zfs inherit mountpoint $testfs
log_must rm -rf $testmnt
}
log_assert "Verify combinations of readonly/readwrite produce correct mount."
log_onexit cleanup
# setup
log_must datasetexists $testfs
log_must zfs set canmount=noauto $testfs
umount $testfs
typeset -a rs=()
for readonly in on off ; do
for method in legacy path ; do
for option in default ro rw ; do
log_must zfs set readonly=$readonly $testfs
if [[ $method == 'legacy' ]] ; then
log_must zfs set mountpoint=legacy $testfs
else
log_must zfs set mountpoint=$testmnt $testfs
fi
# recreate the mountpoint. even if it wasn't mounted,
# changing the mountpoint property can remove it
log_must mkdir -p $testmnt
# issue the mount with the wanted method and option
case $method in
legacy)
case $option in
default) log_must mount_default $testfs $testmnt ;;
ro) log_must mount_ro $testfs $testmnt ;;
rw) log_must mount_rw $testfs $testmnt ;;
esac
;;
path)
case $option in
default) log_must zfs mount $testfs ;;
ro) log_must zfs mount -o ro $testfs ;;
rw) log_must zfs mount -o rw $testfs ;;
esac
;;
esac
result=$(mount_get_ro_rw $testmnt)
rs+=($result)
log_note "result: $result"
log_must umount $testfs
done
done
done
log_note "results: ${rs[@]}"
log_note "wanted: ${rs_wanted[@]}"
log_must test "${rs[*]}" == "${rs_wanted[*]}"
log_pass "All mounts correct for this platform."