• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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