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