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