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