1# 2# CDDL HEADER START 3# 4# The contents of this file are subject to the terms of the 5# Common Development and Distribution License (the "License"). 6# You may not use this file except in compliance with the License. 7# 8# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9# or http://www.opensolaris.org/os/licensing. 10# See the License for the specific language governing permissions 11# and limitations under the License. 12# 13# When distributing Covered Code, include this CDDL HEADER in each 14# file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15# If applicable, add the following below this CDDL HEADER, with the 16# fields enclosed by brackets "[]" replaced with your own identifying 17# information: Portions Copyright [yyyy] [name of copyright owner] 18# 19# CDDL HEADER END 20# 21 22# 23# Copyright 2008 Sun Microsystems, Inc. All rights reserved. 24# Use is subject to license terms. 25# 26 27# 28# Copyright (c) 2012, 2016 by Delphix. All rights reserved. 29# 30 31. $STF_SUITE/include/libtest.shlib 32. $STF_SUITE/tests/functional/cli_root/zfs_rollback/zfs_rollback.cfg 33 34# Get file sum 35# 36# $1 full file name 37function getsum #fname 38{ 39 (( ${#1} == 0 )) && \ 40 log_fail "Need give file name." 41 return $(sum $1 | awk '{print $1}') 42} 43 44# Define global variable checksum, get the original file sum. 45# 46origsum=$(getsum /etc/passwd) 47 48# 49# Setup or recover the test environment. Firstly, copy /etc/passwd to ZFS file 50# system or volume, then make a snapshot or clone. Repeat up to three times. 51# 52# $1 number of snapshot. Note: Currently only support three snapshots. 53# $2 indicate if it is necessary to create clone 54# 55function setup_snap_env 56{ 57 typeset -i cnt=${1:-3} 58 typeset createclone=${2:-"false"} 59 60 if datasetnonexists $FS; then 61 log_must zfs create $FS 62 log_must zfs set mountpoint=$TESTDIR $FS 63 fi 64 # Volume can't be created in Local Zone. 65 if datasetnonexists $VOL && is_global_zone; then 66 log_must zfs create -V $VOLSIZE $VOL 67 fi 68 69 # Make sure $VOL is volume 70 typeset type=$(get_prop type $VOL) 71 if datasetexists $VOL && \ 72 [[ $type == 'volume' ]]; then 73 # 74 # At the first time, Make a UFS file system in volume and 75 # mount it. Otherwise, only check if this ufs file system 76 # was mounted. 77 # 78 log_must eval "echo "y" | \ 79 newfs -v /dev/zvol/dsk/$VOL > /dev/null 2>&1" 80 81 [[ ! -d $TESTDIR1 ]] && log_must mkdir $TESTDIR1 82 83 # Make sure the ufs filesystem hasn't been mounted, 84 # then mount the new ufs filesystem. 85 df -lhF ufs "/dev/zvol/dsk/$VOL" > /dev/null 2>&1 86 if (( $? != 0 )); then 87 log_must mount \ 88 /dev/zvol/dsk/$TESTPOOL/$TESTVOL $TESTDIR1 89 fi 90 fi 91 92 # Separately Create three snapshots for file system & volume 93 typeset -i ind=0 94 typeset dtst 95 for dtst in $FS $VOL; do 96 # Volume can be created in Local Zone. 97 if [[ $dtst == $VOL ]]; then 98 if ! is_global_zone; then 99 break 100 fi 101 fi 102 103 ind=0 104 while (( ind < cnt )); do 105 case $dtst in 106 $FS) 107 eval typeset snap=\$FSSNAP$ind 108 eval typeset clone=\$FSCLONE$ind 109 eval typeset fname=\$TESTDIR/\$TESTFILE$ind 110 ;; 111 $VOL) 112 eval typeset snap=\$VOLSNAP$ind 113 eval typeset clone=\$VOLCLONE$ind 114 eval typeset fname=\$TESTDIR1/\$TESTFILE$ind 115 ;; 116 esac 117 118 if datasetnonexists $snap; then 119 log_must cp /etc/passwd $fname 120 # 121 # using 'lockfs -f' to flush the writes to disk 122 # before taking a snapshot. 123 # 124 if [[ $dtst == $VOL ]]; then 125 log_must lockfs -f $TESTDIR1 126 fi 127 log_must zfs snapshot $snap 128 fi 129 if [[ $createclone == "true" ]]; then 130 if datasetnonexists $clone; then 131 log_must zfs clone $snap $clone 132 fi 133 fi 134 (( ind += 1 )) 135 done 136 done 137} 138 139function setup_clone_env 140{ 141 setup_snap_env $1 "true" 142} 143 144# 145# Clean up the test environmnet 146# 147# $1 number of snapshot Note: Currently only support three snapshots. 148# 149function cleanup_env 150{ 151 typeset -i cnt=${1:-3} 152 typeset -i ind=0 153 typeset dtst 154 typeset snap 155 156 pkill ${DD##*/} 157 158 df -lhF ufs "/dev/zvol/dsk/$VOL" > /dev/null 2>&1 159 if (( $? == 0 )); then 160 log_must umount -f $TESTDIR1 161 fi 162 163 [[ -d $TESTDIR ]] && log_must rm -rf $TESTDIR/* 164 [[ -d $TESTDIR1 ]] && log_must rm -rf $TESTDIR1/* 165 166 for dtst in $FS $VOL; do 167 for snap in $TESTSNAP $TESTSNAP1 $TESTSNAP2; do 168 if snapexists $dtst@$snap; then 169 log_must zfs destroy -Rf $dtst@$snap 170 fi 171 done 172 done 173 174 # Restore original test environment 175 if datasetnonexists $FS ; then 176 log_must zfs create $FS 177 fi 178 if datasetnonexists $VOL ; then 179 if is_global_zone ; then 180 log_must zfs create -V $VOLSIZE $VOL 181 else 182 log_must zfs create $VOL 183 fi 184 fi 185} 186 187# 188# check if the specified files have specified status. 189# 190# $1 expected status 191# $2-n full file name 192# If it is true return 0, else return 1 193# 194function file_status 195{ 196 (( $# == 0 )) && \ 197 log_fail "The file name is not defined." 198 199 typeset opt 200 case $1 in 201 exist) opt="-e" ;; 202 nonexist) opt="! -e" ;; 203 *) log_fail "Unsupported file status." ;; 204 esac 205 206 shift 207 while (( $# > 0 )); do 208 eval [[ $opt $1 ]] || return 1 209 shift 210 done 211 212 return 0 213} 214 215function files_exist 216{ 217 file_status "exist" $@ 218} 219 220function files_nonexist 221{ 222 file_status "nonexist" $@ 223} 224 225# 226# According to snapshot check if the file system was recovered to the right 227# point. 228# 229# $1 snapshot. fs@snap or vol@snap 230# 231function check_files 232{ 233 typeset dtst=$1 234 235 if [[ $(get_prop type $dtst) != snapshot ]]; then 236 log_fail "Parameter must be a snapshot." 237 fi 238 239 typeset fsvol=${dtst%%@*} 240 typeset snap=${dtst##*@} 241 if [[ $(get_prop type $fsvol) == "filesystem" ]]; then 242 ind="" 243 else 244 ind="1" 245 fi 246 247 eval typeset file0=\$TESTDIR$ind/\$TESTFILE0 248 eval typeset file1=\$TESTDIR$ind/\$TESTFILE1 249 eval typeset file2=\$TESTDIR$ind/\$TESTFILE2 250 251 case $snap in 252 $TESTSNAP2) 253 log_must files_exist $file0 $file1 $file2 254 255 typeset sum0=$(getsum $file0) 256 typeset sum1=$(getsum $file1) 257 typeset sum2=$(getsum $file2) 258 if [[ $sum0 != $origsum || \ 259 $sum1 != $origsum || sum2 != $origsum ]] 260 then 261 log_fail "After rollback, file sum is changed." 262 fi 263 ;; 264 $TESTSNAP1) 265 log_must files_exist $file0 $file1 266 log_must files_nonexist $file2 267 268 typeset sum0=$(getsum $file0) 269 typeset sum1=$(getsum $file1) 270 if [[ $sum0 != $origsum || $sum1 != $origsum ]] 271 then 272 log_fail "After rollback, file sum is changed." 273 fi 274 ;; 275 $TESTSNAP) 276 log_must files_exist $file0 277 log_must files_nonexist $file1 $file2 278 279 typeset sum0=$(getsum $file0) 280 if [[ $sum0 != $origsum ]]; then 281 log_fail "After rollback, file sum is changed." 282 fi 283 ;; 284 esac 285} 286 287# According to dataset type, write file to different directories. 288# 289# $1 dataset 290# 291function write_mountpoint_dir 292{ 293 typeset dtst=$1 294 typeset dir 295 296 if [[ $dtst == $FS ]]; then 297 dir=$TESTDIR 298 log_must ismounted $dir 299 else 300 dir=$TESTDIR1 301 log_must ismounted $dir "ufs" 302 fi 303 dd if=/dev/urandom of=$dir/$TESTFILE1 & 304 log_must sleep 3 305} 306