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