aboutsummaryrefslogtreecommitdiff
path: root/sys/contrib/openzfs/tests/zfs-tests/tests/functional/zvol/zvol_misc/zvol_misc_volmode.ksh
blob: af808dc30764aa5f7e949c30184e358f13030019 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
#!/bin/ksh -p
#
# 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 http://www.opensolaris.org/os/licensing.
# 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 2017, loli10K <ezomori.nozomu@gmail.com>. All rights reserved.
#

. $STF_SUITE/include/libtest.shlib
. $STF_SUITE/tests/functional/cli_root/zfs_set/zfs_set_common.kshlib
. $STF_SUITE/tests/functional/zvol/zvol_common.shlib
. $STF_SUITE/tests/functional/zvol/zvol_misc/zvol_misc_common.kshlib

#
# DESCRIPTION:
# Verify that ZFS volume property "volmode" works as intended.
#
# STRATEGY:
# 1. Verify "volmode" property does not accept invalid values
# 2. Verify "volmode=none" hides ZVOL device nodes
# 3. Verify "volmode=full" exposes a fully functional device
# 4. Verify "volmode=dev" hides partition info on the device
# 5. Verify "volmode=default" behaves accordingly to "volmode" module parameter
# 6. Verify "volmode" property is inherited correctly
# 7. Verify "volmode" behaves correctly at import time
# 8. Verify "volmode" behaves accordingly to zvol_inhibit_dev (Linux only)
#

verify_runnable "global"

function cleanup
{
	datasetexists $VOLFS && destroy_dataset $VOLFS -r
	datasetexists $ZVOL && destroy_dataset $ZVOL -r
	zfs inherit volmode $TESTPOOL
	sysctl_inhibit_dev 0
	sysctl_volmode 1
	is_linux && udev_cleanup
}

#
# Set zvol_inhibit_dev tunable to $value
#
function sysctl_inhibit_dev # value
{
	typeset value="$1"

	if is_linux; then
		log_note "Setting zvol_inhibit_dev tunable to $value"
		log_must set_tunable32 VOL_INHIBIT_DEV $value
	fi
}

#
# Set volmode tunable to $value
#
function sysctl_volmode # value
{
	typeset value="$1"

	log_note "Setting volmode tunable to $value"
	log_must set_tunable32 VOL_MODE $value
}

#
# Exercise open and close, read and write operations
#
function test_io # dev
{
	typeset dev=$1

	log_must dd if=$dev of=/dev/null count=1
	log_must dd if=/dev/zero of=$dev count=1
}

#
# Changing volmode may need to remove minors, which could be open, so call
# udev_wait() before we "zfs set volmode=<value>".  This ensures no udev
# process has the zvol open (i.e. blkid) and the zvol_remove_minor_impl()
# function won't skip removing the in use device.
#
function set_volmode # value ds
{
	typeset value="$1"
	typeset ds="$2"

	is_linux && udev_wait
	log_must zfs set volmode="$value" "$ds"
}

log_assert "Verify that ZFS volume property 'volmode' works as intended"
log_onexit cleanup

VOLFS="$TESTPOOL/volfs"
ZVOL="$TESTPOOL/vol"
ZDEV="$ZVOL_DEVDIR/$ZVOL"
SUBZVOL="$VOLFS/subvol"
SUBZDEV="$ZVOL_DEVDIR/$SUBZVOL"

# 0. Verify basic ZVOL functionality
log_must zfs create -o mountpoint=none $VOLFS
log_must zfs create -V $VOLSIZE -s $SUBZVOL
log_must zfs create -V $VOLSIZE -s $ZVOL
blockdev_exists $ZDEV
blockdev_exists $SUBZDEV
test_io $ZDEV
test_io $SUBZDEV

# 1. Verify "volmode" property does not accept invalid values
typeset badvals=("off" "on" "1" "nope" "-")
for badval in ${badvals[@]}
do
	log_mustnot zfs set volmode="$badval" $ZVOL
done

# 2. Verify "volmode=none" hides ZVOL device nodes
set_volmode none $ZVOL
blockdev_missing $ZDEV
log_must_busy zfs destroy $ZVOL
blockdev_missing $ZDEV

# 3. Verify "volmode=full" exposes a fully functional device
log_must zfs create -V $VOLSIZE -s $ZVOL
blockdev_exists $ZDEV
set_volmode full $ZVOL
blockdev_exists $ZDEV
test_io $ZDEV
log_must verify_partition $ZDEV
# 3.1 Verify "volmode=geom" is an alias for "volmode=full"
set_volmode geom $ZVOL
blockdev_exists $ZDEV
if [[ "$(get_prop 'volmode' $ZVOL)" != "full" ]]; then
	log_fail " Volmode value 'geom' is not an alias for 'full'"
fi
log_must_busy zfs destroy $ZVOL
blockdev_missing $ZDEV

# 4. Verify "volmode=dev" hides partition info on the device
log_must zfs create -V $VOLSIZE -s $ZVOL
blockdev_exists $ZDEV
set_volmode dev $ZVOL
blockdev_exists $ZDEV
test_io $ZDEV
log_mustnot verify_partition $ZDEV
log_must_busy zfs destroy $ZVOL
blockdev_missing $ZDEV

# 5. Verify "volmode=default" behaves accordingly to "volmode" module parameter
# 5.1 Verify sysctl "volmode=full"
sysctl_volmode 1
log_must zfs create -V $VOLSIZE -s $ZVOL
blockdev_exists $ZDEV
set_volmode default $ZVOL
blockdev_exists $ZDEV
log_must verify_partition $ZDEV
log_must_busy zfs destroy $ZVOL
blockdev_missing $ZDEV
# 5.2 Verify sysctl "volmode=dev"
sysctl_volmode 2
log_must zfs create -V $VOLSIZE -s $ZVOL
blockdev_exists $ZDEV
set_volmode default $ZVOL
blockdev_exists $ZDEV
log_mustnot verify_partition $ZDEV
log_must_busy zfs destroy $ZVOL
blockdev_missing $ZDEV
# 5.2 Verify sysctl "volmode=none"
sysctl_volmode 3
log_must zfs create -V $VOLSIZE -s $ZVOL
blockdev_missing $ZDEV
set_volmode default $ZVOL
blockdev_missing $ZDEV

# 6. Verify "volmode" property is inherited correctly
log_must zfs inherit volmode $ZVOL
blockdev_missing $ZDEV
# 6.1 Check volmode=full case
set_volmode full $TESTPOOL
verify_inherited 'volmode' 'full' $ZVOL $TESTPOOL
blockdev_exists $ZDEV
# 6.2 Check volmode=none case
set_volmode none $TESTPOOL
verify_inherited 'volmode' 'none' $ZVOL $TESTPOOL
blockdev_missing $ZDEV
# 6.3 Check volmode=dev case
set_volmode dev $TESTPOOL
verify_inherited 'volmode' 'dev' $ZVOL $TESTPOOL
blockdev_exists $ZDEV
# 6.4 Check volmode=default case
sysctl_volmode 1
set_volmode default $TESTPOOL
verify_inherited 'volmode' 'default' $ZVOL $TESTPOOL
blockdev_exists $ZDEV
# 6.5 Check inheritance on multiple levels
log_must zfs inherit volmode $SUBZVOL
set_volmode none $VOLFS
set_volmode full $TESTPOOL
verify_inherited 'volmode' 'none' $SUBZVOL $VOLFS
blockdev_missing $SUBZDEV
blockdev_exists $ZDEV

# 7. Verify "volmode" behaves correctly at import time
log_must zpool export $TESTPOOL
blockdev_missing $ZDEV
blockdev_missing $SUBZDEV
log_must zpool import $TESTPOOL
blockdev_exists $ZDEV
blockdev_missing $SUBZDEV
log_must_busy zfs destroy $ZVOL
log_must_busy zfs destroy $SUBZVOL
blockdev_missing $ZDEV
blockdev_missing $SUBZDEV

# 8. Verify "volmode" behaves accordingly to zvol_inhibit_dev (Linux only)
if is_linux; then
	sysctl_inhibit_dev 1
	# 7.1 Verify device nodes not are not created with "volmode=full"
	sysctl_volmode 1
	log_must zfs create -V $VOLSIZE -s $ZVOL
	blockdev_missing $ZDEV
	set_volmode full $ZVOL
	blockdev_missing $ZDEV
	log_must_busy zfs destroy $ZVOL
	blockdev_missing $ZDEV
	# 7.1 Verify device nodes not are not created with "volmode=dev"
	sysctl_volmode 2
	log_must zfs create -V $VOLSIZE -s $ZVOL
	blockdev_missing $ZDEV
	set_volmode dev $ZVOL
	blockdev_missing $ZDEV
	log_must_busy zfs destroy $ZVOL
	blockdev_missing $ZDEV
	# 7.1 Verify device nodes not are not created with "volmode=none"
	sysctl_volmode 3
	log_must zfs create -V $VOLSIZE -s $ZVOL
	blockdev_missing $ZDEV
	set_volmode none $ZVOL
	blockdev_missing $ZDEV
fi

log_pass "Verify that ZFS volume property 'volmode' works as intended"