1#/bin/bash 2# 3# File system metadata stress testing script v0.1 4# 5# This program is free software; you can redistribute it and/or 6# modify it under the terms of the GNU General Public 7# License as published by the Free Software Foundation; version 8# 2. 9# 10# This program is distributed in the hope that it will be useful, 11# but WITHOUT ANY WARRANTY; without even the implied warranty of 12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13# General Public License for more details. 14# 15# You should find a copy of v2 of the GNU General Public License somewhere 16# on your Linux system; if not, write to the Free Software Foundation, 17# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18# 19# Copyright (C) 2009, Intel Corp. 20# Author: Shaohui Zheng <shaohui.zheng@intel.com> 21 22export K_CWD=$(cd $(dirname $0)>/dev/null;pwd) 23export K_VAR=$K_CWD/var 24export K_TREE_GEN=$K_CWD/k-tree-gen 25export K_TREE_TRAV=$K_CWD/k-tree-trav 26 27 28 29function summary_result() 30{ 31 local total_nr=$(egrep "pass|fail" $K_RESULT | wc -l ) 32 local pass_nr=$(grep pass $K_RESULT| wc -l ) 33 local fail_nr=$(grep fail $K_RESULT| wc -l ) 34 local end_ts=$(date +%s) 35 local run_time=$(expr $end_ts - $K_START_TS) 36 37 k_result "Finish fs-metadata testing within $run_time secs, $total_nr metadata " 38 k_result "testing finished." 39 k_result "PASS:$pass_nr" 40 k_result "FAIL:$fail_nr" 41 k_result "You can refer to result file $K_RESULT," 42 k_result "and log file $K_LOG for details." 43 44 # cleanup 45 for pid in $(cat $K_THREADS_PID) 46 do 47 k_log "killing k-thread $pid" 48 run_quiet kill -9 $pid 49 done 50 : > $K_THREADS_PID 51} 52 53# run program and do not display the output 54function run_quiet() 55{ 56 local cmd=$* 57 $cmd >/dev/null 2>&1 58 return $? 59} 60 61function abort_test() 62{ 63 k_result "finish $sec secs fs stress testing, clean up the envirnment" 64 65 # summary the test result 66 run_quiet unlink $K_FLAG 67 summary_result 68 exit 0 69} 70 71function usage() 72{ 73 alert "File system metadata testing script v0.12 \n" 74 echo "" 75 echo "This script creates a lot of directory entries with k-tree data structure, " 76 echo "It covers i-node creation/removing/linking/unliking operation in heavy I/O " 77 echo "workloads." 78 echo "" 79 echo "A k-tree is a tranformation of binary tree, A binary has 2 children at most" 80 echo "in each node, but a k-tree has k sub-nodes. We test both file and directory" 81 echo "entries, So we do some changes. We create k sub directories and k text file" 82 echo "in each parent." 83 echo "" 84 echo "We will caculate approximate disk space, it depends on your parameter. For " 85 echo "tree_depth, suggest to less than 10. For node_number, suggest to less 20. " 86 echo "If you pass a large number as parameter, it generate a huge directory entry" 87 echo "it exhaust your disk space very fast, very hard to remove." 88 alert "\nWe suggest you to run the script in a standalone partition, you can format\n" 89 alert "it after test finished!\n" 90 echo "" 91 echo "Usage: " 92 echo -e "\ttree_depth node_number threads run_time(secs) [result_file] [temp_dir] [log_file]\n" 93 exit 0 94} 95 96function alert() 97{ 98 echo -en "\\033[40;31m" # set font color as red 99 echo -en "$*" 100 echo -en "\\033[0;39m" # restore font color as normal 101} 102 103function k_result() 104{ 105 echo [$(date "+%m-%d %H:%M:%S")] $* | tee -a $K_LOG 106 echo $* | egrep "pass|fail" 107 ret_val=$? 108 if [ -f $K_FLAG ] ;then 109 echo [$(date "+%m-%d %H:%M:%S")] $* >> $K_RESULT 110 fi 111 112 if [ ! -f $K_FLAG ] && [ $ret_val -ne 0 ] ;then 113 echo [$(date "+%m-%d %H:%M:%S")] $* >> $K_RESULT 114 fi 115} 116 117function check_disk_space() 118{ 119 run_quiet cd $K_CWD 120 local depth=$(expr $1 + 1) 121 local width=$2 122 local thread=$3 123 local tree_size=$(echo "scale=2; (1-$width^$depth)/(1-$width) *2*4/1024 " | bc) 124 local total_size=$(echo "scale=2; $tree_size * 2 * $thread " | bc) 125 local free_space=$( df . -m | awk '{ print $3}' | tail -1) 126 127 k_log "The k-tree size is $tree_size M, the total free space reqirements is about $total_size M." 128 129 local ready=$(echo $free_space $total_size | awk '{if($1>$2){printf "0"}else{printf"1"}}') 130 if [ $ready -ne 0 ];then 131 k_log "You have $free_space M free space only, we can not finish your testing, abort it." 132 return 1 133 else 134 k_log "You have $free_space M free space, ready to run the testing." 135 run_quiet cd - 136 return 0 137 fi 138} 139 140function k_log() 141{ 142 echo [$(date "+%m-%d %H:%M:%S")] $* | tee -a $K_LOG 143} 144 145function k_thread() 146{ 147 local dir=$1 148 local depth=$2 149 local width=$3 150 local result 151 152 # generate new tree 153 k_log "begin to generate tree $dir" 154 $K_TREE_GEN $depth $width 155 k_log "end to generate tree $dir" 156 157 cwd=$(pwd) 158 run_quiet cd $K_VAR 159 while [ -e $K_FLAG ] 160 do 161 new_dir=$dir-new 162 cp $dir $new_dir -pr 163 run_quiet cd $new_dir 164 k_log "thread $dir: begin to traverse dir $new_dir" 165 $K_TREE_TRAV $2 $3 166 k_log "thread $dir: end to traverse dir $new_dir" 167 run_quiet cd - 168 result=PASS 169 k_tree_diff $dir $new_dir || result=FAIL 170 k_result "thread $dir: $result to compare result between dir $dir and $new_dir" 171 172 rm $new_dir -fr 173 done 174 run_quiet cd $cwd 175 # test ends, remove the oringal tree 176 rm $dir -fr 177} 178 179 180 181if [ $# -lt 4 ] ;then 182 usage 183 k_result "[end] invalid input $*" 184fi 185 186if [ $# -gt 4 ];then 187 K_RESULT=$5 188 if [ $(dirname $K_RESULT) = '.' ]; then 189 K_RESULT=$K_CWD/$K_RESULT 190 fi 191else 192 K_RESULT=$K_CWD/result.txt 193fi 194 195if [ $# -gt 5 ];then 196 K_VAR=$6 197 if [ $(dirname $K_VAR) = '.' ]; then 198 K_VAR=$K_CWD/$K_VAR 199 fi 200fi 201 202if [ $# -gt 6 ];then 203 K_LOG=$7 204 if [ $(dirname $K_RESULT) = '.' ]; then 205 K_LOG=$K_VAR/$K_LOG 206 fi 207else 208 K_LOG=$K_VAR/log.txt 209fi 210export K_FLAG=$K_VAR/fs_flag 211export K_START_TS= 212export K_THREADS_PID=$K_VAR/k-threads.pid 213export K_FS_METADATA_PID=$K_VAR/fs_metadata.pid 214export K_RESULT 215export K_LOG 216: > $K_RESULT 217: > $K_LOG 218 219#main portal 220[ -e $K_FLAG ] && unlink $K_FLAG 221k_result "[begin] fs-stress testing start with parameters: $*" 222 223check_disk_space $* 224if [ $? -ne 0 ];then 225 exit 1 226fi 227 228#clean up 229k_log "clean up testing environment" 230[ -d $K_VAR ] && rm $K_VAR -fr 231mkdir -p $K_VAR 232 233touch $K_FS_METADATA_PID 234touch $K_THREADS_PID 235echo $$ > $K_FS_METADATA_PID 236: > $K_THREADS_PID 237touch $K_FLAG 238 239run_quiet cd $K_VAR 240 241K_START_TS=$(date +%s) 242 243# signal handler 244trap abort_test 0 245 246#testing 247counter=0 248while [ $counter -lt $3 ]; 249do 250 mkdir $counter -p 251 cur=$(pwd) 252 run_quiet cd $counter 253 #k_thread $counter $1 $2 & 254 $K_CWD/k-thread.sh $counter $1 $2 & 255 run_quiet cd $cur 256 counter=$(expr $counter + 1) 257done 258 259sec=$4 260sleep $sec 261 262# clean up 263# finish $4 mins fs stress testing 264k_log "[end] fs-stresting testing, all done!" 265 266 267