Whamcloud - gitweb
3df762b3dbe4b529e2df12a89bb17883b048c408
[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
9 ONLY=${ONLY:-"$*"}
10
11 LUSTRE=${LUSTRE:-$(dirname $0)/..}
12 . $LUSTRE/tests/test-framework.sh
13 init_test_env $@
14 init_logging
15
16 ALWAYS_EXCEPT="$SANITY_FLR_EXCEPT "
17 # Bug number for skipped test:    LU-11381
18 ALWAYS_EXCEPT+="                  201"
19 # UPDATE THE COMMENT ABOVE WITH BUG NUMBERS WHEN CHANGING ALWAYS_EXCEPT!
20
21 build_test_filter
22
23 [[ "$MDS1_VERSION" -ge $(version_code 2.10.56) ]] ||
24         skip "Need MDS version at least 2.10.56"
25
26 [ $UID -eq 0 -a $RUNAS_ID -eq 0 ] &&
27         error "\$RUNAS_ID set to 0, but \$UID is also 0!"
28 check_runas_id $RUNAS_ID $RUNAS_GID $RUNAS
29
30 check_and_setup_lustre
31 DIR=${DIR:-$MOUNT}
32 assert_DIR
33
34 assert_DIR
35 rm -rf $DIR/[Rdfs][0-9]*
36
37 # global array to store mirror IDs
38 declare -a mirror_array
39 get_mirror_ids() {
40         local tf=$1
41         local id
42         local array
43
44         array=()
45         for id in $($LFS getstripe $tf | awk '/lcme_id/{print $2}'); do
46                 array[${#array[@]}]=$((id >> 16))
47         done
48
49         mirror_array=($(printf "%s\n" "${array[@]}" | sort -u))
50
51         echo ${#mirror_array[@]}
52 }
53
54 drop_client_cache() {
55         echo 3 > /proc/sys/vm/drop_caches
56 }
57
58 stop_osts() {
59         local idx
60
61         for idx in "$@"; do
62                 stop ost$idx
63         done
64
65         for idx in "$@"; do
66                 wait_osc_import_state client ost$idx "\(DISCONN\|IDLE\)"
67         done
68 }
69
70 start_osts() {
71         local idx
72
73         for idx in "$@"; do
74                 start ost$idx $(ostdevname $idx) $OST_MOUNT_OPTS ||
75                         error "start ost$idx failed"
76         done
77
78         for idx in "$@"; do
79                 wait_recovery_complete ost$idx
80         done
81 }
82
83 #
84 # Verify mirror count with an expected value for a given file.
85 #
86 verify_mirror_count() {
87         local tf=$1
88         local expected=$2
89         local mirror_count=$($LFS getstripe -N $tf)
90
91         [[ $mirror_count = $expected ]] || {
92                 $LFS getstripe -v $tf
93                 error "verify mirror count failed on $tf:" \
94                       "$mirror_count != $expected"
95         }
96 }
97
98 #
99 # Verify component count with an expected value for a given file.
100 #       $1 coposited layout file
101 #       $2 expected component number
102 #
103 verify_comp_count() {
104         local tf=$1
105         local expected=$2
106         local comp_count=$($LFS getstripe --component-count $tf)
107
108         [[ $comp_count = $expected ]] || {
109                 $LFS getstripe -v $tf
110                 error "verify component count failed on $tf:" \
111                       "$comp_count != $expected"
112         }
113 }
114
115 #
116 # Verify component attribute with an expected value for a given file
117 # and component ID.
118 #
119 verify_comp_attr() {
120         local attr=$1
121         local tf=$2
122         local comp_id=$3
123         local expected=$4
124         local cmd="$LFS getstripe -I$comp_id"
125         local getstripe_cmd="$cmd -v"
126         local value
127
128         case $attr in
129                 stripe-size) cmd+=" -S $tf" ;;
130                 stripe-count) cmd+=" -c $tf" ;;
131                 stripe-index) cmd+=" -i $tf" ;;
132                 pool) cmd+=" -p $tf" ;;
133                 comp-start) cmd+=" --component-start $tf" ;;
134                 comp-end) cmd+=" --component-end $tf" ;;
135                 lcme_flags) cmd+=" $tf | awk '/lcme_flags:/ { print \$2 }'" ;;
136                 *) error "invalid attribute $attr";;
137         esac
138
139         value=$(eval $cmd)
140
141         [ $attr = lcme_flags ] && {
142                 local fl
143                 local expected_list=$(comma_list $expected)
144                 for fl in ${expected_list//,/ }; do
145                         local neg=0
146
147                         [[ ${fl:0:1} = "^" ]] && neg=1
148                         [[ $neg = 1 ]] && fl=${fl:1}
149
150                         $(echo $value | grep -q $fl)
151                         local match=$?
152                         # 0: matched; 1: not matched
153
154                         if  [[ $neg = 0 && $match != 0 ||
155                                $neg = 1 && $match = 0 ]]; then
156                                 $getstripe_cmd $tf
157                                 [[ $neg = 0 ]] && # expect the flag
158                                     error "expected flag '$fl' not in $comp_id"
159                                 [[ $neg = 1 ]] && # not expect the flag
160                                     error "not expected flag '$fl' in $comp_id"
161                         fi
162                 done
163                 return
164         }
165
166         [[ $value = $expected ]] || {
167                 $getstripe_cmd $tf
168                 error "verify $attr failed on $tf: $value != $expected"
169         }
170 }
171
172 #
173 # Verify component extent with expected start and end extent values
174 # for a given file and component ID.
175 #
176 verify_comp_extent() {
177         local tf=$1
178         local comp_id=$2
179         local expected_start=$3
180         local expected_end=$4
181
182         verify_comp_attr comp-start $tf $comp_id $expected_start
183         verify_comp_attr comp-end $tf $comp_id $expected_end
184 }
185
186 #
187 # Verify component attribute with parent directory for a given file
188 # and component ID.
189 #
190 verify_comp_attr_with_parent() {
191         local attr=$1
192         local tf=$2
193         local comp_id=$3
194         local td=$(cd $(dirname $tf); echo $PWD)
195         local tf_cmd="$LFS getstripe -I$comp_id"
196         local td_cmd="$LFS getstripe"
197         local opt
198         local expected
199         local value
200
201         case $attr in
202                 stripe-size) opt="-S" ;;
203                 stripe-count) opt="-c" ;;
204                 pool) opt="-p" ;;
205                 *) error "invalid attribute $attr";;
206         esac
207
208         expected=$($td_cmd $opt $td)
209         [[ $expected = -1 ]] && expected=$OSTCOUNT
210
211         value=$($tf_cmd $opt $tf)
212         [[ $value = -1 ]] && value=$OSTCOUNT
213
214         [[ $value = $expected ]] || {
215                 $td_cmd -d $td
216                 $tf_cmd -v $tf
217                 error "verify $attr failed with parent on $tf:" \
218                       "$value != $expected"
219         }
220 }
221
222 #
223 # Verify component attribute with filesystem-wide default value for a given file
224 # and component ID.
225 #
226 verify_comp_attr_with_default() {
227         local attr=$1
228         local tf=$2
229         local comp_id=$3
230         local tf_cmd="$LFS getstripe -I$comp_id"
231         local opt
232         local expected
233         local value
234
235         case $attr in
236                 stripe-size)
237                         opt="-S"
238                         expected=$($LCTL get_param -n \
239                                    lov.$FSNAME-clilov-*.stripesize)
240                         ;;
241                 stripe-count)
242                         opt="-c"
243                         expected=$($LCTL get_param -n \
244                                    lov.$FSNAME-clilov-*.stripecount)
245                         [[ $expected = -1 ]] && expected=$OSTCOUNT
246                         ;;
247                 *) error "invalid attribute $attr";;
248         esac
249
250         value=$($tf_cmd $opt $tf)
251         [[ $value = -1 ]] && value=$OSTCOUNT
252
253         [[ $value = $expected ]] || {
254                 $tf_cmd -v $tf
255                 error "verify $attr failed with default value on $tf:" \
256                       "$value != $expected"
257         }
258 }
259
260 #
261 # Verify unspecified component attributes for a given file
262 # and component ID.
263 #
264 # This will only verify the inherited attributes:
265 # stripe size, stripe count and OST pool name
266 #
267 verify_comp_attrs() {
268         local tf=$1
269         local comp_id=$2
270
271         verify_comp_attr_with_default stripe-size $tf $comp_id
272         verify_comp_attr_with_default stripe-count $tf $comp_id
273         verify_comp_attr_with_parent pool $tf $comp_id
274 }
275
276 verify_flr_state()
277 {
278         local tf=$1
279         local expected_state=$2
280
281         local state=$($LFS getstripe -v $tf | awk '/lcm_flags/{ print $2 }')
282         [ $expected_state = $state ] ||
283                 error "expected: $expected_state, actual $state"
284 }
285
286 # command line test cases
287 test_0a() {
288         local td=$DIR/$tdir
289         local tf=$td/$tfile
290         local mirror_count=16 # LUSTRE_MIRROR_COUNT_MAX
291         local mirror_cmd="$LFS mirror create"
292         local id
293         local ids
294         local i
295
296         # create parent directory
297         mkdir $td || error "mkdir $td failed"
298
299         $mirror_cmd $tf &> /dev/null && error "miss -N option"
300
301         $mirror_cmd -N $tf || error "create mirrored file $tf failed"
302         verify_mirror_count $tf 1
303         id=$($LFS getstripe -I $tf)
304         verify_comp_attrs $tf $id
305         verify_comp_extent $tf $id 0 EOF
306
307         $mirror_cmd -N0 $tf-1 &> /dev/null && error "invalid mirror count 0"
308         $mirror_cmd -N$((mirror_count + 1)) $tf-1 &> /dev/null &&
309                 error "invalid mirror count $((mirror_count + 1))"
310
311         $mirror_cmd -N$mirror_count $tf-1 ||
312                 error "create mirrored file $tf-1 failed"
313         verify_mirror_count $tf-1 $mirror_count
314         ids=($($LFS getstripe $tf-1 | awk '/lcme_id/{print $2}' | tr '\n' ' '))
315         for ((i = 0; i < $mirror_count; i++)); do
316                 verify_comp_attrs $tf-1 ${ids[$i]}
317                 verify_comp_extent $tf-1 ${ids[$i]} 0 EOF
318         done
319
320         $mirror_cmd -N -N2 -N3 -N4 $tf-2 ||
321                 error "create mirrored file $tf-2 failed"
322         verify_mirror_count $tf-2 10
323         ids=($($LFS getstripe $tf-2 | awk '/lcme_id/{print $2}' | tr '\n' ' '))
324         for ((i = 0; i < 10; i++)); do
325                 verify_comp_attrs $tf-2 ${ids[$i]}
326                 verify_comp_extent $tf-2 ${ids[$i]} 0 EOF
327         done
328 }
329 run_test 0a "lfs mirror create with -N option"
330
331 test_0b() {
332         [[ $OSTCOUNT -lt 4 ]] && skip "need >= 4 OSTs" && return
333
334         local td=$DIR/$tdir
335         local tf=$td/$tfile
336         local mirror_cmd="$LFS mirror create"
337         local ids
338         local i
339
340         # create a new OST pool
341         local pool_name=$TESTNAME
342         create_pool $FSNAME.$pool_name ||
343                 error "create OST pool $pool_name failed"
344
345         # add OSTs into the pool
346         pool_add_targets $pool_name 0 $((OSTCOUNT - 1)) ||
347                 error "add OSTs into pool $pool_name failed"
348
349         # create parent directory
350         mkdir $td || error "mkdir $td failed"
351         $LFS setstripe -S 8M -c -1 -p $pool_name $td ||
352                 error "$LFS setstripe $td failed"
353
354         # create a mirrored file with plain layout mirrors
355         $mirror_cmd -N -N -S 4M -c 2 -p flash -i 2 -o 2,3 \
356                     -N -S 16M -N -c -1 -N -p archive -N -p none $tf ||
357                 error "create mirrored file $tf failed"
358         verify_mirror_count $tf 6
359         ids=($($LFS getstripe $tf | awk '/lcme_id/{print $2}' | tr '\n' ' '))
360         for ((i = 0; i < 6; i++)); do
361                 verify_comp_extent $tf ${ids[$i]} 0 EOF
362         done
363
364         # verify component ${ids[0]}
365         verify_comp_attrs $tf ${ids[0]}
366
367         # verify component ${ids[1]}
368         verify_comp_attr stripe-size $tf ${ids[1]} 4194304
369         verify_comp_attr stripe-count $tf ${ids[1]} 2
370         verify_comp_attr stripe-index $tf ${ids[1]} 2
371         verify_comp_attr pool $tf ${ids[1]} flash
372
373         # verify component ${ids[2]}
374         verify_comp_attr stripe-size $tf ${ids[2]} 16777216
375         verify_comp_attr stripe-count $tf ${ids[2]} 2
376         verify_comp_attr pool $tf ${ids[2]} flash
377
378         # verify component ${ids[3]}
379         verify_comp_attr stripe-size $tf ${ids[3]} 16777216
380         verify_comp_attr stripe-count $tf ${ids[3]} $OSTCOUNT
381         verify_comp_attr pool $tf ${ids[3]} flash
382
383         # verify component ${ids[4]}
384         verify_comp_attr stripe-size $tf ${ids[4]} 16777216
385         verify_comp_attr stripe-count $tf ${ids[4]} $OSTCOUNT
386         verify_comp_attr pool $tf ${ids[4]} archive
387
388         # verify component ${ids[5]}
389         verify_comp_attr stripe-size $tf ${ids[5]} 16777216
390         verify_comp_attr stripe-count $tf ${ids[5]} $OSTCOUNT
391         verify_comp_attr_with_parent pool $tf ${ids[5]}
392
393         if [ $MDS1_VERSION -ge $(version_code 2.12.55) ]; then
394                 # LU-11022 - remove mirror by pool name
395                 local=cnt cnt=$($LFS getstripe $tf | grep archive | wc -l)
396                 [ "$cnt" != "1" ] && error "unexpected mirror count $cnt"
397                 $LFS mirror delete --pool archive $tf || error "delete mirror"
398                 cnt=$($LFS getstripe $tf | grep archive | wc -l)
399                 [ "$cnt" != "0" ] && error "mirror count after removal: $cnt"
400         fi
401
402         # destroy OST pool
403         destroy_test_pools
404 }
405 run_test 0b "lfs mirror create plain layout mirrors"
406
407 test_0c() {
408         [[ $OSTCOUNT -lt 4 ]] && skip "need >= 4 OSTs" && return
409
410         local td=$DIR/$tdir
411         local tf=$td/$tfile
412         local mirror_cmd="$LFS mirror create"
413         local ids
414         local i
415
416         # create a new OST pool
417         local pool_name=$TESTNAME
418         create_pool $FSNAME.$pool_name ||
419                 error "create OST pool $pool_name failed"
420
421         # add OSTs into the pool
422         pool_add_targets $pool_name 0 $((OSTCOUNT - 1)) ||
423                 error "add OSTs into pool $pool_name failed"
424
425         # create parent directory
426         mkdir $td || error "mkdir $td failed"
427         $LFS setstripe -E 32M -S 8M -c -1 -p $pool_name -E eof -S 16M $td ||
428                 error "$LFS setstripe $td failed"
429
430         # create a mirrored file with composite layout mirrors
431         $mirror_cmd -N2 -E 4M -c 2 -p flash -i 1 -o 1,3 -E eof -S 4M \
432                     -N -c 4 -p none \
433                     -N3 -E 512M -S 16M -p archive -E -1 -i -1 -c -1 $tf ||
434                 error "create mirrored file $tf failed"
435         verify_mirror_count $tf 6
436         ids=($($LFS getstripe $tf | awk '/lcme_id/{print $2}' | tr '\n' ' '))
437
438         # verify components ${ids[0]} and ${ids[2]}
439         for i in 0 2; do
440                 verify_comp_attr_with_default stripe-size $tf ${ids[$i]}
441                 verify_comp_attr stripe-count $tf ${ids[$i]} 2
442                 verify_comp_attr stripe-index $tf ${ids[$i]} 1
443                 verify_comp_attr pool $tf ${ids[$i]} flash
444                 verify_comp_extent $tf ${ids[$i]} 0 4194304
445         done
446
447         # verify components ${ids[1]} and ${ids[3]}
448         for i in 1 3; do
449                 verify_comp_attr stripe-size $tf ${ids[$i]} 4194304
450                 verify_comp_attr stripe-count $tf ${ids[$i]} 2
451                 verify_comp_attr pool $tf ${ids[$i]} flash
452                 verify_comp_extent $tf ${ids[$i]} 4194304 EOF
453         done
454
455         # verify component ${ids[4]}
456         verify_comp_attr stripe-size $tf ${ids[4]} 4194304
457         verify_comp_attr stripe-count $tf ${ids[4]} 4
458         verify_comp_attr_with_parent pool $tf ${ids[4]}
459         verify_comp_extent $tf ${ids[4]} 0 EOF
460
461         # verify components ${ids[5]}, ${ids[7]} and ${ids[9]}
462         for i in 5 7 9; do
463                 verify_comp_attr stripe-size $tf ${ids[$i]} 16777216
464                 verify_comp_attr stripe-count $tf ${ids[$i]} 4
465                 verify_comp_attr pool $tf ${ids[$i]} archive
466                 verify_comp_extent $tf ${ids[$i]} 0 536870912
467         done
468
469         # verify components ${ids[6]}, ${ids[8]} and ${ids[10]}
470         for i in 6 8 10; do
471                 verify_comp_attr stripe-size $tf ${ids[$i]} 16777216
472                 verify_comp_attr stripe-count $tf ${ids[$i]} -1
473                 verify_comp_attr pool $tf ${ids[$i]} archive
474                 verify_comp_extent $tf ${ids[$i]} 536870912 EOF
475         done
476
477         # destroy OST pool
478         destroy_test_pools
479 }
480 run_test 0c "lfs mirror create composite layout mirrors"
481
482 test_0d() {
483         local td=$DIR/$tdir
484         local tf=$td/$tfile
485         local mirror_count=16 # LUSTRE_MIRROR_COUNT_MAX
486         local mirror_cmd="$LFS mirror extend"
487         local ids
488         local i
489
490         # create parent directory
491         mkdir $td || error "mkdir $td failed"
492
493         $mirror_cmd $tf &> /dev/null && error "miss -N option"
494         $mirror_cmd -N $tf &> /dev/null && error "$tf does not exist"
495
496         # create a non-mirrored file, convert it to a mirrored file and extend
497         touch $tf || error "touch $tf failed"
498         $mirror_cmd -N $tf || error "convert and extend $tf failed"
499         verify_mirror_count $tf 2
500         ids=($($LFS getstripe $tf | awk '/lcme_id/{print $2}' | tr '\n' ' '))
501         for ((i = 0; i < 2; i++)); do
502                 verify_comp_attrs $tf ${ids[$i]}
503                 verify_comp_extent $tf ${ids[$i]} 0 EOF
504         done
505
506         lfsck_verify_pfid $tf || error "PFID is not set"
507
508         # create a mirrored file and extend it
509         $LFS mirror create -N $tf-1 || error "create mirrored file $tf-1 failed"
510         $LFS mirror create -N $tf-2 || error "create mirrored file $tf-2 failed"
511
512         $mirror_cmd -N -S 4M -N -f $tf-2 $tf-1 &> /dev/null &&
513                 error "setstripe options should not be specified with -f option"
514
515         $mirror_cmd -N$((mirror_count - 1)) $tf-1 ||
516                 error "extend mirrored file $tf-1 failed"
517         verify_mirror_count $tf-1 $mirror_count
518         ids=($($LFS getstripe $tf-1 | awk '/lcme_id/{print $2}' | tr '\n' ' '))
519         for ((i = 0; i < $mirror_count; i++)); do
520                 verify_comp_attrs $tf-1 ${ids[$i]}
521                 verify_comp_extent $tf-1 ${ids[$i]} 0 EOF
522         done
523
524         $mirror_cmd -N $tf-1 &> /dev/null &&
525                 error "exceeded maximum mirror count $mirror_count" || true
526 }
527 run_test 0d "lfs mirror extend with -N option"
528
529 test_0e() {
530         [[ $OSTCOUNT -lt 4 ]] && skip "need >= 4 OSTs" && return
531
532         local td=$DIR/$tdir
533         local tf=$td/$tfile
534         local mirror_cmd="$LFS mirror extend"
535         local ids
536         local i
537
538         # create parent directory
539         mkdir $td || error "mkdir $td failed"
540
541         # create a mirrored file with plain layout mirrors
542         $LFS mirror create -N -S 32M -c 3 -p ssd -i 1 -o 1,2,3 $tf ||
543                 error "create mirrored file $tf failed"
544
545         # extend the mirrored file with plain layout mirrors
546         $mirror_cmd -N -S 4M -c 2 -p flash -i 2 -o 2,3 \
547                     -N -S 16M -N -c -1 -N -p archive -N -p none $tf ||
548                 error "extend mirrored file $tf failed"
549         verify_mirror_count $tf 6
550         ids=($($LFS getstripe $tf | awk '/lcme_id/{print $2}' | tr '\n' ' '))
551         for ((i = 0; i < 6; i++)); do
552                 verify_comp_extent $tf ${ids[$i]} 0 EOF
553         done
554
555         # verify component ${ids[0]}
556         verify_comp_attr stripe-size $tf ${ids[0]} 33554432
557         verify_comp_attr stripe-count $tf ${ids[0]} 3
558         verify_comp_attr stripe-index $tf ${ids[0]} 1
559         verify_comp_attr pool $tf ${ids[0]} ssd
560
561         # verify component ${ids[1]}
562         verify_comp_attr stripe-size $tf ${ids[1]} 4194304
563         verify_comp_attr stripe-count $tf ${ids[1]} 2
564         verify_comp_attr stripe-index $tf ${ids[1]} 2
565         verify_comp_attr pool $tf ${ids[1]} flash
566
567         # verify component ${ids[2]}
568         verify_comp_attr stripe-size $tf ${ids[2]} 16777216
569         verify_comp_attr stripe-count $tf ${ids[2]} 2
570         verify_comp_attr pool $tf ${ids[2]} flash
571
572         # verify component ${ids[3]}
573         verify_comp_attr stripe-size $tf ${ids[3]} 16777216
574         verify_comp_attr stripe-count $tf ${ids[3]} $OSTCOUNT
575         verify_comp_attr pool $tf ${ids[3]} flash
576
577         # verify component ${ids[4]}
578         verify_comp_attr stripe-size $tf ${ids[4]} 16777216
579         verify_comp_attr stripe-count $tf ${ids[4]} $OSTCOUNT
580         verify_comp_attr pool $tf ${ids[4]} archive
581
582         # verify component ${ids[5]}
583         verify_comp_attr stripe-size $tf ${ids[5]} 16777216
584         verify_comp_attr stripe-count $tf ${ids[5]} $OSTCOUNT
585         verify_comp_attr_with_parent pool $tf ${ids[5]}
586 }
587 run_test 0e "lfs mirror extend plain layout mirrors"
588
589 test_0f() {
590         [[ $OSTCOUNT -lt 4 ]] && skip "need >= 4 OSTs" && return
591
592         local td=$DIR/$tdir
593         local tf=$td/$tfile
594         local mirror_cmd="$LFS mirror extend"
595         local ids
596         local i
597
598         # create parent directory
599         mkdir $td || error "mkdir $td failed"
600
601         # create a mirrored file with composite layout mirror
602         $LFS mirror create -N -E 32M -S 16M -p ssd -E eof -S 32M $tf ||
603                 error "create mirrored file $tf failed"
604
605         # extend the mirrored file with composite layout mirrors
606         $mirror_cmd -N2 -E 4M -c 2 -p flash -i 1 -o 1,3 -E eof -S 4M \
607                     -N -c -1 -p none \
608                     -N3 -E 512M -S 16M -p archive -E -1 -i -1 -c -1 $tf ||
609                 error "extend mirrored file $tf failed"
610         verify_mirror_count $tf 7
611         ids=($($LFS getstripe $tf | awk '/lcme_id/{print $2}' | tr '\n' ' '))
612
613         # verify component ${ids[0]}
614         verify_comp_attr stripe-size $tf ${ids[0]} 16777216
615         verify_comp_attr_with_default stripe-count $tf ${ids[0]}
616         verify_comp_attr pool $tf ${ids[0]} ssd
617         verify_comp_extent $tf ${ids[0]} 0 33554432
618
619         # verify component ${ids[1]}
620         verify_comp_attr stripe-size $tf ${ids[1]} 33554432
621         verify_comp_attr_with_default stripe-count $tf ${ids[1]}
622         verify_comp_attr pool $tf ${ids[1]} ssd
623         verify_comp_extent $tf ${ids[1]} 33554432 EOF
624
625         # verify components ${ids[2]} and ${ids[4]}
626         for i in 2 4; do
627                 verify_comp_attr_with_default stripe-size $tf ${ids[$i]}
628                 verify_comp_attr stripe-count $tf ${ids[$i]} 2
629                 verify_comp_attr stripe-index $tf ${ids[$i]} 1
630                 verify_comp_attr pool $tf ${ids[$i]} flash
631                 verify_comp_extent $tf ${ids[$i]} 0 4194304
632         done
633
634         # verify components ${ids[3]} and ${ids[5]}
635         for i in 3 5; do
636                 verify_comp_attr stripe-size $tf ${ids[$i]} 4194304
637                 verify_comp_attr stripe-count $tf ${ids[$i]} 2
638                 verify_comp_attr pool $tf ${ids[$i]} flash
639                 verify_comp_extent $tf ${ids[$i]} 4194304 EOF
640         done
641
642         # verify component ${ids[6]}
643         verify_comp_attr stripe-size $tf ${ids[6]} 4194304
644         verify_comp_attr stripe-count $tf ${ids[6]} $OSTCOUNT
645         verify_comp_attr_with_parent pool $tf ${ids[6]}
646         verify_comp_extent $tf ${ids[6]} 0 EOF
647
648         # verify components ${ids[7]}, ${ids[9]} and ${ids[11]}
649         for i in 7 9 11; do
650                 verify_comp_attr stripe-size $tf ${ids[$i]} 16777216
651                 verify_comp_attr stripe-count $tf ${ids[$i]} $OSTCOUNT
652                 verify_comp_attr pool $tf ${ids[$i]} archive
653                 verify_comp_extent $tf ${ids[$i]} 0 536870912
654         done
655
656         # verify components ${ids[8]}, ${ids[10]} and ${ids[12]}
657         for i in 8 10 12; do
658                 verify_comp_attr stripe-size $tf ${ids[$i]} 16777216
659                 verify_comp_attr stripe-count $tf ${ids[$i]} -1
660                 verify_comp_attr pool $tf ${ids[$i]} archive
661                 verify_comp_extent $tf ${ids[$i]} 536870912 EOF
662         done
663 }
664 run_test 0f "lfs mirror extend composite layout mirrors"
665
666 test_0g() {
667         local tf=$DIR/$tfile
668
669         $LFS mirror create -N -E 1M -S 1M -o0 --flags=prefer -E eof -o1 \
670                            -N -o1 $tf || error "create mirrored file $tf failed"
671
672         verify_comp_attr lcme_flags $tf 0x10001 prefer
673         verify_comp_attr lcme_flags $tf 0x10002 prefer
674
675         # write to the mirrored file and check primary
676         cp /etc/hosts $tf || error "error writing file '$tf'"
677
678         verify_comp_attr lcme_flags $tf 0x20003 stale
679
680         # resync file and check prefer flag
681         $LFS mirror resync $tf || error "error resync-ing file '$tf'"
682
683         cancel_lru_locks osc
684         $LCTL set_param osc.*.stats=clear
685         cat $tf &> /dev/null || error "error reading file '$tf'"
686
687         # verify that the data was provided by OST1 where mirror 1 resides
688         local nr_read=$($LCTL get_param -n osc.$FSNAME-OST0000-osc-[-0-9a-f]*.stats |
689                         awk '/ost_read/{print $2}')
690         [ -n "$nr_read" ] || error "read was not provided by OST1"
691 }
692 run_test 0g "lfs mirror create flags support"
693
694 test_0h() {
695         [ $MDS1_VERSION -lt $(version_code 2.11.57) ] &&
696                 skip "Need MDS version at least 2.11.57"
697
698         local td=$DIR/$tdir
699         local tf=$td/$tfile
700         local ids
701         local i
702
703         # create parent directory
704         test_mkdir $td || error "mkdir $td failed"
705
706         $LFS setstripe -N -E 1M -S 1M --flags=prefer -E eof -N2 $td ||
707                 error "set default mirrored layout on directory $td failed"
708
709         # verify flags are inherited from the directory
710         touch $tf
711
712         verify_comp_attr lcme_flags $tf 0x10001 prefer
713         verify_comp_attr lcme_flags $tf 0x10002 prefer
714
715         # set flags to the first component
716         $LFS setstripe --comp-set -I 0x10001 --comp-flags=^prefer,stale $tf
717
718         verify_comp_attr lcme_flags $tf 0x10001 stale
719         verify_comp_attr lcme_flags $tf 0x10002 prefer
720
721         $LFS setstripe --comp-set -I0x10001 --comp-flags=^stale $tf &&
722                 error "clearing 'stale' should fail"
723
724         # write and resync file. It can't resync the file directly because the
725         # file state is still 'ro'
726         cp /etc/hosts $tf || error "error writing file '$tf'"
727         $LFS mirror resync $tf || error "error resync-ing file '$tf'"
728
729         $LFS setstripe --comp-set -I 0x20003 --comp-flags=prefer $tf ||
730                 error "error setting flag prefer"
731
732         verify_comp_attr lcme_flags $tf 0x20003 prefer
733
734         $LFS setstripe --comp-set -I 0x20003 --comp-flags=^prefer $tf ||
735                 error "error clearing prefer flag from component 0x20003"
736
737         # MDS disallows setting stale flag on the last non-stale mirror
738         [[ "$MDS1_VERSION" -ge $(version_code 2.12.57) ]] || return 0
739
740         cp /etc/hosts $tf || error "error writing file '$tf'"
741
742         verify_comp_attr lcme_flags $tf 0x10002 prefer
743         verify_comp_attr lcme_flags $tf 0x20003 stale
744         verify_comp_attr lcme_flags $tf 0x30004 stale
745
746         ! $LFS setstripe --comp-set -I 0x10002 --comp-flags=^prefer,stale $tf \
747                 > /dev/null 2>&1 ||
748                 error "setting stale flag on component 0x10002 should fail"
749
750         $LFS mirror resync $tf || error "error resync-ing file '$tf'"
751
752         $LFS setstripe --comp-set -I 0x10001 --comp-flags=stale $tf ||
753                 error "error setting stale flag on component 0x10001"
754         $LFS setstripe --comp-set -I 0x20003 --comp-flags=stale $tf ||
755                 error "error setting stale flag on component 0x20003"
756
757         ! $LFS setstripe --comp-set -I 0x30004 --comp-flags=stale $tf \
758                 > /dev/null 2>&1 ||
759                 error "setting stale flag on component 0x30004 should fail"
760
761         $LFS mirror resync $tf || error "error resync-ing file '$tf'"
762 }
763 run_test 0h "set, clear and test flags for FLR files"
764
765 test_1() {
766         local tf=$DIR/$tfile
767         local mirror_count=16 # LUSTRE_MIRROR_COUNT_MAX
768         local mirror_create_cmd="$LFS mirror create"
769         local stripes[0]=$OSTCOUNT
770
771         mirror_create_cmd+=" -N -c ${stripes[0]}"
772         for ((i = 1; i < $mirror_count; i++)); do
773                 # add mirrors with different stripes to the file
774                 stripes[$i]=$((RANDOM % OSTCOUNT))
775                 [ ${stripes[$i]} -eq 0 ] && stripes[$i]=1
776
777                 mirror_create_cmd+=" -N -c ${stripes[$i]}"
778         done
779
780         $mirror_create_cmd $tf || error "create mirrored file $tf failed"
781         verify_mirror_count $tf $mirror_count
782
783         # can't create mirrors exceeding LUSTRE_MIRROR_COUNT_MAX
784         $LFS mirror extend -N $tf &&
785                 error "Creating the $((mirror_count+1))th mirror succeeded"
786
787         local ids=($($LFS getstripe $tf | awk '/lcme_id/{print $2}' |
788                         tr '\n' ' '))
789
790         # verify the range of components and stripe counts
791         for ((i = 0; i < $mirror_count; i++)); do
792                 verify_comp_attr stripe-count $tf ${ids[$i]} ${stripes[$i]}
793                 verify_comp_extent $tf ${ids[$i]} 0 EOF
794         done
795 }
796 run_test 1 "create components with setstripe options"
797
798 test_2() {
799         local tf=$DIR/$tfile
800         local tf2=$DIR/$tfile-2
801
802         $LFS setstripe -E 1M -S 1M -E EOF -c 1 $tf
803         $LFS setstripe -E 2M -S 1M -E EOF -c -1 $tf2
804
805         $LFS mirror extend -N -f $tf2 $tf ||
806                 error "merging $tf2 into $tf failed"
807
808         verify_mirror_count $tf 2
809         [[ ! -e $tf2 ]] || error "$tf2 was not unlinked"
810 }
811 run_test 2 "create components from existing files"
812
813 test_3() {
814         [[ $MDSCOUNT -lt 2 ]] && skip "need >= 2 MDTs" && return
815
816         for ((i = 0; i < 2; i++)); do
817                 $LFS mkdir -i $i $DIR/$tdir-$i
818                 $LFS setstripe -E -1 $DIR/$tdir-$i/$tfile
819         done
820
821         $LFS mirror extend -N -f $DIR/$tdir-1/$tfile \
822                 $DIR/$tdir-0/$tfile || error "creating mirrors"
823
824         # mdt doesn't support to cancel layout lock for remote objects, do
825         # it here manually.
826         cancel_lru_locks mdc
827
828         # make sure the mirrorted file was created successfully
829         [[ $($LFS getstripe --component-count $DIR/$tdir-0/$tfile) -eq 2 ]] ||
830                 { $LFS getstripe $DIR/$tdir-0/$tfile;
831                         error "expected 2 components"; }
832
833         # cleanup
834         rm -rf $DIR/$tdir-*
835 }
836 run_test 3 "create components from files located on different MDTs"
837
838 test_4() {
839         local tf=$DIR/$tdir/$tfile
840         local ids=()
841
842         test_mkdir $DIR/$tdir
843
844         # set mirror with setstripe options to directory
845         $LFS mirror create -N2 -E 1M -S 1M -E eof $DIR/$tdir ||
846                 error "set mirror to directory error"
847
848         [ x$($LFS getstripe -v $DIR/$tdir | awk '/lcm_flags/{print $2}') = \
849                 x"mirrored" ] || error "failed to create mirrored dir"
850
851         touch $tf
852         verify_mirror_count $tf 2
853
854         ids=($($LFS getstripe $tf | awk '/lcme_id/{print $2}' | tr '\n' ' '))
855         verify_comp_extent $tf ${ids[0]} 0 1048576
856         verify_comp_extent $tf ${ids[1]} 1048576 EOF
857
858         # sub directory should inherit mirror setting from parent
859         test_mkdir $DIR/$tdir/td
860         [ x$($LFS getstripe -v $DIR/$tdir/td | awk '/lcm_flags/{print $2}') = \
861                 x"mirrored" ] || error "failed to inherit mirror from parent"
862
863         # mirror extend won't be applied to directory
864         $LFS mirror extend -N2 $DIR/$tdir &&
865                 error "expecting mirror extend failure"
866         true
867 }
868 run_test 4 "Make sure mirror attributes can be inhertied from directory"
869
870 test_5() {
871         local tf=$DIR/$tfile
872         local ids=()
873
874         $MULTIOP $tf oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T12345c ||
875                 error "failed to create file with non-empty layout"
876         $CHECKSTAT -t file -s 12345 $tf || error "size error: expecting 12345"
877
878         $LFS mirror create -N3 $tf || error "failed to attach mirror layout"
879         verify_mirror_count $tf 3
880
881         $CHECKSTAT -t file -s 12345 $tf ||
882                 error "size error after attaching layout "
883 }
884 run_test 5 "Make sure init size work for mirrored layout"
885
886 # LU=10112: disable dom+flr for phase 1
887 test_6() {
888         local tf=$DIR/$tfile
889
890         $LFS mirror create -N -E 1M -S 1M -L mdt -E eof -N -E eof $tf &&
891                 error "expect failure to create mirrored file with DoM"
892
893         $LFS mirror create -N -E 1M -S 1M -E eof -N -E 1M -L mdt -E eof $tf &&
894                 error "expect failure to create mirrored file with DoM"
895
896         $LFS setstripe -E 1M -S 1M -L mdt -E eof $tf
897         $LFS mirror extend -N2 $tf &&
898                 error "expect failure to extend mirror with DoM"
899
900         $LFS mirror create -N2 -E 1M -S 1M -E eof $tf-2
901         $LFS mirror extend -N -f $tf $tf-2 &&
902                 error "expect failure to extend mirrored file with DoM extent"
903
904         true
905 }
906 run_test 6 "DoM and FLR won't co-exist for phase 1"
907
908 test_21() {
909         local tf=$DIR/$tfile
910         local tf2=$DIR/$tfile-2
911
912         [[ $OSTCOUNT -lt 2 ]] && skip "need >= 2 OSTs" && return
913
914         $LFS setstripe -E EOF -o 0 $tf
915         $LFS setstripe -E EOF -o 1 $tf2
916
917         local dd_count=$((RANDOM % 20 + 1))
918         dd if=/dev/zero of=$tf bs=1M count=$dd_count oflag=sync
919         dd if=/dev/zero of=$tf2 bs=1M count=1 seek=$((dd_count - 1)) oflag=sync
920
921         # for zfs - sync OST dataset so that du below will return
922         # accurate results
923         [ "$FSTYPE" = "zfs" ] &&
924                 do_nodes $(comma_list $(osts_nodes)) "$ZPOOL sync"
925
926         local blocks=$(du -kc $tf $tf2 | awk '/total/{print $1}')
927
928         # add component
929         $LFS mirror extend -N -f $tf2 $tf ||
930                 error "merging $tf2 into $tf failed"
931
932         # cancel layout lock
933         cancel_lru_locks mdc
934
935         local new_blocks=$(du -k $tf | awk '{print $1}')
936         [ $new_blocks -eq $blocks ] ||
937         error "i_blocks error expected: $blocks, actual: $new_blocks"
938 }
939 run_test 21 "glimpse should report accurate i_blocks"
940
941 get_osc_lock_count() {
942         local lock_count=0
943
944         for idx in "$@"; do
945                 local osc_name
946                 local count
947
948                 osc_name=${FSNAME}-OST$(printf "%04x" $((idx-1)))-osc-'[-0-9a-f]*'
949                 count=$($LCTL get_param -n ldlm.namespaces.$osc_name.lock_count)
950                 lock_count=$((lock_count + count))
951         done
952         echo $lock_count
953 }
954
955 test_22() {
956         local tf=$DIR/$tfile
957
958         $LFS setstripe -E EOF -o 0 $tf
959         dd if=/dev/zero of=$tf bs=1M count=$((RANDOM % 20 + 1))
960
961         # add component, two mirrors located on the same OST ;-)
962         $LFS mirror extend -N -o 0 $tf ||
963                 error "extending mirrored file $tf failed"
964
965         size_blocks=$(stat --format="%b %s" $tf)
966
967         cancel_lru_locks mdc
968         cancel_lru_locks osc
969
970         local new_size_blocks=$(stat --format="%b %s" $tf)
971
972         # make sure there is no lock cached
973         [ $(get_osc_lock_count 1) -eq 0 ] || error "glimpse requests were sent"
974
975         [ "$new_size_blocks" = "$size_blocks" ] ||
976                 echo "size expected: $size_blocks, actual: $new_size_blocks"
977
978         rm -f $tmpfile
979 }
980 run_test 22 "no glimpse to OSTs for READ_ONLY files"
981
982 test_31() {
983         local tf=$DIR/$tfile
984
985         $LFS mirror create -N -o 0 -N -o 1 $tf ||
986                 error "creating mirrored file $tf failed"
987
988         #define OBD_FAIL_GLIMPSE_IMMUTABLE 0x1A00
989         $LCTL set_param fail_loc=0x1A00
990
991         local ost_idx
992         for ((ost_idx = 1; ost_idx <= 2; ost_idx++)); do
993                 cancel_lru_locks osc
994                 stop_osts $ost_idx
995
996                 local tmpfile=$(mktemp)
997                 stat --format="%b %s" $tf > $tmpfile  &
998                 local pid=$!
999
1000                 local cnt=0
1001                 while [ $cnt -le 5 ]; do
1002                         kill -0 $pid > /dev/null 2>&1 || break
1003                         sleep 1
1004                         ((cnt += 1))
1005                 done
1006                 kill -0 $pid > /dev/null 2>&1 &&
1007                         error "stat process stuck due to unavailable OSTs"
1008
1009                 # make sure glimpse request has been sent
1010                 [ $(get_osc_lock_count 1 2) -ne 0 ] ||
1011                         error "OST $ost_idx: no glimpse request was sent"
1012
1013                 start_osts $ost_idx
1014         done
1015 }
1016 run_test 31 "make sure glimpse request can be retried"
1017
1018 test_32() {
1019         [[ $OSTCOUNT -lt 2 ]] && skip "need >= 2 OSTs" && return
1020         rm -f $DIR/$tfile $DIR/$tfile-2
1021
1022         $LFS setstripe -E EOF -o 0 $DIR/$tfile
1023         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=$((RANDOM % 10 + 2))
1024
1025         local fsize=$(stat -c %s $DIR/$tfile)
1026         [[ $fsize -ne 0 ]] || error "file size is (wrongly) zero"
1027
1028         local cksum=$(md5sum $DIR/$tfile)
1029
1030         # create a new mirror in sync mode
1031         $LFS mirror extend -N -o 1 $DIR/$tfile ||
1032                 error "extending mirrored file $DIR/$tfile failed"
1033
1034         # make sure the mirrored file was created successfully
1035         [ $($LFS getstripe -N $DIR/$tfile) -eq 2 ] ||
1036                 { $LFS getstripe $DIR/$tfile; error "expected 2 mirrors"; }
1037
1038         drop_client_cache
1039         stop_osts 1
1040
1041         # check size is correct, glimpse request should go to the 2nd mirror
1042         $CHECKSTAT -t file -s $fsize $DIR/$tfile ||
1043                 error "file size error $fsize vs. $(stat -c %s $DIR/$tfile)"
1044
1045         echo "reading file from the 2nd mirror and verify checksum"
1046         [[ "$cksum" == "$(md5sum $DIR/$tfile)" ]] ||
1047                 error "checksum error: expected $cksum"
1048
1049         start_osts 1
1050 }
1051 run_test 32 "data should be mirrored to newly created mirror"
1052
1053 test_33a() {
1054         [[ $OSTCOUNT -lt 2 ]] && skip "need >= 2 OSTs" && return
1055
1056         rm -f $DIR/$tfile $DIR/$tfile-2
1057
1058         # create a file with two mirrors
1059         $LFS setstripe -E EOF -o 0 $DIR/$tfile
1060         local max_count=100
1061         local count=0
1062         while [ $count -lt $max_count ]; do
1063                 echo "ost1" >> $DIR/$tfile
1064                 count=$((count + 1));
1065         done
1066
1067         # tmp file that will be used as mirror
1068         $LFS setstripe -E EOF -o 1 $DIR/$tfile-2
1069         count=0
1070         while [ $count -lt $max_count ]; do
1071                 echo "ost2" >> $DIR/$tfile-2
1072                 count=$((count + 1));
1073         done
1074
1075         # create a mirrored file
1076         $LFS mirror extend -N -f $DIR/$tfile-2 $DIR/$tfile &&
1077                 error "merging $DIR/$tfile-2 into $DIR/$tfile" \
1078                       "with verification should fail"
1079         $LFS mirror extend --no-verify -N -f $DIR/$tfile-2 $DIR/$tfile ||
1080                 error "merging $DIR/$tfile-2 into $DIR/$tfile" \
1081                       "without verification failed"
1082
1083         # make sure that $tfile has two mirrors and $tfile-2 does not exist
1084         [ $($LFS getstripe -N $DIR/$tfile) -eq 2 ] ||
1085                 { $LFS getstripe $DIR/$tfile; error "expected count 2"; }
1086
1087         [[ ! -e $DIR/$tfile-2 ]] || error "$DIR/$tfile-2 was not unlinked"
1088
1089         # execpted file size
1090         local fsize=$((5 * max_count))
1091         $CHECKSTAT -t file -s $fsize $DIR/$tfile ||
1092                 error "mirrored file size is not $fsize"
1093
1094         # read file - all OSTs are available
1095         echo "reading file (data can be provided by any ost)... "
1096         local rs=$(cat $DIR/$tfile | head -1)
1097         [[ "$rs" == "ost1" || "$rs" == "ost2" ]] ||
1098                 error "file content error: expected: \"ost1\" or \"ost2\""
1099
1100         # read file again with ost1 failed
1101         stop_osts 1
1102         drop_client_cache
1103
1104         echo "reading file (data should be provided by ost2)..."
1105         local rs=$(cat $DIR/$tfile | head -1)
1106         [[ "$rs" == "ost2" ]] ||
1107                 error "file content error: expected: \"ost2\", actual: \"$rs\""
1108
1109         # remount ost1
1110         start_osts 1
1111
1112         # read file again with ost2 failed
1113         stop_osts 2
1114         drop_client_cache
1115
1116         # check size, glimpse should work
1117         $CHECKSTAT -t file -s $fsize $DIR/$tfile ||
1118                 error "mirrored file size is not $fsize"
1119
1120         echo "reading file (data should be provided by ost1)..."
1121         local rs=$(cat $DIR/$tfile | head -1)
1122         [[ "$rs" == "ost1" ]] ||
1123                 error "file content error: expected: \"ost1\", actual: \"$rs\""
1124
1125         start_osts 2
1126 }
1127 run_test 33a "read can choose available mirror to read"
1128
1129 test_33b() {
1130         [[ $OSTCOUNT -lt 2 ]] && skip "need >= 2 OSTs" && return
1131
1132         rm -f $DIR/$tfile
1133
1134         stack_trap "rm -f $DIR/$tfile" EXIT
1135
1136         # create a file with two mirrors on OST0000 and OST0001
1137         $LFS setstripe -N -Eeof -o0 -N -Eeof -o1 $DIR/$tfile
1138
1139         # make sure that $tfile has two mirrors
1140         [ $($LFS getstripe -N $DIR/$tfile) -eq 2 ] ||
1141                 { $LFS getstripe $DIR/$tfile; error "expected count 2"; }
1142
1143         # write 50M
1144         dd if=/dev/urandom of=$DIR/$tfile bs=2M count=25 ||
1145                 error "write failed for $DIR/$tfile"
1146         $LFS mirror resync $DIR/$tfile || error "resync failed for $DIR/$tfile"
1147         verify_flr_state $DIR/$tfile "ro"
1148         drop_client_cache
1149
1150         ls -l $DIR/$tfile
1151
1152         # read file - all OSTs are available
1153         echo "reading file (data can be provided by any ost)... "
1154         local t1=$SECONDS
1155         time cat $DIR/$tfile > /dev/null || error "read all"
1156         local t2=$SECONDS
1157         ra=$((t2 - t1))
1158
1159         # read file again with ost1 {OST0000} failed
1160         stop_osts 1
1161         drop_client_cache
1162         echo "reading file (data should be provided by ost2)..."
1163         t1=$SECONDS
1164         time cat $DIR/$tfile > /dev/null || error "read ost2"
1165         t2=$SECONDS
1166         r1=$((t2 - t1))
1167
1168         # remount ost1
1169         start_osts 1
1170
1171         # read file again with ost2 {OST0001} failed
1172         stop_osts 2
1173         drop_client_cache
1174
1175         echo "reading file (data should be provided by ost1)..."
1176         t1=$SECONDS
1177         time cat $DIR/$tfile > /dev/null || error "read ost1"
1178         t2=$SECONDS
1179         r2=$((t2 - t1))
1180
1181         # remount ost2
1182         start_osts 2
1183
1184         [ $((r1 * 100)) -gt $((ra * 105)) -a $r1 -gt $((ra + 2)) ] &&
1185                 error "read mirror too slow without ost1, from $ra to $r1"
1186         [ $((r2 * 100)) -gt $((ra * 105)) -a $r2 -gt $((ra + 2)) ] &&
1187                 error "read mirror too slow without ost2, from $ra to $r2"
1188
1189         wait_osc_import_ready client ost2
1190 }
1191 run_test 33b "avoid reading from unhealthy mirror"
1192
1193 test_33c() {
1194         [[ $OSTCOUNT -lt 3 ]] && skip "need >= 3 OSTs" && return
1195
1196         rm -f $DIR/$tfile
1197
1198         stack_trap "rm -f $DIR/$tfile" EXIT
1199
1200         # create a file with two mirrors
1201         # mirror1: {OST0000, OST0001}
1202         # mirror2: {OST0001, OST0002}
1203         $LFS setstripe -N -Eeof -c2 -o0,1 -N -Eeof -c2 -o1,2 $DIR/$tfile
1204
1205         # make sure that $tfile has two mirrors
1206         [ $($LFS getstripe -N $DIR/$tfile) -eq 2 ] ||
1207                 { $LFS getstripe $DIR/$tfile; error "expected count 2"; }
1208
1209         # write 50M
1210         dd if=/dev/urandom of=$DIR/$tfile bs=2M count=25 ||
1211                 error "write failed for $DIR/$tfile"
1212         $LFS mirror resync $DIR/$tfile || error "resync failed for $DIR/$tfile"
1213         verify_flr_state $DIR/$tfile "ro"
1214         drop_client_cache
1215
1216         ls -l $DIR/$tfile
1217
1218         # read file - all OSTs are available
1219         echo "reading file (data can be provided by any ost)... "
1220         time cat $DIR/$tfile > /dev/null || error "read all"
1221
1222         # read file again with ost2 (OST0001) failed
1223         stop_osts 2
1224         drop_client_cache
1225
1226         echo "reading file (data should be provided by ost1 and ost3)..."
1227         time cat $DIR/$tfile > /dev/null || error "read ost1 & ost3"
1228
1229         # remount ost2
1230         start_osts 2
1231
1232         wait_osc_import_ready client ost2
1233 }
1234 run_test 33c "keep reading among unhealthy mirrors"
1235
1236 test_34a() {
1237         [[ $OSTCOUNT -lt 4 ]] && skip "need >= 4 OSTs" && return
1238
1239         rm -f $DIR/$tfile $DIR/$tfile-2 $DIR/$tfile-ref
1240
1241         # reference file
1242         $LFS setstripe -o 0 $DIR/$tfile-ref
1243         dd if=/dev/urandom of=$DIR/$tfile-ref bs=1M count=3
1244
1245         # create a file with two mirrors
1246         $LFS setstripe -E -1 -o 0,1 -S 1M $DIR/$tfile
1247         dd if=$DIR/$tfile-ref of=$DIR/$tfile bs=1M
1248
1249         $LFS setstripe -E -1 -o 2,3 -S 1M $DIR/$tfile-2
1250         dd if=$DIR/$tfile-ref of=$DIR/$tfile-2 bs=1M
1251
1252         $CHECKSTAT -t file -s $((3 * 1024 * 1024)) $DIR/$tfile ||
1253                 error "mirrored file size is not 3M"
1254
1255         # merge a mirrored file
1256         $LFS mirror extend -N -f $DIR/$tfile-2 $DIR/$tfile ||
1257                 error "merging $DIR/$tfile-2 into $DIR/$tfile failed"
1258
1259         cancel_lru_locks osc
1260
1261         # stop two OSTs, so the 2nd stripe of the 1st mirror and
1262         # the 1st stripe of the 2nd mirror will be inaccessible, ...
1263         stop_osts 2 3
1264
1265         echo "comparing files ... "
1266
1267         # however, read can still return the correct data. It should return
1268         # the 1st stripe from mirror 1 and 2st stripe from mirror 2.
1269         cmp -n 2097152 <(rwv -f $DIR/$tfile -r -o -n 1 2097152) \
1270                 $DIR/$tfile-ref || error "file reading error"
1271
1272         start_osts 2 3
1273 }
1274 run_test 34a "read mirrored file with multiple stripes"
1275
1276 test_34b() {
1277         [[ $OSTCOUNT -lt 4 ]] && skip "need >= 4 OSTs" && return
1278
1279         rm -f $DIR/$tfile $DIR/$tfile-2 $DIR/$tfile-ref
1280
1281         # reference file
1282         $LFS setstripe -o 0 $DIR/$tfile-ref
1283         dd if=/dev/urandom of=$DIR/$tfile-ref bs=1M count=3
1284
1285         $LFS setstripe -E 1M -S 1M -o 0 -E eof -o 1 $DIR/$tfile
1286         dd if=$DIR/$tfile-ref of=$DIR/$tfile bs=1M
1287
1288         $LFS setstripe -E 1M -S 1M -o 2 -E eof -o 3 $DIR/$tfile-2
1289         dd if=$DIR/$tfile-ref of=$DIR/$tfile-2 bs=1M
1290
1291         $CHECKSTAT -t file -s $((3 * 1024 * 1024)) $DIR/$tfile ||
1292                 error "mirrored file size is not 3M"
1293
1294         # merge a mirrored file
1295         $LFS mirror extend -N -f $DIR/$tfile-2 $DIR/$tfile ||
1296                 error "merging $DIR/$tfile-2 into $DIR/$tfile failed"
1297
1298         cancel_lru_locks osc
1299
1300         # stop two OSTs, so the 2nd component of the 1st mirror and
1301         # the 1st component of the 2nd mirror will be inaccessible, ...
1302         stop_osts 2 3
1303
1304         echo "comparing files ... "
1305
1306         # however, read can still return the correct data. It should return
1307         # the 1st stripe from mirror 1 and 2st stripe from mirror 2.
1308         cmp -n 2097152 <(rwv -f $DIR/$tfile -r -o -n 1 2097152) \
1309                 $DIR/$tfile-ref || error "file reading error"
1310
1311         start_osts 2 3
1312 }
1313 run_test 34b "read mirrored file with multiple components"
1314
1315 test_35() {
1316         local tf=$DIR/$tfile
1317
1318         $LFS setstripe -E eof $tf
1319
1320         # add an out-of-sync mirror to the file
1321         $LFS mirror extend -N -c 2 $tf ||
1322                 error "extending mirrored file $tf failed"
1323
1324         $MULTIOP $tf oO_WRONLY:c ||
1325                 error "write open a mirrored file failed"
1326
1327         # truncate file should return error
1328         $TRUNCATE $tf 100 || error "error truncating a mirrored file"
1329 }
1330 run_test 35 "allow to write to mirrored files"
1331
1332 verify_ost_layout_version() {
1333         local tf=$1
1334
1335         # get file layout version
1336         local flv=$($LFS getstripe $tf | awk '/lcm_layout_gen/{print $2}')
1337
1338         # layout version from OST objects
1339         local olv=$($MULTIOP $tf oXc | awk '/ostlayoutversion/{print $2}')
1340
1341         [ $flv -eq $olv ] || error "layout version mismatch: $flv vs. $olv"
1342 }
1343
1344 create_file_36() {
1345         local tf
1346
1347         for tf in "$@"; do
1348                 $LFS setstripe -E 1M -S 1M -E 2M -E 4M -E eof -c -1 $tf
1349                 $LFS setstripe -E 3M -S 1M -E 6M -E eof -c -1 $tf-tmp
1350
1351                 $LFS mirror extend -N -f $tf-tmp $tf ||
1352                         error "merging $tf-tmp into $tf failed"
1353         done
1354 }
1355
1356 test_36() {
1357         local tf=$DIR/$tfile
1358
1359         create_file_36 $tf $tf-2 $tf-3
1360
1361         [ $($LFS getstripe -N $tf) -gt 1 ] || error "wrong mirror count"
1362
1363         # test case 1 - check file write and verify layout version
1364         $MULTIOP $tf oO_WRONLY:c ||
1365                 error "write open a mirrored file failed"
1366
1367         # write open file should not return error
1368         $MULTIOP $tf oO_WRONLY:w1024Yc || error "write mirrored file error"
1369
1370         # instantiate components should work
1371         dd if=/dev/zero of=$tf bs=1M count=12 || error "write file error"
1372
1373         # verify OST layout version
1374         verify_ost_layout_version $tf
1375
1376         # test case 2
1377         local mds_facet=mds$(($($LFS getstripe -m $tf-2) + 1))
1378
1379         local delay_sec=10
1380         do_facet $mds_facet $LCTL set_param fail_val=$delay_sec
1381
1382         #define OBD_FAIL_FLR_LV_DELAY 0x1A01
1383         do_facet $mds_facet $LCTL set_param fail_loc=0x1A01
1384
1385         # write should take at least $fail_loc seconds and succeed
1386         local st=$(date +%s)
1387         $MULTIOP $tf-2 oO_WRONLY:w1024Yc || error "write mirrored file error"
1388
1389         [ $(date +%s) -ge $((st+delay_sec)) ] ||
1390                 error "write finished before layout version is transmitted"
1391
1392         # verify OST layout version
1393         verify_ost_layout_version $tf
1394
1395         do_facet $mds_facet $LCTL set_param fail_loc=0
1396
1397         # test case 3
1398         mds_idx=mds$(($($LFS getstripe -m $tf-3) + 1))
1399
1400         #define OBD_FAIL_FLR_LV_INC 0x1A02
1401         do_facet $mds_facet $LCTL set_param fail_loc=0x1A02
1402
1403         # write open file should return error
1404         $MULTIOP $tf-3 oO_WRONLY:O_SYNC:w1024c &&
1405                 error "write a mirrored file succeeded" || true
1406
1407         do_facet $mds_facet $LCTL set_param fail_loc=0
1408 }
1409 run_test 36 "write to mirrored files"
1410
1411 create_files_37() {
1412         local tf
1413         local fsize=$1
1414
1415         echo "create test files with size $fsize .."
1416
1417         shift
1418         for tf in "$@"; do
1419                 $LFS setstripe -E 1M -S 1M -c 1 -E eof -c -1 $tf
1420
1421                 dd if=/dev/urandom of=$tf bs=1M count=16 &> /dev/null
1422                 $TRUNCATE $tf $fsize
1423         done
1424 }
1425
1426 test_37()
1427 {
1428         [ $MDS1_VERSION -lt $(version_code 2.11.57) ] &&
1429                 skip "Need MDS version at least 2.11.57"
1430
1431         local tf=$DIR/$tfile
1432         local tf2=$DIR/$tfile-2
1433         local tf3=$DIR/$tfile-3
1434         local tf4=$DIR/$tfile-4
1435
1436         create_files_37 $((RANDOM + 15 * 1048576)) $tf $tf2 $tf3
1437         rm -f $tf4
1438         cp $tf $tf4
1439
1440         # assume the mirror id will be 1, 2, and 3
1441         declare -A checksums
1442         checksums[1]=$(cat $tf | md5sum)
1443         checksums[2]=$(cat $tf2 | md5sum)
1444         checksums[3]=$(cat $tf3 | md5sum)
1445
1446         printf '%s\n' "${checksums[@]}"
1447
1448         # merge these files into a mirrored file
1449         $LFS mirror extend --no-verify -N -f $tf2 $tf ||
1450                 error "merging $tf2 into $tf failed"
1451         $LFS mirror extend --no-verify -N -f $tf3 $tf ||
1452                 error "merging $tf3 into $tf failed"
1453
1454         get_mirror_ids $tf
1455
1456         # verify mirror read, checksums should equal to the original files'
1457         echo "Verifying mirror read .."
1458
1459         local sum
1460         for i in ${mirror_array[@]}; do
1461                 $LCTL set_param ldlm.namespaces.*.lru_size=clear > /dev/null
1462                 sum=$($LFS mirror read -N $i $tf | md5sum)
1463                 [ "$sum" = "${checksums[$i]}" ] ||
1464                         error "$i: mismatch: \'${checksums[$i]}\' vs. \'$sum\'"
1465         done
1466
1467         # verify mirror write
1468         echo "Verifying mirror write .."
1469         $LFS mirror write -N2 $tf < $tf4
1470
1471         sum=$($LFS mirror read -N2 $tf | md5sum)
1472         [[ "$sum" = "${checksums[1]}" ]] ||
1473                 error "2: mismatch \'${checksums[1]}\' vs. \'$sum\'"
1474
1475         # verify mirror copy, write to this mirrored file will invalidate
1476         # the other two mirrors
1477         echo "Verifying mirror copy .."
1478
1479         local osts=$(comma_list $(osts_nodes))
1480
1481         $LFS mirror copy -i ${mirror_array[0]} -o-1 $tf ||
1482                 error "mirror copy error"
1483
1484         # verify copying is successful by checking checksums
1485         remount_client $MOUNT
1486         for i in ${mirror_array[@]}; do
1487                 sum=$($LFS mirror read -N $i $tf | md5sum)
1488                 [ "$sum" = "${checksums[1]}" ] ||
1489                         error "$i: mismatch checksum after copy \'$sum\'"
1490         done
1491
1492         rm -f $tf
1493 }
1494 run_test 37 "mirror I/O API verification"
1495
1496 test_38() {
1497         local tf=$DIR/$tfile
1498         local ref=$DIR/${tfile}-ref
1499
1500         $LFS setstripe -E 1M -S 1M -c 1 -E 4M -c 2 -E eof -c -1 $tf ||
1501                 error "creating $tf failed"
1502         $LFS setstripe -E 2M -S 1M -c 1 -E 6M -c 2 -E 8M -c -1 -E eof -c -1 \
1503                 $tf-2 || error "creating $tf-2 failed"
1504         $LFS setstripe -E 4M -c 1 -E 8M -c 2 -E eof -c -1 $tf-3 ||
1505                 error "creating $tf-3 failed"
1506
1507         # instantiate all components
1508         $LFS mirror extend -N -f $tf-2 $tf ||
1509                 error "merging $tf-2 into $tf failed"
1510         $LFS mirror extend -N -f $tf-3 $tf ||
1511                 error "merging $tf-3 into $tf failed"
1512         $LFS mirror extend -N -c 1 $tf ||
1513                 error "extending mirrored file $tf failed"
1514
1515         verify_flr_state $tf "ro"
1516
1517         dd if=/dev/urandom of=$ref  bs=1M count=16 &> /dev/null
1518
1519         local fsize=$((RANDOM << 8 + 1048576))
1520         $TRUNCATE $ref $fsize
1521
1522         local ref_cksum=$(cat $ref | md5sum)
1523
1524         # case 1: verify write to mirrored file & resync work
1525         cp $ref $tf || error "copy from $ref to $f error"
1526         verify_flr_state $tf "wp"
1527
1528         local file_cksum=$(cat $tf | md5sum)
1529         [ "$file_cksum" = "$ref_cksum" ] || error "write failed, cksum mismatch"
1530
1531         get_mirror_ids $tf
1532         echo "mirror IDs: ${mirror_array[@]}"
1533
1534         local valid_mirror stale_mirror id mirror_cksum
1535         for id in "${mirror_array[@]}"; do
1536                 mirror_cksum=$($LFS mirror read -N $id $tf | md5sum)
1537                 [ "$ref_cksum" == "$mirror_cksum" ] &&
1538                         { valid_mirror=$id; continue; }
1539
1540                 stale_mirror=$id
1541         done
1542
1543         [ -z "$stale_mirror" ] && error "stale mirror doesn't exist"
1544         [ -z "$valid_mirror" ] && error "valid mirror doesn't exist"
1545
1546         mirror_io resync $tf || error "resync failed"
1547         verify_flr_state $tf "ro"
1548
1549         mirror_cksum=$($LFS mirror read -N $stale_mirror $tf | md5sum)
1550         [ "$file_cksum" = "$ref_cksum" ] || error "resync failed"
1551
1552         # case 2: inject an error to make mirror_io exit after changing
1553         # the file state to sync_pending so that we can start a concurrent
1554         # write.
1555         $MULTIOP $tf oO_WRONLY:w$((RANDOM % 1048576 + 1024))c
1556         verify_flr_state $tf "wp"
1557
1558         mirror_io resync -e resync_start $tf && error "resync succeeded"
1559         verify_flr_state $tf "sp"
1560
1561         # from sync_pending to write_pending
1562         $MULTIOP $tf oO_WRONLY:w$((RANDOM % 1048576 + 1024))c
1563         verify_flr_state $tf "wp"
1564
1565         mirror_io resync -e resync_start $tf && error "resync succeeded"
1566         verify_flr_state $tf "sp"
1567
1568         # from sync_pending to read_only
1569         mirror_io resync $tf || error "resync failed"
1570         verify_flr_state $tf "ro"
1571 }
1572 run_test 38 "resync"
1573
1574 test_39() {
1575         local tf=$DIR/$tfile
1576
1577         rm -f $tf
1578         $LFS mirror create -N2 -E1m -c1 -S1M -E-1 $tf ||
1579         error "create PFL file $tf failed"
1580
1581         verify_mirror_count $tf 2
1582         verify_comp_count $tf 4
1583
1584         rm -f $tf || error "delete $tf failed"
1585 }
1586 run_test 39 "check FLR+PFL (a.k.a. PFLR) creation"
1587
1588 test_40() {
1589         local tf=$DIR/$tfile
1590         local ops
1591
1592         for ops in "conv=notrunc" ""; do
1593                 rm -f $tf
1594
1595                 $LFS mirror create -N -E 2M -S 1M -E 4M -E -1 --flags=prefer \
1596                                    -N -E 1M -E 2M -E 4M -E -1 $tf ||
1597                         error "create PFLR file $tf failed"
1598                 dd if=/dev/zero of=$tf $ops bs=1M seek=2 count=1 ||
1599                         error "write PFLR file $tf failed"
1600
1601                 lfs getstripe -vy $tf
1602
1603                 local flags
1604
1605                 # file mirror state should be write_pending
1606                 flags=$($LFS getstripe -v $tf | awk '/lcm_flags:/ { print $2 }')
1607                 [ $flags = wp ] ||
1608                 error "file mirror state $flags"
1609                 # the 1st component (in mirror 1) should be inited
1610                 verify_comp_attr lcme_flags $tf 0x10001 init
1611                 # the 2nd component (in mirror 1) should be inited
1612                 verify_comp_attr lcme_flags $tf 0x10002 init
1613                 # the 3rd component (in mirror 1) should be uninited
1614                 verify_comp_attr lcme_flags $tf 0x10003 prefer
1615                 # the 4th component (in mirror 2) should be inited
1616                 verify_comp_attr lcme_flags $tf 0x20004 init
1617                 # the 5th component (in mirror 2) should be uninited
1618                 verify_comp_attr lcme_flags $tf 0x20005 0
1619                 # the 6th component (in mirror 2) should be stale
1620                 verify_comp_attr lcme_flags $tf 0x20006 stale
1621                 # the 7th component (in mirror 2) should be uninited
1622                 if [[ x$ops = "xconv=notrunc" ]]; then
1623                         verify_comp_attr lcme_flags $tf 0x20007 0
1624                 elif [[ x$ops = "x" ]]; then
1625                         verify_comp_attr lcme_flags $tf 0x20007 stale
1626                 fi
1627         done
1628
1629         rm -f $tf || error "delete $tf failed"
1630 }
1631 run_test 40 "PFLR rdonly state instantiation check"
1632
1633 test_41() {
1634         local tf=$DIR/$tfile
1635
1636         rm -f $tf $tf-1
1637         echo " **create two FLR files $tf $tf-1"
1638         $LFS mirror create -N -E 2M -S 1M -E 4M -E -1 \
1639                            -N -E 1M -E 2M -E 3M -E -1 $tf ||
1640                 error "create PFLR file $tf failed"
1641         $LFS mirror create -N -E 2M -S 1M -E eof \
1642                            -N -E 1M -E eof --flags prefer \
1643                            -N -E 4m -E eof $tf-1 ||
1644                 error "create PFLR file $tf-1 failed"
1645
1646         # file should be in ro status
1647         echo " **verify files be RDONLY"
1648         verify_flr_state $tf "ro"
1649         verify_flr_state $tf-1 "ro"
1650
1651         # write data in [0, 2M)
1652         dd if=/dev/zero of=$tf bs=1M count=2 conv=notrunc ||
1653                 error "writing $tf failed"
1654         dd if=/dev/urandom of=$tf-1 bs=1M count=4 conv=notrunc ||
1655                 error "writing $tf-1 failed"
1656
1657         local sum0=$(cat $tf-1 | md5sum)
1658
1659         echo " **verify files be WRITE_PENDING"
1660         verify_flr_state $tf "wp"
1661         verify_flr_state $tf-1 "wp"
1662
1663         # file should have stale component
1664         echo " **verify files have stale component"
1665         $LFS getstripe $tf | grep lcme_flags | grep stale > /dev/null ||
1666                 error "after writing $tf, it does not contain stale component"
1667         $LFS getstripe $tf-1 | grep lcme_flags | grep stale > /dev/null ||
1668                 error "after writing $tf-1, it does not contain stale component"
1669
1670         echo " **full resync"
1671         $LFS mirror resync $tf $tf-1 || error "mirror resync $tf $tf-1 failed"
1672
1673         echo " **verify $tf-1 data consistency in all mirrors"
1674         for i in 1 2 3; do
1675                 local sum=$($LFS mirror read -N$i $tf-1 | md5sum)
1676                 [[ "$sum" = "$sum0" ]] ||
1677                         error "$tf-1.$i: checksum mismatch: $sum != $sum0"
1678         done
1679
1680         echo " **verify files be RDONLY"
1681         verify_flr_state $tf "ro"
1682         verify_flr_state $tf-1 "ro"
1683
1684         # file should not have stale component
1685         echo " **verify files do not contain stale component"
1686         $LFS getstripe $tf | grep lcme_flags | grep stale &&
1687                 error "after resyncing $tf, it contains stale component"
1688         $LFS getstripe $tf-1 | grep lcme_flags | grep stale &&
1689                 error "after resyncing $tf, it contains stale component"
1690
1691         # verify partial resync
1692         echo " **write $tf-1 for partial resync test"
1693         dd if=/dev/zero of=$tf-1 bs=1M count=2 conv=notrunc ||
1694                 error "writing $tf-1 failed"
1695
1696         echo " **only resync mirror 2"
1697         verify_flr_state $tf-1 "wp"
1698         $LFS mirror resync --only 2 $tf-1 ||
1699                 error "resync mirror 2 of $tf-1 failed"
1700         verify_flr_state $tf "ro"
1701
1702         # resync synced mirror
1703         echo " **resync mirror 2 again"
1704         $LFS mirror resync --only 2 $tf-1 ||
1705                 error "resync mirror 2 of $tf-1 failed"
1706         verify_flr_state $tf "ro"
1707         echo " **verify $tf-1 contains stale component"
1708         $LFS getstripe $tf-1 | grep lcme_flags | grep stale > /dev/null ||
1709                 error "after writing $tf-1, it does not contain stale component"
1710
1711         echo " **full resync $tf-1"
1712         $LFS mirror resync $tf-1 || error "resync of $tf-1 failed"
1713         verify_flr_state $tf "ro"
1714         echo " **full resync $tf-1 again"
1715         $LFS mirror resync $tf-1 || error "resync of $tf-1 failed"
1716         echo " **verify $tf-1 does not contain stale component"
1717         $LFS getstripe $tf | grep lcme_flags | grep stale &&
1718                 error "after resyncing $tf, it contains stale component"
1719
1720         return 0
1721 }
1722 run_test 41 "lfs mirror resync check"
1723
1724 test_42() {
1725         [[ $OSTCOUNT -lt 4 ]] && skip "need >= 4 OSTs" && return
1726
1727         local td=$DIR/$tdir
1728         local tf=$td/$tfile
1729         local mirror_cmd="$LFS mirror verify"
1730         local i
1731
1732         # create parent directory
1733         mkdir $td || error "mkdir $td failed"
1734
1735         $mirror_cmd &> /dev/null && error "no file name given"
1736         $mirror_cmd $tf &> /dev/null && error "cannot stat file $tf"
1737         $mirror_cmd $td &> /dev/null && error "$td is not a regular file"
1738
1739         # create mirrored files
1740         $LFS mirror create -N -E 4M -S 1M -E 10M -E EOF $tf ||
1741                 error "create mirrored file $tf failed"
1742         $LFS mirror create -N -E 2M -S 1M -E EOF \
1743                            -N -E 6M -E 8M -E EOF \
1744                            -N -E 16M -E EOF $tf-1 ||
1745                 error "create mirrored file $tf-1 failed"
1746         $LFS mirror create -N -c 2 -o 1,3 -N -S 2M -c -1 $tf-2 ||
1747                 error "create mirrored file $tf-2 failed"
1748
1749         # write data in [0, 10M)
1750         for i in $tf $tf-1 $tf-2; do
1751                 yes | dd of=$i bs=1M count=10 iflag=fullblock conv=notrunc ||
1752                         error "write $i failed"
1753         done
1754
1755         # resync the mirrored files
1756         $LFS mirror resync $tf-1 $tf-2 ||
1757                 error "resync $tf-1 $tf-2 failed"
1758
1759         # verify the mirrored files
1760         $mirror_cmd $tf-1 $tf-2 ||
1761                 error "verify $tf-1 $tf-2 failed"
1762
1763         get_mirror_ids $tf-1
1764         $mirror_cmd --only ${mirror_array[0]} $tf-1 &> /dev/null &&
1765                 error "at least 2 mirror ids needed with '--only' option"
1766         $mirror_cmd --only ${mirror_array[0]},${mirror_array[1]} $tf-1 $tf-2 \
1767                 &> /dev/null &&
1768                 error "'--only' option cannot be used upon multiple files"
1769         $mirror_cmd --only 65534,${mirror_array[0]},65535 $tf-1 &&
1770                 error "invalid specified mirror ids"
1771
1772         # change the content of $tf and merge it into $tf-1
1773         for i in 6 10; do
1774                 echo a | dd of=$tf bs=1M seek=$i conv=notrunc ||
1775                         error "change $tf with seek=$i failed"
1776                 echo b | dd of=$tf-1 bs=1M seek=$i conv=notrunc ||
1777                         error "change $tf-1 with seek=$i failed"
1778         done
1779
1780         $LFS mirror resync $tf-1 || error "resync $tf-1 failed"
1781         $LFS mirror extend --no-verify -N -f $tf $tf-1 ||
1782                 error "merge $tf into $tf-1 failed"
1783
1784         # verify the mirrored files
1785         echo "Verify $tf-1 without -v option:"
1786         $mirror_cmd $tf-1 &&
1787                 error "verify $tf-1 should fail" || echo "PASS"
1788
1789         echo "Verify $tf-1 with -v option:"
1790         $mirror_cmd -v $tf-1 &&
1791                 error "verify $tf-1 should fail"
1792
1793         get_mirror_ids $tf-1
1794         echo "Verify $tf-1 with --only option:"
1795         $mirror_cmd -v --only ${mirror_array[1]},${mirror_array[-1]} $tf-1 &&
1796                 error "verify $tf-1 with mirror ${mirror_array[1]} and" \
1797                       "${mirror_array[-1]} should fail"
1798
1799         $mirror_cmd --only ${mirror_array[0]},${mirror_array[1]} $tf-1 ||
1800                 error "verify $tf-1 with mirror ${mirror_array[0]} and" \
1801                       "${mirror_array[1]} should succeed"
1802
1803         # set stale components in $tf-1
1804         for i in 0x40002 0x40003; do
1805                 $LFS setstripe --comp-set -I$i --comp-flags=stale $tf-1 ||
1806                         error "set stale flag on component $i failed"
1807         done
1808
1809         # verify the mirrored file
1810         echo "Verify $tf-1 with stale components:"
1811         $mirror_cmd -vvv $tf-1 ||
1812                 error "verify $tf-1 with stale components should succeed"
1813
1814         echo "Verify $tf-1 with stale components and --only option:"
1815         $mirror_cmd -vvv --only ${mirror_array[1]},${mirror_array[-1]} $tf-1 ||
1816                 error "verify $tf-1 with mirror ${mirror_array[1]} and" \
1817                       "${mirror_array[-1]} should succeed"
1818 }
1819 run_test 42 "lfs mirror verify"
1820
1821 # inactivate one OST && write && restore the OST
1822 write_file_43() {
1823         local file=$1
1824         local ost=$2
1825         local PARAM="osp.${FSNAME}-OST000${ost}-osc-M*.active"
1826         local wait
1827
1828         wait=$(do_facet $SINGLEMDS \
1829                 "$LCTL get_param -n lod.*MDT0000-*.qos_maxage")
1830         wait=${wait%%[^0-9]*}
1831
1832         echo "  **deactivate OST$ost, waiting for $((wait*2+2)) seconds"
1833         $(do_facet $SINGLEMDS "$LCTL set_param -n $PARAM 0")
1834         # lod_qos_statfs_update needs 2*$wait seconds to refresh targets statfs
1835         sleep $(($wait * 2 + 2))
1836         echo "  **write $file"
1837         dd if=/dev/zero of=$file bs=1M count=1 || error "write $file failed"
1838         echo "  **restore activating OST$ost, waiting for $((wait*2+2)) seconds"
1839         $(do_facet $SINGLEMDS "$LCTL set_param -n $PARAM 1")
1840         sleep $((wait * 2 + 2))
1841
1842         local flags=$($LFS getstripe -v $file | awk '/lcm_flags:/ { print $2 }')
1843         [ $flags = wp ] || error "file mirror state $flags != wp"
1844 }
1845
1846 test_43() {
1847         [ $OSTCOUNT -lt 3 ] && skip "needs >= 3 OSTs" && return
1848
1849         local tf=$DIR/$tfile
1850         local flags
1851
1852         rm -f $tf
1853         ##   mirror 0  ost (0, 1)
1854         ##   mirror 1  ost (1, 2)
1855         ##   mirror 2  ost (2, 0)
1856         $LFS mirror create -N -Eeof -c2 -o0,1 -N -Eeof -c2 -o1,2 \
1857                 -N -Eeof -c2 -o2,0 $tf ||
1858                 error "create 3 mirrors file $tf failed"
1859
1860         ################## OST0 ###########################################
1861         write_file_43 $tf 0
1862         echo "  **verify components"
1863         verify_comp_attr lcme_flags $tf 0x10001 init,stale
1864         verify_comp_attr lcme_flags $tf 0x20002 init
1865         verify_comp_attr lcme_flags $tf 0x30003 init,stale
1866
1867         # resync
1868         echo "  **resync $tf"
1869         $LFS mirror resync $tf
1870         flags=$($LFS getstripe -v $tf | awk '/lcm_flags:/ { print $2 }')
1871         [ $flags = ro ] || error "file mirror state $flags != ro"
1872
1873         ################## OST1 ###########################################
1874         write_file_43 $tf 1
1875         echo "  **verify components"
1876         verify_comp_attr lcme_flags $tf 0x10001 init,stale
1877         verify_comp_attr lcme_flags $tf 0x20002 init,stale
1878         verify_comp_attr lcme_flags $tf 0x30003 init
1879
1880         # resync
1881         echo "  **resync $tf"
1882         $LFS mirror resync $tf
1883         flags=$($LFS getstripe -v $tf | awk '/lcm_flags:/ { print $2 }')
1884         [ $flags = ro ] || error "file mirror state $flags != ro"
1885
1886         ################## OST2 ###########################################
1887         write_file_43 $tf 2
1888         echo "  **verify components"
1889         verify_comp_attr lcme_flags $tf 0x10001 init
1890         verify_comp_attr lcme_flags $tf 0x20002 init,stale
1891         verify_comp_attr lcme_flags $tf 0x30003 init,stale
1892 }
1893 run_test 43 "mirror pick on write"
1894
1895 test_44() {
1896         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
1897         rm -rf $DIR/$tdir
1898         rm -rf $DIR/$tdir-1
1899         local tf=$DIR/$tdir/$tfile
1900         local tf1=$DIR/$tdir-1/$tfile-1
1901
1902         $LFS setdirstripe -i 0 -c 1 $DIR/$tdir ||
1903                 error "create directory failed"
1904         $LFS setdirstripe -i 1 -c 1 $DIR/$tdir-1 ||
1905                 error "create remote directory failed"
1906         rm -f $tf $tf1 $tf.mirror~2
1907         # create file with 4 mirrors
1908         $LFS mirror create -N -E 2M -S 1M -E 4M -E -1 \
1909                            -N -E 1M -E 2M -E 3M -E -1 -N2 $tf ||
1910                 error "create PFLR file $tf failed"
1911
1912         # file should be in ro status
1913         verify_flr_state $tf "ro"
1914
1915         # write data in [0, 3M)
1916         dd if=/dev/urandom of=$tf bs=1M count=3 conv=notrunc ||
1917                 error "writing $tf failed"
1918
1919         verify_flr_state $tf "wp"
1920
1921         # disallow destroying the last non-stale mirror
1922         ! $LFS mirror delete --mirror-id 1 $tf > /dev/null 2>&1 ||
1923                 error "destroying mirror 1 should fail"
1924
1925         # synchronize all mirrors of the file
1926         $LFS mirror resync $tf || error "mirror resync $tf failed"
1927
1928         verify_flr_state $tf "ro"
1929
1930         # split mirror 1
1931         $LFS mirror split --mirror-id 1 -f $tf1 $tf ||
1932                 error "split to $tf1 failed"
1933
1934         local idx0=$($LFS getstripe -m $tf)
1935         local idx1=$($LFS getstripe -m $tf1)
1936
1937         [[ x$idx0 == x0 ]] || error "$tf is not on MDT0"
1938         [[ x$idx1 == x1 ]] || error "$tf1 is not on MDT1"
1939
1940         # verify mirror count
1941         verify_mirror_count $tf 3
1942         verify_mirror_count $tf1 1
1943
1944         $LFS mirror split --mirror-id 2 $tf ||
1945                 error "split mirror 2 failed"
1946
1947         verify_mirror_count $tf 2
1948         verify_mirror_count $tf.mirror~2 1
1949
1950         $LFS setstripe --comp-set -I 0x30008 --comp-flags=stale $tf ||
1951                 error "setting stale flag on component 0x30008 failed"
1952
1953         # disallow destroying the last non-stale mirror
1954         ! $LFS mirror split --mirror-id 4 -d $tf > /dev/null 2>&1 ||
1955                 error "destroying mirror 4 should fail"
1956
1957         $LFS mirror resync $tf || error "resynchronizing $tf failed"
1958
1959         $LFS mirror split --mirror-id 3 -d $tf ||
1960                 error "destroying mirror 3 failed"
1961         verify_mirror_count $tf 1
1962
1963         # verify splitted file contains the same content as the orig file does
1964         diff $tf $tf1 || error "splited file $tf1 diffs from $tf"
1965         diff $tf $tf.mirror~2 ||
1966                 error "splited file $tf.mirror~2 diffs from $tf"
1967 }
1968 run_test 44 "lfs mirror split check"
1969
1970 test_45() {
1971         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
1972
1973         local file=$DIR/$tdir/$tfile
1974         local dir=$DIR/$tdir/$dir
1975         local temp=$DIR/$tdir/template
1976         rm -rf $DIR/$tdir
1977         test_mkdir $DIR/$tdir
1978
1979         $LFS setstripe -N -E1m -S1m -c2 -o0,1 -E2m -Eeof -N -E4m -Eeof \
1980                 -N -E3m -S1m -Eeof -N -E8m -Eeof $file ||
1981                         error "Create $file failed"
1982
1983         verify_yaml_layout $file $file.copy $temp "1. FLR file"
1984         rm -f $file $file.copy
1985
1986         $LFS setstripe -N -E1m -S1m -c2 -o0,1 -E2m -Eeof -N -E4m -Eeof \
1987                 -N -E3m -S1m -Eeof -N -E8m --flags=prefer -Eeof $file ||
1988                         error "Create $file failed"
1989
1990         verify_yaml_layout $file $file.copy $temp "2. FLR file with flags"
1991 }
1992 run_test 45 "Verify setstripe/getstripe with YAML with FLR file"
1993
1994 verify_46() {
1995         local src=$1
1996         local dst=$2
1997         local msg_prefix=$3
1998
1999         $LFS setstripe --copy=$src $dst || error "setstripe $dst failed"
2000
2001         local layout1=$(get_layout_param $src)
2002         local layout2=$(get_layout_param $dst)
2003         # compare their layout info
2004         [ "$layout1" == "$layout2" ] ||
2005                 error "$msg_prefix $src <=> $dst layouts are not equal"
2006 }
2007
2008 test_46() {
2009         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs" && return
2010
2011         local file=$DIR/$tdir/$tfile
2012         test_mkdir $DIR/$tdir
2013
2014         ########################### 1. PFL file #############################
2015         echo "  ** 1. PFL file"
2016         rm -f $file
2017         $LFS setstripe -E1m -S 1M -c2 -o0,1 -E2m -c2 -E3m -o1,0 -E4m -c1 -E-1 \
2018                 $file || error "1. Create PFL $file failed"
2019
2020         rm -f $file.copy
2021         verify_46 $file $file.copy "1. PFL file"
2022
2023         ########################### 2. plain file ###########################
2024         echo "  ** 2. plain file"
2025         rm -f $file
2026         $LFS setstripe -c2 -o0,1 -i1 $file ||
2027                 error "2. Create plain $file failed"
2028
2029         rm -f $file.copy
2030         verify_46 $file $file.copy "2. plain file"
2031
2032         ########################### 3. FLR file #############################
2033         echo "  ** 3. FLR file"
2034         $LFS setstripe -N -E1m -S 1M -c2 -o0,1 -E4m -c1 -Eeof -N -E16m -Eeof \
2035                 $file || error "3. Create FLR $file failed"
2036
2037         rm -f $file.copy
2038         verify_46 $file $file.copy "3. FLR file"
2039
2040         local dir=$DIR/$tdir/dir
2041         ########################### 4. PFL dir ##############################
2042         echo "  ** 4. PFL dir"
2043         test_mkdir $dir
2044         $LFS setstripe -E1m -S 1M -c2 -E2m -c1 -E-1 $dir ||
2045                 error "4. setstripe PFL $dir failed"
2046
2047         test_mkdir $dir.copy
2048         verify_46 $dir $dir.copy "4. PFL dir"
2049
2050         ########################### 5. plain dir ############################
2051         echo "  ** 5. plain dir"
2052         $LFS setstripe -c2 -i-1 $dir || error "5. setstripe plain $dir failed"
2053
2054         verify_46 $dir $dir.copy "5. plain dir"
2055
2056         ########################### 6. FLR dir ##############################
2057         echo "  ** 6. FLR dir"
2058         $LFS setstripe -N -E1m -S 1M -c2 -E2m -c1 -Eeof -N -E4m -Eeof $dir ||
2059                 error "6. setstripe FLR $dir failed"
2060
2061         verify_46 $dir $dir.copy "6. FLR dir"
2062 }
2063 run_test 46 "Verify setstripe --copy option"
2064
2065 test_47() {
2066         [ $OSTCOUNT -lt 3 ] && skip "needs >= 3 OSTs" && return
2067
2068         local file=$DIR/$tdir/$tfile
2069         local ids
2070         local ost
2071         local osts
2072
2073         test_mkdir $DIR/$tdir
2074
2075         # test case 1:
2076         rm -f $file
2077         # mirror1: [comp0]ost0,    [comp1]ost1 and ost2
2078         # mirror2: [comp2]    ,    [comp3] should not use ost1 or ost2
2079         $LFS mirror create -N -E2m -c1 -o0 --flags=prefer -Eeof -c2 -o1,2 \
2080                 -N -E2m -c1 -Eeof -c1 $file || error "create FLR $file failed"
2081         ids=($($LFS getstripe $file | awk '/lcme_id/{print $2}' | tr '\n' ' '))
2082
2083         dd if=/dev/zero of=$file bs=1M count=3 || error "dd $file failed"
2084         $LFS mirror resync $file || error "resync $file failed"
2085
2086         ost=$($LFS getstripe -I${ids[2]} $file | awk '/l_ost_idx/{print $5}')
2087         if [[ x$ost == "x0," ]]; then
2088                 $LFS getstripe $file
2089                 error "component ${ids[2]} objects allocated on $ost " \
2090                       "shouldn't on OST0"
2091         fi
2092
2093         ost=$($LFS getstripe -I${ids[3]} $file | awk '/l_ost_idx/{print $5}')
2094         if [[ x$ost == "x1," || x$ost == "x2," ]]; then
2095                 $LFS getstripe $file
2096                 error "component ${ids[3]} objects allocated on $ost " \
2097                       "shouldn't on OST1 or on OST2"
2098         fi
2099
2100         ## test case 2:
2101         rm -f $file
2102         # mirror1: [comp0]    [comp1]
2103         # mirror2: [comp2]    [comp3]
2104         # mirror3: [comp4]    [comp5]
2105         # mirror4: [comp6]    [comp7]
2106         $LFS mirror create -N4 -E1m -c1 -Eeof -c1 $file ||
2107                 error "create FLR $file failed"
2108         ids=($($LFS getstripe $file | awk '/lcme_id/{print $2}' | tr '\n' ' '))
2109
2110         dd if=/dev/zero of=$file bs=1M count=3 || error "dd $file failed"
2111         $LFS mirror resync $file || error "resync $file failed"
2112
2113         for ((i = 0; i < 6; i++)); do
2114                 osts[$i]=$($LFS getstripe -I${ids[$i]} $file |
2115                         awk '/l_ost_idx/{print $5}')
2116         done
2117         # comp[0],comp[2],comp[4] should use different osts
2118         if [[ ${osts[0]} == ${osts[2]} || ${osts[0]} == ${osts[4]} ||
2119               ${osts[2]} == ${osts[4]} ]]; then
2120                 $LFS getstripe $file
2121                 error "component ${ids[0]}, ${ids[2]}, ${ids[4]} have objects "\
2122                       "allocated on duplicated OSTs"
2123         fi
2124         # comp[1],comp[3],comp[5] should use different osts
2125         if [[ ${osts[1]} == ${osts[3]} || ${osts[1]} == ${osts[5]} ||
2126               ${osts[3]} == ${osts[5]} ]]; then
2127                 $LFS getstripe $file
2128                 error "component ${ids[1]}, ${ids[3]}, ${ids[5]} have objects "\
2129                       "allocated on duplicated OSTs"
2130         fi
2131
2132         return 0
2133 }
2134 run_test 47 "Verify mirror obj alloc"
2135
2136 test_48() {
2137         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
2138                 skip "Need MDS version at least 2.11.55"
2139
2140         local tf=$DIR/$tfile
2141
2142         rm -f $tf
2143         echo " ** create 2 mirrors FLR file $tf"
2144         $LFS mirror create -N -E2M -Eeof --flags prefer \
2145                            -N -E1M -Eeof $tf ||
2146                 error "create FLR file $tf failed"
2147
2148         echo " ** write it"
2149         dd if=/dev/urandom of=$tf bs=1M count=3 || error "write $tf failed"
2150         verify_flr_state $tf "wp"
2151
2152         local sum0=$(md5sum < $tf)
2153
2154         echo " ** resync the file"
2155         $LFS mirror resync $tf
2156
2157         echo " ** snapshot mirror 2"
2158         $LFS setstripe --comp-set -I 0x20003 --comp-flags=nosync $tf
2159
2160         echo " ** write it again"
2161         dd if=/dev/urandom of=$tf bs=1M count=3 || error "write $tf failed"
2162         echo " ** resync it again"
2163         $LFS mirror resync $tf
2164
2165         verify_flr_state $tf "wp"
2166         verify_comp_attr lcme_flags $tf 0x20003 nosync,stale
2167
2168         local sum1=$($LFS mirror read -N1 $tf | md5sum)
2169         local sum2=$($LFS mirror read -N2 $tf | md5sum)
2170
2171         echo " ** verify mirror 2 doesn't change"
2172         echo "original checksum: $sum0"
2173         echo "mirror 1 checksum: $sum1"
2174         echo "mirror 2 checksum: $sum2"
2175         [[ $sum0 = $sum2 ]] ||
2176                 error "original checksum: $sum0, mirror 2 checksum: $sum2"
2177         echo " ** mirror 2 stripe info"
2178         $LFS getstripe -v --mirror-index=2 $tf
2179
2180         echo " ** resync mirror 2"
2181         $LFS mirror resync --only 2 $tf
2182
2183         verify_flr_state $tf "ro"
2184         verify_comp_attr lcme_flags $tf 0x20003 nosync,^stale
2185
2186         sum1=$($LFS mirror read -N1 $tf | md5sum)
2187         sum2=$($LFS mirror read -N2 $tf | md5sum)
2188
2189         echo " ** verify mirror 2 resync-ed"
2190         echo "original checksum: $sum0"
2191         echo "mirror 1 checksum: $sum1"
2192         echo "mirror 2 checksum: $sum2"
2193         [[ $sum1 = $sum2 ]] ||
2194                 error "mirror 1 checksum: $sum1, mirror 2 checksum: $sum2"
2195         echo " ** mirror 2 stripe info"
2196         $LFS getstripe -v --mirror-index=2 $tf
2197 }
2198 run_test 48 "Verify snapshot mirror"
2199
2200 ctrl_file=$(mktemp /tmp/CTRL.XXXXXX)
2201 lock_file=$(mktemp /var/lock/FLR.XXXXXX)
2202
2203 write_file_200() {
2204         local tf=$1
2205
2206         local fsize=$(stat --printf=%s $tf)
2207
2208         while [ -f $ctrl_file ]; do
2209                 local off=$((RANDOM << 8))
2210                 local len=$((RANDOM << 5 + 131072))
2211
2212                 [ $((off + len)) -gt $fsize ] && {
2213                         fsize=$((off + len))
2214                         echo "Extending file size to $fsize .."
2215                 }
2216
2217                 flock -s $lock_file -c \
2218                         "$MULTIOP $tf oO_WRONLY:z${off}w${len}c" ||
2219                                 { rm -f $ctrl_file;
2220                                   error "failed writing to $off:$len"; }
2221                 sleep 0.$((RANDOM % 2 + 1))
2222         done
2223 }
2224
2225 read_file_200() {
2226         local tf=$1
2227
2228         while [ -f $ctrl_file ]; do
2229                 flock -s $lock_file -c "cat $tf &> /dev/null" ||
2230                         { rm -f $ctrl_file; error "read failed"; }
2231                 sleep 0.$((RANDOM % 2 + 1))
2232         done
2233 }
2234
2235 resync_file_200() {
2236         local tf=$1
2237
2238         options=("" "-e resync_start" "-e delay_before_copy -d 1" "" "")
2239
2240         exec 200<>$lock_file
2241         while [ -f $ctrl_file ]; do
2242                 local lock_taken=false
2243                 local index=$((RANDOM % ${#options[@]}))
2244                 local cmd="mirror_io resync ${options[$index]}"
2245
2246                 [ "${options[$index]}" = "" ] && cmd="$LFS mirror resync"
2247
2248                 [ $((RANDOM % 4)) -eq 0 ] && {
2249                         index=0
2250                         lock_taken=true
2251                         echo -n "lock to "
2252                 }
2253
2254                 echo -n "resync file $tf with '$cmd' .."
2255
2256                 if [[ $lock_taken = "true" ]]; then
2257                         flock -x 200 -c "$cmd $tf &> /dev/null" &&
2258                                 echo "done" || echo "failed"
2259                         flock -u 200
2260                 else
2261                         $cmd $tf &> /dev/null && echo "done" || echo "failed"
2262                 fi
2263
2264                 sleep 0.$((RANDOM % 8 + 1))
2265         done
2266 }
2267
2268 test_200() {
2269         local tf=$DIR/$tfile
2270         local tf2=$DIR2/$tfile
2271         local tf3=$DIR3/$tfile
2272
2273         $LFS setstripe -E 1M -S 1M -E 2M -c 2 -E 4M -E 16M -E eof $tf
2274         $LFS setstripe -E 2M -S 1M -E 6M -c 2 -E 8M -E 32M -E eof $tf-2
2275         $LFS setstripe -E 4M -c 2 -E 8M -E 64M -E eof $tf-3
2276
2277         $LFS mirror extend -N -f $tf-2 $tf ||
2278                 error "merging $tf-2 into $tf failed"
2279         $LFS mirror extend -N -f $tf-3 $tf ||
2280                 error "merging $tf-3 into $tf failed"
2281
2282         mkdir -p $MOUNT2 && mount_client $MOUNT2
2283
2284         mkdir -p $MOUNT3 && mount_client $MOUNT3
2285
2286         verify_flr_state $tf3 "ro"
2287
2288         #define OBD_FAIL_FLR_RANDOM_PICK_MIRROR 0x1A03
2289         $LCTL set_param fail_loc=0x1A03
2290
2291         local mds_idx=mds$(($($LFS getstripe -m $tf) + 1))
2292         do_facet $mds_idx $LCTL set_param fail_loc=0x1A03
2293
2294         declare -a pids
2295
2296         write_file_200 $tf &
2297         pids+=($!)
2298
2299         read_file_200 $tf &
2300         pids+=($!)
2301
2302         write_file_200 $tf2 &
2303         pids+=($!)
2304
2305         read_file_200 $tf2 &
2306         pids+=($!)
2307
2308         resync_file_200 $tf3 &
2309         pids+=($!)
2310
2311         local sleep_time=60
2312         [ "$SLOW" = "yes" ] && sleep_time=360
2313         while [ $sleep_time -gt 0 -a -f $ctrl_file ]; do
2314                 sleep 1
2315                 ((--sleep_time))
2316         done
2317
2318         rm -f $ctrl_file
2319
2320         echo "Waiting ${pids[@]}"
2321         wait ${pids[@]}
2322
2323         umount_client $MOUNT2
2324         umount_client $MOUNT3
2325
2326         rm -f $lock_file
2327
2328         # resync and verify mirrors
2329         mirror_io resync $tf
2330         get_mirror_ids $tf
2331
2332         local csum=$($LFS mirror read -N ${mirror_array[0]} $tf | md5sum)
2333         for id in ${mirror_array[@]:1}; do
2334                 [ "$($LFS mirror read -N $id $tf | md5sum)" = "$csum" ] ||
2335                         error "checksum error for mirror $id"
2336         done
2337
2338         true
2339 }
2340 run_test 200 "stress test"
2341
2342 cleanup_test_201() {
2343         trap 0
2344         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister $CL_USER
2345
2346         umount_client $MOUNT2
2347 }
2348
2349 test_201() {
2350         local delay=${RESYNC_DELAY:-5}
2351
2352         MDT0=$($LCTL get_param -n mdc.*.mds_server_uuid |
2353                awk '{ gsub(/_UUID/,""); print $1 }' | head -n1)
2354
2355         trap cleanup_test_201 EXIT
2356
2357         CL_USER=$(do_facet $SINGLEMDS $LCTL --device $MDT0 \
2358                         changelog_register -n)
2359
2360         mkdir -p $MOUNT2 && mount_client $MOUNT2
2361
2362         local index=0
2363         while :; do
2364                 local log=$($LFS changelog $MDT0 $index | grep FLRW)
2365                 [ -z "$log" ] && { sleep 1; continue; }
2366
2367                 index=$(echo $log | awk '{print $1}')
2368                 local ts=$(date -d "$(echo $log | awk '{print $3}')" "+%s" -u)
2369                 local fid=$(echo $log | awk '{print $6}' | sed -e 's/t=//')
2370                 local file=$($LFS fid2path $MOUNT2 $fid 2> /dev/null)
2371
2372                 ((++index))
2373                 [ -z "$file" ] && continue
2374
2375                 local now=$(date +%s)
2376
2377                 echo "file: $file $fid was modified at $ts, now: $now, " \
2378                      "will be resynced at $((ts+delay))"
2379
2380                 [ $now -lt $((ts + delay)) ] && sleep $((ts + delay - now))
2381
2382                 mirror_io resync $file
2383                 echo "$file resync done"
2384         done
2385
2386         cleanup_test_201
2387 }
2388 run_test 201 "FLR data mover"
2389
2390 test_202() {
2391         [[ $OSTCOUNT -lt 2 ]] && skip "need >= 2 OSTs" && return
2392
2393         local tf=$DIR/$tfile
2394         local ids
2395
2396         $LFS setstripe -E 1M -S 1M -c 1 $tf
2397         ids=($($LFS getstripe $tf | awk '/lcme_id/{print $2}' | tr '\n' ' '))
2398         verify_comp_attr stripe-count $tf ${ids[0]} 1
2399
2400         $LFS setstripe --component-add -E 2M -c -1 $tf
2401         ids=($($LFS getstripe $tf | awk '/lcme_id/{print $2}' | tr '\n' ' '))
2402         verify_comp_attr stripe-count $tf ${ids[0]} 1
2403         verify_comp_attr stripe-count $tf ${ids[1]} -1
2404
2405         dd if=/dev/zero of=$tf bs=1M count=2
2406         ids=($($LFS getstripe $tf | awk '/lcme_id/{print $2}' | tr '\n' ' '))
2407         verify_comp_attr stripe-count $tf ${ids[0]} 1
2408         verify_comp_attr stripe-count $tf ${ids[1]} $OSTCOUNT
2409 }
2410 run_test 202 "lfs setstripe --add-component wide striping"
2411
2412 test_203() {
2413         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
2414                 skip "Need MDS version at least 2.11.55"
2415         [[ $OSTCOUNT -lt 2 ]] && skip "need >= 2 OSTs"
2416
2417         local tf=$DIR/$tfile
2418
2419         #create 2 mirrors
2420         $LFS mirror create -N2 -c1 $tf || error "create FLR file $tf"
2421         #delete first mirror
2422         $LFS mirror delete --mirror-id=1 $tf || error "delete first mirror"
2423
2424         $LFS getstripe $tf
2425         local old_id=$($LFS getstripe --mirror-id=2 -I $tf)
2426         local count=$($LFS getstripe --mirror-id=2 -c $tf) ||
2427                 error "getstripe count of mirror 2"
2428         [[ x$count = x1 ]] || error "mirror 2 stripe count $count is not 1"
2429
2430         #extend a mirror with 2 OSTs
2431         $LFS mirror extend -N -c2 $tf || error "extend mirror"
2432         $LFS getstripe $tf
2433
2434         local new_id=$($LFS getstripe --mirror-id=2 -I $tf)
2435         count=$($LFS getstripe --mirror-id=2 -c $tf) ||
2436                 error "getstripe count of mirror 2"
2437         [[ x$oldid = x$newid ]] ||
2438                 error "mirror 2 changed ID from $old_id to $new_id"
2439         [[ x$count = x1 ]] || error "mirror 2 stripe count $count is not 1"
2440
2441         count=$($LFS getstripe --mirror-id=3 -c $tf) ||
2442                 error "getstripe count of mirror 3"
2443         [[ x$count = x2 ]] || error "mirror 3 stripe count $count is not 2"
2444 }
2445 run_test 203 "mirror file preserve mirror ID"
2446
2447 # Simple test of FLR + self-extending layout, SEL in non-primary mirror
2448 test_204a() {
2449         [ "$MDS1_VERSION" -lt $(version_code $SEL_VER) ] &&
2450                 skip "skipped for lustre < $SEL_VER"
2451
2452         local comp_file=$DIR/$tdir/$tfile
2453         local flg_opts=""
2454         local found=""
2455
2456         test_mkdir $DIR/$tdir
2457
2458         # first mirror is 0-10M, then 10M-(-1), second mirror is 1M followed
2459         # by extension space to -1
2460         $LFS setstripe -N -E 10M -E-1 -N -E 1M -E-1 -z64M $comp_file ||
2461                 error "Create $comp_file failed"
2462
2463         # Write to first component, extending & staling second mirror
2464         dd if=/dev/zero bs=2M count=1 of=$comp_file conv=notrunc ||
2465                 error "dd to extend + stale failed"
2466
2467         $LFS getstripe $comp_file
2468
2469         flg_opts="--component-flags init,stale"
2470         found=$($LFS find --component-end 65M $flg_opts $comp_file | wc -l)
2471         [ $found -eq 1 ] || error "write: Second comp end incorrect"
2472
2473         flg_opts="--component-flags extension"
2474         found=$($LFS find --component-start 65M $flg_opts $comp_file | wc -l)
2475         [ $found -eq 1 ] || error "write: Third comp start incorrect"
2476
2477         # mirror resync should not change the extents
2478         $LFS mirror resync $comp_file
2479
2480         flg_opts="--component-flags init"
2481         found=$($LFS find --component-end 65M $flg_opts $comp_file | wc -l)
2482         [ $found -eq 1 ] || error "resync: Second comp end incorrect"
2483
2484         flg_opts="--component-flags extension"
2485         found=$($LFS find --component-start 65M $flg_opts $comp_file | wc -l)
2486         [ $found -eq 1 ] || error "resync: Third comp start incorrect"
2487
2488         sel_layout_sanity $comp_file 5
2489
2490         rm -f $comp_file
2491 }
2492 run_test 204a "FLR write/stale/resync tests with self-extending mirror"
2493
2494 # Simple test of FLR + self-extending layout, SEL in primary mirror
2495 test_204b() {
2496         [ "$MDS1_VERSION" -lt $(version_code $SEL_VER) ] &&
2497                 skip "skipped for lustre < $SEL_VER"
2498
2499         local comp_file=$DIR/$tdir/$tfile
2500         local flg_opts=""
2501         local found=""
2502
2503         test_mkdir $DIR/$tdir
2504
2505         # first mirror is 1M followed by extension space to -1, second mirror
2506         # is 0-10M, then 10M-(-1),
2507         $LFS setstripe -N -E 1M -E-1 -z64M -N -E 10M -E-1 $comp_file ||
2508                 error "Create $comp_file failed"
2509
2510         # Write to first component, extending first component & staling
2511         # other mirror
2512         dd if=/dev/zero bs=2M count=1 of=$comp_file conv=notrunc ||
2513                 error "dd to extend + stale failed"
2514
2515         $LFS getstripe $comp_file
2516
2517         flg_opts="--component-flags init"
2518         found=$($LFS find --component-end 65M $flg_opts $comp_file | wc -l)
2519         [ $found -eq 1 ] || error "write: First comp end incorrect"
2520
2521         flg_opts="--component-flags extension"
2522         found=$($LFS find --component-start 65M $flg_opts $comp_file | wc -l)
2523         [ $found -eq 1 ] || error "write: Second comp start incorrect"
2524
2525         flg_opts="--component-flags init,stale"
2526         found=$($LFS find --component-end 10M $flg_opts $comp_file | wc -l)
2527         [ $found -eq 1 ] || error "write: First mirror comp flags incorrect"
2528
2529         # This component is staled because it overlaps the extended first
2530         # component of the primary mirror, even though it doesn't overlap
2531         # the actual write - thus not inited.
2532         flg_opts="--component-flags stale"
2533         found=$($LFS find --component-start 10M $flg_opts $comp_file | wc -l)
2534         [ $found -eq 1 ] || error "write: Second mirror comp flags incorrect"
2535
2536         # mirror resync should not change the extents
2537         $LFS mirror resync $comp_file
2538
2539         $LFS getstripe $comp_file
2540
2541         flg_opts="--component-flags init"
2542         found=$($LFS find --component-end 65M $flg_opts $comp_file | wc -l)
2543         [ $found -eq 1 ] || error "resync: First comp end incorrect"
2544
2545         flg_opts="--component-flags extension"
2546         found=$($LFS find --component-start 65M $flg_opts $comp_file | wc -l)
2547         [ $found -eq 1 ] || error "resync: Second comp start incorrect"
2548
2549         flg_opts="--component-flags init"
2550         found=$($LFS find --component-end 10M $flg_opts $comp_file | wc -l)
2551         [ $found -eq 1 ] || error "resync: First mirror comp flags incorrect"
2552
2553         flg_opts="--component-flags init"
2554         found=$($LFS find --component-start 10M $flg_opts $comp_file | wc -l)
2555         [ $found -eq 1 ] || error "resync: Second mirror comp flags incorrect"
2556
2557         sel_layout_sanity $comp_file 5
2558
2559         rm -f $comp_file
2560 }
2561 run_test 204b "FLR write/stale/resync tests with self-extending primary"
2562
2563 # FLR + SEL failed extension & component removal
2564 # extension space in second mirror
2565 test_204c() {
2566         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
2567         [ "$MDS1_VERSION" -lt $(version_code $SEL_VER) ] &&
2568                 skip "skipped for lustre < $SEL_VER"
2569
2570         local comp_file=$DIR/$tdir/$tfile
2571         local found=""
2572         local ost_idx1=0
2573         local ost_name=$(ostname_from_index $ost_idx1)
2574
2575         test_mkdir $DIR/$tdir
2576
2577         # first mirror is is 0-10M, then 10M-(-1), second mirror is 0-1M, then
2578         # extension space from 1M to 1G, then normal space to -1
2579         $LFS setstripe -N -E 10M -E-1 -N -E 1M -E 1G -i $ost_idx1 -z 64M \
2580                 -E -1 $comp_file || error "Create $comp_file failed"
2581
2582         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
2583         sleep_maxage
2584
2585         # write to first comp (0 - 10M) of mirror 1, extending + staling
2586         # first + second comp of mirror 2
2587         dd if=/dev/zero bs=2M count=1 of=$comp_file conv=notrunc
2588         RC=$?
2589
2590         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
2591         sleep_maxage
2592
2593         [ $RC -eq 0 ] || error "dd to extend + stale failed"
2594
2595         $LFS getstripe $comp_file
2596
2597         found=$($LFS find --component-start 0m --component-end 1m \
2598                 --comp-flags init,stale $comp_file | wc -l)
2599         [ $found -eq 1 ] || error "write: First mirror comp incorrect"
2600
2601         found=$($LFS find --component-start 1m --component-end EOF \
2602                 --comp-flags stale,^init $comp_file | wc -l)
2603         [ $found -eq 1 ] || error "write: Second mirror comp incorrect"
2604
2605         local mirror_id=$($LFS getstripe --component-start=1m   \
2606                          --component-end=EOF $comp_file |       \
2607                          grep lcme_mirror_id | awk '{ print $2 }')
2608
2609         [[ $mirror_id -eq 2 ]] ||
2610                 error "component not in correct mirror? $mirror_id"
2611
2612         $LFS mirror resync $comp_file
2613
2614         $LFS getstripe $comp_file
2615
2616         # component dimensions should not change from resync
2617         found=$($LFS find --component-start 1m --component-end EOF \
2618                 --component-flags init $comp_file | wc -l)
2619         [ $found -eq 1 ] || error "resync: Second mirror comp incorrect"
2620
2621         sel_layout_sanity $comp_file 4
2622
2623         rm -f $comp_file
2624 }
2625 run_test 204c "FLR write/stale/resync test with component removal"
2626
2627 # Successful repeated component in primary mirror
2628 test_204d() {
2629         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
2630         [ "$MDS1_VERSION" -lt $(version_code $SEL_VER) ] &&
2631                 skip "skipped for lustre < $SEL_VERSION"
2632
2633         local comp_file=$DIR/$tdir/$tfile
2634         local found=""
2635
2636         wait_delete_completed
2637         wait_mds_ost_sync
2638         test_mkdir $DIR/$tdir
2639
2640         # first mirror is 64M followed by extension space to -1, second mirror
2641         # is 0-10M, then 10M-(-1)
2642         $LFS setstripe -N -E-1 -z64M -N -E 10M -E-1 $comp_file ||
2643                 error "Create $comp_file failed"
2644
2645         local ost_idx1=$($LFS getstripe -I65537 -i $comp_file)
2646         local ost_name=$(ostname_from_index $ost_idx1)
2647         # degrade OST for first comp so we won't extend there
2648         do_facet ost$((ost_idx1+1)) $LCTL set_param -n \
2649                 obdfilter.$ost_name.degraded=1
2650         sleep_maxage
2651
2652         # Write beyond first component, causing repeat & stale second mirror
2653         dd if=/dev/zero bs=1M count=1 seek=66 of=$comp_file conv=notrunc
2654         RC=$?
2655
2656         do_facet ost$((ost_idx1+1)) $LCTL set_param -n \
2657                 obdfilter.$ost_name.degraded=0
2658         sleep_maxage
2659
2660         [ $RC -eq 0 ] || error "dd to repeat & stale failed"
2661
2662         $LFS getstripe $comp_file
2663
2664         found=$($LFS find --component-start 64m --component-end 128m \
2665                 --component-flags init $comp_file | wc -l)
2666         [ $found -eq 1 ] || error "write: Repeat comp incorrect"
2667
2668         local ost_idx2=$($LFS getstripe --component-start=64m           \
2669                          --component-end=128m --component-flags=init    \
2670                          -i $comp_file)
2671         [[ $ost_idx1 -eq $ost_idx2 ]] && error "$ost_idx1 == $ost_idx2"
2672         local mirror_id=$($LFS getstripe --component-start=64m          \
2673                          --component-end=128m --component-flags=init    \
2674                          $comp_file | grep lcme_mirror_id | awk '{ print $2 }')
2675         [[ $mirror_id -eq 1 ]] ||
2676                 error "component not in correct mirror: $mirror_id, not 1"
2677
2678         $LFS mirror resync $comp_file
2679
2680         $LFS getstripe $comp_file
2681
2682         # component dimensions should not change from resync
2683         found=$($LFS find --component-start 0m --component-end 64m \
2684                 --component-flags init $comp_file | wc -l)
2685         [ $found -eq 1 ] || error "resync: first comp incorrect"
2686         found=$($LFS find --component-start 64m --component-end 128m \
2687                 --component-flags init $comp_file | wc -l)
2688         [ $found -eq 1 ] || error "resync: repeat comp incorrect"
2689
2690         sel_layout_sanity $comp_file 5
2691
2692         rm -f $comp_file
2693 }
2694 run_test 204d "FLR write/stale/resync sel test with repeated comp"
2695
2696 # Successful repeated component, SEL in non-primary mirror
2697 test_204e() {
2698         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
2699         [ "$MDS1_VERSION" -lt $(version_code $SEL_VER) ] &&
2700                 skip "skipped for lustre < $SEL_VERSION"
2701
2702         local comp_file=$DIR/$tdir/$tfile
2703         local found=""
2704
2705         wait_delete_completed
2706         wait_mds_ost_sync
2707
2708         test_mkdir $DIR/$tdir
2709
2710         # first mirror is is 0-100M, then 100M-(-1), second mirror is extension
2711         # space to -1 (-z 64M, so first comp is 0-64M)
2712         # Note: we have to place both 1st components on OST0, otherwise 2 OSTs
2713         # will be not enough - one will be degraded, the other is used on
2714         # an overlapping mirror.
2715         $LFS setstripe -N -E 100M -i 0 -E-1 -N -E-1 -i 0 -z 64M $comp_file ||
2716                 error "Create $comp_file failed"
2717
2718         local ost_idx1=$($LFS getstripe --component-start=0 \
2719                          --component-end=64m -i $comp_file)
2720         local ost_name=$(ostname_from_index $ost_idx1)
2721         # degrade OST for first comp of 2nd mirror so we won't extend there
2722         do_facet ost$((ost_idx1+1)) $LCTL set_param -n \
2723                 obdfilter.$ost_name.degraded=1
2724         sleep_maxage
2725
2726         $LFS getstripe $comp_file
2727
2728         # Write to first component, stale & instantiate second mirror components
2729         # overlapping with the written component (0-100M);
2730         dd if=/dev/zero bs=2M count=1 of=$comp_file conv=notrunc
2731         RC=$?
2732
2733         do_facet ost$((ost_idx1+1)) $LCTL set_param -n \
2734                 obdfilter.$ost_name.degraded=0
2735         sleep_maxage
2736         $LFS getstripe $comp_file
2737
2738         [ $RC -eq 0 ] || error "dd to repeat & stale failed"
2739
2740         found=$($LFS find --component-start 0m --component-end 64m \
2741                 --component-flags init,stale $comp_file | wc -l)
2742         [ $found -eq 1 ] || error "write: first comp incorrect"
2743
2744         # was repeated due to degraded ost
2745         found=$($LFS find --component-start 64m --component-end 128m \
2746                 --component-flags init,stale $comp_file | wc -l)
2747         [ $found -eq 1 ] || error "write: repeated comp incorrect"
2748
2749         local ost_idx2=$($LFS getstripe --component-start=64m           \
2750                          --component-end=128m --component-flags=init    \
2751                          -i $comp_file)
2752         [[ $ost_idx1 -eq $ost_idx2 ]] && error "$ost_idx1 == $ost_idx2"
2753         local mirror_id=$($LFS getstripe --component-start=0m           \
2754                          --component-end=64m --component-flags=init     \
2755                          $comp_file | grep lcme_mirror_id | awk '{ print $2 }')
2756         [[ $mirror_id -eq 2 ]] ||
2757                 error "component not in correct mirror? $mirror_id"
2758
2759         $LFS mirror resync $comp_file
2760
2761         $LFS getstripe $comp_file
2762
2763         # component dimensions should not change from resync
2764         found=$($LFS find --component-start 0m --component-end 64m \
2765                 --component-flags init,^stale $comp_file | wc -l)
2766         [ $found -eq 1 ] || error "resync: first comp incorrect"
2767         found=$($LFS find --component-start 64m --component-end 128m \
2768                 --component-flags init,^stale $comp_file | wc -l)
2769         [ $found -eq 1 ] || error "resync: repeated comp incorrect"
2770
2771         sel_layout_sanity $comp_file 5
2772
2773         rm -f $comp_file
2774 }
2775 run_test 204e "FLR write/stale/resync sel test with repeated comp"
2776
2777 # FLR + SEL: failed repeated component, SEL in non-primary mirror
2778 test_204f() {
2779         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
2780         [ "$MDS1_VERSION" -lt $(version_code $SEL_VER) ] &&
2781                 skip "skipped for lustre < $SEL_VERSION"
2782
2783         local comp_file=$DIR/$tdir/$tfile
2784         local found=""
2785
2786         wait_delete_completed
2787         wait_mds_ost_sync
2788         test_mkdir $DIR/$tdir
2789
2790         pool_add $TESTNAME || error "Pool creation failed"
2791         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
2792
2793         # first mirror is is 0-100M, then 100M-(-1), second mirror is extension
2794         # space to -1 (-z 64M, so first comp is 0-64M)
2795         $LFS setstripe -N -E 100M -E-1 -N --pool="$TESTNAME" \
2796                 -E-1 -c 1 -z 64M $comp_file || error "Create $comp_file failed"
2797
2798         local ost_name0=$(ostname_from_index 0)
2799         local ost_name1=$(ostname_from_index 1)
2800
2801         # degrade both OSTs in pool, so we'll try to repeat, then fail and
2802         # extend original comp
2803         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name0.degraded=1
2804         do_facet ost2 $LCTL set_param -n obdfilter.$ost_name1.degraded=1
2805         sleep_maxage
2806
2807         # a write to the 1st component, 100M length, which will try to stale
2808         # the first 100M of mirror 2, attempting to extend its 0-64M component
2809         dd if=/dev/zero bs=2M count=1 of=$comp_file conv=notrunc
2810         RC=$?
2811
2812         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name0.degraded=0
2813         do_facet ost2 $LCTL set_param -n obdfilter.$ost_name1.degraded=0
2814         sleep_maxage
2815
2816         [ $RC -eq 0 ] || error "dd to extend mirror comp failed"
2817
2818         $LFS getstripe $comp_file
2819
2820         found=$($LFS find --component-start 0m --component-end 128m \
2821                 --component-flags init,stale $comp_file | wc -l)
2822         [ $found -eq 1 ] || error "write: First mirror comp incorrect"
2823
2824         local mirror_id=$($LFS getstripe --component-start=0m           \
2825                          --component-end=128m --component-flags=init    \
2826                          $comp_file | grep lcme_mirror_id | awk '{ print $2 }')
2827
2828         [[ $mirror_id -eq 2 ]] ||
2829                 error "component not in correct mirror? $mirror_id, not 2"
2830
2831         $LFS mirror resync $comp_file
2832
2833         $LFS getstripe $comp_file
2834
2835         # component dimensions should not change from resync
2836         found=$($LFS find --component-start 0m --component-end 128m \
2837                 --component-flags init,^stale $comp_file | wc -l)
2838         [ $found -eq 1 ] || error "resync: First mirror comp incorrect"
2839
2840         sel_layout_sanity $comp_file 4
2841
2842         rm -f $comp_file
2843 }
2844 run_test 204f "FLR write/stale/resync sel w/forced extension"
2845
2846 complete $SECONDS
2847 check_and_cleanup_lustre
2848 exit_status