12fae26bdSAlan Somers# vim: filetype=sh 22fae26bdSAlan Somers# 32fae26bdSAlan Somers# CDDL HEADER START 42fae26bdSAlan Somers# 52fae26bdSAlan Somers# The contents of this file are subject to the terms of the 62fae26bdSAlan Somers# Common Development and Distribution License (the "License"). 72fae26bdSAlan Somers# You may not use this file except in compliance with the License. 82fae26bdSAlan Somers# 92fae26bdSAlan Somers# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 102fae26bdSAlan Somers# or http://www.opensolaris.org/os/licensing. 112fae26bdSAlan Somers# See the License for the specific language governing permissions 122fae26bdSAlan Somers# and limitations under the License. 132fae26bdSAlan Somers# 142fae26bdSAlan Somers# When distributing Covered Code, include this CDDL HEADER in each 152fae26bdSAlan Somers# file and include the License file at usr/src/OPENSOLARIS.LICENSE. 162fae26bdSAlan Somers# If applicable, add the following below this CDDL HEADER, with the 172fae26bdSAlan Somers# fields enclosed by brackets "[]" replaced with your own identifying 182fae26bdSAlan Somers# information: Portions Copyright [yyyy] [name of copyright owner] 192fae26bdSAlan Somers# 202fae26bdSAlan Somers# CDDL HEADER END 212fae26bdSAlan Somers# 222fae26bdSAlan Somers 232fae26bdSAlan Somers# 242fae26bdSAlan Somers# Copyright 2007 Sun Microsystems, Inc. All rights reserved. 252fae26bdSAlan Somers# Use is subject to license terms. 262fae26bdSAlan Somers 272fae26bdSAlan Somers. $STF_SUITE/include/libtest.kshlib 282fae26bdSAlan Somers 292fae26bdSAlan Somers# 302fae26bdSAlan Somers# Execute arguments and record them to the log file. 312fae26bdSAlan Somers# Notice: EXPECT_HISTORY need be defined. 322fae26bdSAlan Somers# 332fae26bdSAlan Somers# $1-n arguments for execution. 342fae26bdSAlan Somers# 352fae26bdSAlan Somersfunction exec_record 362fae26bdSAlan Somers{ 372fae26bdSAlan Somers [[ -z $EXPECT_HISTORY ]] && log_fail "EXPECT_HISTORY is undefined." 382fae26bdSAlan Somers 392fae26bdSAlan Somers typeset long_hist 402fae26bdSAlan Somers typeset user='root' 412fae26bdSAlan Somers typeset opt 422fae26bdSAlan Somers while getopts ":lu:" opt; do 432fae26bdSAlan Somers case $opt in 442fae26bdSAlan Somers l) long_hist=1;; 452fae26bdSAlan Somers u) user=$OPTARG ;; 462fae26bdSAlan Somers esac 472fae26bdSAlan Somers done 482fae26bdSAlan Somers shift $(($OPTIND -1)) 492fae26bdSAlan Somers 502fae26bdSAlan Somers if [[ $user == 'root' ]]; then 512fae26bdSAlan Somers log_must "$@" 522fae26bdSAlan Somers else 532fae26bdSAlan Somers log_must $SU $user -c "$@" 542fae26bdSAlan Somers fi 552fae26bdSAlan Somers user_id=$(id -u $user) 562fae26bdSAlan Somers 572fae26bdSAlan Somers typeset cmdline="$@" 582fae26bdSAlan Somers # Remove "eval" ">*" & "<*" for 'zfs send' and 'zfs receive'. 592fae26bdSAlan Somers cmdline=${cmdline#eval} 602fae26bdSAlan Somers cmdline=${cmdline%%\>*} 612fae26bdSAlan Somers cmdline=${cmdline%%\<*} 622fae26bdSAlan Somers 632fae26bdSAlan Somers # Remove additional blank 642fae26bdSAlan Somers cmdline=${cmdline## } 652fae26bdSAlan Somers cmdline=${cmdline%% } 662fae26bdSAlan Somers 672fae26bdSAlan Somers # Get the basename of command. i.e: /usr/sbin/zpool -> zpool 682fae26bdSAlan Somers typeset cmd=$($ECHO $cmdline | $AWK '{print $1}') 692fae26bdSAlan Somers eval cmdline=\${cmdline#$cmd} 702fae26bdSAlan Somers cmd=${cmd##*/} 712fae26bdSAlan Somers 722fae26bdSAlan Somers # Write basic history to file 732fae26bdSAlan Somers print -n $cmd $cmdline >> $EXPECT_HISTORY 742fae26bdSAlan Somers if [[ -n $long_hist ]]; then 752fae26bdSAlan Somers # Write long history to file 762fae26bdSAlan Somers hn=$($HOSTNAME) 772fae26bdSAlan Somers zn=$($ZONENAME) 782fae26bdSAlan Somers [ "$zn" = "global" ] && zn="" 792fae26bdSAlan Somers [ -n "$zn" ] && zn=":$zn" 802fae26bdSAlan Somers print -n " [user $user_id ($user) on $hn$zn]" >> $EXPECT_HISTORY 812fae26bdSAlan Somers fi 822fae26bdSAlan Somers # Plus enter in the end of line 832fae26bdSAlan Somers print >> $EXPECT_HISTORY 842fae26bdSAlan Somers} 852fae26bdSAlan Somers 862fae26bdSAlan Somers# 872fae26bdSAlan Somers# Format 'zpool history' output to specified file. 882fae26bdSAlan Somers# 892fae26bdSAlan Somers# $1 pool name 902fae26bdSAlan Somers# $2 output file. 912fae26bdSAlan Somers# $3 option 922fae26bdSAlan Somers# 932fae26bdSAlan Somersfunction format_history 942fae26bdSAlan Somers{ 952fae26bdSAlan Somers typeset pool=$1 962fae26bdSAlan Somers typeset outfile=$2 972fae26bdSAlan Somers typeset option=$3 982fae26bdSAlan Somers 992fae26bdSAlan Somers [[ -z $pool || -z $outfile ]] && \ 1002fae26bdSAlan Somers log_fail "Usage: format_history <pool> <outfile> [option]" 1012fae26bdSAlan Somers 1022fae26bdSAlan Somers typeset temp_history=$TMPDIR/temp_history.format_history.${TESTCASE_ID} 1032fae26bdSAlan Somers $ZPOOL history $option $pool > $temp_history 1042fae26bdSAlan Somers 1052fae26bdSAlan Somers # Truncate output file 1062fae26bdSAlan Somers $CAT /dev/null > $outfile 1072fae26bdSAlan Somers 1082fae26bdSAlan Somers typeset line 1092fae26bdSAlan Somers typeset -i n=0 1102fae26bdSAlan Somers while read line; do 1112fae26bdSAlan Somers # Ignore the first line and empty line 1122fae26bdSAlan Somers if [[ $n -eq 0 || -z $line ]]; then 1132fae26bdSAlan Somers n=1; continue 1142fae26bdSAlan Somers fi 1152fae26bdSAlan Somers $ECHO ${line#* } >> $outfile 1162fae26bdSAlan Somers done < $temp_history 1172fae26bdSAlan Somers 1182fae26bdSAlan Somers $RM -f $temp_history 1192fae26bdSAlan Somers} 1202fae26bdSAlan Somers 1212fae26bdSAlan Somers# 1222fae26bdSAlan Somers# Get the additional pool history. 1232fae26bdSAlan Somers# 1242fae26bdSAlan Somers# $1 pool name 1252fae26bdSAlan Somers# $2 additional history file 1262fae26bdSAlan Somers# $3 option 1272fae26bdSAlan Somers# 1282fae26bdSAlan Somersfunction additional_history 1292fae26bdSAlan Somers{ 1302fae26bdSAlan Somers typeset pool=$1 1312fae26bdSAlan Somers typeset add_his_file=$2 1322fae26bdSAlan Somers typeset option=$3 1332fae26bdSAlan Somers 1342fae26bdSAlan Somers if [[ -z $pool || -z $add_his_file ]]; then 1352fae26bdSAlan Somers log_fail "Usage: additional_history <pool> " \ 1362fae26bdSAlan Somers "<additional_history_file> [option]" 1372fae26bdSAlan Somers fi 1382fae26bdSAlan Somers 1392fae26bdSAlan Somers typeset temp_history=$TMPDIR/temp_history.additional_history.${TESTCASE_ID} 1402fae26bdSAlan Somers # Current current history 1412fae26bdSAlan Somers format_history $pool $temp_history $option 1422fae26bdSAlan Somers # Figure out new history 1432fae26bdSAlan Somers $DIFF $temp_history $REAL_HISTORY | $GREP "^<" | $SED 's/^<[ ]*//' > \ 1442fae26bdSAlan Somers $add_his_file 1452fae26bdSAlan Somers 1462fae26bdSAlan Somers $CP $temp_history $REAL_HISTORY 1472fae26bdSAlan Somers $RM -f $temp_history 1482fae26bdSAlan Somers} 1492fae26bdSAlan Somers 1502fae26bdSAlan Somers# 1512fae26bdSAlan Somers# Get given dataset id 1522fae26bdSAlan Somers# 1532fae26bdSAlan Somers# $1 dataset name 1542fae26bdSAlan Somers# 1552fae26bdSAlan Somersfunction get_dataset_id 1562fae26bdSAlan Somers{ 1572fae26bdSAlan Somers typeset ds=$1 1582fae26bdSAlan Somers 1592fae26bdSAlan Somers # 1602fae26bdSAlan Somers # The zdb information looks like: 1612fae26bdSAlan Somers # 1622fae26bdSAlan Somers # Dataset pool/fs [ZPL], ID 21, cr_txg 6, 18.0K, 4 objects 1632fae26bdSAlan Somers # 1642fae26bdSAlan Somers typeset dst_id=$($ZDB $ds | $GREP "^Dataset $ds " | \ 1652fae26bdSAlan Somers $AWK -F\, '{print $2}' | $AWK '{print $2}') 1662fae26bdSAlan Somers 1672fae26bdSAlan Somers $ECHO $dst_id 1682fae26bdSAlan Somers} 1692fae26bdSAlan Somers 1702fae26bdSAlan Somers# 1712fae26bdSAlan Somers# Special case of verify_history, but only for destroyed datasets. This is 1722fae26bdSAlan Somers# needed because get_dataset_id depends on still having the original dataset 1732fae26bdSAlan Somers# in order to obtain its dataset id. 1742fae26bdSAlan Somers# 1752fae26bdSAlan Somersfunction verify_destroyed #<his_file> <ds_id> 1762fae26bdSAlan Somers{ 1772fae26bdSAlan Somers typeset his_file=$1 1782fae26bdSAlan Somers typeset ds_id=$2 1792fae26bdSAlan Somers 1802fae26bdSAlan Somers $GREP -E "\[txg:[0-9]+\] destroy [^ ]+ \($ds_id\)" $his_file \ 1812fae26bdSAlan Somers > /dev/null 2>&1 1822fae26bdSAlan Somers (($? == 0)) && return 0 1832fae26bdSAlan Somers return 1 1842fae26bdSAlan Somers} 1852fae26bdSAlan Somers 1862fae26bdSAlan Somers# 1872fae26bdSAlan Somers# Verify directly executed commands in a history file. This differs from 1882fae26bdSAlan Somers# verify_history in that it checks for explicit commands as opposed to 1892fae26bdSAlan Somers# internally generated commands. 1902fae26bdSAlan Somers# 1912fae26bdSAlan Somersfunction verify_direct_history #<his_file> <subcmd> <ds> 1922fae26bdSAlan Somers{ 1932fae26bdSAlan Somers typeset his_file=$1 1942fae26bdSAlan Somers typeset subcmd=$2 1952fae26bdSAlan Somers typeset ds=$3 1962fae26bdSAlan Somers 1972fae26bdSAlan Somers $GREP "zfs ${subcmd} ${ds}" ${his_file} > /dev/null 2>&1 1982fae26bdSAlan Somers (($? == 0)) && return 0 1992fae26bdSAlan Somers return 1 2002fae26bdSAlan Somers} 2012fae26bdSAlan Somers 2022fae26bdSAlan Somers# This function mostly just helps to collapse the case statement 2032fae26bdSAlan Somers# in verify_history. It returns whether the line matches (1==true). 2042fae26bdSAlan Somersfunction verify_history_line 2052fae26bdSAlan Somers{ 2062fae26bdSAlan Somers typeset line=$1 2072fae26bdSAlan Somers typeset subcmd=$2 2082fae26bdSAlan Somers typeset ds=$3 2092fae26bdSAlan Somers typeset keyword=$4 2102fae26bdSAlan Somers 2112fae26bdSAlan Somers typeset dst_id=$(get_dataset_id $ds) 2122fae26bdSAlan Somers log_note "Line: '$line'" 2132fae26bdSAlan Somers log_note "Checking cmd($subcmd) for $ds, keyword='$keyword'" 2142fae26bdSAlan Somers $ECHO $line | $GREP -E "\[txg:[0-9]+\] $subcmd $ds \($dst_id\)" | \ 2152fae26bdSAlan Somers $GREP $keyword >/dev/null 2>&1 2162fae26bdSAlan Somers [[ $? == 0 ]] && return 1 2172fae26bdSAlan Somers return 0 2182fae26bdSAlan Somers} 2192fae26bdSAlan Somers 2202fae26bdSAlan Somers# 2212fae26bdSAlan Somers# Scan history file and check if it include expected internal history 2222fae26bdSAlan Somers# information 2232fae26bdSAlan Somers# 2242fae26bdSAlan Somers# $1 history file 2252fae26bdSAlan Somers# $2 subcmd 2262fae26bdSAlan Somers# $3 dataset 2272fae26bdSAlan Somers# $4 keyword 2282fae26bdSAlan Somers# 2292fae26bdSAlan Somersfunction verify_history #<his_file> <subcmd> <ds> [keyword] 2302fae26bdSAlan Somers{ 2312fae26bdSAlan Somers typeset his_file=$1 2322fae26bdSAlan Somers typeset subcmd=$2 2332fae26bdSAlan Somers typeset ds=$3 2342fae26bdSAlan Somers typeset keyword=$4 2352fae26bdSAlan Somers 2362fae26bdSAlan Somers typeset line found=0 2372fae26bdSAlan Somers log_note "Test1" 2382fae26bdSAlan Somers while read line; do 2392fae26bdSAlan Somers case $subcmd in 2402fae26bdSAlan Somers snapshot|rollback|inherit) 2412fae26bdSAlan Somers # [txg:12] snapshot system/foo@0 (46) 2422fae26bdSAlan Somers keyword="$subcmd" 2432fae26bdSAlan Somers verify_history_line "$line" $subcmd $ds $keyword 2442fae26bdSAlan Somers [[ $? == 0 ]] && return 0 2452fae26bdSAlan Somers ;; 2462fae26bdSAlan Somers allow) 2472fae26bdSAlan Somers # [txg:10] permission update testpool.1477/testfs.1477 (40) s-$@basic snapshot 2482fae26bdSAlan Somers _subcmd="permission update" 2492fae26bdSAlan Somers verify_history_line "$line" "$_subcmd" $ds "$keyword" 2502fae26bdSAlan Somers [[ $? == 0 ]] && return 0 2512fae26bdSAlan Somers ;; 2522fae26bdSAlan Somers unallow) 2532fae26bdSAlan Somers # [txg:174] permission remove testpool.1477/testfs.1477 (40) El$ @set 2542fae26bdSAlan Somers _subcmd="permission remove" 2552fae26bdSAlan Somers verify_history_line "$line" "$_subcmd" $ds "$keyword" 2562fae26bdSAlan Somers [[ $? == 0 ]] && return 0 2572fae26bdSAlan Somers ;; 2582fae26bdSAlan Somers *) 2592fae26bdSAlan Somers ;; 2602fae26bdSAlan Somers esac 2612fae26bdSAlan Somers done < $his_file 2622fae26bdSAlan Somers return 1 2632fae26bdSAlan Somers} 264