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