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 2007 Sun Microsystems, Inc. All rights reserved. 25# Use is subject to license terms. 26 27. $STF_SUITE/include/libtest.kshlib 28 29# 30# Execute arguments and record them to the log file. 31# Notice: EXPECT_HISTORY need be defined. 32# 33# $1-n arguments for execution. 34# 35function exec_record 36{ 37 [[ -z $EXPECT_HISTORY ]] && log_fail "EXPECT_HISTORY is undefined." 38 39 typeset long_hist 40 typeset user='root' 41 typeset opt 42 while getopts ":lu:" opt; do 43 case $opt in 44 l) long_hist=1;; 45 u) user=$OPTARG ;; 46 esac 47 done 48 shift $(($OPTIND -1)) 49 50 if [[ $user == 'root' ]]; then 51 log_must "$@" 52 else 53 log_must $SU $user -c "$@" 54 fi 55 user_id=$(id -u $user) 56 57 typeset cmdline="$@" 58 # Remove "eval" ">*" & "<*" for 'zfs send' and 'zfs receive'. 59 cmdline=${cmdline#eval} 60 cmdline=${cmdline%%\>*} 61 cmdline=${cmdline%%\<*} 62 63 # Remove additional blank 64 cmdline=${cmdline## } 65 cmdline=${cmdline%% } 66 67 # Get the basename of command. i.e: /usr/sbin/zpool -> zpool 68 typeset cmd=$($ECHO $cmdline | $AWK '{print $1}') 69 eval cmdline=\${cmdline#$cmd} 70 cmd=${cmd##*/} 71 72 # Write basic history to file 73 print -n $cmd $cmdline >> $EXPECT_HISTORY 74 if [[ -n $long_hist ]]; then 75 # Write long history to file 76 hn=$($HOSTNAME) 77 zn=$($ZONENAME) 78 [ "$zn" = "global" ] && zn="" 79 [ -n "$zn" ] && zn=":$zn" 80 print -n " [user $user_id ($user) on $hn$zn]" >> $EXPECT_HISTORY 81 fi 82 # Plus enter in the end of line 83 print >> $EXPECT_HISTORY 84} 85 86# 87# Format 'zpool history' output to specified file. 88# 89# $1 pool name 90# $2 output file. 91# $3 option 92# 93function format_history 94{ 95 typeset pool=$1 96 typeset outfile=$2 97 typeset option=$3 98 99 [[ -z $pool || -z $outfile ]] && \ 100 log_fail "Usage: format_history <pool> <outfile> [option]" 101 102 typeset temp_history=$TMPDIR/temp_history.format_history.${TESTCASE_ID} 103 $ZPOOL history $option $pool > $temp_history 104 105 # Truncate output file 106 $CAT /dev/null > $outfile 107 108 typeset line 109 typeset -i n=0 110 while read line; do 111 # Ignore the first line and empty line 112 if [[ $n -eq 0 || -z $line ]]; then 113 n=1; continue 114 fi 115 $ECHO ${line#* } >> $outfile 116 done < $temp_history 117 118 $RM -f $temp_history 119} 120 121# 122# Get the additional pool history. 123# 124# $1 pool name 125# $2 additional history file 126# $3 option 127# 128function additional_history 129{ 130 typeset pool=$1 131 typeset add_his_file=$2 132 typeset option=$3 133 134 if [[ -z $pool || -z $add_his_file ]]; then 135 log_fail "Usage: additional_history <pool> " \ 136 "<additional_history_file> [option]" 137 fi 138 139 typeset temp_history=$TMPDIR/temp_history.additional_history.${TESTCASE_ID} 140 # Current current history 141 format_history $pool $temp_history $option 142 # Figure out new history 143 $DIFF $temp_history $REAL_HISTORY | $GREP "^<" | $SED 's/^<[ ]*//' > \ 144 $add_his_file 145 146 $CP $temp_history $REAL_HISTORY 147 $RM -f $temp_history 148} 149 150# 151# Get given dataset id 152# 153# $1 dataset name 154# 155function get_dataset_id 156{ 157 typeset ds=$1 158 159 # 160 # The zdb information looks like: 161 # 162 # Dataset pool/fs [ZPL], ID 21, cr_txg 6, 18.0K, 4 objects 163 # 164 typeset dst_id=$($ZDB $ds | $GREP "^Dataset $ds " | \ 165 $AWK -F\, '{print $2}' | $AWK '{print $2}') 166 167 $ECHO $dst_id 168} 169 170# 171# Special case of verify_history, but only for destroyed datasets. This is 172# needed because get_dataset_id depends on still having the original dataset 173# in order to obtain its dataset id. 174# 175function verify_destroyed #<his_file> <ds_id> 176{ 177 typeset his_file=$1 178 typeset ds_id=$2 179 180 $GREP -E "\[txg:[0-9]+\] destroy [^ ]+ \($ds_id\)" $his_file \ 181 > /dev/null 2>&1 182 (($? == 0)) && return 0 183 return 1 184} 185 186# 187# Verify directly executed commands in a history file. This differs from 188# verify_history in that it checks for explicit commands as opposed to 189# internally generated commands. 190# 191function verify_direct_history #<his_file> <subcmd> <ds> 192{ 193 typeset his_file=$1 194 typeset subcmd=$2 195 typeset ds=$3 196 197 $GREP "zfs ${subcmd} ${ds}" ${his_file} > /dev/null 2>&1 198 (($? == 0)) && return 0 199 return 1 200} 201 202# This function mostly just helps to collapse the case statement 203# in verify_history. It returns whether the line matches (1==true). 204function verify_history_line 205{ 206 typeset line=$1 207 typeset subcmd=$2 208 typeset ds=$3 209 typeset keyword=$4 210 211 typeset dst_id=$(get_dataset_id $ds) 212 log_note "Line: '$line'" 213 log_note "Checking cmd($subcmd) for $ds, keyword='$keyword'" 214 $ECHO $line | $GREP -E "\[txg:[0-9]+\] $subcmd $ds \($dst_id\)" | \ 215 $GREP $keyword >/dev/null 2>&1 216 [[ $? == 0 ]] && return 1 217 return 0 218} 219 220# 221# Scan history file and check if it include expected internal history 222# information 223# 224# $1 history file 225# $2 subcmd 226# $3 dataset 227# $4 keyword 228# 229function verify_history #<his_file> <subcmd> <ds> [keyword] 230{ 231 typeset his_file=$1 232 typeset subcmd=$2 233 typeset ds=$3 234 typeset keyword=$4 235 236 typeset line found=0 237 log_note "Test1" 238 while read line; do 239 case $subcmd in 240 snapshot|rollback|inherit) 241 # [txg:12] snapshot system/foo@0 (46) 242 keyword="$subcmd" 243 verify_history_line "$line" $subcmd $ds $keyword 244 [[ $? == 0 ]] && return 0 245 ;; 246 allow) 247 # [txg:10] permission update testpool.1477/testfs.1477 (40) s-$@basic snapshot 248 _subcmd="permission update" 249 verify_history_line "$line" "$_subcmd" $ds "$keyword" 250 [[ $? == 0 ]] && return 0 251 ;; 252 unallow) 253 # [txg:174] permission remove testpool.1477/testfs.1477 (40) El$ @set 254 _subcmd="permission remove" 255 verify_history_line "$line" "$_subcmd" $ds "$keyword" 256 [[ $? == 0 ]] && return 0 257 ;; 258 *) 259 ;; 260 esac 261 done < $his_file 262 return 1 263} 264