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