Whamcloud - gitweb
LU-9771 flr: mirror resync multiple files
[fs/lustre-release.git] / lustre / tests / sanity-flr.sh
1 #!/bin/bash
2 #
3 # Run select tests by setting ONLY, or as arguments to the script.
4 # Skip specific tests by setting EXCEPT.
5 set -e
6 set +o posix
7
8 SRCDIR=$(dirname $0)
9 export PATH=$PWD/$SRCDIR:$SRCDIR:$PWD/$SRCDIR/../utils:$PATH:/sbin
10
11 ONLY=${ONLY:-"$*"}
12 # Bug number for skipped test:
13 ALWAYS_EXCEPT="$SANITY_FLR_EXCEPT 201"
14 # UPDATE THE COMMENT ABOVE WITH BUG NUMBERS WHEN CHANGING ALWAYS_EXCEPT!
15
16 LUSTRE=${LUSTRE:-$(cd $(dirname $0)/..; echo $PWD)}
17 . $LUSTRE/tests/test-framework.sh
18 init_test_env $@
19 . ${CONFIG:=$LUSTRE/tests/cfg/$NAME.sh}
20 init_logging
21
22 [ $UID -eq 0 -a $RUNAS_ID -eq 0 ] &&
23         error "\$RUNAS_ID set to 0, but \$UID is also 0!"
24 check_runas_id $RUNAS_ID $RUNAS_GID $RUNAS
25
26 check_and_setup_lustre
27 DIR=${DIR:-$MOUNT}
28 assert_DIR
29
30 build_test_filter
31
32 # global array to store mirror IDs
33 declare -a mirror_array
34 get_mirror_ids() {
35         local tf=$1
36         local id
37         local array
38
39         array=()
40         for id in $($LFS getstripe $tf | awk '/lcme_id/{print $2}'); do
41                 array[${#array[@]}]=$((id >> 16))
42         done
43
44         mirror_array=($(printf "%s\n" "${array[@]}" | sort -u))
45
46         echo ${#mirror_array[@]}
47 }
48
49 drop_client_cache() {
50         echo 3 > /proc/sys/vm/drop_caches
51 }
52
53 stop_osts() {
54         local idx
55
56         for idx in "$@"; do
57                 stop ost$idx
58         done
59
60         for idx in "$@"; do
61                 wait_osc_import_state client ost$idx DISCONN
62         done
63 }
64
65 start_osts() {
66         local idx
67
68         for idx in "$@"; do
69                 start ost$idx $(ostdevname $idx) $OST_MOUNT_OPTS ||
70                         error "start ost$idx failed"
71         done
72
73         for idx in "$@"; do
74                 wait_osc_import_state client ost$idx FULL
75         done
76 }
77
78 #
79 # Verify mirror count with an expected value for a given file.
80 #
81 verify_mirror_count() {
82         local tf=$1
83         local expected=$2
84         local mirror_count=$(get_mirror_ids $tf)
85
86         [[ $mirror_count = $expected ]] || {
87                 $LFS getstripe -v $tf
88                 error "verify mirror count failed on $tf:" \
89                       "$mirror_count != $expected"
90         }
91 }
92
93 #
94 # Verify component count with an expected value for a given file.
95 #       $1 coposited layout file
96 #       $2 expected component number
97 #
98 verify_comp_count() {
99         local tf=$1
100         local expected=$2
101         local comp_count=$($LFS getstripe --component-count $tf)
102
103         [[ $comp_count = $expected ]] || {
104                 $LFS getstripe -v $tf
105                 error "verify component count failed on $tf:" \
106                       "$comp_count != $expected"
107         }
108 }
109
110 #
111 # Verify component attribute with an expected value for a given file
112 # and component ID.
113 #
114 verify_comp_attr() {
115         local attr=$1
116         local tf=$2
117         local comp_id=$3
118         local expected=$4
119         local cmd="$LFS getstripe -I$comp_id"
120         local getstripe_cmd="$cmd -v"
121         local value
122
123         case $attr in
124                 stripe-size) cmd+=" -S $tf" ;;
125                 stripe-count) cmd+=" -c $tf" ;;
126                 stripe-index) cmd+=" -i $tf" ;;
127                 pool) cmd+=" -p $tf" ;;
128                 comp-start) cmd+=" --component-start $tf" ;;
129                 comp-end) cmd+=" --component-end $tf" ;;
130                 lcme_flags) cmd+=" $tf | awk '/lcme_flags:/ { print \$2 }'" ;;
131                 *) error "invalid attribute $attr";;
132         esac
133
134         value=$(eval $cmd)
135
136         [[ $value = $expected ]] || {
137                 $getstripe_cmd $tf
138                 error "verify $attr failed on $tf: $value != $expected"
139         }
140 }
141
142 #
143 # Verify component extent with expected start and end extent values
144 # for a given file and component ID.
145 #
146 verify_comp_extent() {
147         local tf=$1
148         local comp_id=$2
149         local expected_start=$3
150         local expected_end=$4
151
152         verify_comp_attr comp-start $tf $comp_id $expected_start
153         verify_comp_attr comp-end $tf $comp_id $expected_end
154 }
155
156 #
157 # Verify component attribute with parent directory for a given file
158 # and component ID.
159 #
160 verify_comp_attr_with_parent() {
161         local attr=$1
162         local tf=$2
163         local comp_id=$3
164         local td=$(cd $(dirname $tf); echo $PWD)
165         local tf_cmd="$LFS getstripe -I$comp_id"
166         local td_cmd="$LFS getstripe"
167         local opt
168         local expected
169         local value
170
171         case $attr in
172                 stripe-size) opt="-S" ;;
173                 stripe-count) opt="-c" ;;
174                 pool) opt="-p" ;;
175                 *) error "invalid attribute $attr";;
176         esac
177
178         expected=$($td_cmd $opt $td)
179         [[ $expected = -1 ]] && expected=$OSTCOUNT
180
181         value=$($tf_cmd $opt $tf)
182         [[ $value = -1 ]] && value=$OSTCOUNT
183
184         [[ $value = $expected ]] || {
185                 $td_cmd -d $td
186                 $tf_cmd -v $tf
187                 error "verify $attr failed with parent on $tf:" \
188                       "$value != $expected"
189         }
190 }
191
192 #
193 # Verify component attributes with parent directory for a given file
194 # and component ID.
195 #
196 # This will only verify the inherited attributes:
197 # stripe size, stripe count and OST pool name
198 #
199 verify_comp_attrs_with_parent() {
200         local tf=$1
201         local comp_id=$2
202
203         verify_comp_attr_with_parent stripe-size $tf $comp_id
204         verify_comp_attr_with_parent stripe-count $tf $comp_id
205         verify_comp_attr_with_parent pool $tf $comp_id
206 }
207
208 # command line test cases
209 test_0a() {
210         local td=$DIR/$tdir
211         local tf=$td/$tfile
212         local mirror_count=16 # LUSTRE_MIRROR_COUNT_MAX
213         local mirror_cmd="$LFS mirror create"
214         local id
215         local ids
216         local i
217
218         # create parent directory
219         mkdir $td || error "mkdir $td failed"
220
221         $mirror_cmd $tf &> /dev/null && error "miss -N option"
222
223         $mirror_cmd -N $tf || error "create mirrored file $tf failed"
224         verify_mirror_count $tf 1
225         id=$($LFS getstripe -I $tf)
226         verify_comp_attrs_with_parent $tf $id
227         verify_comp_extent $tf $id 0 EOF
228
229         $mirror_cmd -N0 $tf-1 &> /dev/null && error "invalid mirror count 0"
230         $mirror_cmd -N$((mirror_count + 1)) $tf-1 &> /dev/null &&
231                 error "invalid mirror count $((mirror_count + 1))"
232
233         $mirror_cmd -N$mirror_count $tf-1 ||
234                 error "create mirrored file $tf-1 failed"
235         verify_mirror_count $tf-1 $mirror_count
236         ids=($($LFS getstripe $tf-1 | awk '/lcme_id/{print $2}' | tr '\n' ' '))
237         for ((i = 0; i < $mirror_count; i++)); do
238                 verify_comp_attrs_with_parent $tf-1 ${ids[$i]}
239                 verify_comp_extent $tf-1 ${ids[$i]} 0 EOF
240         done
241
242         $mirror_cmd -N -N2 -N3 -N4 $tf-2 ||
243                 error "create mirrored file $tf-2 failed"
244         verify_mirror_count $tf-2 10
245         ids=($($LFS getstripe $tf-2 | awk '/lcme_id/{print $2}' | tr '\n' ' '))
246         for ((i = 0; i < 10; i++)); do
247                 verify_comp_attrs_with_parent $tf-2 ${ids[$i]}
248                 verify_comp_extent $tf-2 ${ids[$i]} 0 EOF
249         done
250 }
251 run_test 0a "lfs mirror create with -N option"
252
253 test_0b() {
254         [[ $OSTCOUNT -lt 4 ]] && skip "need >= 4 OSTs" && return
255
256         local td=$DIR/$tdir
257         local tf=$td/$tfile
258         local mirror_cmd="$LFS mirror create"
259         local ids
260         local i
261
262         # create parent directory
263         mkdir $td || error "mkdir $td failed"
264
265         # create a mirrored file with plain layout mirrors
266         $mirror_cmd -N -S 4M -c 2 -p flash -i 2 -o 2,3 \
267                     -N -S 16M -N -c -1 -N -p archive -N --parent $tf ||
268                 error "create mirrored file $tf failed"
269         verify_mirror_count $tf 5
270         ids=($($LFS getstripe $tf | awk '/lcme_id/{print $2}' | tr '\n' ' '))
271         for ((i = 0; i < 5; i++)); do
272                 verify_comp_extent $tf ${ids[$i]} 0 EOF
273         done
274
275         # verify component ${ids[0]}
276         verify_comp_attr stripe-size $tf ${ids[0]} 4194304
277         verify_comp_attr stripe-count $tf ${ids[0]} 2
278         verify_comp_attr stripe-index $tf ${ids[0]} 2
279         verify_comp_attr pool $tf ${ids[0]} flash
280
281         # verify component ${ids[1]}
282         verify_comp_attr stripe-size $tf ${ids[1]} 16777216
283         verify_comp_attr stripe-count $tf ${ids[1]} 2
284         verify_comp_attr pool $tf ${ids[1]} flash
285
286         # verify component ${ids[2]}
287         verify_comp_attr stripe-size $tf ${ids[2]} 16777216
288         verify_comp_attr stripe-count $tf ${ids[2]} $OSTCOUNT
289         verify_comp_attr pool $tf ${ids[2]} flash
290
291         # verify component ${ids[3]}
292         verify_comp_attr stripe-size $tf ${ids[3]} 16777216
293         verify_comp_attr stripe-count $tf ${ids[3]} $OSTCOUNT
294         verify_comp_attr pool $tf ${ids[3]} archive
295
296         # verify component ${ids[4]}
297         verify_comp_attrs_with_parent $tf ${ids[4]}
298 }
299 run_test 0b "lfs mirror create plain layout mirrors"
300
301 test_0c() {
302         [[ $OSTCOUNT -lt 4 ]] && skip "need >= 4 OSTs" && return
303
304         local td=$DIR/$tdir
305         local tf=$td/$tfile
306         local mirror_cmd="$LFS mirror create"
307         local ids
308         local i
309
310         # create parent directory
311         mkdir $td || error "mkdir $td failed"
312
313         # create a mirrored file with composite layout mirrors
314         $mirror_cmd -N2 -E 4M -c 2 -p flash -i 1 -o 1,3 -E eof -S 4M \
315                     -N --parent \
316                     -N3 -E 512M -S 16M -p archive -E -1 -i -1 -c -1 $tf ||
317                 error "create mirrored file $tf failed"
318         verify_mirror_count $tf 6
319         ids=($($LFS getstripe $tf | awk '/lcme_id/{print $2}' | tr '\n' ' '))
320
321         # verify components ${ids[0]} and ${ids[2]}
322         for i in 0 2; do
323                 verify_comp_attr_with_parent stripe-size $tf ${ids[$i]}
324                 verify_comp_attr stripe-count $tf ${ids[$i]} 2
325                 verify_comp_attr stripe-index $tf ${ids[$i]} 1
326                 verify_comp_attr pool $tf ${ids[$i]} flash
327                 verify_comp_extent $tf ${ids[$i]} 0 4194304
328         done
329
330         # verify components ${ids[1]} and ${ids[3]}
331         for i in 1 3; do
332                 verify_comp_attr stripe-size $tf ${ids[$i]} 4194304
333                 verify_comp_attr stripe-count $tf ${ids[$i]} 2
334                 verify_comp_attr pool $tf ${ids[$i]} flash
335                 verify_comp_extent $tf ${ids[$i]} 4194304 EOF
336         done
337
338         # verify component ${ids[4]}
339         verify_comp_attrs_with_parent $tf ${ids[4]}
340         verify_comp_extent $tf ${ids[4]} 0 EOF
341
342         # verify components ${ids[5]}, ${ids[7]} and ${ids[9]}
343         for i in 5 7 9; do
344                 verify_comp_attr stripe-size $tf ${ids[$i]} 16777216
345                 verify_comp_attr_with_parent stripe-count $tf ${ids[$i]}
346                 verify_comp_attr pool $tf ${ids[$i]} archive
347                 verify_comp_extent $tf ${ids[$i]} 0 536870912
348         done
349
350         # verify components ${ids[6]}, ${ids[8]} and ${ids[10]}
351         for i in 6 8 10; do
352                 verify_comp_attr stripe-size $tf ${ids[$i]} 16777216
353                 verify_comp_attr stripe-count $tf ${ids[$i]} -1
354                 verify_comp_attr pool $tf ${ids[$i]} archive
355                 verify_comp_extent $tf ${ids[$i]} 536870912 EOF
356         done
357 }
358 run_test 0c "lfs mirror create composite layout mirrors"
359
360 test_0d() {
361         local td=$DIR/$tdir
362         local tf=$td/$tfile
363         local mirror_count=16 # LUSTRE_MIRROR_COUNT_MAX
364         local mirror_cmd="$LFS mirror extend"
365         local ids
366         local i
367
368         # create parent directory
369         mkdir $td || error "mkdir $td failed"
370
371         $mirror_cmd $tf &> /dev/null && error "miss -N option"
372         $mirror_cmd -N $tf &> /dev/null && error "$tf does not exist"
373
374         # create a non-mirrored file, convert it to a mirrored file and extend
375         touch $tf || error "touch $tf failed"
376         $mirror_cmd -N $tf || error "convert and extend $tf failed"
377         verify_mirror_count $tf 2
378         ids=($($LFS getstripe $tf | awk '/lcme_id/{print $2}' | tr '\n' ' '))
379         for ((i = 0; i < 2; i++)); do
380                 verify_comp_attrs_with_parent $tf ${ids[$i]}
381                 verify_comp_extent $tf ${ids[$i]} 0 EOF
382         done
383
384         # create a mirrored file and extend it
385         $LFS mirror create -N $tf-1 || error "create mirrored file $tf-1 failed"
386         $LFS mirror create -N $tf-2 || error "create mirrored file $tf-2 failed"
387
388         $mirror_cmd -N -S 4M -N -f $tf-2 $tf-1 &> /dev/null &&
389                 error "setstripe options should not be specified with -f option"
390
391         $mirror_cmd -N -f $tf-2 -N --parent $tf-1 &> /dev/null &&
392                 error "--parent option should not be specified with -f option"
393
394         $mirror_cmd -N$((mirror_count - 1)) $tf-1 ||
395                 error "extend mirrored file $tf-1 failed"
396         verify_mirror_count $tf-1 $mirror_count
397         ids=($($LFS getstripe $tf-1 | awk '/lcme_id/{print $2}' | tr '\n' ' '))
398         for ((i = 0; i < $mirror_count; i++)); do
399                 verify_comp_attrs_with_parent $tf-1 ${ids[$i]}
400                 verify_comp_extent $tf-1 ${ids[$i]} 0 EOF
401         done
402
403         $mirror_cmd -N $tf-1 &> /dev/null &&
404                 error "exceeded maximum mirror count $mirror_count" || true
405 }
406 run_test 0d "lfs mirror extend with -N option"
407
408 test_0e() {
409         [[ $OSTCOUNT -lt 4 ]] && skip "need >= 4 OSTs" && return
410
411         local td=$DIR/$tdir
412         local tf=$td/$tfile
413         local mirror_cmd="$LFS mirror extend"
414         local ids
415         local i
416
417         # create parent directory
418         mkdir $td || error "mkdir $td failed"
419
420         # create a mirrored file with plain layout mirrors
421         $LFS mirror create -N -S 32M -c 3 -p ssd -i 1 -o 1,2,3 $tf ||
422                 error "create mirrored file $tf failed"
423
424         # extend the mirrored file with plain layout mirrors
425         $mirror_cmd -N -S 4M -c 2 -p flash -i 2 -o 2,3 \
426                     -N -S 16M -N -c -1 -N -p archive -N --parent $tf ||
427                 error "extend mirrored file $tf failed"
428         verify_mirror_count $tf 6
429         ids=($($LFS getstripe $tf | awk '/lcme_id/{print $2}' | tr '\n' ' '))
430         for ((i = 0; i < 6; i++)); do
431                 verify_comp_extent $tf ${ids[$i]} 0 EOF
432         done
433
434         # verify component ${ids[0]}
435         verify_comp_attr stripe-size $tf ${ids[0]} 33554432
436         verify_comp_attr stripe-count $tf ${ids[0]} 3
437         verify_comp_attr stripe-index $tf ${ids[0]} 1
438         verify_comp_attr pool $tf ${ids[0]} ssd
439
440         # verify component ${ids[1]}
441         verify_comp_attr stripe-size $tf ${ids[1]} 4194304
442         verify_comp_attr stripe-count $tf ${ids[1]} 2
443         verify_comp_attr stripe-index $tf ${ids[1]} 2
444         verify_comp_attr pool $tf ${ids[1]} flash
445
446         # verify component ${ids[2]}
447         verify_comp_attr stripe-size $tf ${ids[2]} 16777216
448         verify_comp_attr stripe-count $tf ${ids[2]} 2
449         verify_comp_attr pool $tf ${ids[2]} flash
450
451         # verify component ${ids[3]}
452         verify_comp_attr stripe-size $tf ${ids[3]} 16777216
453         verify_comp_attr stripe-count $tf ${ids[3]} $OSTCOUNT
454         verify_comp_attr pool $tf ${ids[3]} flash
455
456         # verify component ${ids[4]}
457         verify_comp_attr stripe-size $tf ${ids[4]} 16777216
458         verify_comp_attr stripe-count $tf ${ids[4]} $OSTCOUNT
459         verify_comp_attr pool $tf ${ids[4]} archive
460
461         # verify component ${ids[5]}
462         verify_comp_attrs_with_parent $tf ${ids[5]}
463 }
464 run_test 0e "lfs mirror extend plain layout mirrors"
465
466 test_0f() {
467         [[ $OSTCOUNT -lt 4 ]] && skip "need >= 4 OSTs" && return
468
469         local td=$DIR/$tdir
470         local tf=$td/$tfile
471         local mirror_cmd="$LFS mirror extend"
472         local ids
473         local i
474
475         # create parent directory
476         mkdir $td || error "mkdir $td failed"
477
478         # create a mirrored file with composite layout mirror
479         $LFS mirror create -N -E 32M -S 16M -p ssd -E eof -S 32M $tf ||
480                 error "create mirrored file $tf failed"
481
482         # extend the mirrored file with composite layout mirrors
483         $mirror_cmd -N2 -E 4M -c 2 -p flash -i 1 -o 1,3 -E eof -S 4M \
484                     -N --parent \
485                     -N3 -E 512M -S 16M -p archive -E -1 -i -1 -c -1 $tf ||
486                 error "extend mirrored file $tf failed"
487         verify_mirror_count $tf 7
488         ids=($($LFS getstripe $tf | awk '/lcme_id/{print $2}' | tr '\n' ' '))
489
490         # verify component ${ids[0]}
491         verify_comp_attr stripe-size $tf ${ids[0]} 16777216
492         verify_comp_attr_with_parent stripe-count $tf ${ids[0]}
493         verify_comp_attr pool $tf ${ids[0]} ssd
494         verify_comp_extent $tf ${ids[0]} 0 33554432
495
496         # verify component ${ids[1]}
497         verify_comp_attr stripe-size $tf ${ids[1]} 33554432
498         verify_comp_attr_with_parent stripe-count $tf ${ids[1]}
499         verify_comp_attr pool $tf ${ids[1]} ssd
500         verify_comp_extent $tf ${ids[1]} 33554432 EOF
501
502         # verify components ${ids[2]} and ${ids[4]}
503         for i in 2 4; do
504                 verify_comp_attr_with_parent stripe-size $tf ${ids[$i]}
505                 verify_comp_attr stripe-count $tf ${ids[$i]} 2
506                 verify_comp_attr stripe-index $tf ${ids[$i]} 1
507                 verify_comp_attr pool $tf ${ids[$i]} flash
508                 verify_comp_extent $tf ${ids[$i]} 0 4194304
509         done
510
511         # verify components ${ids[3]} and ${ids[5]}
512         for i in 3 5; do
513                 verify_comp_attr stripe-size $tf ${ids[$i]} 4194304
514                 verify_comp_attr stripe-count $tf ${ids[$i]} 2
515                 verify_comp_attr pool $tf ${ids[$i]} flash
516                 verify_comp_extent $tf ${ids[$i]} 4194304 EOF
517         done
518
519         # verify component ${ids[6]}
520         verify_comp_attrs_with_parent $tf ${ids[6]}
521         verify_comp_extent $tf ${ids[6]} 0 EOF
522
523         # verify components ${ids[7]}, ${ids[9]} and ${ids[11]}
524         for i in 7 9 11; do
525                 verify_comp_attr stripe-size $tf ${ids[$i]} 16777216
526                 verify_comp_attr_with_parent stripe-count $tf ${ids[$i]}
527                 verify_comp_attr pool $tf ${ids[$i]} archive
528                 verify_comp_extent $tf ${ids[$i]} 0 536870912
529         done
530
531         # verify components ${ids[8]}, ${ids[10]} and ${ids[12]}
532         for i in 8 10 12; do
533                 verify_comp_attr stripe-size $tf ${ids[$i]} 16777216
534                 verify_comp_attr stripe-count $tf ${ids[$i]} -1
535                 verify_comp_attr pool $tf ${ids[$i]} archive
536                 verify_comp_extent $tf ${ids[$i]} 536870912 EOF
537         done
538 }
539 run_test 0f "lfs mirror extend composite layout mirrors"
540
541 test_1() {
542         local tf=$DIR/$tfile
543         local mirror_count=16 # LUSTRE_MIRROR_COUNT_MAX
544         local mirror_create_cmd="$LFS mirror create"
545         local stripes[0]=$OSTCOUNT
546
547         mirror_create_cmd+=" -N -c ${stripes[0]}"
548         for ((i = 1; i < $mirror_count; i++)); do
549                 # add mirrors with different stripes to the file
550                 stripes[$i]=$((RANDOM % OSTCOUNT))
551                 [ ${stripes[$i]} -eq 0 ] && stripes[$i]=1
552
553                 mirror_create_cmd+=" -N -c ${stripes[$i]}"
554         done
555
556         $mirror_create_cmd $tf || error "create mirrored file $tf failed"
557         verify_mirror_count $tf $mirror_count
558
559         # can't create mirrors exceeding LUSTRE_MIRROR_COUNT_MAX
560         $LFS mirror extend -N $tf &&
561                 error "Creating the $((mirror_count+1))th mirror succeeded"
562
563         local ids=($($LFS getstripe $tf | awk '/lcme_id/{print $2}' |
564                         tr '\n' ' '))
565
566         # verify the range of components and stripe counts
567         for ((i = 0; i < $mirror_count; i++)); do
568                 verify_comp_attr stripe-count $tf ${ids[$i]} ${stripes[$i]}
569                 verify_comp_extent $tf ${ids[$i]} 0 EOF
570         done
571 }
572 run_test 1 "create components with setstripe options"
573
574 test_2() {
575         local tf=$DIR/$tfile
576         local tf2=$DIR/$tfile-2
577
578         $LFS setstripe -E 1M -E EOF -c 1 $tf
579         $LFS setstripe -E 2M -E EOF -c -1 $tf2
580
581         local layout=$($LFS getstripe $tf2 | grep -A 4 lmm_objects)
582
583         $LFS mirror extend -N -f $tf2 $tf ||
584                 error "merging $tf2 into $tf failed"
585
586         verify_mirror_count $tf 2
587         [[ ! -e $tf2 ]] || error "$tf2 was not unlinked"
588 }
589 run_test 2 "create components from existing files"
590
591 test_3() {
592         [[ $MDSCOUNT -lt 2 ]] && skip "need >= 2 MDTs" && return
593
594         for ((i = 0; i < 2; i++)); do
595                 $LFS mkdir -i $i $DIR/$tdir-$i
596                 $LFS setstripe -E -1 $DIR/$tdir-$i/$tfile
597         done
598
599         $LFS mirror extend -N -f $DIR/$tdir-1/$tfile \
600                 $DIR/$tdir-0/$tfile || error "creating mirrors"
601
602         # mdt doesn't support to cancel layout lock for remote objects, do
603         # it here manually.
604         cancel_lru_locks mdc
605
606         # make sure the mirrorted file was created successfully
607         [[ $($LFS getstripe --component-count $DIR/$tdir-0/$tfile) -eq 2 ]] ||
608                 { $LFS getstripe $DIR/$tdir-0/$tfile;
609                         error "expected 2 components"; }
610
611         # cleanup
612         rm -rf $DIR/$tdir-*
613 }
614 run_test 3 "create components from files located on different MDTs"
615
616 test_4() {
617         local tf=$DIR/$tdir/$tfile
618         local ids=()
619
620         test_mkdir $DIR/$tdir
621
622         # set mirror with setstripe options to directory
623         $LFS mirror create -N2 -E 1M -E eof $DIR/$tdir ||
624                 error "set mirror to directory error"
625
626         [ x$($LFS getstripe -v $DIR/$tdir | awk '/lcm_flags/{print $2}') = \
627                 x"mirrored" ] || error "failed to create mirrored dir"
628
629         touch $tf
630         verify_mirror_count $tf 2
631
632         ids=($($LFS getstripe $tf | awk '/lcme_id/{print $2}' | tr '\n' ' '))
633         verify_comp_extent $tf ${ids[0]} 0 1048576
634         verify_comp_extent $tf ${ids[1]} 1048576 EOF
635
636         # sub directory should inherit mirror setting from parent
637         test_mkdir $DIR/$tdir/td
638         [ x$($LFS getstripe -v $DIR/$tdir/td | awk '/lcm_flags/{print $2}') = \
639                 x"mirrored" ] || error "failed to inherit mirror from parent"
640
641         # mirror extend won't be applied to directory
642         $LFS mirror extend -N2 $DIR/$tdir &&
643                 error "expecting mirror extend failure"
644         true
645 }
646 run_test 4 "Make sure mirror attributes can be inhertied from directory"
647
648 test_5() {
649         local tf=$DIR/$tfile
650         local ids=()
651
652         $MULTIOP $tf oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T12345c ||
653                 error "failed to create file with non-empty layout"
654         $CHECKSTAT -t file -s 12345 $tf || error "size error: expecting 12345"
655
656         $LFS mirror create -N3 $tf || error "failed to attach mirror layout"
657         verify_mirror_count $tf 3
658
659         $CHECKSTAT -t file -s 12345 $tf ||
660                 error "size error after attaching layout "
661 }
662 run_test 5 "Make sure init size work for mirrored layout"
663
664 # LU=10112: disable dom+flr for phase 1
665 test_6() {
666         local tf=$DIR/$tfile
667
668         $LFS mirror create -N -E 1M -L mdt -E eof -N -E eof $tf &&
669                 error "expect failure to create mirrored file with DoM"
670
671         $LFS mirror create -N -E 1M -E eof -N -E 1M -L mdt -E eof $tf &&
672                 error "expect failure to create mirrored file with DoM"
673
674         $LFS setstripe -E 1M -L mdt -E eof $tf
675         $LFS mirror extend -N2 $tf &&
676                 error "expect failure to extend mirror with DoM"
677
678         $LFS mirror create -N2 -E 1M -E eof $tf-2
679         $LFS mirror extend -N -f $tf $tf-2 &&
680                 error "expect failure to extend mirrored file with DoM extent"
681
682         true
683 }
684 run_test 6 "DoM and FLR won't co-exist for phase 1"
685
686 test_21() {
687         local tf=$DIR/$tfile
688         local tf2=$DIR/$tfile-2
689
690         [[ $OSTCOUNT -lt 2 ]] && skip "need >= 2 OSTs" && return
691
692         $LFS setstripe -E EOF -o 0 $tf
693         $LFS setstripe -E EOF -o 1 $tf2
694
695         local dd_count=$((RANDOM % 20 + 1))
696         dd if=/dev/zero of=$tf bs=1M count=$dd_count
697         dd if=/dev/zero of=$tf2 bs=1M count=1 seek=$((dd_count - 1))
698         cancel_lru_locks osc
699
700         local blocks=$(du -kc $tf $tf2 | awk '/total/{print $1}')
701
702         # add component
703         $LFS mirror extend -N -f $tf2 $tf ||
704                 error "merging $tf2 into $tf failed"
705
706         # cancel layout lock
707         cancel_lru_locks mdc
708
709         local new_blocks=$(du -k $tf | awk '{print $1}')
710         [ $new_blocks -eq $blocks ] ||
711         error "i_blocks error expected: $blocks, actual: $new_blocks"
712 }
713 run_test 21 "glimpse should report accurate i_blocks"
714
715 get_osc_lock_count() {
716         local lock_count=0
717
718         for idx in "$@"; do
719                 local osc_name
720                 local count
721
722                 osc_name=${FSNAME}-OST$(printf "%04x" $((idx-1)))-osc-'ffff*'
723                 count=$($LCTL get_param -n ldlm.namespaces.$osc_name.lock_count)
724                 lock_count=$((lock_count + count))
725         done
726         echo $lock_count
727 }
728
729 test_22() {
730         local tf=$DIR/$tfile
731
732         $LFS setstripe -E EOF -o 0 $tf
733         dd if=/dev/zero of=$tf bs=1M count=$((RANDOM % 20 + 1))
734
735         # add component, two mirrors located on the same OST ;-)
736         $LFS mirror extend -N -o 0 $tf ||
737                 error "extending mirrored file $tf failed"
738
739         size_blocks=$(stat --format="%b %s" $tf)
740
741         cancel_lru_locks mdc
742         cancel_lru_locks osc
743
744         local new_size_blocks=$(stat --format="%b %s" $tf)
745
746         # make sure there is no lock cached
747         [ $(get_osc_lock_count 1) -eq 0 ] || error "glimpse requests were sent"
748
749         [ "$new_size_blocks" = "$size_blocks" ] ||
750                 echo "size expected: $size_blocks, actual: $new_size_blocks"
751
752         rm -f $tmpfile
753 }
754 run_test 22 "no glimpse to OSTs for READ_ONLY files"
755
756 test_31() {
757         local tf=$DIR/$tfile
758
759         $LFS mirror create -N -o 0 -N -o 1 $tf ||
760                 error "creating mirrored file $tf failed"
761
762         #define OBD_FAIL_GLIMPSE_IMMUTABLE 0x1A00
763         $LCTL set_param fail_loc=0x1A00
764
765         local ost_idx
766         for ((ost_idx = 1; ost_idx <= 2; ost_idx++)); do
767                 cancel_lru_locks osc
768                 stop_osts $ost_idx
769
770                 local tmpfile=$(mktemp)
771                 stat --format="%b %s" $tf > $tmpfile  &
772                 local pid=$!
773
774                 local cnt=0
775                 while [ $cnt -le 5 ]; do
776                         kill -0 $pid > /dev/null 2>&1 || break
777                         sleep 1
778                         ((cnt += 1))
779                 done
780                 kill -0 $pid > /dev/null 2>&1 &&
781                         error "stat process stuck due to unavailable OSTs"
782
783                 # make sure glimpse request has been sent
784                 [ $(get_osc_lock_count 1 2) -ne 0 ] ||
785                         error "OST $ost_idx: no glimpse request was sent"
786
787                 start_osts $ost_idx
788         done
789 }
790 run_test 31 "make sure glimpse request can be retried"
791
792 test_32() {
793         [[ $OSTCOUNT -lt 2 ]] && skip "need >= 2 OSTs" && return
794         rm -f $DIR/$tfile $DIR/$tfile-2
795
796         $LFS setstripe -E EOF -o 0 $DIR/$tfile
797         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=$((RANDOM % 10 + 2))
798
799         local fsize=$(stat -c %s $DIR/$tfile)
800         [[ $fsize -ne 0 ]] || error "file size is (wrongly) zero"
801
802         local cksum=$(md5sum $DIR/$tfile)
803
804         # create a new mirror in sync mode
805         $LFS mirror extend -N -o 1 $DIR/$tfile ||
806                 error "extending mirrored file $DIR/$tfile failed"
807
808         # make sure the mirrored file was created successfully
809         [ $(get_mirror_ids $DIR/$tfile) -eq 2 ] ||
810                 { $LFS getstripe $DIR/$tfile; error "expected 2 mirrors"; }
811
812         drop_client_cache
813         stop_osts 1
814
815         # check size is correct, glimpse request should go to the 2nd mirror
816         $CHECKSTAT -t file -s $fsize $DIR/$tfile ||
817                 error "file size error $fsize vs. $(stat -c %s $DIR/$tfile)"
818
819         echo "reading file from the 2nd mirror and verify checksum"
820         [[ "$cksum" == "$(md5sum $DIR/$tfile)" ]] ||
821                 error "checksum error: expected $cksum"
822
823         start_osts 1
824 }
825 run_test 32 "data should be mirrored to newly created mirror"
826
827 test_33() {
828         [[ $OSTCOUNT -lt 2 ]] && skip "need >= 2 OSTs" && return
829
830         rm -f $DIR/$tfile $DIR/$tfile-2
831
832         # create a file with two mirrors
833         $LFS setstripe -E EOF -o 0 $DIR/$tfile
834         local max_count=100
835         local count=0
836         while [ $count -lt $max_count ]; do
837                 echo "ost1" >> $DIR/$tfile
838                 count=$((count + 1));
839         done
840
841         # tmp file that will be used as mirror
842         $LFS setstripe -E EOF -o 1 $DIR/$tfile-2
843         count=0
844         while [ $count -lt $max_count ]; do
845                 echo "ost2" >> $DIR/$tfile-2
846                 count=$((count + 1));
847         done
848
849         # create a mirrored file
850         $LFS mirror extend -N -f $DIR/$tfile-2 $DIR/$tfile &&
851                 error "merging $DIR/$tfile-2 into $DIR/$tfile" \
852                       "with verification should fail"
853         $LFS mirror extend --no-verify -N -f $DIR/$tfile-2 $DIR/$tfile ||
854                 error "merging $DIR/$tfile-2 into $DIR/$tfile" \
855                       "without verification failed"
856
857         # make sure that $tfile has two mirrors and $tfile-2 does not exist
858         [ $(get_mirror_ids $DIR/$tfile) -eq 2 ] ||
859                 { $LFS getstripe $DIR/$tfile; error "expected count 2"; }
860
861         [[ ! -e $DIR/$tfile-2 ]] || error "$DIR/$tfile-2 was not unlinked"
862
863         # execpted file size
864         local fsize=$((5 * max_count))
865         $CHECKSTAT -t file -s $fsize $DIR/$tfile ||
866                 error "mirrored file size is not $fsize"
867
868         # read file - all OSTs are available
869         echo "reading file (data should be provided by ost1)... "
870         local rs=$(cat $DIR/$tfile | head -1)
871         [[ "$rs" == "ost1" ]] ||
872                 error "file content error: expected: \"ost1\", actual: \"$rs\""
873
874         # read file again with ost1 failed
875         stop_osts 1
876         drop_client_cache
877
878         echo "reading file (data should be provided by ost2)..."
879         local rs=$(cat $DIR/$tfile | head -1)
880         [[ "$rs" == "ost2" ]] ||
881                 error "file content error: expected: \"ost2\", actual: \"$rs\""
882
883         # remount ost1
884         start_osts 1
885
886         # read file again with ost2 failed
887         $LCTL set_param ldlm.namespaces.lustre-*-osc-ffff*.lru_size=clear
888
889         fail ost2 &
890         sleep 1
891
892         # check size, glimpse should work
893         $CHECKSTAT -t file -s $fsize $DIR/$tfile ||
894                 error "mirrored file size is not $fsize"
895
896         echo "reading file (data should be provided by ost1)..."
897         local rs=$(cat $DIR/$tfile | head -1)
898         [[ "$rs" == "ost1" ]] ||
899                 error "file content error: expected: \"ost1\", actual: \"$rs\""
900
901         wait_osc_import_state client ost2 FULL
902 }
903 run_test 33 "read can choose available mirror to read"
904
905 test_34a() {
906         [[ $OSTCOUNT -lt 4 ]] && skip "need >= 4 OSTs" && return
907
908         rm -f $DIR/$tfile $DIR/$tfile-2 $DIR/$tfile-ref
909
910         # reference file
911         $LFS setstripe -o 0 $DIR/$tfile-ref
912         dd if=/dev/urandom of=$DIR/$tfile-ref bs=1M count=3
913
914         # create a file with two mirrors
915         $LFS setstripe -E -1 -o 0,1 -S 1M $DIR/$tfile
916         dd if=$DIR/$tfile-ref of=$DIR/$tfile bs=1M
917
918         $LFS setstripe -E -1 -o 2,3 -S 1M $DIR/$tfile-2
919         dd if=$DIR/$tfile-ref of=$DIR/$tfile-2 bs=1M
920
921         $CHECKSTAT -t file -s $((3 * 1024 * 1024)) $DIR/$tfile ||
922                 error "mirrored file size is not 3M"
923
924         # merge a mirrored file
925         $LFS mirror extend -N -f $DIR/$tfile-2 $DIR/$tfile ||
926                 error "merging $DIR/$tfile-2 into $DIR/$tfile failed"
927
928         cancel_lru_locks osc
929
930         # stop two OSTs, so the 2nd stripe of the 1st mirror and
931         # the 1st stripe of the 2nd mirror will be inaccessible, ...
932         stop_osts 2 3
933
934         echo "comparing files ... "
935
936         # however, read can still return the correct data. It should return
937         # the 1st stripe from mirror 1 and 2st stripe from mirror 2.
938         cmp -n 2097152 <(rwv -f $DIR/$tfile -r -o -n 1 2097152) \
939                 $DIR/$tfile-ref || error "file reading error"
940
941         start_osts 2 3
942 }
943 run_test 34a "read mirrored file with multiple stripes"
944
945 test_34b() {
946         [[ $OSTCOUNT -lt 4 ]] && skip "need >= 4 OSTs" && return
947
948         rm -f $DIR/$tfile $DIR/$tfile-2 $DIR/$tfile-ref
949
950         # reference file
951         $LFS setstripe -o 0 $DIR/$tfile-ref
952         dd if=/dev/urandom of=$DIR/$tfile-ref bs=1M count=3
953
954         $LFS setstripe -E 1M -S 1M -o 0 -E eof -o 1 $DIR/$tfile
955         dd if=$DIR/$tfile-ref of=$DIR/$tfile bs=1M
956
957         $LFS setstripe -E 1M -S 1M -o 2 -E eof -o 3 $DIR/$tfile-2
958         dd if=$DIR/$tfile-ref of=$DIR/$tfile-2 bs=1M
959
960         $CHECKSTAT -t file -s $((3 * 1024 * 1024)) $DIR/$tfile ||
961                 error "mirrored file size is not 3M"
962
963         # merge a mirrored file
964         $LFS mirror extend -N -f $DIR/$tfile-2 $DIR/$tfile ||
965                 error "merging $DIR/$tfile-2 into $DIR/$tfile failed"
966
967         cancel_lru_locks osc
968
969         # stop two OSTs, so the 2nd component of the 1st mirror and
970         # the 1st component of the 2nd mirror will be inaccessible, ...
971         stop_osts 2 3
972
973         echo "comparing files ... "
974
975         # however, read can still return the correct data. It should return
976         # the 1st stripe from mirror 1 and 2st stripe from mirror 2.
977         cmp -n 2097152 <(rwv -f $DIR/$tfile -r -o -n 1 2097152) \
978                 $DIR/$tfile-ref || error "file reading error"
979
980         start_osts 2 3
981 }
982 run_test 34b "read mirrored file with multiple components"
983
984 test_35() {
985         local tf=$DIR/$tfile
986
987         $LFS setstripe -E eof $tf
988
989         # add an out-of-sync mirror to the file
990         $LFS mirror extend -N -c 2 $tf ||
991                 error "extending mirrored file $tf failed"
992
993         $MULTIOP $tf oO_WRONLY:c ||
994                 error "write open a mirrored file failed"
995
996         # truncate file should return error
997         $TRUNCATE $tf 100 || error "error truncating a mirrored file"
998 }
999 run_test 35 "allow to write to mirrored files"
1000
1001 verify_ost_layout_version() {
1002         local tf=$1
1003
1004         # get file layout version
1005         local flv=$($LFS getstripe $tf | awk '/lcm_layout_gen/{print $2}')
1006
1007         # layout version from OST objects
1008         local olv=$($MULTIOP $tf oXc | awk '/ostlayoutversion/{print $2}')
1009
1010         [ $flv -eq $olv ] || error "layout version mismatch: $flv vs. $olv"
1011 }
1012
1013 create_file_36() {
1014         local tf
1015
1016         for tf in "$@"; do
1017                 $LFS setstripe -E 1M -E 2M -E 4M -E eof -c -1 $tf
1018                 $LFS setstripe -E 3M -E 6M -E eof -c -1 $tf-tmp
1019
1020                 $LFS mirror extend -N -f $tf-tmp $tf ||
1021                         error "merging $tf-tmp into $tf failed"
1022         done
1023 }
1024
1025 test_36() {
1026         local tf=$DIR/$tfile
1027
1028         create_file_36 $tf $tf-2 $tf-3
1029
1030         [ $(get_mirror_ids $tf) -gt 1 ] || error "wrong mirror count"
1031
1032         # test case 1 - check file write and verify layout version
1033         $MULTIOP $tf oO_WRONLY:c ||
1034                 error "write open a mirrored file failed"
1035
1036         # write open file should not return error
1037         $MULTIOP $tf oO_WRONLY:w1024Yc || error "write mirrored file error"
1038
1039         # instantiate components should work
1040         dd if=/dev/zero of=$tf bs=1M count=12 || error "write file error"
1041
1042         # verify OST layout version
1043         verify_ost_layout_version $tf
1044
1045         # test case 2
1046         local mds_idx=mds$(($($LFS getstripe -M $tf-2) + 1))
1047
1048         local delay_sec=10
1049         do_facet $mds_idx $LCTL set_param fail_val=$delay_sec
1050
1051         #define OBD_FAIL_FLR_LV_DELAY 0x1A01
1052         do_facet $mds_idx $LCTL set_param fail_loc=0x1A01
1053
1054         # write should take at least $fail_loc seconds and succeed
1055         local st=$(date +%s)
1056         $MULTIOP $tf-2 oO_WRONLY:w1024Yc || error "write mirrored file error"
1057
1058         [ $(date +%s) -ge $((st+delay_sec)) ] ||
1059                 error "write finished before layout version is transmitted"
1060
1061         # verify OST layout version
1062         verify_ost_layout_version $tf
1063
1064         do_facet $mds_idx $LCTL set_param fail_loc=0
1065
1066         # test case 3
1067         mds_idx=mds$(($($LFS getstripe -M $tf-3) + 1))
1068
1069         #define OBD_FAIL_FLR_LV_INC 0x1A02
1070         do_facet $mds_idx $LCTL set_param fail_loc=0x1A02
1071
1072         # write open file should return error
1073         $MULTIOP $tf-3 oO_WRONLY:O_SYNC:w1024c &&
1074                 error "write a mirrored file succeeded" || true
1075
1076         do_facet $mds_idx $LCTL set_param fail_loc=0
1077 }
1078 run_test 36 "write to mirrored files"
1079
1080 create_files_37() {
1081         local tf
1082         local fsize=$1
1083
1084         echo "create test files with size $fsize .."
1085
1086         shift
1087         for tf in "$@"; do
1088                 $LFS setstripe -E 1M -c 1 -E eof -c -1 $tf
1089
1090                 dd if=/dev/urandom of=$tf bs=1M count=16 &> /dev/null
1091                 $TRUNCATE $tf $fsize
1092         done
1093 }
1094
1095 test_37()
1096 {
1097         local tf=$DIR/$tfile
1098         local tf2=$DIR/$tfile-2
1099         local tf3=$DIR/$tfile-3
1100
1101         create_files_37 $((RANDOM + 15 * 1048576)) $tf $tf2 $tf3
1102
1103         # assume the mirror id will be 1, 2, and 3
1104         declare -A checksums
1105         checksums[1]=$(md5sum $tf | cut -f 1 -d' ')
1106         checksums[2]=$(md5sum $tf2 | cut -f 1 -d' ')
1107         checksums[3]=$(md5sum $tf3 | cut -f 1 -d' ')
1108
1109         printf '%s\n' "${checksums[@]}"
1110
1111         # merge these files into a mirrored file
1112         $LFS mirror extend --no-verify -N -f $tf2 $tf ||
1113                 error "merging $tf2 into $tf failed"
1114         $LFS mirror extend --no-verify -N -f $tf3 $tf ||
1115                 error "merging $tf3 into $tf failed"
1116
1117         get_mirror_ids $tf
1118
1119         # verify mirror read, checksums should equal to the original files'
1120         echo "Verifying mirror read .."
1121
1122         local sum
1123         for i in ${mirror_array[@]}; do
1124                 sum=$(mirror_io dump -i $i $tf | md5sum | cut -f 1 -d' ')
1125                 [ "$sum" = "${checksums[$i]}" ] ||
1126                         error "$i: mismatch: \'${checksums[$i]}\' vs. \'$sum\'"
1127         done
1128
1129         # verify mirror copy, write to this mirrored file will invalidate
1130         # the other two mirrors
1131         echo "Verifying mirror copy .."
1132
1133         local osts=$(comma_list $(osts_nodes))
1134
1135         # define OBD_FAIL_OST_SKIP_LV_CHECK     0x241
1136         do_nodes $osts lctl set_param fail_loc=0x241
1137
1138         mirror_io copy -i ${mirror_array[0]} \
1139                 -t $(echo ${mirror_array[@]:1} | tr ' ' ',') $tf ||
1140                         error "mirror copy error"
1141
1142         do_nodes $osts lctl set_param fail_loc=0
1143
1144         # verify copying is successful by checking checksums
1145         remount_client $MOUNT
1146         for i in ${mirror_array[@]}; do
1147                 sum=$(mirror_io dump -i $i $tf | md5sum | cut -f 1 -d' ')
1148                 [ "$sum" = "${checksums[1]}" ] ||
1149                         error "$i: mismatch checksum after copy"
1150         done
1151
1152         rm -f $tf
1153 }
1154 run_test 37 "mirror I/O API verification"
1155
1156 verify_flr_state()
1157 {
1158         local tf=$1
1159         local expected_state=$2
1160
1161         local state=$($LFS getstripe -v $tf | awk '/lcm_flags/{ print $2 }')
1162         [ $expected_state = $state ] ||
1163                 error "expected: $expected_state, actual $state"
1164 }
1165
1166 test_38() {
1167         local tf=$DIR/$tfile
1168         local ref=$DIR/${tfile}-ref
1169
1170         $LFS setstripe -E 1M -c 1 -E 4M -c 2 -E eof -c -1 $tf
1171         $LFS setstripe -E 2M -c 1 -E 6M -c 2 -E 8M -c -1 -E eof -c -1 $tf-2
1172         $LFS setstripe -E 4M -c 1 -E 8M -c 2 -E eof -c -1 $tf-3
1173
1174         # instantiate all components
1175         $LFS mirror extend -N -f $tf-2 $tf ||
1176                 error "merging $tf-2 into $tf failed"
1177         $LFS mirror extend -N -f $tf-3 $tf ||
1178                 error "merging $tf-3 into $tf failed"
1179         $LFS mirror extend -N -c 1 $tf ||
1180                 error "extending mirrored file $tf failed"
1181
1182         verify_flr_state $tf "ro"
1183
1184         dd if=/dev/urandom of=$ref  bs=1M count=16 &> /dev/null
1185
1186         local fsize=$((RANDOM << 8 + 1048576))
1187         $TRUNCATE $ref $fsize
1188
1189         local ref_cksum=$(md5sum $ref | cut -f 1 -d' ')
1190
1191         # case 1: verify write to mirrored file & resync work
1192         cp $ref $tf || error "copy from $ref to $f error"
1193         verify_flr_state $tf "wp"
1194
1195         local file_cksum=$(md5sum $tf | cut -f 1 -d' ')
1196         [ "$file_cksum" = "$ref_cksum" ] || error "write failed, cksum mismatch"
1197
1198         get_mirror_ids $tf
1199         echo "mirror IDs: ${mirror_array[@]}"
1200
1201         local valid_mirror stale_mirror id mirror_cksum
1202         for id in "${mirror_array[@]}"; do
1203                 mirror_cksum=$(mirror_io dump -i $id $tf |
1204                                 md5sum | cut -f 1 -d' ')
1205                 [ "$ref_cksum" == "$mirror_cksum" ] &&
1206                         { valid_mirror=$id; continue; }
1207
1208                 stale_mirror=$id
1209         done
1210
1211         [ -z "$stale_mirror" ] && error "stale mirror doesn't exist"
1212         [ -z "$valid_mirror" ] && error "valid mirror doesn't exist"
1213
1214         mirror_io resync $tf || error "resync failed"
1215         verify_flr_state $tf "ro"
1216
1217         mirror_cksum=$(mirror_io dump -i $stale_mirror $tf |
1218                         md5sum | cut -f 1 -d' ')
1219         [ "$file_cksum" = "$ref_cksum" ] || error "resync failed"
1220
1221         # case 2: inject an error to make mirror_io exit after changing
1222         # the file state to sync_pending so that we can start a concurrent
1223         # write.
1224         $MULTIOP $tf oO_WRONLY:w$((RANDOM % 1048576 + 1024))c
1225         verify_flr_state $tf "wp"
1226
1227         mirror_io resync -e resync_start $tf && error "resync succeeded"
1228         verify_flr_state $tf "sp"
1229
1230         # from sync_pending to write_pending
1231         $MULTIOP $tf oO_WRONLY:w$((RANDOM % 1048576 + 1024))c
1232         verify_flr_state $tf "wp"
1233
1234         mirror_io resync -e resync_start $tf && error "resync succeeded"
1235         verify_flr_state $tf "sp"
1236
1237         # from sync_pending to read_only
1238         mirror_io resync $tf || error "resync failed"
1239         verify_flr_state $tf "ro"
1240 }
1241 run_test 38 "resync"
1242
1243 test_39() {
1244         local tf=$DIR/$tfile
1245
1246         rm -f $tf
1247         $LFS mirror create -N2 -E1m -c1 -S1M -E-1 $tf ||
1248         error "create PFL file $tf failed"
1249
1250         verify_mirror_count $tf 2
1251         verify_comp_count $tf 4
1252
1253         rm -f $tf || error "delete $tf failed"
1254 }
1255 run_test 39 "check FLR+PFL (a.k.a. PFLR) creation"
1256
1257 test_40() {
1258         local tf=$DIR/$tfile
1259         local ops
1260
1261         for ops in "conv=notrunc" ""; do
1262                 rm -f $tf
1263
1264                 $LFS mirror create -N -E2m -E4m -E-1 -N -E1m -E2m -E4m -E-1 \
1265                         $tf || error "create PFLR file $tf failed"
1266                 dd if=/dev/zero of=$tf $ops bs=1M seek=2 count=1 ||
1267                         error "write PFLR file $tf failed"
1268
1269                 lfs getstripe -vy $tf
1270
1271                 local flags
1272
1273                 # file mirror state should be write_pending
1274                 flags=$($LFS getstripe -v $tf | awk '/lcm_flags:/ { print $2 }')
1275                 [ $flags = wp ] ||
1276                 error "file mirror state $flags"
1277                 # the 1st component (in mirror 1) should be inited
1278                 verify_comp_attr lcme_flags $tf 0x10001 init
1279                 # the 2nd component (in mirror 1) should be inited
1280                 verify_comp_attr lcme_flags $tf 0x10002 init
1281                 # the 3rd component (in mirror 1) should be uninited
1282                 verify_comp_attr lcme_flags $tf 0x10003 0
1283                 # the 4th component (in mirror 2) should be inited
1284                 verify_comp_attr lcme_flags $tf 0x20004 init
1285                 # the 5th component (in mirror 2) should be uninited
1286                 verify_comp_attr lcme_flags $tf 0x20005 0
1287                 # the 6th component (in mirror 2) should be stale
1288                 verify_comp_attr lcme_flags $tf 0x20006 stale
1289                 # the 7th component (in mirror 2) should be uninited
1290                 if [[ x$ops = "xconv=notrunc" ]]; then
1291                         verify_comp_attr lcme_flags $tf 0x20007 0
1292                 elif [[ x$ops = "x" ]]; then
1293                         verify_comp_attr lcme_flags $tf 0x20007 stale
1294                 fi
1295         done
1296
1297         rm -f $tf || error "delete $tf failed"
1298 }
1299 run_test 40 "PFLR rdonly state instantiation check"
1300
1301 test_41() {
1302         local tf=$DIR/$tfile
1303
1304         rm -f $tf $tf-1
1305         $LFS mirror create -N -E2m -E4m -E-1 -N -E1m -E2m -E3m -E-1 $tf ||
1306                 error "create PFLR file $tf failed"
1307         $LFS mirror create -N -E4m -E-1 -N -E2m -E3m -E-1 $tf-1 ||
1308                 error "create PFLR file $tf-1 failed"
1309
1310         # file should be in ro status
1311         verify_flr_state $tf "ro"
1312         verify_flr_state $tf-1 "ro"
1313
1314         # write data in [0, 2M)
1315         dd if=/dev/zero of=$tf bs=1M count=2 conv=notrunc ||
1316                 error "writing $tf failed"
1317         dd if=/dev/zero of=$tf-1 bs=1M count=4 conv=notrunc ||
1318                 error "writing $tf-1 failed"
1319
1320         verify_flr_state $tf "wp"
1321         verify_flr_state $tf-1 "wp"
1322
1323         # file should have stale component
1324         $LFS getstripe $tf | grep lcme_flags | grep stale > /dev/null ||
1325                 error "after writing $tf, it does not contain stale component"
1326         $LFS getstripe $tf-1 | grep lcme_flags | grep stale > /dev/null ||
1327                 error "after writing $tf-1, it does not contain stale component"
1328
1329         $LFS mirror resync $tf $tf-1 || error "mirror resync $tf $tf-1 failed"
1330
1331         verify_flr_state $tf "ro"
1332         verify_flr_state $tf-1 "ro"
1333
1334         # file should not have stale component
1335         $LFS getstripe $tf | grep lcme_flags | grep stale &&
1336                 error "after resyncing $tf, it contains stale component"
1337         $LFS getstripe $tf-1 | grep lcme_flags | grep stale &&
1338                 error "after resyncing $tf, it contains stale component"
1339
1340         return 0
1341 }
1342 run_test 41 "lfs mirror resync check"
1343
1344 ctrl_file=$(mktemp /tmp/CTRL.XXXXXX)
1345 lock_file=$(mktemp /var/lock/FLR.XXXXXX)
1346
1347 write_file_200() {
1348         local tf=$1
1349
1350         local fsize=$(stat --printf=%s $tf)
1351
1352         while [ -f $ctrl_file ]; do
1353                 local off=$((RANDOM << 8))
1354                 local len=$((RANDOM << 5 + 131072))
1355
1356                 [ $((off + len)) -gt $fsize ] && {
1357                         fsize=$((off + len))
1358                         echo "Extending file size to $fsize .."
1359                 }
1360
1361                 flock -s $lock_file -c \
1362                         "$MULTIOP $tf oO_WRONLY:z${off}w${len}c" ||
1363                                 { rm -f $ctrl_file;
1364                                   error "failed writing to $off:$len"; }
1365                 sleep 0.$((RANDOM % 2 + 1))
1366         done
1367 }
1368
1369 read_file_200() {
1370         local tf=$1
1371
1372         while [ -f $ctrl_file ]; do
1373                 flock -s $lock_file -c "cat $tf &> /dev/null" ||
1374                         { rm -f $ctrl_file; error "read failed"; }
1375                 sleep 0.$((RANDOM % 2 + 1))
1376         done
1377 }
1378
1379 resync_file_200() {
1380         local tf=$1
1381
1382         options=("" "-e resync_start" "-e delay_before_copy -d 1" "" "")
1383
1384         exec 200<>$lock_file
1385         while [ -f $ctrl_file ]; do
1386                 local lock_taken=false
1387                 local index=$((RANDOM % ${#options[@]}))
1388                 local cmd="mirror_io resync ${options[$index]}"
1389
1390                 [ "${options[$index]}" = "" ] && cmd="$LFS mirror resync"
1391
1392                 [ $((RANDOM % 4)) -eq 0 ] && {
1393                         index=0
1394                         lock_taken=true
1395                         echo -n "lock to "
1396                 }
1397
1398                 echo -n "resync file $tf with '$cmd' .."
1399
1400                 $lock_taken && flock -x 200
1401                 $cmd $tf &> /dev/null && echo "done" || echo "failed"
1402                 $lock_taken && flock -u 200
1403
1404                 sleep 0.$((RANDOM % 8 + 1))
1405         done
1406 }
1407
1408 test_200() {
1409         local tf=$DIR/$tfile
1410         local tf2=$DIR2/$tfile
1411         local tf3=$DIR3/$tfile
1412
1413         $LFS setstripe -E 1M -E 2M -c 2 -E 4M -E 16M -E eof $tf
1414         $LFS setstripe -E 2M -E 6M -c 2 -E 8M -E 32M -E eof $tf-2
1415         $LFS setstripe -E 4M -c 2 -E 8M -E 64M -E eof $tf-3
1416
1417         $LFS mirror extend -N -f $tf-2 $tf ||
1418                 error "merging $tf-2 into $tf failed"
1419         $LFS mirror extend -N -f $tf-3 $tf ||
1420                 error "merging $tf-3 into $tf failed"
1421
1422         mkdir -p $MOUNT2 && mount_client $MOUNT2
1423
1424         mkdir -p $MOUNT3 && mount_client $MOUNT3
1425
1426         verify_flr_state $tf3 "ro"
1427
1428         #define OBD_FAIL_FLR_RANDOM_PICK_MIRROR 0x1A03
1429         $LCTL set_param fail_loc=0x1A03
1430
1431         local mds_idx=mds$(($($LFS getstripe -M $tf) + 1))
1432         do_facet $mds_idx $LCTL set_param fail_loc=0x1A03
1433
1434         declare -a pids
1435
1436         write_file_200 $tf &
1437         pids+=($!)
1438
1439         read_file_200 $tf &
1440         pids+=($!)
1441
1442         write_file_200 $tf2 &
1443         pids+=($!)
1444
1445         read_file_200 $tf2 &
1446         pids+=($!)
1447
1448         resync_file_200 $tf3 &
1449         pids+=($!)
1450
1451         local sleep_time=60
1452         [ "$SLOW" = "yes" ] && sleep_time=360
1453         while [ $sleep_time -gt 0 -a -f $ctrl_file ]; do
1454                 sleep 1
1455                 ((--sleep_time))
1456         done
1457
1458         rm -f $ctrl_file
1459
1460         echo "Waiting ${pids[@]}"
1461         wait ${pids[@]}
1462
1463         umount_client $MOUNT2
1464         umount_client $MOUNT3
1465
1466         rm -f $lock_file
1467
1468         # resync and verify mirrors
1469         mirror_io resync $tf
1470         get_mirror_ids $tf
1471
1472         local csum=$(mirror_io dump -i ${mirror_array[0]} $tf | md5sum)
1473         for id in ${mirror_array[@]:1}; do
1474                 [ "$(mirror_io dump -i $id $tf | md5sum)" = "$csum" ] ||
1475                         error "checksum error for mirror $id"
1476         done
1477
1478         true
1479 }
1480 run_test 200 "stress test"
1481
1482 cleanup_test_201() {
1483         trap 0
1484         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister $CL_USER
1485
1486         umount_client $MOUNT2
1487 }
1488
1489 test_201() {
1490         local delay=${RESYNC_DELAY:-5}
1491
1492         MDT0=$($LCTL get_param -n mdc.*.mds_server_uuid |
1493                awk '{ gsub(/_UUID/,""); print $1 }' | head -n1)
1494
1495         trap cleanup_test_201 EXIT
1496
1497         CL_USER=$(do_facet $SINGLEMDS $LCTL --device $MDT0 \
1498                         changelog_register -n)
1499
1500         mkdir -p $MOUNT2 && mount_client $MOUNT2
1501
1502         local index=0
1503         while :; do
1504                 local log=$($LFS changelog $MDT0 $index | grep FLRW)
1505                 [ -z "$log" ] && { sleep 1; continue; }
1506
1507                 index=$(echo $log | awk '{print $1}')
1508                 local ts=$(date -d "$(echo $log | awk '{print $3}')" "+%s" -u)
1509                 local fid=$(echo $log | awk '{print $6}' | sed -e 's/t=//')
1510                 local file=$($LFS fid2path $MOUNT2 $fid 2> /dev/null)
1511
1512                 ((++index))
1513                 [ -z "$file" ] && continue
1514
1515                 local now=$(date +%s)
1516
1517                 echo "file: $file $fid was modified at $ts, now: $now, " \
1518                      "will be resynced at $((ts+delay))"
1519
1520                 [ $now -lt $((ts + delay)) ] && sleep $((ts + delay - now))
1521
1522                 mirror_io resync $file
1523                 echo "$file resync done"
1524         done
1525
1526         cleanup_test_201
1527 }
1528 run_test 201 "FLR data mover"
1529
1530 complete $SECONDS
1531 check_and_cleanup_lustre
1532 exit_status