1#!/bin/ksh -p 2# 3# CDDL HEADER START 4# 5# The contents of this file are subject to the terms of the 6# Common Development and Distribution License (the "License"). 7# You may not use this file except in compliance with the License. 8# 9# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10# or https://opensource.org/licenses/CDDL-1.0. 11# See the License for the specific language governing permissions 12# and limitations under the License. 13# 14# When distributing Covered Code, include this CDDL HEADER in each 15# file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16# If applicable, add the following below this CDDL HEADER, with the 17# fields enclosed by brackets "[]" replaced with your own identifying 18# information: Portions Copyright [yyyy] [name of copyright owner] 19# 20# CDDL HEADER END 21# 22 23# 24# Copyright 2017, loli10K <ezomori.nozomu@gmail.com>. All rights reserved. 25# 26 27. $STF_SUITE/include/libtest.shlib 28. $STF_SUITE/tests/functional/cli_root/zfs_set/zfs_set_common.kshlib 29. $STF_SUITE/tests/functional/zvol/zvol_common.shlib 30. $STF_SUITE/tests/functional/zvol/zvol_misc/zvol_misc_common.kshlib 31 32# 33# DESCRIPTION: 34# Verify that ZFS volume property "volmode" works as intended. 35# 36# STRATEGY: 37# 1. Verify "volmode" property does not accept invalid values 38# 2. Verify "volmode=none" hides ZVOL device nodes 39# 3. Verify "volmode=full" exposes a fully functional device 40# 4. Verify "volmode=dev" hides partition info on the device 41# 5. Verify "volmode=default" behaves accordingly to "volmode" module parameter 42# 6. Verify "volmode" property is inherited correctly 43# 7. Verify "volmode" behaves correctly at import time 44# 8. Verify "volmode" behaves accordingly to zvol_inhibit_dev (Linux only) 45# 46 47verify_runnable "global" 48 49function cleanup 50{ 51 datasetexists $VOLFS && destroy_dataset $VOLFS -r 52 datasetexists $ZVOL && destroy_dataset $ZVOL -r 53 zfs inherit volmode $TESTPOOL 54 sysctl_inhibit_dev 0 55 sysctl_volmode 1 56 is_linux && udev_cleanup 57} 58 59# 60# Set zvol_inhibit_dev tunable to $value 61# 62function sysctl_inhibit_dev # value 63{ 64 typeset value="$1" 65 66 if is_linux; then 67 log_note "Setting zvol_inhibit_dev tunable to $value" 68 log_must set_tunable32 VOL_INHIBIT_DEV $value 69 fi 70} 71 72# 73# Set volmode tunable to $value 74# 75function sysctl_volmode # value 76{ 77 typeset value="$1" 78 79 log_note "Setting volmode tunable to $value" 80 log_must set_tunable32 VOL_MODE $value 81} 82 83# 84# Exercise open and close, read and write operations 85# 86function test_io # dev 87{ 88 typeset dev=$1 89 90 log_must dd if=$dev of=/dev/null count=1 91 log_must dd if=/dev/zero of=$dev count=1 92} 93 94# 95# Changing volmode may need to remove minors, which could be open, so call 96# udev_wait() before we "zfs set volmode=<value>". This ensures no udev 97# process has the zvol open (i.e. blkid) and the zvol_remove_minor_impl() 98# function won't skip removing the in use device. 99# 100function set_volmode # value ds 101{ 102 typeset value="$1" 103 typeset ds="$2" 104 105 is_linux && udev_wait 106 log_must zfs set volmode="$value" "$ds" 107} 108 109log_assert "Verify that ZFS volume property 'volmode' works as intended" 110log_onexit cleanup 111 112VOLFS="$TESTPOOL/volfs" 113ZVOL="$TESTPOOL/vol" 114ZDEV="$ZVOL_DEVDIR/$ZVOL" 115SUBZVOL="$VOLFS/subvol" 116SUBZDEV="$ZVOL_DEVDIR/$SUBZVOL" 117 118# 0. Verify basic ZVOL functionality 119log_must zfs create -o mountpoint=none $VOLFS 120log_must zfs create -V $VOLSIZE -s $SUBZVOL 121log_must zfs create -V $VOLSIZE -s $ZVOL 122blockdev_exists $ZDEV 123blockdev_exists $SUBZDEV 124test_io $ZDEV 125test_io $SUBZDEV 126 127# 1. Verify "volmode" property does not accept invalid values 128typeset badvals=("off" "on" "1" "nope" "-") 129for badval in ${badvals[@]} 130do 131 log_mustnot zfs set volmode="$badval" $ZVOL 132done 133 134# 2. Verify "volmode=none" hides ZVOL device nodes 135set_volmode none $ZVOL 136blockdev_missing $ZDEV 137log_must_busy zfs destroy $ZVOL 138blockdev_missing $ZDEV 139 140# 3. Verify "volmode=full" exposes a fully functional device 141log_must zfs create -V $VOLSIZE -s $ZVOL 142blockdev_exists $ZDEV 143set_volmode full $ZVOL 144blockdev_exists $ZDEV 145test_io $ZDEV 146log_must verify_partition $ZDEV 147# 3.1 Verify "volmode=geom" is an alias for "volmode=full" 148set_volmode geom $ZVOL 149blockdev_exists $ZDEV 150if [[ "$(get_prop 'volmode' $ZVOL)" != "full" ]]; then 151 log_fail " Volmode value 'geom' is not an alias for 'full'" 152fi 153log_must_busy zfs destroy $ZVOL 154blockdev_missing $ZDEV 155 156# 4. Verify "volmode=dev" hides partition info on the device 157log_must zfs create -V $VOLSIZE -s $ZVOL 158blockdev_exists $ZDEV 159set_volmode dev $ZVOL 160blockdev_exists $ZDEV 161test_io $ZDEV 162log_mustnot verify_partition $ZDEV 163log_must_busy zfs destroy $ZVOL 164blockdev_missing $ZDEV 165 166# 5. Verify "volmode=default" behaves accordingly to "volmode" module parameter 167# 5.1 Verify sysctl "volmode=full" 168sysctl_volmode 1 169log_must zfs create -V $VOLSIZE -s $ZVOL 170blockdev_exists $ZDEV 171set_volmode default $ZVOL 172blockdev_exists $ZDEV 173log_must verify_partition $ZDEV 174log_must_busy zfs destroy $ZVOL 175blockdev_missing $ZDEV 176# 5.2 Verify sysctl "volmode=dev" 177sysctl_volmode 2 178log_must zfs create -V $VOLSIZE -s $ZVOL 179blockdev_exists $ZDEV 180set_volmode default $ZVOL 181blockdev_exists $ZDEV 182log_mustnot verify_partition $ZDEV 183log_must_busy zfs destroy $ZVOL 184blockdev_missing $ZDEV 185# 5.2 Verify sysctl "volmode=none" 186sysctl_volmode 3 187log_must zfs create -V $VOLSIZE -s $ZVOL 188blockdev_missing $ZDEV 189set_volmode default $ZVOL 190blockdev_missing $ZDEV 191 192# 6. Verify "volmode" property is inherited correctly 193log_must zfs inherit volmode $ZVOL 194blockdev_missing $ZDEV 195# 6.1 Check volmode=full case 196set_volmode full $TESTPOOL 197verify_inherited 'volmode' 'full' $ZVOL $TESTPOOL 198blockdev_exists $ZDEV 199# 6.2 Check volmode=none case 200set_volmode none $TESTPOOL 201verify_inherited 'volmode' 'none' $ZVOL $TESTPOOL 202blockdev_missing $ZDEV 203# 6.3 Check volmode=dev case 204set_volmode dev $TESTPOOL 205verify_inherited 'volmode' 'dev' $ZVOL $TESTPOOL 206blockdev_exists $ZDEV 207# 6.4 Check volmode=default case 208sysctl_volmode 1 209set_volmode default $TESTPOOL 210verify_inherited 'volmode' 'default' $ZVOL $TESTPOOL 211blockdev_exists $ZDEV 212# 6.5 Check inheritance on multiple levels 213log_must zfs inherit volmode $SUBZVOL 214set_volmode none $VOLFS 215set_volmode full $TESTPOOL 216verify_inherited 'volmode' 'none' $SUBZVOL $VOLFS 217blockdev_missing $SUBZDEV 218blockdev_exists $ZDEV 219 220# 7. Verify "volmode" behaves correctly at import time 221log_must zpool export $TESTPOOL 222blockdev_missing $ZDEV 223blockdev_missing $SUBZDEV 224log_must zpool import $TESTPOOL 225blockdev_exists $ZDEV 226blockdev_missing $SUBZDEV 227log_must_busy zfs destroy $ZVOL 228log_must_busy zfs destroy $SUBZVOL 229blockdev_missing $ZDEV 230blockdev_missing $SUBZDEV 231 232# 8. Verify "volmode" behaves accordingly to zvol_inhibit_dev (Linux only) 233if is_linux; then 234 sysctl_inhibit_dev 1 235 # 7.1 Verify device nodes not are not created with "volmode=full" 236 sysctl_volmode 1 237 log_must zfs create -V $VOLSIZE -s $ZVOL 238 blockdev_missing $ZDEV 239 set_volmode full $ZVOL 240 blockdev_missing $ZDEV 241 log_must_busy zfs destroy $ZVOL 242 blockdev_missing $ZDEV 243 # 7.1 Verify device nodes not are not created with "volmode=dev" 244 sysctl_volmode 2 245 log_must zfs create -V $VOLSIZE -s $ZVOL 246 blockdev_missing $ZDEV 247 set_volmode dev $ZVOL 248 blockdev_missing $ZDEV 249 log_must_busy zfs destroy $ZVOL 250 blockdev_missing $ZDEV 251 # 7.1 Verify device nodes not are not created with "volmode=none" 252 sysctl_volmode 3 253 log_must zfs create -V $VOLSIZE -s $ZVOL 254 blockdev_missing $ZDEV 255 set_volmode none $ZVOL 256 blockdev_missing $ZDEV 257fi 258 259log_pass "Verify that ZFS volume property 'volmode' works as intended" 260