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