Whamcloud - gitweb
LU-10468 tests: sync zfs dataset before reading blocks
[fs/lustre-release.git] / lustre / tests / sanity-flr.sh
1 #!/bin/bash
2 #
3 # Run select tests by setting ONLY, or as arguments to the script.
4 # Skip specific tests by setting EXCEPT.
5 set -e
6 set +o posix
7
8 SRCDIR=$(dirname $0)
9 export PATH=$PWD/$SRCDIR:$SRCDIR:$PWD/$SRCDIR/../utils:$PATH:/sbin
10
11 ONLY=${ONLY:-"$*"}
12 # Bug number for skipped test:
13 ALWAYS_EXCEPT="$SANITY_FLR_EXCEPT 201"
14 # UPDATE THE COMMENT ABOVE WITH BUG NUMBERS WHEN CHANGING ALWAYS_EXCEPT!
15
16 LUSTRE=${LUSTRE:-$(cd $(dirname $0)/..; echo $PWD)}
17 . $LUSTRE/tests/test-framework.sh
18 init_test_env $@
19 . ${CONFIG:=$LUSTRE/tests/cfg/$NAME.sh}
20 init_logging
21
22 [ $UID -eq 0 -a $RUNAS_ID -eq 0 ] &&
23         error "\$RUNAS_ID set to 0, but \$UID is also 0!"
24 check_runas_id $RUNAS_ID $RUNAS_GID $RUNAS
25
26 check_and_setup_lustre
27 DIR=${DIR:-$MOUNT}
28 assert_DIR
29
30 build_test_filter
31
32 # global array to store mirror IDs
33 declare -a mirror_array
34 get_mirror_ids() {
35         local tf=$1
36         local id
37         local array
38
39         array=()
40         for id in $($LFS getstripe $tf | awk '/lcme_id/{print $2}'); do
41                 array[${#array[@]}]=$((id >> 16))
42         done
43
44         mirror_array=($(printf "%s\n" "${array[@]}" | sort -u))
45
46         echo ${#mirror_array[@]}
47 }
48
49 drop_client_cache() {
50         echo 3 > /proc/sys/vm/drop_caches
51 }
52
53 stop_osts() {
54         local idx
55
56         for idx in "$@"; do
57                 stop ost$idx
58         done
59
60         for idx in "$@"; do
61                 wait_osc_import_state client ost$idx DISCONN
62         done
63 }
64
65 start_osts() {
66         local idx
67
68         for idx in "$@"; do
69                 start ost$idx $(ostdevname $idx) $OST_MOUNT_OPTS ||
70                         error "start ost$idx failed"
71         done
72
73         for idx in "$@"; do
74                 wait_osc_import_state client ost$idx FULL
75         done
76 }
77
78 #
79 # Verify mirror count with an expected value for a given file.
80 #
81 verify_mirror_count() {
82         local tf=$1
83         local expected=$2
84         local mirror_count=$(get_mirror_ids $tf)
85
86         [[ $mirror_count = $expected ]] || {
87                 $LFS getstripe -v $tf
88                 error "verify mirror count failed on $tf:" \
89                       "$mirror_count != $expected"
90         }
91 }
92
93 #
94 # Verify component count with an expected value for a given file.
95 #       $1 coposited layout file
96 #       $2 expected component number
97 #
98 verify_comp_count() {
99         local tf=$1
100         local expected=$2
101         local comp_count=$($LFS getstripe --component-count $tf)
102
103         [[ $comp_count = $expected ]] || {
104                 $LFS getstripe -v $tf
105                 error "verify component count failed on $tf:" \
106                       "$comp_count != $expected"
107         }
108 }
109
110 #
111 # Verify component attribute with an expected value for a given file
112 # and component ID.
113 #
114 verify_comp_attr() {
115         local attr=$1
116         local tf=$2
117         local comp_id=$3
118         local expected=$4
119         local cmd="$LFS getstripe -I$comp_id"
120         local getstripe_cmd="$cmd -v"
121         local value
122
123         case $attr in
124                 stripe-size) cmd+=" -S $tf" ;;
125                 stripe-count) cmd+=" -c $tf" ;;
126                 stripe-index) cmd+=" -i $tf" ;;
127                 pool) cmd+=" -p $tf" ;;
128                 comp-start) cmd+=" --component-start $tf" ;;
129                 comp-end) cmd+=" --component-end $tf" ;;
130                 lcme_flags) cmd+=" $tf | awk '/lcme_flags:/ { print \$2 }'" ;;
131                 *) error "invalid attribute $attr";;
132         esac
133
134         value=$(eval $cmd)
135
136         [[ $value = $expected ]] || {
137                 $getstripe_cmd $tf
138                 error "verify $attr failed on $tf: $value != $expected"
139         }
140 }
141
142 #
143 # Verify component extent with expected start and end extent values
144 # for a given file and component ID.
145 #
146 verify_comp_extent() {
147         local tf=$1
148         local comp_id=$2
149         local expected_start=$3
150         local expected_end=$4
151
152         verify_comp_attr comp-start $tf $comp_id $expected_start
153         verify_comp_attr comp-end $tf $comp_id $expected_end
154 }
155
156 #
157 # Verify component attribute with parent directory for a given file
158 # and component ID.
159 #
160 verify_comp_attr_with_parent() {
161         local attr=$1
162         local tf=$2
163         local comp_id=$3
164         local td=$(cd $(dirname $tf); echo $PWD)
165         local tf_cmd="$LFS getstripe -I$comp_id"
166         local td_cmd="$LFS getstripe"
167         local opt
168         local expected
169         local value
170
171         case $attr in
172                 stripe-size) opt="-S" ;;
173                 stripe-count) opt="-c" ;;
174                 pool) opt="-p" ;;
175                 *) error "invalid attribute $attr";;
176         esac
177
178         expected=$($td_cmd $opt $td)
179         [[ $expected = -1 ]] && expected=$OSTCOUNT
180
181         value=$($tf_cmd $opt $tf)
182         [[ $value = -1 ]] && value=$OSTCOUNT
183
184         [[ $value = $expected ]] || {
185                 $td_cmd -d $td
186                 $tf_cmd -v $tf
187                 error "verify $attr failed with parent on $tf:" \
188                       "$value != $expected"
189         }
190 }
191
192 #
193 # Verify component attributes with parent directory for a given file
194 # and component ID.
195 #
196 # This will only verify the inherited attributes:
197 # stripe size, stripe count and OST pool name
198 #
199 verify_comp_attrs_with_parent() {
200         local tf=$1
201         local comp_id=$2
202
203         verify_comp_attr_with_parent stripe-size $tf $comp_id
204         verify_comp_attr_with_parent stripe-count $tf $comp_id
205         verify_comp_attr_with_parent pool $tf $comp_id
206 }
207
208 # command line test cases
209 test_0a() {
210         local td=$DIR/$tdir
211         local tf=$td/$tfile
212         local mirror_count=16 # LUSTRE_MIRROR_COUNT_MAX
213         local mirror_cmd="$LFS mirror create"
214         local id
215         local ids
216         local i
217
218         # create parent directory
219         mkdir $td || error "mkdir $td failed"
220
221         $mirror_cmd $tf &> /dev/null && error "miss -N option"
222
223         $mirror_cmd -N $tf || error "create mirrored file $tf failed"
224         verify_mirror_count $tf 1
225         id=$($LFS getstripe -I $tf)
226         verify_comp_attrs_with_parent $tf $id
227         verify_comp_extent $tf $id 0 EOF
228
229         $mirror_cmd -N0 $tf-1 &> /dev/null && error "invalid mirror count 0"
230         $mirror_cmd -N$((mirror_count + 1)) $tf-1 &> /dev/null &&
231                 error "invalid mirror count $((mirror_count + 1))"
232
233         $mirror_cmd -N$mirror_count $tf-1 ||
234                 error "create mirrored file $tf-1 failed"
235         verify_mirror_count $tf-1 $mirror_count
236         ids=($($LFS getstripe $tf-1 | awk '/lcme_id/{print $2}' | tr '\n' ' '))
237         for ((i = 0; i < $mirror_count; i++)); do
238                 verify_comp_attrs_with_parent $tf-1 ${ids[$i]}
239                 verify_comp_extent $tf-1 ${ids[$i]} 0 EOF
240         done
241
242         $mirror_cmd -N -N2 -N3 -N4 $tf-2 ||
243                 error "create mirrored file $tf-2 failed"
244         verify_mirror_count $tf-2 10
245         ids=($($LFS getstripe $tf-2 | awk '/lcme_id/{print $2}' | tr '\n' ' '))
246         for ((i = 0; i < 10; i++)); do
247                 verify_comp_attrs_with_parent $tf-2 ${ids[$i]}
248                 verify_comp_extent $tf-2 ${ids[$i]} 0 EOF
249         done
250 }
251 run_test 0a "lfs mirror create with -N option"
252
253 test_0b() {
254         [[ $OSTCOUNT -lt 4 ]] && skip "need >= 4 OSTs" && return
255
256         local td=$DIR/$tdir
257         local tf=$td/$tfile
258         local mirror_cmd="$LFS mirror create"
259         local ids
260         local i
261
262         # create parent directory
263         mkdir $td || error "mkdir $td failed"
264
265         # create a mirrored file with plain layout mirrors
266         $mirror_cmd -N -S 4M -c 2 -p flash -i 2 -o 2,3 \
267                     -N -S 16M -N -c -1 -N -p archive -N --parent $tf ||
268                 error "create mirrored file $tf failed"
269         verify_mirror_count $tf 5
270         ids=($($LFS getstripe $tf | awk '/lcme_id/{print $2}' | tr '\n' ' '))
271         for ((i = 0; i < 5; i++)); do
272                 verify_comp_extent $tf ${ids[$i]} 0 EOF
273         done
274
275         # verify component ${ids[0]}
276         verify_comp_attr stripe-size $tf ${ids[0]} 4194304
277         verify_comp_attr stripe-count $tf ${ids[0]} 2
278         verify_comp_attr stripe-index $tf ${ids[0]} 2
279         verify_comp_attr pool $tf ${ids[0]} flash
280
281         # verify component ${ids[1]}
282         verify_comp_attr stripe-size $tf ${ids[1]} 16777216
283         verify_comp_attr stripe-count $tf ${ids[1]} 2
284         verify_comp_attr pool $tf ${ids[1]} flash
285
286         # verify component ${ids[2]}
287         verify_comp_attr stripe-size $tf ${ids[2]} 16777216
288         verify_comp_attr stripe-count $tf ${ids[2]} $OSTCOUNT
289         verify_comp_attr pool $tf ${ids[2]} flash
290
291         # verify component ${ids[3]}
292         verify_comp_attr stripe-size $tf ${ids[3]} 16777216
293         verify_comp_attr stripe-count $tf ${ids[3]} $OSTCOUNT
294         verify_comp_attr pool $tf ${ids[3]} archive
295
296         # verify component ${ids[4]}
297         verify_comp_attrs_with_parent $tf ${ids[4]}
298 }
299 run_test 0b "lfs mirror create plain layout mirrors"
300
301 test_0c() {
302         [[ $OSTCOUNT -lt 4 ]] && skip "need >= 4 OSTs" && return
303
304         local td=$DIR/$tdir
305         local tf=$td/$tfile
306         local mirror_cmd="$LFS mirror create"
307         local ids
308         local i
309
310         # create parent directory
311         mkdir $td || error "mkdir $td failed"
312
313         # create a mirrored file with composite layout mirrors
314         $mirror_cmd -N2 -E 4M -c 2 -p flash -i 1 -o 1,3 -E eof -S 4M \
315                     -N --parent \
316                     -N3 -E 512M -S 16M -p archive -E -1 -i -1 -c -1 $tf ||
317                 error "create mirrored file $tf failed"
318         verify_mirror_count $tf 6
319         ids=($($LFS getstripe $tf | awk '/lcme_id/{print $2}' | tr '\n' ' '))
320
321         # verify components ${ids[0]} and ${ids[2]}
322         for i in 0 2; do
323                 verify_comp_attr_with_parent stripe-size $tf ${ids[$i]}
324                 verify_comp_attr stripe-count $tf ${ids[$i]} 2
325                 verify_comp_attr stripe-index $tf ${ids[$i]} 1
326                 verify_comp_attr pool $tf ${ids[$i]} flash
327                 verify_comp_extent $tf ${ids[$i]} 0 4194304
328         done
329
330         # verify components ${ids[1]} and ${ids[3]}
331         for i in 1 3; do
332                 verify_comp_attr stripe-size $tf ${ids[$i]} 4194304
333                 verify_comp_attr stripe-count $tf ${ids[$i]} 2
334                 verify_comp_attr pool $tf ${ids[$i]} flash
335                 verify_comp_extent $tf ${ids[$i]} 4194304 EOF
336         done
337
338         # verify component ${ids[4]}
339         verify_comp_attrs_with_parent $tf ${ids[4]}
340         verify_comp_extent $tf ${ids[4]} 0 EOF
341
342         # verify components ${ids[5]}, ${ids[7]} and ${ids[9]}
343         for i in 5 7 9; do
344                 verify_comp_attr stripe-size $tf ${ids[$i]} 16777216
345                 verify_comp_attr_with_parent stripe-count $tf ${ids[$i]}
346                 verify_comp_attr pool $tf ${ids[$i]} archive
347                 verify_comp_extent $tf ${ids[$i]} 0 536870912
348         done
349
350         # verify components ${ids[6]}, ${ids[8]} and ${ids[10]}
351         for i in 6 8 10; do
352                 verify_comp_attr stripe-size $tf ${ids[$i]} 16777216
353                 verify_comp_attr stripe-count $tf ${ids[$i]} -1
354                 verify_comp_attr pool $tf ${ids[$i]} archive
355                 verify_comp_extent $tf ${ids[$i]} 536870912 EOF
356         done
357 }
358 run_test 0c "lfs mirror create composite layout mirrors"
359
360 test_0d() {
361         local td=$DIR/$tdir
362         local tf=$td/$tfile
363         local mirror_count=16 # LUSTRE_MIRROR_COUNT_MAX
364         local mirror_cmd="$LFS mirror extend"
365         local ids
366         local i
367
368         # create parent directory
369         mkdir $td || error "mkdir $td failed"
370
371         $mirror_cmd $tf &> /dev/null && error "miss -N option"
372         $mirror_cmd -N $tf &> /dev/null && error "$tf does not exist"
373
374         # create a non-mirrored file, convert it to a mirrored file and extend
375         touch $tf || error "touch $tf failed"
376         $mirror_cmd -N $tf || error "convert and extend $tf failed"
377         verify_mirror_count $tf 2
378         ids=($($LFS getstripe $tf | awk '/lcme_id/{print $2}' | tr '\n' ' '))
379         for ((i = 0; i < 2; i++)); do
380                 verify_comp_attrs_with_parent $tf ${ids[$i]}
381                 verify_comp_extent $tf ${ids[$i]} 0 EOF
382         done
383
384         lfsck_verify_pfid $tf || error "PFID is not set"
385
386         # create a mirrored file and extend it
387         $LFS mirror create -N $tf-1 || error "create mirrored file $tf-1 failed"
388         $LFS mirror create -N $tf-2 || error "create mirrored file $tf-2 failed"
389
390         $mirror_cmd -N -S 4M -N -f $tf-2 $tf-1 &> /dev/null &&
391                 error "setstripe options should not be specified with -f option"
392
393         $mirror_cmd -N -f $tf-2 -N --parent $tf-1 &> /dev/null &&
394                 error "--parent option should not be specified with -f option"
395
396         $mirror_cmd -N$((mirror_count - 1)) $tf-1 ||
397                 error "extend mirrored file $tf-1 failed"
398         verify_mirror_count $tf-1 $mirror_count
399         ids=($($LFS getstripe $tf-1 | awk '/lcme_id/{print $2}' | tr '\n' ' '))
400         for ((i = 0; i < $mirror_count; i++)); do
401                 verify_comp_attrs_with_parent $tf-1 ${ids[$i]}
402                 verify_comp_extent $tf-1 ${ids[$i]} 0 EOF
403         done
404
405         $mirror_cmd -N $tf-1 &> /dev/null &&
406                 error "exceeded maximum mirror count $mirror_count" || true
407 }
408 run_test 0d "lfs mirror extend with -N option"
409
410 test_0e() {
411         [[ $OSTCOUNT -lt 4 ]] && skip "need >= 4 OSTs" && return
412
413         local td=$DIR/$tdir
414         local tf=$td/$tfile
415         local mirror_cmd="$LFS mirror extend"
416         local ids
417         local i
418
419         # create parent directory
420         mkdir $td || error "mkdir $td failed"
421
422         # create a mirrored file with plain layout mirrors
423         $LFS mirror create -N -S 32M -c 3 -p ssd -i 1 -o 1,2,3 $tf ||
424                 error "create mirrored file $tf failed"
425
426         # extend the mirrored file with plain layout mirrors
427         $mirror_cmd -N -S 4M -c 2 -p flash -i 2 -o 2,3 \
428                     -N -S 16M -N -c -1 -N -p archive -N --parent $tf ||
429                 error "extend mirrored file $tf failed"
430         verify_mirror_count $tf 6
431         ids=($($LFS getstripe $tf | awk '/lcme_id/{print $2}' | tr '\n' ' '))
432         for ((i = 0; i < 6; i++)); do
433                 verify_comp_extent $tf ${ids[$i]} 0 EOF
434         done
435
436         # verify component ${ids[0]}
437         verify_comp_attr stripe-size $tf ${ids[0]} 33554432
438         verify_comp_attr stripe-count $tf ${ids[0]} 3
439         verify_comp_attr stripe-index $tf ${ids[0]} 1
440         verify_comp_attr pool $tf ${ids[0]} ssd
441
442         # verify component ${ids[1]}
443         verify_comp_attr stripe-size $tf ${ids[1]} 4194304
444         verify_comp_attr stripe-count $tf ${ids[1]} 2
445         verify_comp_attr stripe-index $tf ${ids[1]} 2
446         verify_comp_attr pool $tf ${ids[1]} flash
447
448         # verify component ${ids[2]}
449         verify_comp_attr stripe-size $tf ${ids[2]} 16777216
450         verify_comp_attr stripe-count $tf ${ids[2]} 2
451         verify_comp_attr pool $tf ${ids[2]} flash
452
453         # verify component ${ids[3]}
454         verify_comp_attr stripe-size $tf ${ids[3]} 16777216
455         verify_comp_attr stripe-count $tf ${ids[3]} $OSTCOUNT
456         verify_comp_attr pool $tf ${ids[3]} flash
457
458         # verify component ${ids[4]}
459         verify_comp_attr stripe-size $tf ${ids[4]} 16777216
460         verify_comp_attr stripe-count $tf ${ids[4]} $OSTCOUNT
461         verify_comp_attr pool $tf ${ids[4]} archive
462
463         # verify component ${ids[5]}
464         verify_comp_attrs_with_parent $tf ${ids[5]}
465 }
466 run_test 0e "lfs mirror extend plain layout mirrors"
467
468 test_0f() {
469         [[ $OSTCOUNT -lt 4 ]] && skip "need >= 4 OSTs" && return
470
471         local td=$DIR/$tdir
472         local tf=$td/$tfile
473         local mirror_cmd="$LFS mirror extend"
474         local ids
475         local i
476
477         # create parent directory
478         mkdir $td || error "mkdir $td failed"
479
480         # create a mirrored file with composite layout mirror
481         $LFS mirror create -N -E 32M -S 16M -p ssd -E eof -S 32M $tf ||
482                 error "create mirrored file $tf failed"
483
484         # extend the mirrored file with composite layout mirrors
485         $mirror_cmd -N2 -E 4M -c 2 -p flash -i 1 -o 1,3 -E eof -S 4M \
486                     -N --parent \
487                     -N3 -E 512M -S 16M -p archive -E -1 -i -1 -c -1 $tf ||
488                 error "extend mirrored file $tf failed"
489         verify_mirror_count $tf 7
490         ids=($($LFS getstripe $tf | awk '/lcme_id/{print $2}' | tr '\n' ' '))
491
492         # verify component ${ids[0]}
493         verify_comp_attr stripe-size $tf ${ids[0]} 16777216
494         verify_comp_attr_with_parent stripe-count $tf ${ids[0]}
495         verify_comp_attr pool $tf ${ids[0]} ssd
496         verify_comp_extent $tf ${ids[0]} 0 33554432
497
498         # verify component ${ids[1]}
499         verify_comp_attr stripe-size $tf ${ids[1]} 33554432
500         verify_comp_attr_with_parent stripe-count $tf ${ids[1]}
501         verify_comp_attr pool $tf ${ids[1]} ssd
502         verify_comp_extent $tf ${ids[1]} 33554432 EOF
503
504         # verify components ${ids[2]} and ${ids[4]}
505         for i in 2 4; do
506                 verify_comp_attr_with_parent stripe-size $tf ${ids[$i]}
507                 verify_comp_attr stripe-count $tf ${ids[$i]} 2
508                 verify_comp_attr stripe-index $tf ${ids[$i]} 1
509                 verify_comp_attr pool $tf ${ids[$i]} flash
510                 verify_comp_extent $tf ${ids[$i]} 0 4194304
511         done
512
513         # verify components ${ids[3]} and ${ids[5]}
514         for i in 3 5; do
515                 verify_comp_attr stripe-size $tf ${ids[$i]} 4194304
516                 verify_comp_attr stripe-count $tf ${ids[$i]} 2
517                 verify_comp_attr pool $tf ${ids[$i]} flash
518                 verify_comp_extent $tf ${ids[$i]} 4194304 EOF
519         done
520
521         # verify component ${ids[6]}
522         verify_comp_attrs_with_parent $tf ${ids[6]}
523         verify_comp_extent $tf ${ids[6]} 0 EOF
524
525         # verify components ${ids[7]}, ${ids[9]} and ${ids[11]}
526         for i in 7 9 11; do
527                 verify_comp_attr stripe-size $tf ${ids[$i]} 16777216
528                 verify_comp_attr_with_parent stripe-count $tf ${ids[$i]}
529                 verify_comp_attr pool $tf ${ids[$i]} archive
530                 verify_comp_extent $tf ${ids[$i]} 0 536870912
531         done
532
533         # verify components ${ids[8]}, ${ids[10]} and ${ids[12]}
534         for i in 8 10 12; do
535                 verify_comp_attr stripe-size $tf ${ids[$i]} 16777216
536                 verify_comp_attr stripe-count $tf ${ids[$i]} -1
537                 verify_comp_attr pool $tf ${ids[$i]} archive
538                 verify_comp_extent $tf ${ids[$i]} 536870912 EOF
539         done
540 }
541 run_test 0f "lfs mirror extend composite layout mirrors"
542
543 test_1() {
544         local tf=$DIR/$tfile
545         local mirror_count=16 # LUSTRE_MIRROR_COUNT_MAX
546         local mirror_create_cmd="$LFS mirror create"
547         local stripes[0]=$OSTCOUNT
548
549         mirror_create_cmd+=" -N -c ${stripes[0]}"
550         for ((i = 1; i < $mirror_count; i++)); do
551                 # add mirrors with different stripes to the file
552                 stripes[$i]=$((RANDOM % OSTCOUNT))
553                 [ ${stripes[$i]} -eq 0 ] && stripes[$i]=1
554
555                 mirror_create_cmd+=" -N -c ${stripes[$i]}"
556         done
557
558         $mirror_create_cmd $tf || error "create mirrored file $tf failed"
559         verify_mirror_count $tf $mirror_count
560
561         # can't create mirrors exceeding LUSTRE_MIRROR_COUNT_MAX
562         $LFS mirror extend -N $tf &&
563                 error "Creating the $((mirror_count+1))th mirror succeeded"
564
565         local ids=($($LFS getstripe $tf | awk '/lcme_id/{print $2}' |
566                         tr '\n' ' '))
567
568         # verify the range of components and stripe counts
569         for ((i = 0; i < $mirror_count; i++)); do
570                 verify_comp_attr stripe-count $tf ${ids[$i]} ${stripes[$i]}
571                 verify_comp_extent $tf ${ids[$i]} 0 EOF
572         done
573 }
574 run_test 1 "create components with setstripe options"
575
576 test_2() {
577         local tf=$DIR/$tfile
578         local tf2=$DIR/$tfile-2
579
580         $LFS setstripe -E 1M -E EOF -c 1 $tf
581         $LFS setstripe -E 2M -E EOF -c -1 $tf2
582
583         local layout=$($LFS getstripe $tf2 | grep -A 4 lmm_objects)
584
585         $LFS mirror extend -N -f $tf2 $tf ||
586                 error "merging $tf2 into $tf failed"
587
588         verify_mirror_count $tf 2
589         [[ ! -e $tf2 ]] || error "$tf2 was not unlinked"
590 }
591 run_test 2 "create components from existing files"
592
593 test_3() {
594         [[ $MDSCOUNT -lt 2 ]] && skip "need >= 2 MDTs" && return
595
596         for ((i = 0; i < 2; i++)); do
597                 $LFS mkdir -i $i $DIR/$tdir-$i
598                 $LFS setstripe -E -1 $DIR/$tdir-$i/$tfile
599         done
600
601         $LFS mirror extend -N -f $DIR/$tdir-1/$tfile \
602                 $DIR/$tdir-0/$tfile || error "creating mirrors"
603
604         # mdt doesn't support to cancel layout lock for remote objects, do
605         # it here manually.
606         cancel_lru_locks mdc
607
608         # make sure the mirrorted file was created successfully
609         [[ $($LFS getstripe --component-count $DIR/$tdir-0/$tfile) -eq 2 ]] ||
610                 { $LFS getstripe $DIR/$tdir-0/$tfile;
611                         error "expected 2 components"; }
612
613         # cleanup
614         rm -rf $DIR/$tdir-*
615 }
616 run_test 3 "create components from files located on different MDTs"
617
618 test_4() {
619         local tf=$DIR/$tdir/$tfile
620         local ids=()
621
622         test_mkdir $DIR/$tdir
623
624         # set mirror with setstripe options to directory
625         $LFS mirror create -N2 -E 1M -E eof $DIR/$tdir ||
626                 error "set mirror to directory error"
627
628         [ x$($LFS getstripe -v $DIR/$tdir | awk '/lcm_flags/{print $2}') = \
629                 x"mirrored" ] || error "failed to create mirrored dir"
630
631         touch $tf
632         verify_mirror_count $tf 2
633
634         ids=($($LFS getstripe $tf | awk '/lcme_id/{print $2}' | tr '\n' ' '))
635         verify_comp_extent $tf ${ids[0]} 0 1048576
636         verify_comp_extent $tf ${ids[1]} 1048576 EOF
637
638         # sub directory should inherit mirror setting from parent
639         test_mkdir $DIR/$tdir/td
640         [ x$($LFS getstripe -v $DIR/$tdir/td | awk '/lcm_flags/{print $2}') = \
641                 x"mirrored" ] || error "failed to inherit mirror from parent"
642
643         # mirror extend won't be applied to directory
644         $LFS mirror extend -N2 $DIR/$tdir &&
645                 error "expecting mirror extend failure"
646         true
647 }
648 run_test 4 "Make sure mirror attributes can be inhertied from directory"
649
650 test_5() {
651         local tf=$DIR/$tfile
652         local ids=()
653
654         $MULTIOP $tf oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T12345c ||
655                 error "failed to create file with non-empty layout"
656         $CHECKSTAT -t file -s 12345 $tf || error "size error: expecting 12345"
657
658         $LFS mirror create -N3 $tf || error "failed to attach mirror layout"
659         verify_mirror_count $tf 3
660
661         $CHECKSTAT -t file -s 12345 $tf ||
662                 error "size error after attaching layout "
663 }
664 run_test 5 "Make sure init size work for mirrored layout"
665
666 # LU=10112: disable dom+flr for phase 1
667 test_6() {
668         local tf=$DIR/$tfile
669
670         $LFS mirror create -N -E 1M -L mdt -E eof -N -E eof $tf &&
671                 error "expect failure to create mirrored file with DoM"
672
673         $LFS mirror create -N -E 1M -E eof -N -E 1M -L mdt -E eof $tf &&
674                 error "expect failure to create mirrored file with DoM"
675
676         $LFS setstripe -E 1M -L mdt -E eof $tf
677         $LFS mirror extend -N2 $tf &&
678                 error "expect failure to extend mirror with DoM"
679
680         $LFS mirror create -N2 -E 1M -E eof $tf-2
681         $LFS mirror extend -N -f $tf $tf-2 &&
682                 error "expect failure to extend mirrored file with DoM extent"
683
684         true
685 }
686 run_test 6 "DoM and FLR won't co-exist for phase 1"
687
688 test_21() {
689         local tf=$DIR/$tfile
690         local tf2=$DIR/$tfile-2
691
692         [[ $OSTCOUNT -lt 2 ]] && skip "need >= 2 OSTs" && return
693
694         $LFS setstripe -E EOF -o 0 $tf
695         $LFS setstripe -E EOF -o 1 $tf2
696
697         local dd_count=$((RANDOM % 20 + 1))
698         dd if=/dev/zero of=$tf bs=1M count=$dd_count oflag=sync
699         dd if=/dev/zero of=$tf2 bs=1M count=1 seek=$((dd_count - 1)) oflag=sync
700
701         # for zfs - sync OST dataset so that du below will return
702         # accurate results
703         [ "$FSTYPE" = "zfs" ] &&
704                 do_nodes $(comma_list $(osts_nodes)) "$ZPOOL sync"
705
706         local blocks=$(du -kc $tf $tf2 | awk '/total/{print $1}')
707
708         # add component
709         $LFS mirror extend -N -f $tf2 $tf ||
710                 error "merging $tf2 into $tf failed"
711
712         # cancel layout lock
713         cancel_lru_locks mdc
714
715         local new_blocks=$(du -k $tf | awk '{print $1}')
716         [ $new_blocks -eq $blocks ] ||
717         error "i_blocks error expected: $blocks, actual: $new_blocks"
718 }
719 run_test 21 "glimpse should report accurate i_blocks"
720
721 get_osc_lock_count() {
722         local lock_count=0
723
724         for idx in "$@"; do
725                 local osc_name
726                 local count
727
728                 osc_name=${FSNAME}-OST$(printf "%04x" $((idx-1)))-osc-'ffff*'
729                 count=$($LCTL get_param -n ldlm.namespaces.$osc_name.lock_count)
730                 lock_count=$((lock_count + count))
731         done
732         echo $lock_count
733 }
734
735 test_22() {
736         local tf=$DIR/$tfile
737
738         $LFS setstripe -E EOF -o 0 $tf
739         dd if=/dev/zero of=$tf bs=1M count=$((RANDOM % 20 + 1))
740
741         # add component, two mirrors located on the same OST ;-)
742         $LFS mirror extend -N -o 0 $tf ||
743                 error "extending mirrored file $tf failed"
744
745         size_blocks=$(stat --format="%b %s" $tf)
746
747         cancel_lru_locks mdc
748         cancel_lru_locks osc
749
750         local new_size_blocks=$(stat --format="%b %s" $tf)
751
752         # make sure there is no lock cached
753         [ $(get_osc_lock_count 1) -eq 0 ] || error "glimpse requests were sent"
754
755         [ "$new_size_blocks" = "$size_blocks" ] ||
756                 echo "size expected: $size_blocks, actual: $new_size_blocks"
757
758         rm -f $tmpfile
759 }
760 run_test 22 "no glimpse to OSTs for READ_ONLY files"
761
762 test_31() {
763         local tf=$DIR/$tfile
764
765         $LFS mirror create -N -o 0 -N -o 1 $tf ||
766                 error "creating mirrored file $tf failed"
767
768         #define OBD_FAIL_GLIMPSE_IMMUTABLE 0x1A00
769         $LCTL set_param fail_loc=0x1A00
770
771         local ost_idx
772         for ((ost_idx = 1; ost_idx <= 2; ost_idx++)); do
773                 cancel_lru_locks osc
774                 stop_osts $ost_idx
775
776                 local tmpfile=$(mktemp)
777                 stat --format="%b %s" $tf > $tmpfile  &
778                 local pid=$!
779
780                 local cnt=0
781                 while [ $cnt -le 5 ]; do
782                         kill -0 $pid > /dev/null 2>&1 || break
783                         sleep 1
784                         ((cnt += 1))
785                 done
786                 kill -0 $pid > /dev/null 2>&1 &&
787                         error "stat process stuck due to unavailable OSTs"
788
789                 # make sure glimpse request has been sent
790                 [ $(get_osc_lock_count 1 2) -ne 0 ] ||
791                         error "OST $ost_idx: no glimpse request was sent"
792
793                 start_osts $ost_idx
794         done
795 }
796 run_test 31 "make sure glimpse request can be retried"
797
798 test_32() {
799         [[ $OSTCOUNT -lt 2 ]] && skip "need >= 2 OSTs" && return
800         rm -f $DIR/$tfile $DIR/$tfile-2
801
802         $LFS setstripe -E EOF -o 0 $DIR/$tfile
803         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=$((RANDOM % 10 + 2))
804
805         local fsize=$(stat -c %s $DIR/$tfile)
806         [[ $fsize -ne 0 ]] || error "file size is (wrongly) zero"
807
808         local cksum=$(md5sum $DIR/$tfile)
809
810         # create a new mirror in sync mode
811         $LFS mirror extend -N -o 1 $DIR/$tfile ||
812                 error "extending mirrored file $DIR/$tfile failed"
813
814         # make sure the mirrored file was created successfully
815         [ $(get_mirror_ids $DIR/$tfile) -eq 2 ] ||
816                 { $LFS getstripe $DIR/$tfile; error "expected 2 mirrors"; }
817
818         drop_client_cache
819         stop_osts 1
820
821         # check size is correct, glimpse request should go to the 2nd mirror
822         $CHECKSTAT -t file -s $fsize $DIR/$tfile ||
823                 error "file size error $fsize vs. $(stat -c %s $DIR/$tfile)"
824
825         echo "reading file from the 2nd mirror and verify checksum"
826         [[ "$cksum" == "$(md5sum $DIR/$tfile)" ]] ||
827                 error "checksum error: expected $cksum"
828
829         start_osts 1
830 }
831 run_test 32 "data should be mirrored to newly created mirror"
832
833 test_33() {
834         [[ $OSTCOUNT -lt 2 ]] && skip "need >= 2 OSTs" && return
835
836         rm -f $DIR/$tfile $DIR/$tfile-2
837
838         # create a file with two mirrors
839         $LFS setstripe -E EOF -o 0 $DIR/$tfile
840         local max_count=100
841         local count=0
842         while [ $count -lt $max_count ]; do
843                 echo "ost1" >> $DIR/$tfile
844                 count=$((count + 1));
845         done
846
847         # tmp file that will be used as mirror
848         $LFS setstripe -E EOF -o 1 $DIR/$tfile-2
849         count=0
850         while [ $count -lt $max_count ]; do
851                 echo "ost2" >> $DIR/$tfile-2
852                 count=$((count + 1));
853         done
854
855         # create a mirrored file
856         $LFS mirror extend -N -f $DIR/$tfile-2 $DIR/$tfile &&
857                 error "merging $DIR/$tfile-2 into $DIR/$tfile" \
858                       "with verification should fail"
859         $LFS mirror extend --no-verify -N -f $DIR/$tfile-2 $DIR/$tfile ||
860                 error "merging $DIR/$tfile-2 into $DIR/$tfile" \
861                       "without verification failed"
862
863         # make sure that $tfile has two mirrors and $tfile-2 does not exist
864         [ $(get_mirror_ids $DIR/$tfile) -eq 2 ] ||
865                 { $LFS getstripe $DIR/$tfile; error "expected count 2"; }
866
867         [[ ! -e $DIR/$tfile-2 ]] || error "$DIR/$tfile-2 was not unlinked"
868
869         # execpted file size
870         local fsize=$((5 * max_count))
871         $CHECKSTAT -t file -s $fsize $DIR/$tfile ||
872                 error "mirrored file size is not $fsize"
873
874         # read file - all OSTs are available
875         echo "reading file (data should be provided by ost1)... "
876         local rs=$(cat $DIR/$tfile | head -1)
877         [[ "$rs" == "ost1" ]] ||
878                 error "file content error: expected: \"ost1\", actual: \"$rs\""
879
880         # read file again with ost1 failed
881         stop_osts 1
882         drop_client_cache
883
884         echo "reading file (data should be provided by ost2)..."
885         local rs=$(cat $DIR/$tfile | head -1)
886         [[ "$rs" == "ost2" ]] ||
887                 error "file content error: expected: \"ost2\", actual: \"$rs\""
888
889         # remount ost1
890         start_osts 1
891
892         # read file again with ost2 failed
893         $LCTL set_param ldlm.namespaces.lustre-*-osc-ffff*.lru_size=clear
894
895         fail ost2 &
896         sleep 1
897
898         # check size, glimpse should work
899         $CHECKSTAT -t file -s $fsize $DIR/$tfile ||
900                 error "mirrored file size is not $fsize"
901
902         echo "reading file (data should be provided by ost1)..."
903         local rs=$(cat $DIR/$tfile | head -1)
904         [[ "$rs" == "ost1" ]] ||
905                 error "file content error: expected: \"ost1\", actual: \"$rs\""
906
907         wait_osc_import_state client ost2 FULL
908 }
909 run_test 33 "read can choose available mirror to read"
910
911 test_34a() {
912         [[ $OSTCOUNT -lt 4 ]] && skip "need >= 4 OSTs" && return
913
914         rm -f $DIR/$tfile $DIR/$tfile-2 $DIR/$tfile-ref
915
916         # reference file
917         $LFS setstripe -o 0 $DIR/$tfile-ref
918         dd if=/dev/urandom of=$DIR/$tfile-ref bs=1M count=3
919
920         # create a file with two mirrors
921         $LFS setstripe -E -1 -o 0,1 -S 1M $DIR/$tfile
922         dd if=$DIR/$tfile-ref of=$DIR/$tfile bs=1M
923
924         $LFS setstripe -E -1 -o 2,3 -S 1M $DIR/$tfile-2
925         dd if=$DIR/$tfile-ref of=$DIR/$tfile-2 bs=1M
926
927         $CHECKSTAT -t file -s $((3 * 1024 * 1024)) $DIR/$tfile ||
928                 error "mirrored file size is not 3M"
929
930         # merge a mirrored file
931         $LFS mirror extend -N -f $DIR/$tfile-2 $DIR/$tfile ||
932                 error "merging $DIR/$tfile-2 into $DIR/$tfile failed"
933
934         cancel_lru_locks osc
935
936         # stop two OSTs, so the 2nd stripe of the 1st mirror and
937         # the 1st stripe of the 2nd mirror will be inaccessible, ...
938         stop_osts 2 3
939
940         echo "comparing files ... "
941
942         # however, read can still return the correct data. It should return
943         # the 1st stripe from mirror 1 and 2st stripe from mirror 2.
944         cmp -n 2097152 <(rwv -f $DIR/$tfile -r -o -n 1 2097152) \
945                 $DIR/$tfile-ref || error "file reading error"
946
947         start_osts 2 3
948 }
949 run_test 34a "read mirrored file with multiple stripes"
950
951 test_34b() {
952         [[ $OSTCOUNT -lt 4 ]] && skip "need >= 4 OSTs" && return
953
954         rm -f $DIR/$tfile $DIR/$tfile-2 $DIR/$tfile-ref
955
956         # reference file
957         $LFS setstripe -o 0 $DIR/$tfile-ref
958         dd if=/dev/urandom of=$DIR/$tfile-ref bs=1M count=3
959
960         $LFS setstripe -E 1M -S 1M -o 0 -E eof -o 1 $DIR/$tfile
961         dd if=$DIR/$tfile-ref of=$DIR/$tfile bs=1M
962
963         $LFS setstripe -E 1M -S 1M -o 2 -E eof -o 3 $DIR/$tfile-2
964         dd if=$DIR/$tfile-ref of=$DIR/$tfile-2 bs=1M
965
966         $CHECKSTAT -t file -s $((3 * 1024 * 1024)) $DIR/$tfile ||
967                 error "mirrored file size is not 3M"
968
969         # merge a mirrored file
970         $LFS mirror extend -N -f $DIR/$tfile-2 $DIR/$tfile ||
971                 error "merging $DIR/$tfile-2 into $DIR/$tfile failed"
972
973         cancel_lru_locks osc
974
975         # stop two OSTs, so the 2nd component of the 1st mirror and
976         # the 1st component of the 2nd mirror will be inaccessible, ...
977         stop_osts 2 3
978
979         echo "comparing files ... "
980
981         # however, read can still return the correct data. It should return
982         # the 1st stripe from mirror 1 and 2st stripe from mirror 2.
983         cmp -n 2097152 <(rwv -f $DIR/$tfile -r -o -n 1 2097152) \
984                 $DIR/$tfile-ref || error "file reading error"
985
986         start_osts 2 3
987 }
988 run_test 34b "read mirrored file with multiple components"
989
990 test_35() {
991         local tf=$DIR/$tfile
992
993         $LFS setstripe -E eof $tf
994
995         # add an out-of-sync mirror to the file
996         $LFS mirror extend -N -c 2 $tf ||
997                 error "extending mirrored file $tf failed"
998
999         $MULTIOP $tf oO_WRONLY:c ||
1000                 error "write open a mirrored file failed"
1001
1002         # truncate file should return error
1003         $TRUNCATE $tf 100 || error "error truncating a mirrored file"
1004 }
1005 run_test 35 "allow to write to mirrored files"
1006
1007 verify_ost_layout_version() {
1008         local tf=$1
1009
1010         # get file layout version
1011         local flv=$($LFS getstripe $tf | awk '/lcm_layout_gen/{print $2}')
1012
1013         # layout version from OST objects
1014         local olv=$($MULTIOP $tf oXc | awk '/ostlayoutversion/{print $2}')
1015
1016         [ $flv -eq $olv ] || error "layout version mismatch: $flv vs. $olv"
1017 }
1018
1019 create_file_36() {
1020         local tf
1021
1022         for tf in "$@"; do
1023                 $LFS setstripe -E 1M -E 2M -E 4M -E eof -c -1 $tf
1024                 $LFS setstripe -E 3M -E 6M -E eof -c -1 $tf-tmp
1025
1026                 $LFS mirror extend -N -f $tf-tmp $tf ||
1027                         error "merging $tf-tmp into $tf failed"
1028         done
1029 }
1030
1031 test_36() {
1032         local tf=$DIR/$tfile
1033
1034         create_file_36 $tf $tf-2 $tf-3
1035
1036         [ $(get_mirror_ids $tf) -gt 1 ] || error "wrong mirror count"
1037
1038         # test case 1 - check file write and verify layout version
1039         $MULTIOP $tf oO_WRONLY:c ||
1040                 error "write open a mirrored file failed"
1041
1042         # write open file should not return error
1043         $MULTIOP $tf oO_WRONLY:w1024Yc || error "write mirrored file error"
1044
1045         # instantiate components should work
1046         dd if=/dev/zero of=$tf bs=1M count=12 || error "write file error"
1047
1048         # verify OST layout version
1049         verify_ost_layout_version $tf
1050
1051         # test case 2
1052         local mds_idx=mds$(($($LFS getstripe -M $tf-2) + 1))
1053
1054         local delay_sec=10
1055         do_facet $mds_idx $LCTL set_param fail_val=$delay_sec
1056
1057         #define OBD_FAIL_FLR_LV_DELAY 0x1A01
1058         do_facet $mds_idx $LCTL set_param fail_loc=0x1A01
1059
1060         # write should take at least $fail_loc seconds and succeed
1061         local st=$(date +%s)
1062         $MULTIOP $tf-2 oO_WRONLY:w1024Yc || error "write mirrored file error"
1063
1064         [ $(date +%s) -ge $((st+delay_sec)) ] ||
1065                 error "write finished before layout version is transmitted"
1066
1067         # verify OST layout version
1068         verify_ost_layout_version $tf
1069
1070         do_facet $mds_idx $LCTL set_param fail_loc=0
1071
1072         # test case 3
1073         mds_idx=mds$(($($LFS getstripe -M $tf-3) + 1))
1074
1075         #define OBD_FAIL_FLR_LV_INC 0x1A02
1076         do_facet $mds_idx $LCTL set_param fail_loc=0x1A02
1077
1078         # write open file should return error
1079         $MULTIOP $tf-3 oO_WRONLY:O_SYNC:w1024c &&
1080                 error "write a mirrored file succeeded" || true
1081
1082         do_facet $mds_idx $LCTL set_param fail_loc=0
1083 }
1084 run_test 36 "write to mirrored files"
1085
1086 create_files_37() {
1087         local tf
1088         local fsize=$1
1089
1090         echo "create test files with size $fsize .."
1091
1092         shift
1093         for tf in "$@"; do
1094                 $LFS setstripe -E 1M -c 1 -E eof -c -1 $tf
1095
1096                 dd if=/dev/urandom of=$tf bs=1M count=16 &> /dev/null
1097                 $TRUNCATE $tf $fsize
1098         done
1099 }
1100
1101 test_37()
1102 {
1103         local tf=$DIR/$tfile
1104         local tf2=$DIR/$tfile-2
1105         local tf3=$DIR/$tfile-3
1106
1107         create_files_37 $((RANDOM + 15 * 1048576)) $tf $tf2 $tf3
1108
1109         # assume the mirror id will be 1, 2, and 3
1110         declare -A checksums
1111         checksums[1]=$(md5sum $tf | cut -f 1 -d' ')
1112         checksums[2]=$(md5sum $tf2 | cut -f 1 -d' ')
1113         checksums[3]=$(md5sum $tf3 | cut -f 1 -d' ')
1114
1115         printf '%s\n' "${checksums[@]}"
1116
1117         # merge these files into a mirrored file
1118         $LFS mirror extend --no-verify -N -f $tf2 $tf ||
1119                 error "merging $tf2 into $tf failed"
1120         $LFS mirror extend --no-verify -N -f $tf3 $tf ||
1121                 error "merging $tf3 into $tf failed"
1122
1123         get_mirror_ids $tf
1124
1125         # verify mirror read, checksums should equal to the original files'
1126         echo "Verifying mirror read .."
1127
1128         local sum
1129         for i in ${mirror_array[@]}; do
1130                 sum=$(mirror_io dump -i $i $tf | md5sum | cut -f 1 -d' ')
1131                 [ "$sum" = "${checksums[$i]}" ] ||
1132                         error "$i: mismatch: \'${checksums[$i]}\' vs. \'$sum\'"
1133         done
1134
1135         # verify mirror copy, write to this mirrored file will invalidate
1136         # the other two mirrors
1137         echo "Verifying mirror copy .."
1138
1139         local osts=$(comma_list $(osts_nodes))
1140
1141         # define OBD_FAIL_OST_SKIP_LV_CHECK     0x241
1142         do_nodes $osts lctl set_param fail_loc=0x241
1143
1144         mirror_io copy -i ${mirror_array[0]} \
1145                 -t $(echo ${mirror_array[@]:1} | tr ' ' ',') $tf ||
1146                         error "mirror copy error"
1147
1148         do_nodes $osts lctl set_param fail_loc=0
1149
1150         # verify copying is successful by checking checksums
1151         remount_client $MOUNT
1152         for i in ${mirror_array[@]}; do
1153                 sum=$(mirror_io dump -i $i $tf | md5sum | cut -f 1 -d' ')
1154                 [ "$sum" = "${checksums[1]}" ] ||
1155                         error "$i: mismatch checksum after copy"
1156         done
1157
1158         rm -f $tf
1159 }
1160 run_test 37 "mirror I/O API verification"
1161
1162 verify_flr_state()
1163 {
1164         local tf=$1
1165         local expected_state=$2
1166
1167         local state=$($LFS getstripe -v $tf | awk '/lcm_flags/{ print $2 }')
1168         [ $expected_state = $state ] ||
1169                 error "expected: $expected_state, actual $state"
1170 }
1171
1172 test_38() {
1173         local tf=$DIR/$tfile
1174         local ref=$DIR/${tfile}-ref
1175
1176         $LFS setstripe -E 1M -c 1 -E 4M -c 2 -E eof -c -1 $tf
1177         $LFS setstripe -E 2M -c 1 -E 6M -c 2 -E 8M -c -1 -E eof -c -1 $tf-2
1178         $LFS setstripe -E 4M -c 1 -E 8M -c 2 -E eof -c -1 $tf-3
1179
1180         # instantiate all components
1181         $LFS mirror extend -N -f $tf-2 $tf ||
1182                 error "merging $tf-2 into $tf failed"
1183         $LFS mirror extend -N -f $tf-3 $tf ||
1184                 error "merging $tf-3 into $tf failed"
1185         $LFS mirror extend -N -c 1 $tf ||
1186                 error "extending mirrored file $tf failed"
1187
1188         verify_flr_state $tf "ro"
1189
1190         dd if=/dev/urandom of=$ref  bs=1M count=16 &> /dev/null
1191
1192         local fsize=$((RANDOM << 8 + 1048576))
1193         $TRUNCATE $ref $fsize
1194
1195         local ref_cksum=$(md5sum $ref | cut -f 1 -d' ')
1196
1197         # case 1: verify write to mirrored file & resync work
1198         cp $ref $tf || error "copy from $ref to $f error"
1199         verify_flr_state $tf "wp"
1200
1201         local file_cksum=$(md5sum $tf | cut -f 1 -d' ')
1202         [ "$file_cksum" = "$ref_cksum" ] || error "write failed, cksum mismatch"
1203
1204         get_mirror_ids $tf
1205         echo "mirror IDs: ${mirror_array[@]}"
1206
1207         local valid_mirror stale_mirror id mirror_cksum
1208         for id in "${mirror_array[@]}"; do
1209                 mirror_cksum=$(mirror_io dump -i $id $tf |
1210                                 md5sum | cut -f 1 -d' ')
1211                 [ "$ref_cksum" == "$mirror_cksum" ] &&
1212                         { valid_mirror=$id; continue; }
1213
1214                 stale_mirror=$id
1215         done
1216
1217         [ -z "$stale_mirror" ] && error "stale mirror doesn't exist"
1218         [ -z "$valid_mirror" ] && error "valid mirror doesn't exist"
1219
1220         mirror_io resync $tf || error "resync failed"
1221         verify_flr_state $tf "ro"
1222
1223         mirror_cksum=$(mirror_io dump -i $stale_mirror $tf |
1224                         md5sum | cut -f 1 -d' ')
1225         [ "$file_cksum" = "$ref_cksum" ] || error "resync failed"
1226
1227         # case 2: inject an error to make mirror_io exit after changing
1228         # the file state to sync_pending so that we can start a concurrent
1229         # write.
1230         $MULTIOP $tf oO_WRONLY:w$((RANDOM % 1048576 + 1024))c
1231         verify_flr_state $tf "wp"
1232
1233         mirror_io resync -e resync_start $tf && error "resync succeeded"
1234         verify_flr_state $tf "sp"
1235
1236         # from sync_pending to write_pending
1237         $MULTIOP $tf oO_WRONLY:w$((RANDOM % 1048576 + 1024))c
1238         verify_flr_state $tf "wp"
1239
1240         mirror_io resync -e resync_start $tf && error "resync succeeded"
1241         verify_flr_state $tf "sp"
1242
1243         # from sync_pending to read_only
1244         mirror_io resync $tf || error "resync failed"
1245         verify_flr_state $tf "ro"
1246 }
1247 run_test 38 "resync"
1248
1249 test_39() {
1250         local tf=$DIR/$tfile
1251
1252         rm -f $tf
1253         $LFS mirror create -N2 -E1m -c1 -S1M -E-1 $tf ||
1254         error "create PFL file $tf failed"
1255
1256         verify_mirror_count $tf 2
1257         verify_comp_count $tf 4
1258
1259         rm -f $tf || error "delete $tf failed"
1260 }
1261 run_test 39 "check FLR+PFL (a.k.a. PFLR) creation"
1262
1263 test_40() {
1264         local tf=$DIR/$tfile
1265         local ops
1266
1267         for ops in "conv=notrunc" ""; do
1268                 rm -f $tf
1269
1270                 $LFS mirror create -N -E2m -E4m -E-1 -N -E1m -E2m -E4m -E-1 \
1271                         $tf || error "create PFLR file $tf failed"
1272                 dd if=/dev/zero of=$tf $ops bs=1M seek=2 count=1 ||
1273                         error "write PFLR file $tf failed"
1274
1275                 lfs getstripe -vy $tf
1276
1277                 local flags
1278
1279                 # file mirror state should be write_pending
1280                 flags=$($LFS getstripe -v $tf | awk '/lcm_flags:/ { print $2 }')
1281                 [ $flags = wp ] ||
1282                 error "file mirror state $flags"
1283                 # the 1st component (in mirror 1) should be inited
1284                 verify_comp_attr lcme_flags $tf 0x10001 init
1285                 # the 2nd component (in mirror 1) should be inited
1286                 verify_comp_attr lcme_flags $tf 0x10002 init
1287                 # the 3rd component (in mirror 1) should be uninited
1288                 verify_comp_attr lcme_flags $tf 0x10003 0
1289                 # the 4th component (in mirror 2) should be inited
1290                 verify_comp_attr lcme_flags $tf 0x20004 init
1291                 # the 5th component (in mirror 2) should be uninited
1292                 verify_comp_attr lcme_flags $tf 0x20005 0
1293                 # the 6th component (in mirror 2) should be stale
1294                 verify_comp_attr lcme_flags $tf 0x20006 stale
1295                 # the 7th component (in mirror 2) should be uninited
1296                 if [[ x$ops = "xconv=notrunc" ]]; then
1297                         verify_comp_attr lcme_flags $tf 0x20007 0
1298                 elif [[ x$ops = "x" ]]; then
1299                         verify_comp_attr lcme_flags $tf 0x20007 stale
1300                 fi
1301         done
1302
1303         rm -f $tf || error "delete $tf failed"
1304 }
1305 run_test 40 "PFLR rdonly state instantiation check"
1306
1307 test_41() {
1308         local tf=$DIR/$tfile
1309
1310         rm -f $tf $tf-1
1311         $LFS mirror create -N -E2m -E4m -E-1 -N -E1m -E2m -E3m -E-1 $tf ||
1312                 error "create PFLR file $tf failed"
1313         $LFS mirror create -N -E4m -E-1 -N -E2m -E3m -E-1 $tf-1 ||
1314                 error "create PFLR file $tf-1 failed"
1315
1316         # file should be in ro status
1317         verify_flr_state $tf "ro"
1318         verify_flr_state $tf-1 "ro"
1319
1320         # write data in [0, 2M)
1321         dd if=/dev/zero of=$tf bs=1M count=2 conv=notrunc ||
1322                 error "writing $tf failed"
1323         dd if=/dev/zero of=$tf-1 bs=1M count=4 conv=notrunc ||
1324                 error "writing $tf-1 failed"
1325
1326         verify_flr_state $tf "wp"
1327         verify_flr_state $tf-1 "wp"
1328
1329         # file should have stale component
1330         $LFS getstripe $tf | grep lcme_flags | grep stale > /dev/null ||
1331                 error "after writing $tf, it does not contain stale component"
1332         $LFS getstripe $tf-1 | grep lcme_flags | grep stale > /dev/null ||
1333                 error "after writing $tf-1, it does not contain stale component"
1334
1335         $LFS mirror resync $tf $tf-1 || error "mirror resync $tf $tf-1 failed"
1336
1337         verify_flr_state $tf "ro"
1338         verify_flr_state $tf-1 "ro"
1339
1340         # file should not have stale component
1341         $LFS getstripe $tf | grep lcme_flags | grep stale &&
1342                 error "after resyncing $tf, it contains stale component"
1343         $LFS getstripe $tf-1 | grep lcme_flags | grep stale &&
1344                 error "after resyncing $tf, it contains stale component"
1345
1346         return 0
1347 }
1348 run_test 41 "lfs mirror resync check"
1349
1350 ctrl_file=$(mktemp /tmp/CTRL.XXXXXX)
1351 lock_file=$(mktemp /var/lock/FLR.XXXXXX)
1352
1353 write_file_200() {
1354         local tf=$1
1355
1356         local fsize=$(stat --printf=%s $tf)
1357
1358         while [ -f $ctrl_file ]; do
1359                 local off=$((RANDOM << 8))
1360                 local len=$((RANDOM << 5 + 131072))
1361
1362                 [ $((off + len)) -gt $fsize ] && {
1363                         fsize=$((off + len))
1364                         echo "Extending file size to $fsize .."
1365                 }
1366
1367                 flock -s $lock_file -c \
1368                         "$MULTIOP $tf oO_WRONLY:z${off}w${len}c" ||
1369                                 { rm -f $ctrl_file;
1370                                   error "failed writing to $off:$len"; }
1371                 sleep 0.$((RANDOM % 2 + 1))
1372         done
1373 }
1374
1375 read_file_200() {
1376         local tf=$1
1377
1378         while [ -f $ctrl_file ]; do
1379                 flock -s $lock_file -c "cat $tf &> /dev/null" ||
1380                         { rm -f $ctrl_file; error "read failed"; }
1381                 sleep 0.$((RANDOM % 2 + 1))
1382         done
1383 }
1384
1385 resync_file_200() {
1386         local tf=$1
1387
1388         options=("" "-e resync_start" "-e delay_before_copy -d 1" "" "")
1389
1390         exec 200<>$lock_file
1391         while [ -f $ctrl_file ]; do
1392                 local lock_taken=false
1393                 local index=$((RANDOM % ${#options[@]}))
1394                 local cmd="mirror_io resync ${options[$index]}"
1395
1396                 [ "${options[$index]}" = "" ] && cmd="$LFS mirror resync"
1397
1398                 [ $((RANDOM % 4)) -eq 0 ] && {
1399                         index=0
1400                         lock_taken=true
1401                         echo -n "lock to "
1402                 }
1403
1404                 echo -n "resync file $tf with '$cmd' .."
1405
1406                 $lock_taken && flock -x 200
1407                 $cmd $tf &> /dev/null && echo "done" || echo "failed"
1408                 $lock_taken && flock -u 200
1409
1410                 sleep 0.$((RANDOM % 8 + 1))
1411         done
1412 }
1413
1414 test_200() {
1415         local tf=$DIR/$tfile
1416         local tf2=$DIR2/$tfile
1417         local tf3=$DIR3/$tfile
1418
1419         $LFS setstripe -E 1M -E 2M -c 2 -E 4M -E 16M -E eof $tf
1420         $LFS setstripe -E 2M -E 6M -c 2 -E 8M -E 32M -E eof $tf-2
1421         $LFS setstripe -E 4M -c 2 -E 8M -E 64M -E eof $tf-3
1422
1423         $LFS mirror extend -N -f $tf-2 $tf ||
1424                 error "merging $tf-2 into $tf failed"
1425         $LFS mirror extend -N -f $tf-3 $tf ||
1426                 error "merging $tf-3 into $tf failed"
1427
1428         mkdir -p $MOUNT2 && mount_client $MOUNT2
1429
1430         mkdir -p $MOUNT3 && mount_client $MOUNT3
1431
1432         verify_flr_state $tf3 "ro"
1433
1434         #define OBD_FAIL_FLR_RANDOM_PICK_MIRROR 0x1A03
1435         $LCTL set_param fail_loc=0x1A03
1436
1437         local mds_idx=mds$(($($LFS getstripe -M $tf) + 1))
1438         do_facet $mds_idx $LCTL set_param fail_loc=0x1A03
1439
1440         declare -a pids
1441
1442         write_file_200 $tf &
1443         pids+=($!)
1444
1445         read_file_200 $tf &
1446         pids+=($!)
1447
1448         write_file_200 $tf2 &
1449         pids+=($!)
1450
1451         read_file_200 $tf2 &
1452         pids+=($!)
1453
1454         resync_file_200 $tf3 &
1455         pids+=($!)
1456
1457         local sleep_time=60
1458         [ "$SLOW" = "yes" ] && sleep_time=360
1459         while [ $sleep_time -gt 0 -a -f $ctrl_file ]; do
1460                 sleep 1
1461                 ((--sleep_time))
1462         done
1463
1464         rm -f $ctrl_file
1465
1466         echo "Waiting ${pids[@]}"
1467         wait ${pids[@]}
1468
1469         umount_client $MOUNT2
1470         umount_client $MOUNT3
1471
1472         rm -f $lock_file
1473
1474         # resync and verify mirrors
1475         mirror_io resync $tf
1476         get_mirror_ids $tf
1477
1478         local csum=$(mirror_io dump -i ${mirror_array[0]} $tf | md5sum)
1479         for id in ${mirror_array[@]:1}; do
1480                 [ "$(mirror_io dump -i $id $tf | md5sum)" = "$csum" ] ||
1481                         error "checksum error for mirror $id"
1482         done
1483
1484         true
1485 }
1486 run_test 200 "stress test"
1487
1488 cleanup_test_201() {
1489         trap 0
1490         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister $CL_USER
1491
1492         umount_client $MOUNT2
1493 }
1494
1495 test_201() {
1496         local delay=${RESYNC_DELAY:-5}
1497
1498         MDT0=$($LCTL get_param -n mdc.*.mds_server_uuid |
1499                awk '{ gsub(/_UUID/,""); print $1 }' | head -n1)
1500
1501         trap cleanup_test_201 EXIT
1502
1503         CL_USER=$(do_facet $SINGLEMDS $LCTL --device $MDT0 \
1504                         changelog_register -n)
1505
1506         mkdir -p $MOUNT2 && mount_client $MOUNT2
1507
1508         local index=0
1509         while :; do
1510                 local log=$($LFS changelog $MDT0 $index | grep FLRW)
1511                 [ -z "$log" ] && { sleep 1; continue; }
1512
1513                 index=$(echo $log | awk '{print $1}')
1514                 local ts=$(date -d "$(echo $log | awk '{print $3}')" "+%s" -u)
1515                 local fid=$(echo $log | awk '{print $6}' | sed -e 's/t=//')
1516                 local file=$($LFS fid2path $MOUNT2 $fid 2> /dev/null)
1517
1518                 ((++index))
1519                 [ -z "$file" ] && continue
1520
1521                 local now=$(date +%s)
1522
1523                 echo "file: $file $fid was modified at $ts, now: $now, " \
1524                      "will be resynced at $((ts+delay))"
1525
1526                 [ $now -lt $((ts + delay)) ] && sleep $((ts + delay - now))
1527
1528                 mirror_io resync $file
1529                 echo "$file resync done"
1530         done
1531
1532         cleanup_test_201
1533 }
1534 run_test 201 "FLR data mover"
1535
1536 complete $SECONDS
1537 check_and_cleanup_lustre
1538 exit_status