Whamcloud - gitweb
LU-9771 flr: to not support dom+flr for phase 1
[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         if false; then
376         touch $tf || error "touch $tf failed"
377         $mirror_cmd -N $tf || error "convert and extend $tf failed"
378         verify_mirror_count $tf 2
379         ids=($($LFS getstripe $tf | awk '/lcme_id/{print $2}' | tr '\n' ' '))
380         for ((i = 0; i < 2; i++)); do
381                 verify_comp_attrs_with_parent $tf ${ids[$i]}
382                 verify_comp_extent $tf ${ids[$i]} 0 EOF
383         done
384         fi
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
699         dd if=/dev/zero of=$tf2 bs=1M count=1 seek=$((dd_count - 1))
700         cancel_lru_locks osc
701
702         local blocks=$(du -kc $tf $tf2 | awk '/total/{print $1}')
703
704         # add component
705         $LFS mirror extend -N -f $tf2 $tf ||
706                 error "merging $tf2 into $tf failed"
707
708         # cancel layout lock
709         cancel_lru_locks mdc
710
711         local new_blocks=$(du -k $tf | awk '{print $1}')
712         [ $new_blocks -eq $blocks ] ||
713         error "i_blocks error expected: $blocks, actual: $new_blocks"
714 }
715 run_test 21 "glimpse should report accurate i_blocks"
716
717 get_osc_lock_count() {
718         local lock_count=0
719
720         for idx in "$@"; do
721                 local osc_name
722                 local count
723
724                 osc_name=${FSNAME}-OST$(printf "%04x" $((idx-1)))-osc-'ffff*'
725                 count=$($LCTL get_param -n ldlm.namespaces.$osc_name.lock_count)
726                 lock_count=$((lock_count + count))
727         done
728         echo $lock_count
729 }
730
731 test_22() {
732         local tf=$DIR/$tfile
733
734         $LFS setstripe -E EOF -o 0 $tf
735         dd if=/dev/zero of=$tf bs=1M count=$((RANDOM % 20 + 1))
736
737         # add component, two mirrors located on the same OST ;-)
738         $LFS mirror extend -N -o 0 $tf ||
739                 error "extending mirrored file $tf failed"
740
741         size_blocks=$(stat --format="%b %s" $tf)
742
743         cancel_lru_locks mdc
744         cancel_lru_locks osc
745
746         local new_size_blocks=$(stat --format="%b %s" $tf)
747
748         # make sure there is no lock cached
749         [ $(get_osc_lock_count 1) -eq 0 ] || error "glimpse requests were sent"
750
751         [ "$new_size_blocks" = "$size_blocks" ] ||
752                 echo "size expected: $size_blocks, actual: $new_size_blocks"
753
754         rm -f $tmpfile
755 }
756 run_test 22 "no glimpse to OSTs for READ_ONLY files"
757
758 test_31() {
759         local tf=$DIR/$tfile
760
761         $LFS mirror create -N -o 0 -N -o 1 $tf ||
762                 error "creating mirrored file $tf failed"
763
764         #define OBD_FAIL_GLIMPSE_IMMUTABLE 0x1A00
765         $LCTL set_param fail_loc=0x1A00
766
767         local ost_idx
768         for ((ost_idx = 1; ost_idx <= 2; ost_idx++)); do
769                 cancel_lru_locks osc
770                 stop_osts $ost_idx
771
772                 local tmpfile=$(mktemp)
773                 stat --format="%b %s" $tf > $tmpfile  &
774                 local pid=$!
775
776                 local cnt=0
777                 while [ $cnt -le 5 ]; do
778                         kill -0 $pid > /dev/null 2>&1 || break
779                         sleep 1
780                         ((cnt += 1))
781                 done
782                 kill -0 $pid > /dev/null 2>&1 &&
783                         error "stat process stuck due to unavailable OSTs"
784
785                 # make sure glimpse request has been sent
786                 [ $(get_osc_lock_count 1 2) -ne 0 ] ||
787                         error "OST $ost_idx: no glimpse request was sent"
788
789                 start_osts $ost_idx
790         done
791 }
792 run_test 31 "make sure glimpse request can be retried"
793
794 test_32() {
795         [[ $OSTCOUNT -lt 2 ]] && skip "need >= 2 OSTs" && return
796         rm -f $DIR/$tfile $DIR/$tfile-2
797
798         $LFS setstripe -E EOF -o 0 $DIR/$tfile
799         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=$((RANDOM % 10 + 2))
800
801         local fsize=$(stat -c %s $DIR/$tfile)
802         [[ $fsize -ne 0 ]] || error "file size is (wrongly) zero"
803
804         local cksum=$(md5sum $DIR/$tfile)
805
806         # create a new mirror in sync mode
807         $LFS mirror extend -N -o 1 $DIR/$tfile ||
808                 error "extending mirrored file $DIR/$tfile failed"
809
810         # make sure the mirrored file was created successfully
811         [ $(get_mirror_ids $DIR/$tfile) -eq 2 ] ||
812                 { $LFS getstripe $DIR/$tfile; error "expected 2 mirrors"; }
813
814         drop_client_cache
815         stop_osts 1
816
817         # check size is correct, glimpse request should go to the 2nd mirror
818         $CHECKSTAT -t file -s $fsize $DIR/$tfile ||
819                 error "file size error $fsize vs. $(stat -c %s $DIR/$tfile)"
820
821         echo "reading file from the 2nd mirror and verify checksum"
822         [[ "$cksum" == "$(md5sum $DIR/$tfile)" ]] ||
823                 error "checksum error: expected $cksum"
824
825         start_osts 1
826 }
827 run_test 32 "data should be mirrored to newly created mirror"
828
829 test_33() {
830         [[ $OSTCOUNT -lt 2 ]] && skip "need >= 2 OSTs" && return
831
832         rm -f $DIR/$tfile $DIR/$tfile-2
833
834         # create a file with two mirrors
835         $LFS setstripe -E EOF -o 0 $DIR/$tfile
836         local max_count=100
837         local count=0
838         while [ $count -lt $max_count ]; do
839                 echo "ost1" >> $DIR/$tfile
840                 count=$((count + 1));
841         done
842
843         # tmp file that will be used as mirror
844         $LFS setstripe -E EOF -o 1 $DIR/$tfile-2
845         count=0
846         while [ $count -lt $max_count ]; do
847                 echo "ost2" >> $DIR/$tfile-2
848                 count=$((count + 1));
849         done
850
851         # create a mirrored file
852         $LFS mirror extend -N -f $DIR/$tfile-2 $DIR/$tfile &&
853                 error "merging $DIR/$tfile-2 into $DIR/$tfile" \
854                       "with verification should fail"
855         $LFS mirror extend --no-verify -N -f $DIR/$tfile-2 $DIR/$tfile ||
856                 error "merging $DIR/$tfile-2 into $DIR/$tfile" \
857                       "without verification failed"
858
859         # make sure that $tfile has two mirrors and $tfile-2 does not exist
860         [ $(get_mirror_ids $DIR/$tfile) -eq 2 ] ||
861                 { $LFS getstripe $DIR/$tfile; error "expected count 2"; }
862
863         [[ ! -e $DIR/$tfile-2 ]] || error "$DIR/$tfile-2 was not unlinked"
864
865         # execpted file size
866         local fsize=$((5 * max_count))
867         $CHECKSTAT -t file -s $fsize $DIR/$tfile ||
868                 error "mirrored file size is not $fsize"
869
870         # read file - all OSTs are available
871         echo "reading file (data should be provided by ost1)... "
872         local rs=$(cat $DIR/$tfile | head -1)
873         [[ "$rs" == "ost1" ]] ||
874                 error "file content error: expected: \"ost1\", actual: \"$rs\""
875
876         # read file again with ost1 failed
877         stop_osts 1
878         drop_client_cache
879
880         echo "reading file (data should be provided by ost2)..."
881         local rs=$(cat $DIR/$tfile | head -1)
882         [[ "$rs" == "ost2" ]] ||
883                 error "file content error: expected: \"ost2\", actual: \"$rs\""
884
885         # remount ost1
886         start_osts 1
887
888         # read file again with ost2 failed
889         $LCTL set_param ldlm.namespaces.lustre-*-osc-ffff*.lru_size=clear
890
891         fail ost2 &
892         sleep 1
893
894         # check size, glimpse should work
895         $CHECKSTAT -t file -s $fsize $DIR/$tfile ||
896                 error "mirrored file size is not $fsize"
897
898         echo "reading file (data should be provided by ost1)..."
899         local rs=$(cat $DIR/$tfile | head -1)
900         [[ "$rs" == "ost1" ]] ||
901                 error "file content error: expected: \"ost1\", actual: \"$rs\""
902
903         wait_osc_import_state client ost2 FULL
904 }
905 run_test 33 "read can choose available mirror to read"
906
907 test_34a() {
908         [[ $OSTCOUNT -lt 4 ]] && skip "need >= 4 OSTs" && return
909
910         rm -f $DIR/$tfile $DIR/$tfile-2 $DIR/$tfile-ref
911
912         # reference file
913         $LFS setstripe -o 0 $DIR/$tfile-ref
914         dd if=/dev/urandom of=$DIR/$tfile-ref bs=1M count=3
915
916         # create a file with two mirrors
917         $LFS setstripe -E -1 -o 0,1 -S 1M $DIR/$tfile
918         dd if=$DIR/$tfile-ref of=$DIR/$tfile bs=1M
919
920         $LFS setstripe -E -1 -o 2,3 -S 1M $DIR/$tfile-2
921         dd if=$DIR/$tfile-ref of=$DIR/$tfile-2 bs=1M
922
923         $CHECKSTAT -t file -s $((3 * 1024 * 1024)) $DIR/$tfile ||
924                 error "mirrored file size is not 3M"
925
926         # merge a mirrored file
927         $LFS mirror extend -N -f $DIR/$tfile-2 $DIR/$tfile ||
928                 error "merging $DIR/$tfile-2 into $DIR/$tfile failed"
929
930         cancel_lru_locks osc
931
932         # stop two OSTs, so the 2nd stripe of the 1st mirror and
933         # the 1st stripe of the 2nd mirror will be inaccessible, ...
934         stop_osts 2 3
935
936         echo "comparing files ... "
937
938         # however, read can still return the correct data. It should return
939         # the 1st stripe from mirror 1 and 2st stripe from mirror 2.
940         cmp -n 2097152 <(rwv -f $DIR/$tfile -r -o -n 1 2097152) \
941                 $DIR/$tfile-ref || error "file reading error"
942
943         start_osts 2 3
944 }
945 run_test 34a "read mirrored file with multiple stripes"
946
947 test_34b() {
948         [[ $OSTCOUNT -lt 4 ]] && skip "need >= 4 OSTs" && return
949
950         rm -f $DIR/$tfile $DIR/$tfile-2 $DIR/$tfile-ref
951
952         # reference file
953         $LFS setstripe -o 0 $DIR/$tfile-ref
954         dd if=/dev/urandom of=$DIR/$tfile-ref bs=1M count=3
955
956         $LFS setstripe -E 1M -S 1M -o 0 -E eof -o 1 $DIR/$tfile
957         dd if=$DIR/$tfile-ref of=$DIR/$tfile bs=1M
958
959         $LFS setstripe -E 1M -S 1M -o 2 -E eof -o 3 $DIR/$tfile-2
960         dd if=$DIR/$tfile-ref of=$DIR/$tfile-2 bs=1M
961
962         $CHECKSTAT -t file -s $((3 * 1024 * 1024)) $DIR/$tfile ||
963                 error "mirrored file size is not 3M"
964
965         # merge a mirrored file
966         $LFS mirror extend -N -f $DIR/$tfile-2 $DIR/$tfile ||
967                 error "merging $DIR/$tfile-2 into $DIR/$tfile failed"
968
969         cancel_lru_locks osc
970
971         # stop two OSTs, so the 2nd component of the 1st mirror and
972         # the 1st component of the 2nd mirror will be inaccessible, ...
973         stop_osts 2 3
974
975         echo "comparing files ... "
976
977         # however, read can still return the correct data. It should return
978         # the 1st stripe from mirror 1 and 2st stripe from mirror 2.
979         cmp -n 2097152 <(rwv -f $DIR/$tfile -r -o -n 1 2097152) \
980                 $DIR/$tfile-ref || error "file reading error"
981
982         start_osts 2 3
983 }
984 run_test 34b "read mirrored file with multiple components"
985
986 test_35() {
987         local tf=$DIR/$tfile
988
989         $LFS setstripe -E eof $tf
990
991         # add an out-of-sync mirror to the file
992         $LFS mirror extend -N -c 2 $tf ||
993                 error "extending mirrored file $tf failed"
994
995         $MULTIOP $tf oO_WRONLY:c ||
996                 error "write open a mirrored file failed"
997
998         # truncate file should return error
999         $TRUNCATE $tf 100 || error "error truncating a mirrored file"
1000 }
1001 run_test 35 "allow to write to mirrored files"
1002
1003 verify_ost_layout_version() {
1004         local tf=$1
1005
1006         # get file layout version
1007         local flv=$($LFS getstripe $tf | awk '/lcm_layout_gen/{print $2}')
1008
1009         # layout version from OST objects
1010         local olv=$($MULTIOP $tf oXc | awk '/ostlayoutversion/{print $2}')
1011
1012         [ $flv -eq $olv ] || error "layout version mismatch: $flv vs. $olv"
1013 }
1014
1015 create_file_36() {
1016         local tf
1017
1018         for tf in "$@"; do
1019                 $LFS setstripe -E 1M -E 2M -E 4M -E eof -c -1 $tf
1020                 $LFS setstripe -E 3M -E 6M -E eof -c -1 $tf-tmp
1021
1022                 $LFS mirror extend -N -f $tf-tmp $tf ||
1023                         error "merging $tf-tmp into $tf failed"
1024         done
1025 }
1026
1027 test_36() {
1028         local tf=$DIR/$tfile
1029
1030         create_file_36 $tf $tf-2 $tf-3
1031
1032         [ $(get_mirror_ids $tf) -gt 1 ] || error "wrong mirror count"
1033
1034         # test case 1 - check file write and verify layout version
1035         $MULTIOP $tf oO_WRONLY:c ||
1036                 error "write open a mirrored file failed"
1037
1038         # write open file should not return error
1039         $MULTIOP $tf oO_WRONLY:w1024Yc || error "write mirrored file error"
1040
1041         # instantiate components should work
1042         dd if=/dev/zero of=$tf bs=1M count=12 || error "write file error"
1043
1044         # verify OST layout version
1045         verify_ost_layout_version $tf
1046
1047         # test case 2
1048         local mds_idx=mds$(($($LFS getstripe -M $tf-2) + 1))
1049
1050         local delay_sec=10
1051         do_facet $mds_idx $LCTL set_param fail_val=$delay_sec
1052
1053         #define OBD_FAIL_FLR_LV_DELAY 0x1A01
1054         do_facet $mds_idx $LCTL set_param fail_loc=0x1A01
1055
1056         # write should take at least $fail_loc seconds and succeed
1057         local st=$(date +%s)
1058         $MULTIOP $tf-2 oO_WRONLY:w1024Yc || error "write mirrored file error"
1059
1060         [ $(date +%s) -ge $((st+delay_sec)) ] ||
1061                 error "write finished before layout version is transmitted"
1062
1063         # verify OST layout version
1064         verify_ost_layout_version $tf
1065
1066         do_facet $mds_idx $LCTL set_param fail_loc=0
1067
1068         # test case 3
1069         mds_idx=mds$(($($LFS getstripe -M $tf-3) + 1))
1070
1071         #define OBD_FAIL_FLR_LV_INC 0x1A02
1072         do_facet $mds_idx $LCTL set_param fail_loc=0x1A02
1073
1074         # write open file should return error
1075         $MULTIOP $tf-3 oO_WRONLY:O_SYNC:w1024c &&
1076                 error "write a mirrored file succeeded" || true
1077
1078         do_facet $mds_idx $LCTL set_param fail_loc=0
1079 }
1080 run_test 36 "write to mirrored files"
1081
1082 create_files_37() {
1083         local tf
1084         local fsize=$1
1085
1086         echo "create test files with size $fsize .."
1087
1088         shift
1089         for tf in "$@"; do
1090                 $LFS setstripe -E 1M -c 1 -E eof -c -1 $tf
1091
1092                 dd if=/dev/urandom of=$tf bs=1M count=16 &> /dev/null
1093                 $TRUNCATE $tf $fsize
1094         done
1095 }
1096
1097 test_37()
1098 {
1099         local tf=$DIR/$tfile
1100         local tf2=$DIR/$tfile-2
1101         local tf3=$DIR/$tfile-3
1102
1103         create_files_37 $((RANDOM + 15 * 1048576)) $tf $tf2 $tf3
1104
1105         # assume the mirror id will be 1, 2, and 3
1106         declare -A checksums
1107         checksums[1]=$(md5sum $tf | cut -f 1 -d' ')
1108         checksums[2]=$(md5sum $tf2 | cut -f 1 -d' ')
1109         checksums[3]=$(md5sum $tf3 | cut -f 1 -d' ')
1110
1111         printf '%s\n' "${checksums[@]}"
1112
1113         # merge these files into a mirrored file
1114         $LFS mirror extend --no-verify -N -f $tf2 $tf ||
1115                 error "merging $tf2 into $tf failed"
1116         $LFS mirror extend --no-verify -N -f $tf3 $tf ||
1117                 error "merging $tf3 into $tf failed"
1118
1119         get_mirror_ids $tf
1120
1121         # verify mirror read, checksums should equal to the original files'
1122         echo "Verifying mirror read .."
1123
1124         local sum
1125         for i in ${mirror_array[@]}; do
1126                 sum=$(mirror_io dump -i $i $tf | md5sum | cut -f 1 -d' ')
1127                 [ "$sum" = "${checksums[$i]}" ] ||
1128                         error "$i: mismatch: \'${checksums[$i]}\' vs. \'$sum\'"
1129         done
1130
1131         # verify mirror copy, write to this mirrored file will invalidate
1132         # the other two mirrors
1133         echo "Verifying mirror copy .."
1134
1135         local osts=$(comma_list $(osts_nodes))
1136
1137         # define OBD_FAIL_OST_SKIP_LV_CHECK     0x241
1138         do_nodes $osts lctl set_param fail_loc=0x241
1139
1140         mirror_io copy -i ${mirror_array[0]} \
1141                 -t $(echo ${mirror_array[@]:1} | tr ' ' ',') $tf ||
1142                         error "mirror copy error"
1143
1144         do_nodes $osts lctl set_param fail_loc=0
1145
1146         # verify copying is successful by checking checksums
1147         remount_client $MOUNT
1148         for i in ${mirror_array[@]}; do
1149                 sum=$(mirror_io dump -i $i $tf | md5sum | cut -f 1 -d' ')
1150                 [ "$sum" = "${checksums[1]}" ] ||
1151                         error "$i: mismatch checksum after copy"
1152         done
1153
1154         rm -f $tf
1155 }
1156 run_test 37 "mirror I/O API verification"
1157
1158 verify_flr_state()
1159 {
1160         local tf=$1
1161         local expected_state=$2
1162
1163         local state=$($LFS getstripe -v $tf | awk '/lcm_flags/{ print $2 }')
1164         [ $expected_state = $state ] ||
1165                 error "expected: $expected_state, actual $state"
1166 }
1167
1168 test_38() {
1169         local tf=$DIR/$tfile
1170         local ref=$DIR/${tfile}-ref
1171
1172         $LFS setstripe -E 1M -c 1 -E 4M -c 2 -E eof -c -1 $tf
1173         $LFS setstripe -E 2M -c 1 -E 6M -c 2 -E 8M -c -1 -E eof -c -1 $tf-2
1174         $LFS setstripe -E 4M -c 1 -E 8M -c 2 -E eof -c -1 $tf-3
1175
1176         # instantiate all components
1177         $LFS mirror extend -N -f $tf-2 $tf ||
1178                 error "merging $tf-2 into $tf failed"
1179         $LFS mirror extend -N -f $tf-3 $tf ||
1180                 error "merging $tf-3 into $tf failed"
1181         $LFS mirror extend -N -c 1 $tf ||
1182                 error "extending mirrored file $tf failed"
1183
1184         verify_flr_state $tf "ro"
1185
1186         dd if=/dev/urandom of=$ref  bs=1M count=16 &> /dev/null
1187
1188         local fsize=$((RANDOM << 8 + 1048576))
1189         $TRUNCATE $ref $fsize
1190
1191         local ref_cksum=$(md5sum $ref | cut -f 1 -d' ')
1192
1193         # case 1: verify write to mirrored file & resync work
1194         cp $ref $tf || error "copy from $ref to $f error"
1195         verify_flr_state $tf "wp"
1196
1197         local file_cksum=$(md5sum $tf | cut -f 1 -d' ')
1198         [ "$file_cksum" = "$ref_cksum" ] || error "write failed, cksum mismatch"
1199
1200         get_mirror_ids $tf
1201         echo "mirror IDs: ${mirror_array[@]}"
1202
1203         local valid_mirror stale_mirror id mirror_cksum
1204         for id in "${mirror_array[@]}"; do
1205                 mirror_cksum=$(mirror_io dump -i $id $tf |
1206                                 md5sum | cut -f 1 -d' ')
1207                 [ "$ref_cksum" == "$mirror_cksum" ] &&
1208                         { valid_mirror=$id; continue; }
1209
1210                 stale_mirror=$id
1211         done
1212
1213         [ -z "$stale_mirror" ] && error "stale mirror doesn't exist"
1214         [ -z "$valid_mirror" ] && error "valid mirror doesn't exist"
1215
1216         mirror_io resync $tf || error "resync failed"
1217         verify_flr_state $tf "ro"
1218
1219         mirror_cksum=$(mirror_io dump -i $stale_mirror $tf |
1220                         md5sum | cut -f 1 -d' ')
1221         [ "$file_cksum" = "$ref_cksum" ] || error "resync failed"
1222
1223         # case 2: inject an error to make mirror_io exit after changing
1224         # the file state to sync_pending so that we can start a concurrent
1225         # write.
1226         $MULTIOP $tf oO_WRONLY:w$((RANDOM % 1048576 + 1024))c
1227         verify_flr_state $tf "wp"
1228
1229         mirror_io resync -e resync_start $tf && error "resync succeeded"
1230         verify_flr_state $tf "sp"
1231
1232         # from sync_pending to write_pending
1233         $MULTIOP $tf oO_WRONLY:w$((RANDOM % 1048576 + 1024))c
1234         verify_flr_state $tf "wp"
1235
1236         mirror_io resync -e resync_start $tf && error "resync succeeded"
1237         verify_flr_state $tf "sp"
1238
1239         # from sync_pending to read_only
1240         mirror_io resync $tf || error "resync failed"
1241         verify_flr_state $tf "ro"
1242 }
1243 run_test 38 "resync"
1244
1245 test_39() {
1246         local tf=$DIR/$tfile
1247
1248         rm -f $tf
1249         $LFS mirror create -N2 -E1m -c1 -S1M -E-1 $tf ||
1250         error "create PFL file $tf failed"
1251
1252         verify_mirror_count $tf 2
1253         verify_comp_count $tf 4
1254
1255         rm -f $tf || error "delete $tf failed"
1256 }
1257 run_test 39 "check FLR+PFL (a.k.a. PFLR) creation"
1258
1259 test_40() {
1260         local tf=$DIR/$tfile
1261         local ops
1262
1263         for ops in "conv=notrunc" ""; do
1264                 rm -f $tf
1265
1266                 $LFS mirror create -N -E2m -E4m -E-1 -N -E1m -E2m -E4m -E-1 \
1267                         $tf || error "create PFLR file $tf failed"
1268                 dd if=/dev/zero of=$tf $ops bs=1M seek=2 count=1 ||
1269                         error "write PFLR file $tf failed"
1270
1271                 lfs getstripe -vy $tf
1272
1273                 local flags
1274
1275                 # file mirror state should be write_pending
1276                 flags=$($LFS getstripe -v $tf | awk '/lcm_flags:/ { print $2 }')
1277                 [ $flags = wp ] ||
1278                 error "file mirror state $flags"
1279                 # the 1st component (in mirror 1) should be inited
1280                 verify_comp_attr lcme_flags $tf 0x10001 init
1281                 # the 2nd component (in mirror 1) should be inited
1282                 verify_comp_attr lcme_flags $tf 0x10002 init
1283                 # the 3rd component (in mirror 1) should be uninited
1284                 verify_comp_attr lcme_flags $tf 0x10003 0
1285                 # the 4th component (in mirror 2) should be inited
1286                 verify_comp_attr lcme_flags $tf 0x20004 init
1287                 # the 5th component (in mirror 2) should be uninited
1288                 verify_comp_attr lcme_flags $tf 0x20005 0
1289                 # the 6th component (in mirror 2) should be stale
1290                 verify_comp_attr lcme_flags $tf 0x20006 stale
1291                 # the 7th component (in mirror 2) should be uninited
1292                 if [[ x$ops = "xconv=notrunc" ]]; then
1293                         verify_comp_attr lcme_flags $tf 0x20007 0
1294                 elif [[ x$ops = "x" ]]; then
1295                         verify_comp_attr lcme_flags $tf 0x20007 stale
1296                 fi
1297         done
1298
1299         rm -f $tf || error "delete $tf failed"
1300 }
1301 run_test 40 "PFLR rdonly state instantiation check"
1302
1303 test_41() {
1304         local tf=$DIR/$tfile
1305
1306         rm -f $tf
1307         $LFS mirror create -N -E2m -E4m -E-1 -N -E1m -E2m -E3m -E-1 $tf ||
1308                 error "create PFLR file $tf failed"
1309
1310         # file should be in ro status
1311         verify_flr_state $tf "ro"
1312
1313         # write data in [0, 2M)
1314         dd if=/dev/zero of=$tf bs=1M count=2 conv=notrunc ||
1315                 error "writing $tf failed"
1316
1317         verify_flr_state $tf "wp"
1318
1319         # file should have stale component
1320         $LFS getstripe $tf | grep lcme_flags | grep stale > /dev/null ||
1321                 error "after writing $tf, it does not contain stale component"
1322
1323         $LFS mirror resync $tf || error "mirror resync $tf failed"
1324
1325         verify_flr_state $tf "ro"
1326
1327         # file should not have stale component
1328         $LFS getstripe $tf | grep lcme_flags | grep stale &&
1329                 error "after resyncing $tf, it contains stale component"
1330
1331         return 0
1332 }
1333 run_test 41 "lfs mirror resync check"
1334
1335 ctrl_file=$(mktemp /tmp/CTRL.XXXXXX)
1336 lock_file=$(mktemp /var/lock/FLR.XXXXXX)
1337
1338 write_file_200() {
1339         local tf=$1
1340
1341         local fsize=$(stat --printf=%s $tf)
1342
1343         while [ -f $ctrl_file ]; do
1344                 local off=$((RANDOM << 8))
1345                 local len=$((RANDOM << 5 + 131072))
1346
1347                 [ $((off + len)) -gt $fsize ] && {
1348                         fsize=$((off + len))
1349                         echo "Extending file size to $fsize .."
1350                 }
1351
1352                 flock -s $lock_file -c \
1353                         "$MULTIOP $tf oO_WRONLY:z${off}w${len}c" ||
1354                                 { rm -f $ctrl_file;
1355                                   error "failed writing to $off:$len"; }
1356                 sleep 0.$((RANDOM % 2 + 1))
1357         done
1358 }
1359
1360 read_file_200() {
1361         local tf=$1
1362
1363         while [ -f $ctrl_file ]; do
1364                 flock -s $lock_file -c "cat $tf &> /dev/null" ||
1365                         { rm -f $ctrl_file; error "read failed"; }
1366                 sleep 0.$((RANDOM % 2 + 1))
1367         done
1368 }
1369
1370 resync_file_200() {
1371         local tf=$1
1372
1373         options=("" "-e resync_start" "-e delay_before_copy -d 1" "" "")
1374
1375         exec 200<>$lock_file
1376         while [ -f $ctrl_file ]; do
1377                 local lock_taken=false
1378                 local index=$((RANDOM % ${#options[@]}))
1379                 local cmd="mirror_io resync ${options[$index]}"
1380
1381                 [ "${options[$index]}" = "" ] && cmd="$LFS mirror resync"
1382
1383                 [ $((RANDOM % 4)) -eq 0 ] && {
1384                         index=0
1385                         lock_taken=true
1386                         echo -n "lock to "
1387                 }
1388
1389                 echo -n "resync file $tf with '$cmd' .."
1390
1391                 $lock_taken && flock -x 200
1392                 $cmd $tf &> /dev/null && echo "done" || echo "failed"
1393                 $lock_taken && flock -u 200
1394
1395                 sleep 0.$((RANDOM % 8 + 1))
1396         done
1397 }
1398
1399 test_200() {
1400         local tf=$DIR/$tfile
1401         local tf2=$DIR2/$tfile
1402         local tf3=$DIR3/$tfile
1403
1404         $LFS setstripe -E 1M -E 2M -c 2 -E 4M -E 16M -E eof $tf
1405         $LFS setstripe -E 2M -E 6M -c 2 -E 8M -E 32M -E eof $tf-2
1406         $LFS setstripe -E 4M -c 2 -E 8M -E 64M -E eof $tf-3
1407
1408         $LFS mirror extend -N -f $tf-2 $tf ||
1409                 error "merging $tf-2 into $tf failed"
1410         $LFS mirror extend -N -f $tf-3 $tf ||
1411                 error "merging $tf-3 into $tf failed"
1412
1413         mkdir -p $MOUNT2 && mount_client $MOUNT2
1414
1415         mkdir -p $MOUNT3 && mount_client $MOUNT3
1416
1417         verify_flr_state $tf3 "ro"
1418
1419         #define OBD_FAIL_FLR_RANDOM_PICK_MIRROR 0x1A03
1420         $LCTL set_param fail_loc=0x1A03
1421
1422         local mds_idx=mds$(($($LFS getstripe -M $tf) + 1))
1423         do_facet $mds_idx $LCTL set_param fail_loc=0x1A03
1424
1425         declare -a pids
1426
1427         write_file_200 $tf &
1428         pids+=($!)
1429
1430         read_file_200 $tf &
1431         pids+=($!)
1432
1433         write_file_200 $tf2 &
1434         pids+=($!)
1435
1436         read_file_200 $tf2 &
1437         pids+=($!)
1438
1439         resync_file_200 $tf3 &
1440         pids+=($!)
1441
1442         local sleep_time=60
1443         [ "$SLOW" = "yes" ] && sleep_time=360
1444         while [ $sleep_time -gt 0 -a -f $ctrl_file ]; do
1445                 sleep 1
1446                 ((--sleep_time))
1447         done
1448
1449         rm -f $ctrl_file
1450
1451         echo "Waiting ${pids[@]}"
1452         wait ${pids[@]}
1453
1454         umount_client $MOUNT2
1455         umount_client $MOUNT3
1456
1457         rm -f $lock_file
1458
1459         # resync and verify mirrors
1460         mirror_io resync $tf
1461         get_mirror_ids $tf
1462
1463         local csum=$(mirror_io dump -i ${mirror_array[0]} $tf | md5sum)
1464         for id in ${mirror_array[@]:1}; do
1465                 [ "$(mirror_io dump -i $id $tf | md5sum)" = "$csum" ] ||
1466                         error "checksum error for mirror $id"
1467         done
1468
1469         true
1470 }
1471 run_test 200 "stress test"
1472
1473 cleanup_test_201() {
1474         trap 0
1475         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister $CL_USER
1476
1477         umount_client $MOUNT2
1478 }
1479
1480 test_201() {
1481         local delay=${RESYNC_DELAY:-5}
1482
1483         MDT0=$($LCTL get_param -n mdc.*.mds_server_uuid |
1484                awk '{ gsub(/_UUID/,""); print $1 }' | head -n1)
1485
1486         trap cleanup_test_201 EXIT
1487
1488         CL_USER=$(do_facet $SINGLEMDS $LCTL --device $MDT0 \
1489                         changelog_register -n)
1490
1491         mkdir -p $MOUNT2 && mount_client $MOUNT2
1492
1493         local index=0
1494         while :; do
1495                 local log=$($LFS changelog $MDT0 $index | grep FLRW)
1496                 [ -z "$log" ] && { sleep 1; continue; }
1497
1498                 index=$(echo $log | awk '{print $1}')
1499                 local ts=$(date -d "$(echo $log | awk '{print $3}')" "+%s" -u)
1500                 local fid=$(echo $log | awk '{print $6}' | sed -e 's/t=//')
1501                 local file=$($LFS fid2path $MOUNT2 $fid 2> /dev/null)
1502
1503                 ((++index))
1504                 [ -z "$file" ] && continue
1505
1506                 local now=$(date +%s)
1507
1508                 echo "file: $file $fid was modified at $ts, now: $now, " \
1509                      "will be resynced at $((ts+delay))"
1510
1511                 [ $now -lt $((ts + delay)) ] && sleep $((ts + delay - now))
1512
1513                 mirror_io resync $file
1514                 echo "$file resync done"
1515         done
1516
1517         cleanup_test_201
1518 }
1519 run_test 201 "FLR data mover"
1520
1521 complete $SECONDS
1522 check_and_cleanup_lustre
1523 exit_status