ltp测试脚本ltpstress.sh分析
LTP是由 Linux Test Project 所开发的一套系统测试套件。它基于系统资源的利用率统计开发了一个测试的组合,为系统提供足够的压力。通过压力测试来判断系统的稳定性和可靠性。压力测试是一种破坏性的测试,即系统在非正常的、超负荷的条件下的运行情况 。用来评估在超越最大负载的情况下系统将如何运行,是系统在正常的情况下对某种负载强度的承受能力的考验。
服务器产品一般进行72h压力测试,桌面产品一般进行24小时压力测试,常用测试命令:
# ./ltpstress.sh -n -t 72
其中 -n参数表示不进行网络相关测试,-t参数指定测试时长(小时为单位,最小为 1,默认24),该脚本最终调用genload程序来运行,genload根据传入的进程个数fork子进程,每个子进程的读写的内存为1GB,启动多少个进程由测试时的内存状态(含SWAP分区情况)决定。
该脚本测试与系统下的SWAP分区息息相关:
1)当系统下存在SWAP分区时,测试所用的内存大小为:全部物理内存 + 1/2 SWAP分区大小
2)当系统下不存在SWAP分区时(或使用swapoff -a命令关闭swap分区时),测试所用的内存大小为:通过free -m命令获取的当前空闲内存(多次测试间或有不同)
这个测试用例的本质是调用genload程序,以1G为单位来不断申请内存,然后执行写内存及释放的过程,ltpstrees.sh中只调用一次genload, genload根据 PROC_NUM个数来决定fork多少个genload子进程。
genload --vm $PROC_NUM --vm-bytes 1073741824 >/dev/null 2>&1 &
genload每次申请内存均以1G为单位进行,不足1G的会以剩余内存大小单独生成一个进程,例如:如果有31.5G可用内存,那么就创建32个genload进程。脚本执行后,可通过以下命令查看genload的状态和数量:
# ps -ef | grep genload
以下是ltpstress.sh脚本分析:
#!/bin/sh
# Copyright (c) International Business Machines Corp., 2003
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
# the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
#
# FILE : ltpstress.sh
# DESCRIPTION : A script that will stress your system using the LTP testsuite.
# REQUIREMENTS:
# 1) The 'rsh' daemon must be running and NFS (versions 2 &3) must be
# configured into the kernel and installed for networking tests.
# 2) The 'sar' application must be installed to use the "-S" option
# HISTORY :
# 02/11/2003 Robbie Williamson (robbiew@austin.ibm.com)
# written
# 11/20/2008 Aime Le Rouzic (aime.lerouzic@bull.net)
# adapt script to work with portmap and rpcbind
##############################################################
export LTPROOT=${PWD} # ltp/testscripts
echo $LTPROOT | grep testscripts > /dev/null 2>&1 # 不在ltp/testscripts目录下时返回1,在时返回0
if [ $? -eq 0 ]; then # 最后运行的命令返回的结束代码(0表示正常,其他表示异常)
cd ..
export LTPROOT=${PWD} # $LTPROOT=ltp/
fi
export TMPBASE="/tmp"
export PATH=$LTPROOT/testcases/bin:$PATH
memsize=0
hours=24
PROC_NUM=0
leftover_memsize=0
duration=86400
datafile="/tmp/ltpstress.data"
iofile="/tmp/ltpstress.iodata"
logfile="/tmp/ltpstress.log"
interval=10
Sar=0
Top=0
Iostat=0
LOGGING=0
PRETTY_PRT=""
QUIET_MODE=""
NO_NETWORK=0
usage()
{
cat <<-END >&2
usage: ${0##*/} [ -d datafile ] [ -i # (in seconds) ] [ -I iofile ] [ -l logfile ] [ -m # (in Mb) ]
[ -n ] [ -p ] [ -q ] [ -t duration ] [ -x TMPDIR ] [-b DEVICE] [-B LTP_DEV_FS_TYPE] [ [-S]|[-T] ]
-d datafile Data file for 'sar' or 'top' to log to. Default is "/tmp/ltpstress.data".
-i # (in sec) Interval that 'sar' or 'top' should take snapshots. Default is 10 seconds.
-I iofile Log results of 'iostat' to a file every interval. Default is "/tmp/ltpstress.iodata".
-l logfile Log results of test in a logfile. Default is "/tmp/ltpstress.log"
-m # (in Mb) Specify the _minimum_ memory load of # megabytes in background. Default is all the RAM + 1/2 swap.
-n Disable networking stress.
-p Human readable format logfiles.
-q Print less verbose output to the output files.
-S Use 'sar' to measure data.
-T Use LTP's modified 'top' tool to measure data.
-t duration Execute the testsuite for given duration in hours. Default is 24.
-x TMPDIR Directory where temporary files will be created.
-b DEVICE Some tests require an unmounted block device
to run correctly. If DEVICE is not set, a loop device is
created and used automatically.
-B LTP_DEV_FS_TYPE The file system of DEVICE.
example: ${0##*/} -d /tmp/sardata -l /tmp/ltplog.$$ -m 128 -t 24 -S
END
exit
}
check_memsize() #函数作用:检查测试所用内存大小,计算得出PROC_NUM大小
{
while [ $memsize -gt 1048576 ] #if greater than 1GB #测试所用内存大于1GB时,$memsize单位为KB,1048576=1024*1024
do
PROC_NUM=$(( PROC_NUM + 1 )) #PROC_NUM初始值为0
memsize=$(( $memsize - 1048576 )) #以1GB为单位递减,计算PROC_NUM数量
done
leftover_memsize=$memsize #leftover_memsize初始值为0,使用leftover_memsize记录小于1GB的内存部分,后续用来单独创建一个线程
}
while getopts d:hi:I:l:STt:m:npqx:b:B:\? arg #遍历参数,初始化状态
do case $arg in
d) datafile="$OPTARG";;
h) echo "Help info:"
usage;;
i) interval=$OPTARG;;
I) Iostat=1
iofile=$OPTARG;;
l) logfile=$OPTARG
LOGGING=1;;
m) memsize=$(($OPTARG * 1024)) # -m参数指定的测试内存大小,单位为MB
check_memsize;;
n) NO_NETWORK=1;;
p) PRETTY_PRT=" -p ";;
q) QUIET_MODE=" -q ";;
S) if [ $Top -eq 0 ]; then
Sar=1
else
echo "Cannot specify -S and -T...exiting"
exit
fi;;
T) if [ $Sar -eq 0 ]; then
$LTPROOT/testcases/bin/top -h 2>&1 | grep "\-f filename" >/dev/null
if [ $? -eq 0 ]; then
Top=1
else
echo "ERROR: Please build and install the version of top in the /tools dir"
exit
fi
else
echo "Cannot specify -S and -T...exiting"
exit
fi;;
t) hours=$OPTARG
duration=$(($hours * 60 * 60));; #duration单位为秒
x) export TMPBASE=$(readlink -f ${OPTARG});;
b) export LTP_DEV=${OPTARG};;
B) export LTP_DEV_FS_TYPE=${OPTARG};;
\?) echo "Help info:"
usage;;
esac
done
export TMP="${TMPBASE}/ltpstress-$$" # $$ shell本身的pid #TMP=/tmp/ltpstress-pid
export TMPDIR=${TMP}
mkdir -p ${TMP} #创建临时目录,修改权限并进入目录
# to write as user nobody into tst_tmpdir()
chmod 777 $TMP || \
{
echo "unable to chmod 777 $TMP ... aborting"
exit 1
}
cd $TMP || \
{
echo "could not cd ${TMP} ... exiting"
exit 1
}
if [ $NO_NETWORK -eq 0 ];then #测试时未加-n参数,进行网络相关测试,测试时未使用
# Networking setup
echo `hostname` >> /root/.rhosts
chmod 644 /root/.rhosts
netstat -an | grep 514
if [ $? -eq 1 ];then
echo "Error: 'rsh' daemon not active on this machine."
exit 1
fi
ps -ef | grep portmap | grep -v grep
if [ $? -eq 1 ];then
ps -ef | grep rpcbind | grep -v grep
if [ $? -eq 1 ];then
echo "Portmap and rpcbind not running"
echo "Let's start portmap"
/sbin/portmap &
sleep 1
ps -ef | grep portmap | grep -v grep
if [ $? -eq 1 ];then
echo "Could not start portmap, Let's start rpcbind"
/sbin/rpcbind &
sleep 1
ps -ef | grep rpcbind | grep -v grep
if [ $? -eq 1 ];then
Echo "Error: Could not start rpcbind daemon."
exit 1
else
echo "The RPC test suite is using rpcbind"
fi
else
echo "The RPC test suite is using portmap"
fi
else
echo "The RPC test suite is using rpcbind"
fi
else
echo "The RPC test suite is using portmap"
fi
ps -e | grep nfsd
if [ $? -eq 1 ];then
/usr/sbin/rpc.nfsd
fi
sleep 1
ps -e | grep nfsd
if [ $? -eq 1 ];then
echo "Error: Could not start nfs server daemon."
exit 1
fi
ps -e | grep rpc.statd
if [ $? -eq 1 ];then
/sbin/rpc.statd
fi
sleep 1
ps -e | grep rpc.statd
if [ $? -eq 1 ];then
echo "Error: Could not start statd daemon."
exit 1
fi
ps -e | grep rpc.mountd
if [ $? -eq 1 ];then
/usr/sbin/rpc.mountd
fi
sleep 1
ps -e | grep rpc.mountd
if [ $? -eq 1 ];then
echo "Error: Could not start mountd daemon."
exit 1
fi
# End of network setup
fi #结束网络相关测试
#If -m not set, use all the RAM + 1/2 swapspace
if [ $memsize -eq 0 ]; then #$memsize初始值为0
TOTALRAM=$(free -m | grep 内存: | awk {'print $2'}) #取出free输出的total mem数值,单位为MB
TOTALSWAP=$(free -m | grep 交换: | awk {'print $2'}) #取出free输出的total Swap数值,单位为MB
TESTSWAP=$(($TOTALSWAP / 2)) #测试用到的TESTSWAP空间为总SWAP大小的一半
if [ $TESTSWAP -eq 0 ]; then #没有SWAP空间或关闭了SWAP空间
#if there is no swap in the system, use only the free RAM
TESTMEM=$(free -m | grep Mem: | awk {'print $4'}) #没有SWAP参与的情况下,测试所用的TESTMEM大小为free输出的空闲空间大小(非total大小),单位为MB
else
TESTMEM=$(($TESTSWAP + $TOTALRAM)) #有SWAP参与的情况下,测试所用的TESTMEM大小为总内存+1/2SWAP空间大小,单位为MB
fi
#Convert to kilobytes
memsize=$(($TESTMEM * 1024)) #将TESTMEM数值转换为KB,保存在memsize变量
check_memsize #调用check_memsize函数
fi
# Set max processes to unlimited.
ulimit -u unlimited #解除最大线程限制
if [ $PROC_NUM -gt 0 ];then
genload --vm $PROC_NUM --vm-bytes 1073741824 >/dev/null 2>&1 & #-m, --vm n spawn n procs spinning on malloc()
fi #--vm-bytes b malloc chunks of b bytes (default is 256MB),以字节Byte为单位,1073741824=1024*1024*1024,Byte转为GB,每个线程申请1GB内存
if [ $leftover_memsize -gt 0 ];then #将小于1Gb的内存部分单独创建一个线程
genload --vm 1 --vm-bytes $(($leftover_memsize * 1024)) >/dev/null 2>&1 &
fi
if [ $NO_NETWORK -eq 0 ];then #加了-n参数则不执行if内语句
netpipe.sh >/dev/null 2>/dev/null &
fi
${LTPROOT}/bin/rand_lines -g ${LTPROOT}/runtest/stress.part1 > ${TMP}/stress.part1
${LTPROOT}/bin/rand_lines -g ${LTPROOT}/runtest/stress.part2 > ${TMP}/stress.part2
${LTPROOT}/bin/rand_lines -g ${LTPROOT}/runtest/stress.part3 > ${TMP}/stress.part3
sleep 2
if [ $Sar -eq 1 ]; then
sar -o $datafile $interval > /dev/null &
fi
if [ $Top -eq 1 ]; then
screen -d -m $LTPROOT/testcases/bin/top -o $datafile -d $interval &
SCREEN_PID=$(ps -e | grep screen | awk {'print $1'})
fi
sleep 2
if [ $Iostat -eq 1 ]; then
while [ 0 = 0 ];do iostat -dt >> $iofile; sleep $interval;done &
Iostat_PID=$?
fi
sleep 2
output1=${TMPBASE}/ltpstress.$$.output1
output2=${TMPBASE}/ltpstress.$$.output2
output3=${TMPBASE}/ltpstress.$$.output3
${LTPROOT}/bin/ltp-pan -e ${PRETTY_PRT} ${QUIET_MODE} -S -t ${hours}h -a stress1 -n stress1 -l $logfile -f ${TMP}/stress.part1 -o $output1 &
${LTPROOT}/bin/ltp-pan -e ${PRETTY_PRT} ${QUIET_MODE} -S -t ${hours}h -a stress2 -n stress2 -l $logfile -f ${TMP}/stress.part2 -o $output2 &
${LTPROOT}/bin/ltp-pan -e ${PRETTY_PRT} ${QUIET_MODE} -S -t ${hours}h -a stress3 -n stress3 -l $logfile -f ${TMP}/stress.part3 -o $output3 &
echo "Running LTP Stress for $hours hour(s) using $(($memsize/1024)) Mb" #此处$memsize大小为经过check_memsize后小于1GB的部分
echo ""
echo "Test output recorded in:"
echo " $output1"
echo " $output2"
echo " $output3"
# Sleep a little longer than duration to let ltp-pan "try" to gracefully end itself.
sleep $(($duration + 10))
if [ $Sar -eq 1 ]; then
killall -9 sadc >/dev/null 2>&1
fi
if [ $Top -eq 1 ]; then
kill $SCREEN_PID >/dev/null 2>&1
fi
killall -9 ltp-pan >/dev/null 2>&1
killall -9 genload >/dev/null 2>&1
if [ $NO_NETWORK -eq 0 ];then
killall -9 netpipe.sh >/dev/null 2>&1
killall -9 NPtcp >/dev/null 2>&1
fi
if [ $Iostat -eq 1 ];then
kill -9 $Iostat_PID >/dev/null 2>&1
fi
rm -rf ${TMP}
echo "Testing done"
if [ $LOGGING -eq 1 ];then
if [ ! -z $PRETTY_PRT ]; then
grep FAIL $logfile > /dev/null 2>&1
else
grep 'stat=' $logfile | grep -v 'stat=0' > /dev/null 2>&1
fi
if [ $? -eq 1 ]; then
echo "All Tests PASSED!"
else
echo "Testing yielded failures. See logfile: $logfile"
if [ $NO_NETWORK -eq 1 ];then
echo "The NFS related tests should fail because network stress was disabled"
fi
fi
fi
更多推荐
所有评论(0)