summaryrefslogtreecommitdiffstats
path: root/tests/unit-wipe-test
blob: 4d0a078b31e85df94c16ad8583730f72282ad897 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
#!/bin/bash

WIPE_UNIT=./unit-wipe
FILE=./wipe_localfile
FILE_RAND=./wipe_random_localfile
MB_BYTES=$((1024*1024))
DEVSIZEMB=8
DEVSIZE=$((DEVSIZEMB*$MB_BYTES))

HASH_EMPTY=2daeb1f36095b44b318410b3f4e8b5d989dcc7bb023d1426c492dab0a3053e74

function cleanup() {
	rm -f $FILE $FILE_RAND 2> /dev/null
	sleep 1
	rmmod scsi_debug >/dev/null 2>&1
}

function fail()
{
	if [ -n "$1" ] ; then echo "FAIL $1" ; else echo "FAIL" ; fi
	echo "FAILED backtrace:"
	while caller $frame; do ((frame++)); done
	cleanup
	exit 100
}

function skip()
{
	echo "TEST SKIPPED: $1"
	cleanup
	exit 77
}

function add_device()
{
	rmmod scsi_debug >/dev/null 2>&1
	if [ -d /sys/module/scsi_debug ] ; then
		skip "Cannot use scsi_debug module (in use or compiled-in)."
	fi
	modprobe scsi_debug dev_size_mb=$DEVSIZEMB num_tgts=1 delay=0 >/dev/null 2>&1
	if [ $? -ne 0 ] ; then
		skip "This kernel seems to not support proper scsi_debug module."
	fi
	grep -q scsi_debug /sys/block/*/device/model || sleep 2
	DEV=$(grep -l -e scsi_debug /sys/block/*/device/model | cut -f4 -d /)
	DEV="/dev/$DEV"
	[ -b $DEV ] || fail "Cannot find $DEV."
}

function check_hash() # $1 dev, $2 hash
{
	local HASH=$(sha256sum $1 | cut -d' ' -f 1)
	[ $HASH == "$2" ]
}

function init_hash_dd() # $1 dev, $dev orig
{
	dd if=/dev/urandom of=$2 bs=1M count=$DEVSIZEMB conv=notrunc 2> /dev/null
	dd if=$2 of=$1 bs=1M conv=notrunc 2> /dev/null
	HASH_0=$(sha256sum $1 | cut -d' ' -f 1)
	# second MB wiped
	dd if=/dev/zero of=$1 bs=1M seek=1 count=1 conv=notrunc 2> /dev/null
	HASH_1=$(sha256sum $1 | cut -d' ' -f 1)
	# 4,5,6 MB wiped
	dd if=/dev/zero of=$1 bs=1M seek=4 count=3 conv=notrunc 2> /dev/null
	HASH_2=$(sha256sum $1 | cut -d' ' -f 1)
	dd if=$2 of=$1 bs=1M conv=notrunc 2> /dev/null
}

function add_file()
{
	dd if=/dev/zero of=$FILE      bs=1M count=$DEVSIZEMB 2> /dev/null || fail
	dd if=/dev/zero of=$FILE_RAND bs=1M count=$DEVSIZEMB 2> /dev/null || fail
	check_hash $FILE $HASH_EMPTY || fail
	check_hash $FILE_RAND $HASH_EMPTY || fail
	dd if=$FILE of=/dev/null bs=4096 count=1 iflag=direct >/dev/null 2>&1 || FILE_NODIO=1
}

function test_wipe_full() # $1 dev, $2 block size, [$3 flags]
{
	# wipe random and back to zero
	$WIPE_UNIT $1 random 0 $DEVSIZE $2 $3 || fail
	check_hash $1 $HASH_EMPTY && fail "Failed random wipe"
	$WIPE_UNIT $1 zero 0 $DEVSIZE $2 $3 || fail
	check_hash $1 $HASH_EMPTY || fail "Failed zero wipe"
}

# wipe MB blocks, with zero, random and special and back to original
function test_wipe_blocks() # $1 dev $2 block sizem [$3 flags]
{
	init_hash_dd $1 $FILE_RAND
	check_hash $1 $HASH_0 || fail

	$WIPE_UNIT $1 zero    $((1*$MB_BYTES)) $((1*$MB_BYTES)) $2 $3 || fail
	check_hash $1 $HASH_1 || fail
	$WIPE_UNIT $1 random  $((1*$MB_BYTES)) $((1*$MB_BYTES)) $2 $3 || fail
	check_hash $1 $HASH_1 && fail
	$WIPE_UNIT $1 special $((1*$MB_BYTES)) $((1*$MB_BYTES)) $2 $3 || fail
	check_hash $1 $HASH_1 && fail
	$WIPE_UNIT $1 zero    $((1*$MB_BYTES)) $((1*$MB_BYTES)) $2 $3 || fail
	check_hash $1 $HASH_1 || fail

	$WIPE_UNIT $1 zero    $((4*$MB_BYTES)) $((3*$MB_BYTES)) $2 $3 || fail
	check_hash $1 $HASH_2 || fail
	$WIPE_UNIT $1 random  $((4*$MB_BYTES)) $((3*$MB_BYTES)) $2 $3 || fail
	check_hash $1 $HASH_2 && fail
	$WIPE_UNIT $1 special $((4*$MB_BYTES)) $((3*$MB_BYTES)) $2 $3 || fail
	check_hash $1 $HASH_2 && fail
	$WIPE_UNIT $1 zero    $((4*$MB_BYTES)) $((3*$MB_BYTES)) $2 $3 || fail
	check_hash $1 $HASH_2 || fail
}

test -x $WIPE_UNIT || skip "Run \"make `basename $WIPE_UNIT`\" first"

cleanup
add_file

echo -n "[1] Wipe full file "
for bs in 0 $MB_BYTES $((4*$MB_BYTES)); do
	if [ -n "$FILE_NODIO" ]; then
		echo -n [$bs/DIO N/A]
	else
		echo -n [$bs/DIO]
		test_wipe_full $FILE $bs
	fi
	echo -n [$bs]
	test_wipe_full $FILE $bs no-dio
done
echo "[OK]"

echo -n "[2] Wipe blocks in file "
for bs in 0 $MB_BYTES $((4*$MB_BYTES)); do
	if [ -n "$FILE_NODIO" ]; then
		echo -n [$bs/DIO N/A]
	else
		echo -n [$bs/DIO]
		test_wipe_blocks $FILE $bs
	fi
	echo -n [$bs]
	test_wipe_blocks $FILE $bs no-dio
done
echo "[OK]"

[ $(id -u) -eq 0 ] || {
	echo "WARNING: You must be root to run remaining tests."
	cleanup
	exit 0
}

add_device

echo -n "[3] Wipe full block device "
for bs in 0 $MB_BYTES $((4*$MB_BYTES)); do
	echo -n [$bs/DIO]
	test_wipe_full $DEV $bs
	echo -n [$bs]
	test_wipe_full $DEV $bs no-dio
done
echo "[OK]"

echo -n "[4] Wipe blocks in block device "
for bs in 0 $MB_BYTES $((4*$MB_BYTES)); do
	echo -n [$bs/DIO]
	test_wipe_blocks $DEV $bs
	echo -n [$bs]
	test_wipe_blocks $DEV $bs no-dio
done
echo "[OK]"

cleanup