xref: /freebsd/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zfs_mount/zfs_mount_remount.ksh (revision 61145dc2b94f12f6a47344fb9aac702321880e43)
1#!/bin/ksh -p
2# SPDX-License-Identifier: CDDL-1.0
3#
4# CDDL HEADER START
5#
6# The contents of this file are subject to the terms of the
7# Common Development and Distribution License (the "License").
8# You may not use this file except in compliance with the License.
9#
10# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
11# or https://opensource.org/licenses/CDDL-1.0.
12# See the License for the specific language governing permissions
13# and limitations under the License.
14#
15# When distributing Covered Code, include this CDDL HEADER in each
16# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
17# If applicable, add the following below this CDDL HEADER, with the
18# fields enclosed by brackets "[]" replaced with your own identifying
19# information: Portions Copyright [yyyy] [name of copyright owner]
20#
21# CDDL HEADER END
22#
23
24#
25# Copyright 2017, loli10K <ezomori.nozomu@gmail.com>. All rights reserved.
26#
27
28. $STF_SUITE/include/libtest.shlib
29. $STF_SUITE/tests/functional/cli_root/zfs_mount/zfs_mount.kshlib
30
31#
32# DESCRIPTION:
33# Verify remount functionality, especially on readonly objects.
34#
35# STRATEGY:
36# 1. Prepare a filesystem and a snapshot
37# 2. Verify we can (re)mount the dataset readonly/read-write
38# 3. Verify we can mount the snapshot and it's mounted readonly
39# 4. Verify we can't remount it read-write
40# 5. Verify we can remount a dataset readonly and unmount it with
41#    encryption=on and sync=disabled (issue #7753)
42# 6. Re-import the pool readonly
43# 7. Verify we can't remount its filesystem read-write
44#
45
46verify_runnable "both"
47
48function cleanup
49{
50	log_must_busy zpool export $TESTPOOL
51	log_must zpool import $TESTPOOL
52	snapexists $TESTSNAP && destroy_dataset $TESTSNAP
53	[[ -d $MNTPSNAP ]] && log_must rmdir $MNTPSNAP
54	return 0
55}
56
57if is_freebsd; then
58	typeset RO="-t zfs -ur"
59	typeset RW="-t zfs -uw"
60else
61	typeset RO="-o remount,ro"
62	typeset RW="-o remount,rw"
63fi
64
65#
66# Verify the $filesystem is mounted readonly
67# This is preferred over "log_mustnot touch $fs" because we actually want to
68# verify the error returned is EROFS
69#
70function readonlyfs # filesystem
71{
72	typeset filesystem="$1"
73
74	file_write -o create -f $filesystem/file.dat
75	ret=$?
76	if [[ $ret != 30 ]]; then
77		log_fail "Writing to $filesystem did not return EROFS ($ret)."
78	fi
79}
80
81#
82# Verify $dataset is mounted with $option
83#
84function checkmount # dataset option
85{
86	typeset dataset="$1"
87	typeset option="$2"
88	typeset options=""
89
90	if is_freebsd; then
91		options=$(mount -p | awk -v ds="$dataset" '$1 == ds { print $4 }')
92	else
93		options=$(awk -v ds="$dataset" '$1 == ds { print $4 }' /proc/mounts)
94	fi
95	if [[ "$options" == '' ]]; then
96		log_fail "Dataset $dataset is not mounted"
97	elif [[ ! -z "${options##*$option*}" ]]; then
98		log_fail "Dataset $dataset is not mounted with expected "\
99		    "option $option ($options)"
100	else
101		log_note "Dataset $dataset is mounted with option $option"
102	fi
103}
104
105log_assert "Verify remount functionality on both filesystem and snapshots"
106
107log_onexit cleanup
108
109# 1. Prepare a filesystem and a snapshot
110TESTFS=$TESTPOOL/$TESTFS
111TESTSNAP="$TESTFS@snap"
112datasetexists $TESTFS || log_must zfs create $TESTFS
113snapexists $TESTSNAP || log_must zfs snapshot $TESTSNAP
114log_must zfs set readonly=off $TESTFS
115MNTPFS="$(get_prop mountpoint $TESTFS)"
116MNTPSNAP="$TESTDIR/zfs_snap_mount"
117log_must mkdir -p $MNTPSNAP
118
119# 2. Verify we can (re)mount the dataset readonly/read-write
120log_must touch $MNTPFS/file.dat
121checkmount $TESTFS 'rw'
122log_must mount $RO $TESTFS $MNTPFS
123readonlyfs $MNTPFS
124checkmount $TESTFS 'ro'
125log_must mount $RW $TESTFS $MNTPFS
126log_must touch $MNTPFS/file.dat
127checkmount $TESTFS 'rw'
128
129if is_linux; then
130	# 3. Verify we can (re)mount the snapshot readonly
131	log_must mount -t zfs $TESTSNAP $MNTPSNAP
132	readonlyfs $MNTPSNAP
133	checkmount $TESTSNAP 'ro'
134	log_must mount $RO $TESTSNAP $MNTPSNAP
135	readonlyfs $MNTPSNAP
136	checkmount $TESTSNAP 'ro'
137	log_must umount $MNTPSNAP
138fi
139
140# 4. Verify we can't remount a snapshot read-write
141# The "mount -o rw" command will succeed but the snapshot is mounted readonly.
142# The "mount -o remount,rw" command must fail with an explicit error.
143log_must mount -t zfs -o rw $TESTSNAP $MNTPSNAP
144readonlyfs $MNTPSNAP
145checkmount $TESTSNAP 'ro'
146log_mustnot mount $RW $TESTSNAP $MNTPSNAP
147readonlyfs $MNTPSNAP
148checkmount $TESTSNAP 'ro'
149log_must umount $MNTPSNAP
150
151# 5. Verify we can remount a dataset readonly and unmount it with
152#    encryption=on and sync=disabled (issue #7753)
153log_must eval "echo 'password' | zfs create -o sync=disabled \
154    -o encryption=on -o keyformat=passphrase $TESTFS/crypt"
155CRYPT_MNTPFS="$(get_prop mountpoint $TESTFS/crypt)"
156log_must touch $CRYPT_MNTPFS/file.dat
157log_must mount $RO $TESTFS/crypt $CRYPT_MNTPFS
158log_must umount -f $CRYPT_MNTPFS
159sync_pool $TESTPOOL
160
161# 6. Re-import the pool readonly
162log_must zpool export $TESTPOOL
163log_must zpool import -o readonly=on $TESTPOOL
164
165# 7. Verify we can't remount its filesystem read-write
166readonlyfs $MNTPFS
167checkmount $TESTFS 'ro'
168log_mustnot mount $RW $MNTPFS
169readonlyfs $MNTPFS
170checkmount $TESTFS 'ro'
171
172log_pass "Both filesystem and snapshots can be remounted correctly."
173