]> git.ipfire.org Git - thirdparty/mdadm.git/blame - tests/func.sh
tests: Gate tests for linear flavor with variable LINEAR
[thirdparty/mdadm.git] / tests / func.sh
CommitLineData
cbb8d34a
ZL
1#!/bin/bash
2
3# We test mdadm on loop-back block devices.
4# dir for storing files should be settable by command line maybe
5size=20000
6# super0, round down to multiple of 64 and substract 64
7mdsize0=19904
8# super00 is nested, subtract 128
9mdsize00=19840
10# super1.0 round down to multiple of 2, subtract 8
11mdsize1=19992
12mdsize1a=19988
13mdsize12=19988
14# super1.2 for linear: round to multiple of 2, subtract 4
15mdsize1_l=19996
16mdsize2_l=19996
17# subtract another 4 for bitmaps
18mdsize1b=19988
19mdsize11=19992
20mdsize11a=19456
21mdsize12=19988
22
23# ddf needs bigger devices as 32Meg is reserved!
24ddfsize=65536
25
26# $1 is optional parameter, it shows why to save log
27save_log() {
28 status=$1
29 logfile="$status""$_basename".log
30
31 cat $targetdir/stderr >> $targetdir/log
32 cp $targetdir/log $logdir/$_basename.log
33 echo "## $HOSTNAME: saving dmesg." >> $logdir/$logfile
34 dmesg -c >> $logdir/$logfile
35 echo "## $HOSTNAME: saving proc mdstat." >> $logdir/$logfile
36 cat /proc/mdstat >> $logdir/$logfile
37 array=($(mdadm -Ds | cut -d' ' -f2))
38 [ "$1" == "fail" ] &&
39 echo "FAILED - see $logdir/$_basename.log and $logdir/$logfile for details"
40 if [ $DEVTYPE == 'lvm' ]
41 then
42 # not supported lvm type yet
43 echo
44 elif [ "$DEVTYPE" == 'loop' -o "$DEVTYPE" == 'disk' ]
45 then
46 if [ ! -z "$array" -a ${#array[@]} -ge 1 ]
47 then
48 echo "## $HOSTNAME: mdadm -D ${array[@]}" >> $logdir/$logfile
49 $mdadm -D ${array[@]} >> $logdir/$logfile
50 # ignore saving external(external file, imsm...) bitmap
51 cat /proc/mdstat | grep -q "linear\|external" && return 0
52 md_disks=($($mdadm -D -Y ${array[@]} | grep "/dev/" | cut -d'=' -f2))
53 cat /proc/mdstat | grep -q "bitmap"
54 if [ $? -eq 0 ]
55 then
56 echo "## $HOSTNAME: mdadm -X ${md_disks[@]}" >> $logdir/$logfile
57 $mdadm -X ${md_disks[@]} >> $logdir/$logfile
7d81135e
ZL
58 echo "## $HOSTNAME: mdadm -E ${md_disks[@]}" >> $logdir/$logfile
59 $mdadm -E ${md_disks[@]} >> $logdir/$logfile
cbb8d34a
ZL
60 fi
61 else
62 echo "## $HOSTNAME: no array assembled!" >> $logdir/$logfile
63 fi
64 fi
65}
66
67cleanup() {
68 udevadm settle
69 $mdadm -Ssq 2> /dev/null
70 case $DEVTYPE in
71 loop )
72 for d in 0 1 2 3 4 5 6 7 8 9 10 11 12 13
73 do
74 losetup -d /dev/loop$d &> /dev/null
75 rm -f /dev/disk/by-path/loop*
76 rm -f /var/tmp/mdtest$d
77 done
78 ;;
79 lvm )
80 for d in 0 1 2 3 4 5 6 7 8 9 10 11 12 13
81 do
82 eval "lvremove --quiet -f \$dev$d"
83 done
84 ;;
85 disk )
86 $mdadm --zero ${disks[@]} &> /dev/null
87 ;;
88 esac
89}
90
064bd3f5
ZL
91do_clean()
92{
93 mdadm -Ss > /dev/null
94 mdadm --zero $devlist 2> /dev/null
95 dmesg -c > /dev/null
96}
97
cbb8d34a
ZL
98check_env() {
99 user=$(id -un)
100 [ "X$user" != "Xroot" ] && {
101 echo "test: testing can only be done as 'root'."
102 exit 1
103 }
59416da7
JS
104 [ \! -x $mdadm ] && {
105 echo "test: please run make everything before perform testing."
cbb8d34a
ZL
106 exit 1
107 }
108 cmds=(mdadm lsblk df udevadm losetup mkfs.ext3 fsck seq)
109 for cmd in ${cmds[@]}
110 do
111 which $cmd > /dev/null || {
112 echo "$cmd command not found!"
113 exit 1
114 }
115 done
cbb8d34a
ZL
116 if $(lsblk -a | grep -iq raid)
117 then
118 # donot run mdadm -Ss directly if there are RAIDs working.
119 echo "test: please run test suite without running RAIDs environment."
120 exit 1
121 fi
122 # Check whether to run multipath tests
123 modprobe multipath 2> /dev/null
124 grep -sq 'Personalities : .*multipath' /proc/mdstat &&
125 MULTIPATH="yes"
64a4fcb4
SL
126 if [ "$MULTIPATH" != "yes" ]; then
127 echo "test: skipping tests for multipath, which is removed in upstream 6.8+ kernels"
128 fi
129
130 # Check whether to run linear tests
131 modprobe linear 2> /dev/null
132 grep -sq 'Personalities : .*linear' /proc/mdstat &&
133 LINEAR="yes"
134 if [ "$LINEAR" != "yes" ]; then
135 echo "test: skipping tests for linear, which is removed in upstream 6.8+ kernels"
136 fi
cbb8d34a
ZL
137}
138
139do_setup() {
140 trap cleanup 0 1 3 15
141 trap ctrl_c 2
142
143 check_env
144 [ -d $logdir ] || mkdir -p $logdir
cbb8d34a
ZL
145
146 devlist=
147 if [ "$DEVTYPE" == "loop" ]
148 then
149 # make sure there are no loop devices remaining.
150 # udev started things can sometimes prevent them being stopped
151 # immediately
152 while grep loop /proc/partitions > /dev/null 2>&1
153 do
154 $mdadm -Ssq
155 losetup -d /dev/loop[0-9]* 2> /dev/null
156 sleep 0.2
157 done
158 elif [ "$DEVTYPE" == "disk" ]
159 then
160 if [ ! -z "$disks" ]
161 then
162 for d in $(seq 0 ${#disks[@]})
163 do
164 eval "dev$d=${disks[$d]}"
165 eval devlist=\"\$devlist \$dev$d\"
166 eval devlist$d=\"\$devlist\"
167 done
168 $mdadm --zero ${disks[@]} &> /dev/null
169 else
170 echo "Forget to provide physical devices for disk mode."
171 exit 1
172 fi
173 fi
174 for d in 0 1 2 3 4 5 6 7 8 9 10 11 12 13
175 do
176 sz=$size
177 [ $d -gt 7 ] && sz=$ddfsize
178 case $DEVTYPE in
179 loop)
180 [ -f $targetdir/mdtest$d ] ||
181 dd if=/dev/zero of=$targetdir/mdtest$d count=$sz bs=1K > /dev/null 2>&1
182 # make sure udev doesn't touch
183 mdadm --zero $targetdir/mdtest$d 2> /dev/null
cbb8d34a
ZL
184 if [ $d -eq 7 ]
185 then
186 losetup /dev/loop$d $targetdir/mdtest6 # for multipath use
187 else
188 losetup /dev/loop$d $targetdir/mdtest$d
189 fi
190 eval dev$d=/dev/loop$d
191 eval file$d=$targetdir/mdtest$d
192 ;;
193 lvm)
194 unset MULTIPATH
195 eval dev$d=/dev/mapper/${LVM_VOLGROUP}-mdtest$d
196 if ! lvcreate --quiet -L ${sz}K -n mdtest$d $LVM_VOLGROUP
197 then
198 trap '' 0 # make sure lvremove is not called
199 eval echo error creating \$dev$d
200 exit 129
201 fi
202 ;;
203 ram)
204 unset MULTIPATH
205 eval dev$d=/dev/ram$d
206 ;;
207 esac
208 eval devlist=\"\$devlist \$dev$d\"
209 eval devlist$d=\"\$devlist\"
210 #" <-- add this quote to un-confuse vim syntax highlighting
211 done
212 path0=$dev6
213 path1=$dev7
214 ulimit -c unlimited
215 [ -f /proc/mdstat ] || modprobe md_mod
216 echo 2000 > /proc/sys/dev/raid/speed_limit_max
217 echo 0 > /sys/module/md_mod/parameters/start_ro
218}
219
220# check various things
221check() {
222 case $1 in
9c816fe2
XN
223 opposite_result )
224 if [ $? -eq 0 ]; then
225 die "This command shouldn't run successfully"
226 fi
59416da7 227 ;;
cbb8d34a
ZL
228 spares )
229 spares=$(tr '] ' '\012\012' < /proc/mdstat | grep -c '(S)' || exit 0)
230 [ $spares -ne $2 ] &&
231 die "expected $2 spares, found $spares"
232 ;;
233 raid* | linear )
234 grep -sq "active $1 " /proc/mdstat ||
235 die "active $1 not found"
236 ;;
237 algorithm )
238 grep -sq " algorithm $2 " /proc/mdstat ||
239 die "algorithm $2 not found"
240 ;;
241 resync | recovery | reshape )
242 cnt=5
243 while ! grep -sq $1 /proc/mdstat
244 do
245 if [ $cnt -gt 0 ] && grep -v idle /sys/block/md*/md/sync_action > /dev/null
246 then # Something isn't idle - wait a bit
247 sleep 0.5
248 cnt=$[cnt-1]
249 else
250 die "no $1 happening"
251 fi
252 done
253 ;;
254 nosync )
255 sleep 0.5
256 # Since 4.2 we delay the close of recovery until there has been a chance for
257 # spares to be activated. That means that a recovery that finds nothing
258 # to do can still take a little longer than expected.
259 # add an extra check: is sync_completed shows the end is reached, assume
260 # there is no recovery.
261 if grep -sq -E '(resync|recovery|reshape) *=' /proc/mdstat
262 then
263 incomplete=`grep / /sys/block/md*/md/sync_completed 2> /dev/null | sed '/^ *\([0-9]*\) \/ \1/d'`
264 [ -n "$incomplete" ] &&
265 die "resync or recovery is happening!"
266 fi
267 ;;
268 wait )
269 p=`cat /proc/sys/dev/raid/speed_limit_max`
270 echo 2000000 > /proc/sys/dev/raid/speed_limit_max
271 sleep 0.1
272 while grep -Eq '(resync|recovery|reshape|check|repair) *=' /proc/mdstat ||
273 grep -v idle > /dev/null /sys/block/md*/md/sync_action
274 do
275 sleep 0.5
276 done
277 echo $p > /proc/sys/dev/raid/speed_limit_max
278 ;;
279 state )
280 grep -sq "blocks.*\[$2\]\$" /proc/mdstat ||
281 die "state $2 not found!"
282 sleep 0.5
283 ;;
284 bitmap )
285 grep -sq bitmap /proc/mdstat ||
286 die "no bitmap"
287 ;;
288 nobitmap )
289 grep -sq "bitmap" /proc/mdstat &&
290 die "bitmap present"
291 ;;
292 readonly )
293 grep -sq "read-only" /proc/mdstat ||
294 die "array is not read-only!"
295 ;;
296 inactive )
297 grep -sq "inactive" /proc/mdstat ||
298 die "array is not inactive!"
299 ;;
300 # It only can be used when there is only one raid
301 chunk )
302 chunk_size=`awk -F',' '/chunk/{print $2}' /proc/mdstat | awk -F'[a-z]' '{print $1}'`
303 if [ "$chunk_size" -ne "$2" ] ; then
304 die "chunksize should be $2, but it's $chunk_size"
305 fi
306 ;;
307 * )
308 die "unknown check $1"
309 ;;
310 esac
311}
312
313no_errors() {
314 if [ -s $targetdir/stderr ]
315 then
316 echo Bad errors from mdadm:
317 cat $targetdir/stderr
318 exit 2
319 fi
320}
321
322# basic device test
323testdev() {
324 [ -b $1 ] || die "$1 isn't a block device."
325 [ "$DEVTYPE" == "disk" ] && return 0
326 udevadm settle
327 dev=$1
328 cnt=$2
329 dvsize=$3
330 chunk=$4
331 if [ -z "$5" ]
332 then
333 mkfs.ext3 -F -j $dev > /dev/null 2>&1 && fsck -fn $dev >&2
334 fi
335 dsize=$[dvsize/chunk]
336 dsize=$[dsize*chunk]
337 rasize=$[dsize*2*cnt]
338 # rasize is in sectors
339 if [ -n "$DEV_ROUND_K" ]
340 then
341 rasize=$[rasize/DEV_ROUND_K/2]
342 rasize=$[rasize*DEV_ROUND_K*2]
343 fi
344 [ `/sbin/blockdev --getsize $dev` -eq 0 ] && sleep 2
345 _sz=`/sbin/blockdev --getsize $dev`
346 [ $rasize -lt $_sz -o $[rasize*4/5] -gt $_sz ] &&
347 die "size is wrong for $dev: $cnt * $dvsize (chunk=$chunk) = $rasize, not $_sz"
348 return 0
349}
350
351rotest() {
352 dev=$1
353 fsck -fn $dev >&2
354}