206 lines
4.9 KiB
Bash
Executable file
206 lines
4.9 KiB
Bash
Executable file
#!/bin/bash
|
|
|
|
source test-variables
|
|
|
|
DISK=$1
|
|
if [[ -z $DISK ]] ; then
|
|
echo "Missing DISK parameter"
|
|
exit 11
|
|
fi
|
|
|
|
SERIAL=$2
|
|
if [[ -z $SERIAL ]] ; then
|
|
echo "Missing SERIAL parameter"
|
|
exit 12
|
|
fi
|
|
|
|
MY_PROC=$3
|
|
if [[ -z $MY_PROC ]] ; then
|
|
echo "Missing parameter 2: MY_PROC"
|
|
exit 16
|
|
fi
|
|
|
|
if [[ ! -b /dev/$DISK ]] ; then
|
|
echo "Device /dev/$DISK is not a block special file"
|
|
exit 13
|
|
fi
|
|
|
|
DISK_SERIAL=`smartctl -i /dev/$DISK \
|
|
| grep -i 'serial number' \
|
|
| cut -d ':' -f 2 \
|
|
| sed 's/\s\+//'`
|
|
|
|
if [[ -z $DISK_SERIAL ]] ; then
|
|
echo "Empty serial number in disk /dev/$DISK"
|
|
exit 14
|
|
fi
|
|
|
|
if [[ $DISK_SERIAL != $SERIAL ]] ; then
|
|
echo "Serial numbers $SERIAL and $DISK_SERIAL for $DISK do not match"
|
|
exit 15
|
|
fi
|
|
|
|
# TODO: Debug limit. Comment out for production
|
|
#LST_BLCK=10000000
|
|
SMARTLOG=300 # check every 5 minutes
|
|
#SMARTLOG=60 # check every minute
|
|
# TODO: Debug variable. Comment out for production
|
|
#SMARTLOG=15 # Check every second
|
|
BLK_SIZE=`cat /sys/block/$DISK/queue/physical_block_size`
|
|
|
|
cat > $OUTPUT_DIR/disk/$DISK.job << EOF
|
|
[global]
|
|
ioengine=libaio
|
|
direct=1
|
|
gtod_reduce=1
|
|
bs=$BLK_SIZE
|
|
iodepth=64
|
|
# TODO: Uncomment for production
|
|
size=4G
|
|
# TODO: Debug variable. Comment out for production
|
|
#size=16M
|
|
readwrite=randrw
|
|
rwmixread=75
|
|
directory=/mnt/$DISK
|
|
|
|
[file1]
|
|
name=test
|
|
filename=test
|
|
|
|
EOF
|
|
|
|
BEGIN=`date +%s`
|
|
# Check SMART overall self test
|
|
ERROR=`smartctl -H /dev/$DISK \
|
|
| grep '\(overall-health\|Health Status\)' \
|
|
| grep -v '\(PASSED\|OK\)'
|
|
`
|
|
if [[ -n $ERROR ]] ; then
|
|
smartctl -H /dev/$DISK \
|
|
> $OUTPUT_DIR/disk/$SERIAL.smart.error
|
|
else
|
|
ERROR=`smartctl -A -f brief /dev/$DISK \
|
|
| parse-smart-attr \
|
|
| grep ERROR \
|
|
| cut -d ':' -f 2
|
|
`
|
|
# TODO: Debug variable. Comment out for production
|
|
ERROR=
|
|
if [[ -n $ERROR ]] ; then
|
|
RAW_ERROR=$ERROR
|
|
ERROR=''
|
|
for TOKEN in $RAW_ERROR ; do
|
|
ERROR="$ERROR $TOKEN"
|
|
done
|
|
smartctl -A -f brief /dev/$DISK \
|
|
| parse-smart-attr \
|
|
| sed "s/ERROR/$RES_ERROR/g" \
|
|
> $OUTPUT_DIR/disk/$SERIAL.smart.error
|
|
fi
|
|
fi
|
|
if [[ -z $ERROR ]] ; then
|
|
# Reset partition table to zero
|
|
dd if=/dev/zero of=/dev/${DISK} bs=$BLK_SIZE count=128 \
|
|
>> /run/$SERIAL.fio.out 2>&1
|
|
parted /dev/${DISK} mklabel gpt mkpart primary 1 128G \
|
|
>> /run/$SERIAL.fio.out 2>&1
|
|
sleep 1
|
|
if [[ ! -b /dev/${DISK}1 ]] ; then
|
|
echo "Device /dev/${DISK}1 is not a block special file"
|
|
exit 17
|
|
fi
|
|
mkfs.ext4 /dev/${DISK}1 \
|
|
>> /run/$SERIAL.fio.out 2>&1
|
|
mkdir -pv /mnt/${DISK}
|
|
mount /dev/${DISK}1 /mnt/${DISK}
|
|
MOUNTED=`cat /proc/mounts | grep ${DISK}1`
|
|
if [[ -z $MOUNTED ]] ; then
|
|
echo "Device /dev/${DISK}1 is not mounted"
|
|
exit 18
|
|
fi
|
|
fio --output $OUTPUT_DIR/disk/$SERIAL.fio.out \
|
|
$OUTPUT_DIR/disk/$DISK.job &
|
|
TEST_PID=`jobs -p %+`
|
|
echo $TEST_PID > /run/$SERIAL.fio.pid
|
|
while [[ -d /proc/$TEST_PID ]] ; do
|
|
# Check SMART error log
|
|
ERROR=`smartctl -l error /dev/$DISK \
|
|
| parse-smart-error \
|
|
| sed 's/://g'
|
|
`
|
|
# TODO: Debug variable. Comment out for production
|
|
ERROR=
|
|
if [[ -n $ERROR ]] ; then
|
|
smartctl -l error /dev/$DISK \
|
|
> $OUTPUT_DIR/disk/$SERIAL.smart.error
|
|
kill $TEST_PID
|
|
sleep 5
|
|
fi
|
|
sleep $SMARTLOG
|
|
done
|
|
umount -f /mnt/${DISK}
|
|
# Reset partition table to zero
|
|
dd if=/dev/zero of=/dev/${DISK} bs=$BLK_SIZE count=128 \
|
|
>> /run/$SERIAL.fio.out 2>&1
|
|
if [[ -z $ERROR ]] ; then
|
|
# Check smart attributes after the fio test
|
|
ERROR=`smartctl -A -f brief /dev/$DISK \
|
|
| parse-smart-attr \
|
|
| grep ERROR \
|
|
| cut -d ':' -f 2
|
|
`
|
|
# TODO: Debug variable. Comment out for production
|
|
ERROR=
|
|
if [[ -n $ERROR ]] ; then
|
|
RAW_ERROR=$ERROR
|
|
ERROR=''
|
|
for TOKEN in $RAW_ERROR ; do
|
|
ERROR="$ERROR $TOKEN"
|
|
done
|
|
smartctl -A -f brief /dev/$DISK \
|
|
| parse-smart-attr \
|
|
| sed "s/ERROR/$RES_ERROR/g" \
|
|
> $OUTPUT_DIR/disk/$SERIAL.smart.error
|
|
fi
|
|
fi
|
|
#RET=$?
|
|
#echo $RET > $OUTPUT_DIR/disk/$SERIAL.fio.ret
|
|
rm -f /run/$SERIAL.fio.pid
|
|
fi
|
|
END=`date +%s`
|
|
|
|
DURATION=$(( END - BEGIN ))
|
|
|
|
echo -n "${BLD}Process $MY_PROC${OFF} : " \
|
|
> $OUTPUT_DIR/disk/$SERIAL.fio.result
|
|
if [[ -n $ERROR ]] ; then
|
|
echo -n "Disk $DISK $SERIAL $ERROR : " \
|
|
>> $OUTPUT_DIR/disk/$SERIAL.fio.result
|
|
echo $RES_FAIL \
|
|
>> $OUTPUT_DIR/disk/$SERIAL.fio.result
|
|
echo "$SERVER_SERIAL|$DISK|$SERIAL|FAIL|$ERROR" \
|
|
> $OUTPUT_DIR/disk/$SERIAL.fio.csv
|
|
else
|
|
echo -n "disk $DISK $SERIAL tested in ${DURATION}s : " \
|
|
>> $OUTPUT_DIR/disk/$SERIAL.fio.result
|
|
echo $RES_OK \
|
|
>> $OUTPUT_DIR/disk/$SERIAL.fio.result
|
|
echo "$SERVER_SERIAL|$DISK|$SERIAL|OK|${DURATION}s" \
|
|
> $OUTPUT_DIR/disk/$SERIAL.fio.csv
|
|
fi
|
|
|
|
ln -sf $OUTPUT_DIR/disk/$SERIAL.fio.out \
|
|
$OUTPUT_DIR/disk/$DISK.fio.out
|
|
ln -sf $OUTPUT_DIR/disk/$SERIAL.fio.result \
|
|
$OUTPUT_DIR/disk/$DISK.fio.result
|
|
ln -sf $OUTPUT_DIR/disk/$SERIAL.fio.csv \
|
|
$OUTPUT_DIR/disk/$DISK.fio.csv
|
|
if [[ -f $OUTPUT_DIR/disk/$SERIAL.smart.error ]] ; then
|
|
ln -sf $OUTPUT_DIR/disk/$SERIAL.smart.error \
|
|
$OUTPUT_DIR/disk/$DISK.smart.error
|
|
fi
|
|
|
|
cat $OUTPUT_DIR/disk/$SERIAL.fio.result
|
|
cat $OUTPUT_DIR/disk/$SERIAL.fio.result \
|
|
>> $OUTPUT_DIR/fio.log
|
|
|