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