1# vim: filetype=sh 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 http://www.opensolaris.org/os/licensing. 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 2008 Sun Microsystems, Inc. All rights reserved. 25# Use is subject to license terms. 26 27. $STF_SUITE/include/libtest.kshlib 28 29# Get file sum 30# 31# $1 full file name 32function getsum #fname 33{ 34 (( ${#1} == 0 )) && \ 35 log_fail "Need give file name." 36 return $($SUM $1 | $AWK '{print $1}') 37} 38 39# Define global variable checksum, get the original file sum. 40# 41origsum=$(getsum /etc/passwd) 42 43# 44# Setup or recover the test environment. Firstly, copy /etc/passwd to ZFS file 45# system or volume, then make a snapshot or clone. Repeat up to three times. 46# 47# $1 number of snapshot. Note: Currently only support three snapshots. 48# $2 indicate if it is necessary to create clone 49# 50function setup_snap_env 51{ 52 typeset -i cnt=${1:-3} 53 typeset createclone=${2:-"false"} 54 55 if datasetnonexists $FS; then 56 log_must $ZFS create $FS 57 log_must $ZFS set mountpoint=$TESTDIR $FS 58 fi 59 # Volume can't be created in Local Zone. 60 if datasetnonexists $VOL && is_global_zone; then 61 log_must $ZFS create -V $VOLSIZE $VOL 62 fi 63 64 # Make sure $VOL is volume 65 typeset type=$(get_prop type $VOL) 66 if datasetexists $VOL && \ 67 [[ $type == 'volume' ]]; then 68 # 69 # At the first time, Make a UFS file system in volume and 70 # mount it. Otherwise, only check if this ufs file system 71 # was mounted. 72 # 73 log_must eval "$ECHO "y" | \ 74 $NEWFS /dev/zvol/$VOL > /dev/null 2>&1" 75 76 [[ ! -d $TESTDIR1 ]] && log_must $MKDIR $TESTDIR1 77 78 # Make sure the ufs filesystem hasn't been mounted, 79 # then mount the new ufs filesystem. 80 $MOUNT | grep -q "/dev/zvol/$VOL" > /dev/null 2>&1 81 if (( $? != 0 )); then 82 log_must $MOUNT \ 83 /dev/zvol/$TESTPOOL/$TESTVOL $TESTDIR1 84 fi 85 fi 86 87 # Separately Create three snapshots for file system & volume 88 typeset -i ind=0 89 typeset dtst 90 for dtst in $FS $VOL; do 91 # Volume can be created in Local Zone. 92 if [[ $dtst == $VOL ]]; then 93 if ! is_global_zone; then 94 break 95 fi 96 fi 97 98 ind=0 99 while (( ind < cnt )); do 100 case $dtst in 101 $FS) 102 eval typeset snap=\$FSSNAP$ind 103 eval typeset clone=\$FSCLONE$ind 104 eval typeset fname=\$TESTDIR/\$TESTFILE$ind 105 ;; 106 $VOL) 107 eval typeset snap=\$VOLSNAP$ind 108 eval typeset clone=\$VOLCLONE$ind 109 eval typeset fname=\$TESTDIR1/\$TESTFILE$ind 110 ;; 111 esac 112 113 if datasetnonexists $snap; then 114 log_must $CP /etc/passwd $fname 115 # 116 # Take the snapshot with the zvol unmounted so 117 # that its filesystem's state will be 118 # consistent. 119 # 120 mount -u -o ro /dev/zvol/$TESTPOOL/$TESTVOL 121 log_must $ZFS snapshot $snap 122 mount -u -o rw /dev/zvol/$TESTPOOL/$TESTVOL 123 fi 124 if [[ $createclone == "true" ]]; then 125 if datasetnonexists $clone; then 126 log_must $ZFS clone $snap $clone 127 fi 128 fi 129 (( ind += 1 )) 130 done 131 done 132} 133 134function setup_clone_env 135{ 136 setup_snap_env $1 "true" 137} 138 139# 140# Clean up the test environmnet 141# 142# $1 number of snapshot Note: Currently only support three snapshots. 143# 144function cleanup_env 145{ 146 typeset -i cnt=${1:-3} 147 typeset -i ind=0 148 typeset dtst 149 typeset snap 150 151 $PKILL ${DD##*/} 152 153 $MOUNT | grep -q "/dev/zvol/$VOL" > /dev/null 2>&1 154 if (( $? == 0 )); then 155 log_must $UMOUNT -f $TESTDIR1 156 fi 157 158 [[ -d $TESTDIR ]] && log_must $RM -rf $TESTDIR/* 159 [[ -d $TESTDIR1 ]] && log_must $RM -rf $TESTDIR1/* 160 161 for dtst in $FS $VOL; do 162 for snap in $TESTSNAP $TESTSNAP1 $TESTSNAP2; do 163 if snapexists $dtst@$snap; then 164 log_must $ZFS destroy -Rf $dtst@$snap 165 fi 166 done 167 done 168 169 # Restore original test environment 170 if datasetnonexists $FS ; then 171 log_must $ZFS create $FS 172 fi 173 if datasetnonexists $VOL ; then 174 if is_global_zone ; then 175 log_must $ZFS create -V $VOLSIZE $VOL 176 else 177 log_must $ZFS create $VOL 178 fi 179 fi 180} 181 182# 183# check if the specified files have specified status. 184# 185# $1 expected status 186# $2-n full file name 187# If it is true return 0, else return 1 188# 189function file_status 190{ 191 (( $# == 0 )) && \ 192 log_fail "The file name is not defined." 193 194 typeset opt 195 case $1 in 196 exist) opt="-e" ;; 197 nonexist) opt="! -e" ;; 198 *) log_fail "Unsupported file status." ;; 199 esac 200 201 shift 202 while (( $# > 0 )); do 203 eval [[ $opt $1 ]] || return 1 204 shift 205 done 206 207 return 0 208} 209 210function files_exist 211{ 212 file_status "exist" $@ 213} 214 215function files_nonexist 216{ 217 file_status "nonexist" $@ 218} 219 220# 221# According to snapshot check if the file system was recovered to the right 222# point. 223# 224# $1 snapshot. fs@snap or vol@snap 225# 226function check_files 227{ 228 typeset dtst=$1 229 230 if [[ $(get_prop type $dtst) != snapshot ]]; then 231 log_fail "Parameter must be a snapshot." 232 fi 233 234 typeset fsvol=${dtst%%@*} 235 typeset snap=${dtst##*@} 236 if [[ $(get_prop type $fsvol) == "filesystem" ]]; then 237 ind="" 238 else 239 ind="1" 240 fi 241 242 eval typeset file0=\$TESTDIR$ind/\$TESTFILE0 243 eval typeset file1=\$TESTDIR$ind/\$TESTFILE1 244 eval typeset file2=\$TESTDIR$ind/\$TESTFILE2 245 246 case $snap in 247 $TESTSNAP2) 248 log_must files_exist $file0 $file1 $file2 249 250 typeset sum0=$(getsum $file0) 251 typeset sum1=$(getsum $file1) 252 typeset sum2=$(getsum $file2) 253 if [[ $sum0 != $origsum || \ 254 $sum1 != $origsum || sum2 != $origsum ]] 255 then 256 log_fail "After rollback, file sum is changed." 257 fi 258 ;; 259 $TESTSNAP1) 260 log_must files_exist $file0 $file1 261 log_must files_nonexist $file2 262 263 typeset sum0=$(getsum $file0) 264 typeset sum1=$(getsum $file1) 265 if [[ $sum0 != $origsum || $sum1 != $origsum ]] 266 then 267 log_fail "After rollback, file sum is changed." 268 fi 269 ;; 270 $TESTSNAP) 271 log_must files_exist $file0 272 log_must files_nonexist $file1 $file2 273 274 typeset sum0=$(getsum $file0) 275 if [[ $sum0 != $origsum ]]; then 276 log_fail "After rollback, file sum is changed." 277 fi 278 ;; 279 esac 280} 281 282# According to dataset type, write file to different directories. 283# 284# $1 dataset 285# 286function write_mountpoint_dir 287{ 288 typeset dtst=$1 289 typeset dir 290 291 if [[ $dtst == $FS ]]; then 292 dir=$TESTDIR 293 log_must ismounted $dir 294 else 295 dir=$TESTDIR1 296 log_must ismounted $dir "ufs" 297 fi 298 $DD if=/dev/urandom of=$dir/$TESTFILE1 & 299 log_must $SLEEP 3 300} 301