Whamcloud - gitweb
LU-11729 obdclass: align to T10 sector size when generating guard
[fs/lustre-release.git] / lustre / tests / sanity.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 #
6 # e.g. ONLY="22 23" or ONLY="`seq 32 39`" or EXCEPT="31"
7 set -e
8
9 ONLY=${ONLY:-"$*"}
10
11 # Check Grants after these tests
12 GRANT_CHECK_LIST="$GRANT_CHECK_LIST 42a 42b 42c 42d 42e 63a 63b 64a 64b 64c 64d"
13
14 OSC=${OSC:-"osc"}
15
16 CC=${CC:-cc}
17 CREATETEST=${CREATETEST:-createtest}
18 LVERIFY=${LVERIFY:-ll_dirstripe_verify}
19 OPENFILE=${OPENFILE:-openfile}
20 OPENUNLINK=${OPENUNLINK:-openunlink}
21 READS=${READS:-"reads"}
22 MUNLINK=${MUNLINK:-munlink}
23 SOCKETSERVER=${SOCKETSERVER:-socketserver}
24 SOCKETCLIENT=${SOCKETCLIENT:-socketclient}
25 MEMHOG=${MEMHOG:-memhog}
26 DIRECTIO=${DIRECTIO:-directio}
27 ACCEPTOR_PORT=${ACCEPTOR_PORT:-988}
28 DEF_STRIPE_COUNT=-1
29 CHECK_GRANT=${CHECK_GRANT:-"yes"}
30 GRANT_CHECK_LIST=${GRANT_CHECK_LIST:-""}
31 export PARALLEL=${PARALLEL:-"no"}
32
33 TRACE=${TRACE:-""}
34 LUSTRE_TESTS_API_DIR=${LUSTRE_TESTS_API_DIR:-${LUSTRE}/tests/clientapi}
35 LUSTRE=${LUSTRE:-$(dirname $0)/..}
36 . $LUSTRE/tests/test-framework.sh
37 init_test_env $@
38
39 init_logging
40
41 ALWAYS_EXCEPT="$SANITY_EXCEPT "
42 # bug number for skipped test: LU-9693 LU-6493 LU-9693
43 ALWAYS_EXCEPT+="               42a     42b     42c "
44 # bug number:    LU-8411 LU-9054
45 ALWAYS_EXCEPT+=" 407     312 "
46
47 if $SHARED_KEY; then
48         # bug number:    LU-9795 LU-9795 LU-9795 LU-9795
49         ALWAYS_EXCEPT+=" 17n     60a     133g    300f "
50 fi
51
52 # skip the grant tests for ARM until they are fixed
53 if [[ $(uname -m) = aarch64 ]]; then
54         # bug number:    LU-11596
55         ALWAYS_EXCEPT+=" $GRANT_CHECK_LIST"
56         # bug number:    LU-11671 LU-11667 LU-4398
57         ALWAYS_EXCEPT+=" 45       317      817"
58 fi
59
60 #                                  5          12          (min)"
61 [ "$SLOW" = "no" ] && EXCEPT_SLOW="27m 64b 68 71 115 300o"
62
63 if [ "$mds1_FSTYPE" = "zfs" ]; then
64         # bug number for skipped test:
65         ALWAYS_EXCEPT="$ALWAYS_EXCEPT  "
66         #                                               13    (min)"
67         [ "$SLOW" = "no" ] && EXCEPT_SLOW="$EXCEPT_SLOW 51b"
68 fi
69
70 # Get the SLES distro version
71 #
72 # Returns a version string that should only be used in comparing
73 # strings returned by version_code()
74 sles_version_code()
75 {
76         local version=$(grep VERSION_ID /etc/os-release | cut -d'"' -f2)
77
78         # All SuSE Linux versions have one decimal. version_code expects two
79         local sles_version=$version.0
80         version_code $sles_version
81 }
82
83 # Check if we are running on Ubuntu or SLES so we can make decisions on
84 # what tests to run
85 if [ -r /etc/SuSE-release ]; then
86         sles_version=$(sles_version_code)
87         [ $sles_version -lt $(version_code 11.4.0) ] &&
88                 # bug number for skipped test: LU-4341
89                 ALWAYS_EXCEPT="$ALWAYS_EXCEPT  170"
90         [ $sles_version -lt $(version_code 12.0.0) ] &&
91                 # bug number for skipped test: LU-3703
92                 ALWAYS_EXCEPT="$ALWAYS_EXCEPT  234"
93 elif [ -r /etc/os-release ]; then
94         if grep -qi ubuntu /etc/os-release; then
95                 ubuntu_version=$(version_code $(sed -n -e 's/"//g' \
96                                                 -e 's/^VERSION=//p' \
97                                                 /etc/os-release |
98                                                 awk '{ print $1 }'))
99
100                 if [[ $ubuntu_version -gt $(version_code 16.0.0) ]]; then
101                         # bug number for skipped test:
102                         #                LU-10334 LU-10366
103                         ALWAYS_EXCEPT+=" 103a     410"
104                 fi
105         fi
106 fi
107
108 build_test_filter
109 FAIL_ON_ERROR=false
110
111 cleanup() {
112         echo -n "cln.."
113         pgrep ll_sa > /dev/null && { echo "There are ll_sa thread not exit!"; exit 20; }
114         cleanupall ${FORCE} $* || { echo "FAILed to clean up"; exit 20; }
115 }
116 setup() {
117         echo -n "mnt.."
118         load_modules
119         setupall || exit 10
120         echo "done"
121 }
122
123 check_swap_layouts_support()
124 {
125         $LCTL get_param -n llite.*.sbi_flags | grep -q layout ||
126                 skip "Does not support layout lock."
127 }
128
129 check_and_setup_lustre
130 DIR=${DIR:-$MOUNT}
131 assert_DIR
132
133 MAXFREE=${MAXFREE:-$((200000 * $OSTCOUNT))}
134
135 [ -f $DIR/d52a/foo ] && chattr -a $DIR/d52a/foo
136 [ -f $DIR/d52b/foo ] && chattr -i $DIR/d52b/foo
137 rm -rf $DIR/[Rdfs][0-9]*
138
139 # $RUNAS_ID may get set incorrectly somewhere else
140 [ $UID -eq 0 -a $RUNAS_ID -eq 0 ] &&
141         error "\$RUNAS_ID set to 0, but \$UID is also 0!"
142
143 check_runas_id $RUNAS_ID $RUNAS_GID $RUNAS
144
145 if [ "${ONLY}" = "MOUNT" ] ; then
146         echo "Lustre is up, please go on"
147         exit
148 fi
149
150 echo "preparing for tests involving mounts"
151 EXT2_DEV=${EXT2_DEV:-$TMP/SANITY.LOOP}
152 touch $EXT2_DEV
153 mke2fs -j -F $EXT2_DEV 8000 > /dev/null
154 echo # add a newline after mke2fs.
155
156 umask 077
157
158 OLDDEBUG=$(lctl get_param -n debug 2> /dev/null)
159 lctl set_param debug=-1 2> /dev/null || true
160 test_0a() {
161         touch $DIR/$tfile
162         $CHECKSTAT -t file $DIR/$tfile || error "$tfile is not a file"
163         rm $DIR/$tfile
164         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
165 }
166 run_test 0a "touch; rm ====================="
167
168 test_0b() {
169         chmod 0755 $DIR || error "chmod 0755 $DIR failed"
170         $CHECKSTAT -p 0755 $DIR || error "$DIR permission is not 0755"
171 }
172 run_test 0b "chmod 0755 $DIR ============================="
173
174 test_0c() {
175         $LCTL get_param mdc.*.import | grep "state: FULL" ||
176                 error "import not FULL"
177         $LCTL get_param mdc.*.import | grep "target: $FSNAME-MDT" ||
178                 error "bad target"
179 }
180 run_test 0c "check import proc"
181
182 test_0d() { # LU-3397
183         [ $MGS_VERSION -lt $(version_code 2.10.57) ] &&
184                 skip "proc exports not supported before 2.10.57"
185
186         local mgs_exp="mgs.MGS.exports"
187         local client_uuid=$($LCTL get_param -n mgc.*.uuid)
188         local exp_client_nid
189         local exp_client_version
190         local exp_val
191         local imp_val
192         local temp_imp=$DIR/$tfile.import
193         local temp_exp=$DIR/$tfile.export
194
195         # save mgc import file to $temp_imp
196         $LCTL get_param mgc.*.import | tee $temp_imp
197         # Check if client uuid is found in MGS export
198         for exp_client_nid in $(do_facet mgs $LCTL get_param -N $mgs_exp.*); do
199                 [ $(do_facet mgs $LCTL get_param -n $exp_client_nid.uuid) == \
200                         $client_uuid ] &&
201                         break;
202         done
203         # save mgs export file to $temp_exp
204         do_facet mgs $LCTL get_param $exp_client_nid.export | tee $temp_exp
205
206         # Compare the value of field "connect_flags"
207         imp_val=$(grep "connect_flags" $temp_imp)
208         exp_val=$(grep "connect_flags" $temp_exp)
209         [ "$exp_val" == "$imp_val" ] ||
210                 error "export flags '$exp_val' != import flags '$imp_val'"
211
212         # Compare the value of client version
213         exp_client_version=$(awk '/target_version:/ { print $2 }' $temp_exp)
214         exp_val=$(version_code $exp_client_version)
215         imp_val=$CLIENT_VERSION
216         [ "$exp_val" == "$imp_val" ] ||
217                 error "export client version '$exp_val' != '$imp_val'"
218 }
219 run_test 0d "check export proc ============================="
220
221 test_1() {
222         test_mkdir $DIR/$tdir
223         test_mkdir $DIR/$tdir/d2
224         mkdir $DIR/$tdir/d2 && error "we expect EEXIST, but not returned"
225         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a dir"
226         rmdir $DIR/$tdir/d2
227         rmdir $DIR/$tdir
228         $CHECKSTAT -a $DIR/$tdir || error "$tdir was not removed"
229 }
230 run_test 1 "mkdir; remkdir; rmdir"
231
232 test_2() {
233         test_mkdir $DIR/$tdir
234         touch $DIR/$tdir/$tfile || error "touch $tdir/$tfile failed"
235         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
236         rm -r $DIR/$tdir
237         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$file is not removed"
238 }
239 run_test 2 "mkdir; touch; rmdir; check file"
240
241 test_3() {
242         test_mkdir $DIR/$tdir
243         $CHECKSTAT -t dir $DIR/$tdir || error "$tdir is not a directory"
244         touch $DIR/$tdir/$tfile
245         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
246         rm -r $DIR/$tdir
247         $CHECKSTAT -a $DIR/$tdir || error "$tdir is not removed"
248 }
249 run_test 3 "mkdir; touch; rmdir; check dir"
250
251 # LU-4471 - failed rmdir on remote directories still removes directory on MDT0
252 test_4() {
253         test_mkdir -i 1 $DIR/$tdir
254
255         touch $DIR/$tdir/$tfile ||
256                 error "Create file under remote directory failed"
257
258         rmdir $DIR/$tdir &&
259                 error "Expect error removing in-use dir $DIR/$tdir"
260
261         test -d $DIR/$tdir || error "Remote directory disappeared"
262
263         rm -rf $DIR/$tdir || error "remove remote dir error"
264 }
265 run_test 4 "mkdir; touch dir/file; rmdir; checkdir (expect error)"
266
267 test_5() {
268         test_mkdir $DIR/$tdir
269         test_mkdir $DIR/$tdir/d2
270         chmod 0707 $DIR/$tdir/d2 || error "chmod 0707 $tdir/d2 failed"
271         $CHECKSTAT -t dir -p 0707 $DIR/$tdir/d2 || error "$tdir/d2 not mode 707"
272         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a directory"
273 }
274 run_test 5 "mkdir .../d5 .../d5/d2; chmod .../d5/d2"
275
276 test_6a() {
277         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
278         chmod 0666 $DIR/$tfile || error "chmod 0666 $tfile failed"
279         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
280                 error "$tfile does not have perm 0666 or UID $UID"
281         $RUNAS chmod 0444 $DIR/$tfile && error "chmod $tfile worked on UID $UID"
282         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
283                 error "$tfile should be 0666 and owned by UID $UID"
284 }
285 run_test 6a "touch f6a; chmod f6a; $RUNAS chmod f6a (should return error) =="
286
287 test_6c() {
288         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
289
290         touch $DIR/$tfile
291         chown $RUNAS_ID $DIR/$tfile || error "chown $RUNAS_ID $file failed"
292         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
293                 error "$tfile should be owned by UID $RUNAS_ID"
294         $RUNAS chown $UID $DIR/$tfile && error "chown $UID $file succeeded"
295         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
296                 error "$tfile should be owned by UID $RUNAS_ID"
297 }
298 run_test 6c "touch f6c; chown f6c; $RUNAS chown f6c (should return error) =="
299
300 test_6e() {
301         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
302
303         touch $DIR/$tfile
304         chgrp $RUNAS_ID $DIR/$tfile || error "chgrp $RUNAS_ID $file failed"
305         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
306                 error "$tfile should be owned by GID $UID"
307         $RUNAS chgrp $UID $DIR/$tfile && error "chgrp $UID $file succeeded"
308         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
309                 error "$tfile should be owned by UID $UID and GID $RUNAS_ID"
310 }
311 run_test 6e "touch+chgrp $tfile; $RUNAS chgrp $tfile (should return error)"
312
313 test_6g() {
314         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
315
316         test_mkdir $DIR/$tdir
317         chmod 777 $DIR/$tdir || error "chmod 0777 $tdir failed"
318         $RUNAS mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
319         chmod g+s $DIR/$tdir/d || error "chmod g+s $tdir/d failed"
320         test_mkdir $DIR/$tdir/d/subdir
321         $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir/d/subdir ||
322                 error "$tdir/d/subdir should be GID $RUNAS_GID"
323         if [[ $MDSCOUNT -gt 1 ]]; then
324                 # check remote dir sgid inherite
325                 $LFS mkdir -i 0 $DIR/$tdir.local ||
326                         error "mkdir $tdir.local failed"
327                 chmod g+s $DIR/$tdir.local ||
328                         error "chmod $tdir.local failed"
329                 chgrp $RUNAS_GID $DIR/$tdir.local ||
330                         error "chgrp $tdir.local failed"
331                 $LFS mkdir -i 1 $DIR/$tdir.local/$tdir.remote ||
332                         error "mkdir $tdir.remote failed"
333                 $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir.local/$tdir.remote ||
334                         error "$tdir.remote should be owned by $UID.$RUNAS_ID"
335                 $CHECKSTAT -p 02755 $DIR/$tdir.local/$tdir.remote ||
336                         error "$tdir.remote should be mode 02755"
337         fi
338 }
339 run_test 6g "verify new dir in sgid dir inherits group"
340
341 test_6h() { # bug 7331
342         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
343
344         touch $DIR/$tfile || error "touch failed"
345         chown $RUNAS_ID:$RUNAS_GID $DIR/$tfile || error "initial chown failed"
346         $RUNAS -G$RUNAS_GID chown $RUNAS_ID:0 $DIR/$tfile &&
347                 error "chown $RUNAS_ID:0 $tfile worked as GID $RUNAS_GID"
348         $CHECKSTAT -t file -u \#$RUNAS_ID -g \#$RUNAS_GID $DIR/$tfile ||
349                 error "$tdir/$tfile should be UID $RUNAS_UID GID $RUNAS_GID"
350 }
351 run_test 6h "$RUNAS chown RUNAS_ID.0 .../$tfile (should return error)"
352
353 test_7a() {
354         test_mkdir $DIR/$tdir
355         $MCREATE $DIR/$tdir/$tfile
356         chmod 0666 $DIR/$tdir/$tfile
357         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
358                 error "$tdir/$tfile should be mode 0666"
359 }
360 run_test 7a "mkdir .../d7; mcreate .../d7/f; chmod .../d7/f ===="
361
362 test_7b() {
363         if [ ! -d $DIR/$tdir ]; then
364                 test_mkdir $DIR/$tdir
365         fi
366         $MCREATE $DIR/$tdir/$tfile
367         echo -n foo > $DIR/$tdir/$tfile
368         [ "$(cat $DIR/$tdir/$tfile)" = "foo" ] || error "$tdir/$tfile not 'foo'"
369         $CHECKSTAT -t file -s 3 $DIR/$tdir/$tfile || error "$tfile size not 3"
370 }
371 run_test 7b "mkdir .../d7; mcreate d7/f2; echo foo > d7/f2 ====="
372
373 test_8() {
374         test_mkdir $DIR/$tdir
375         touch $DIR/$tdir/$tfile
376         chmod 0666 $DIR/$tdir/$tfile
377         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
378                 error "$tfile mode not 0666"
379 }
380 run_test 8 "mkdir .../d8; touch .../d8/f; chmod .../d8/f ======="
381
382 test_9() {
383         test_mkdir $DIR/$tdir
384         test_mkdir $DIR/$tdir/d2
385         test_mkdir $DIR/$tdir/d2/d3
386         $CHECKSTAT -t dir $DIR/$tdir/d2/d3 || error "$tdir/d2/d3 not a dir"
387 }
388 run_test 9 "mkdir .../d9 .../d9/d2 .../d9/d2/d3 ================"
389
390 test_10() {
391         test_mkdir $DIR/$tdir
392         test_mkdir $DIR/$tdir/d2
393         touch $DIR/$tdir/d2/$tfile
394         $CHECKSTAT -t file $DIR/$tdir/d2/$tfile ||
395                 error "$tdir/d2/$tfile not a file"
396 }
397 run_test 10 "mkdir .../d10 .../d10/d2; touch .../d10/d2/f ======"
398
399 test_11() {
400         test_mkdir $DIR/$tdir
401         test_mkdir $DIR/$tdir/d2
402         chmod 0666 $DIR/$tdir/d2
403         chmod 0705 $DIR/$tdir/d2
404         $CHECKSTAT -t dir -p 0705 $DIR/$tdir/d2 ||
405                 error "$tdir/d2 mode not 0705"
406 }
407 run_test 11 "mkdir .../d11 d11/d2; chmod .../d11/d2 ============"
408
409 test_12() {
410         test_mkdir $DIR/$tdir
411         touch $DIR/$tdir/$tfile
412         chmod 0666 $DIR/$tdir/$tfile
413         chmod 0654 $DIR/$tdir/$tfile
414         $CHECKSTAT -t file -p 0654 $DIR/$tdir/$tfile ||
415                 error "$tdir/d2 mode not 0654"
416 }
417 run_test 12 "touch .../d12/f; chmod .../d12/f .../d12/f ========"
418
419 test_13() {
420         test_mkdir $DIR/$tdir
421         dd if=/dev/zero of=$DIR/$tdir/$tfile count=10
422         >  $DIR/$tdir/$tfile
423         $CHECKSTAT -t file -s 0 $DIR/$tdir/$tfile ||
424                 error "$tdir/$tfile size not 0 after truncate"
425 }
426 run_test 13 "creat .../d13/f; dd .../d13/f; > .../d13/f ========"
427
428 test_14() {
429         test_mkdir $DIR/$tdir
430         touch $DIR/$tdir/$tfile
431         rm $DIR/$tdir/$tfile
432         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
433 }
434 run_test 14 "touch .../d14/f; rm .../d14/f; rm .../d14/f ======="
435
436 test_15() {
437         test_mkdir $DIR/$tdir
438         touch $DIR/$tdir/$tfile
439         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}_2
440         $CHECKSTAT -t file $DIR/$tdir/${tfile}_2 ||
441                 error "$tdir/${tfile_2} not a file after rename"
442         rm $DIR/$tdir/${tfile}_2 || error "unlink failed after rename"
443 }
444 run_test 15 "touch .../d15/f; mv .../d15/f .../d15/f2 =========="
445
446 test_16() {
447         test_mkdir $DIR/$tdir
448         touch $DIR/$tdir/$tfile
449         rm -rf $DIR/$tdir/$tfile
450         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
451 }
452 run_test 16 "touch .../d16/f; rm -rf .../d16/f"
453
454 test_17a() {
455         test_mkdir $DIR/$tdir
456         touch $DIR/$tdir/$tfile
457         ln -s $DIR/$tdir/$tfile $DIR/$tdir/l-exist
458         ls -l $DIR/$tdir
459         $CHECKSTAT -l $DIR/$tdir/$tfile $DIR/$tdir/l-exist ||
460                 error "$tdir/l-exist not a symlink"
461         $CHECKSTAT -f -t f $DIR/$tdir/l-exist ||
462                 error "$tdir/l-exist not referencing a file"
463         rm -f $DIR/$tdir/l-exist
464         $CHECKSTAT -a $DIR/$tdir/l-exist || error "$tdir/l-exist not removed"
465 }
466 run_test 17a "symlinks: create, remove (real)"
467
468 test_17b() {
469         test_mkdir $DIR/$tdir
470         ln -s no-such-file $DIR/$tdir/l-dangle
471         ls -l $DIR/$tdir
472         $CHECKSTAT -l no-such-file $DIR/$tdir/l-dangle ||
473                 error "$tdir/l-dangle not referencing no-such-file"
474         $CHECKSTAT -fa $DIR/$tdir/l-dangle ||
475                 error "$tdir/l-dangle not referencing non-existent file"
476         rm -f $DIR/$tdir/l-dangle
477         $CHECKSTAT -a $DIR/$tdir/l-dangle || error "$tdir/l-dangle not removed"
478 }
479 run_test 17b "symlinks: create, remove (dangling)"
480
481 test_17c() { # bug 3440 - don't save failed open RPC for replay
482         test_mkdir $DIR/$tdir
483         ln -s foo $DIR/$tdir/$tfile
484         cat $DIR/$tdir/$tfile && error "opened non-existent symlink" || true
485 }
486 run_test 17c "symlinks: open dangling (should return error)"
487
488 test_17d() {
489         test_mkdir $DIR/$tdir
490         ln -s foo $DIR/$tdir/$tfile
491         touch $DIR/$tdir/$tfile || error "creating to new symlink"
492 }
493 run_test 17d "symlinks: create dangling"
494
495 test_17e() {
496         test_mkdir $DIR/$tdir
497         local foo=$DIR/$tdir/$tfile
498         ln -s $foo $foo || error "create symlink failed"
499         ls -l $foo || error "ls -l failed"
500         ls $foo && error "ls not failed" || true
501 }
502 run_test 17e "symlinks: create recursive symlink (should return error)"
503
504 test_17f() {
505         test_mkdir $DIR/$tdir
506         ln -s 1234567890/2234567890/3234567890/4234567890 $DIR/$tdir/111
507         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890 $DIR/$tdir/222
508         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890 $DIR/$tdir/333
509         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890 $DIR/$tdir/444
510         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890 $DIR/$tdir/555
511         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890/aaaaaaaaaa/bbbbbbbbbb/cccccccccc/dddddddddd/eeeeeeeeee/ffffffffff/ $DIR/$tdir/666
512         ls -l  $DIR/$tdir
513 }
514 run_test 17f "symlinks: long and very long symlink name"
515
516 # str_repeat(S, N) generate a string that is string S repeated N times
517 str_repeat() {
518         local s=$1
519         local n=$2
520         local ret=''
521         while [ $((n -= 1)) -ge 0 ]; do
522                 ret=$ret$s
523         done
524         echo $ret
525 }
526
527 # Long symlinks and LU-2241
528 test_17g() {
529         test_mkdir $DIR/$tdir
530         local TESTS="59 60 61 4094 4095"
531
532         # Fix for inode size boundary in 2.1.4
533         [ $MDS1_VERSION -lt $(version_code 2.1.4) ] &&
534                 TESTS="4094 4095"
535
536         # Patch not applied to 2.2 or 2.3 branches
537         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
538         [ $MDS1_VERSION -le $(version_code 2.3.55) ] &&
539                 TESTS="4094 4095"
540
541         # skip long symlink name for rhel6.5.
542         # rhel6.5 has a limit (PATH_MAX - sizeof(struct filename))
543         grep -q '6.5' /etc/redhat-release &>/dev/null &&
544                 TESTS="59 60 61 4062 4063"
545
546         for i in $TESTS; do
547                 local SYMNAME=$(str_repeat 'x' $i)
548                 ln -s $SYMNAME $DIR/$tdir/f$i || error "failed $i-char symlink"
549                 readlink $DIR/$tdir/f$i || error "failed $i-char readlink"
550         done
551 }
552 run_test 17g "symlinks: really long symlink name and inode boundaries"
553
554 test_17h() { #bug 17378
555         [ $PARALLEL == "yes" ] && skip "skip parallel run"
556         remote_mds_nodsh && skip "remote MDS with nodsh"
557
558         local mdt_idx
559
560         test_mkdir $DIR/$tdir
561         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
562         $LFS setstripe -c -1 $DIR/$tdir
563         #define OBD_FAIL_MDS_LOV_PREP_CREATE 0x141
564         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000141
565         touch $DIR/$tdir/$tfile || true
566 }
567 run_test 17h "create objects: lov_free_memmd() doesn't lbug"
568
569 test_17i() { #bug 20018
570         [ $PARALLEL == "yes" ] && skip "skip parallel run"
571         remote_mds_nodsh && skip "remote MDS with nodsh"
572
573         local foo=$DIR/$tdir/$tfile
574         local mdt_idx
575
576         test_mkdir -c1 $DIR/$tdir
577         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
578         ln -s $foo $foo || error "create symlink failed"
579 #define OBD_FAIL_MDS_READLINK_EPROTO     0x143
580         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000143
581         ls -l $foo && error "error not detected"
582         return 0
583 }
584 run_test 17i "don't panic on short symlink (should return error)"
585
586 test_17k() { #bug 22301
587         [ $PARALLEL == "yes" ] && skip "skip parallel run"
588         [[ -z "$(which rsync 2>/dev/null)" ]] &&
589                 skip "no rsync command"
590         rsync --help | grep -q xattr ||
591                 skip_env "$(rsync --version | head -n1) does not support xattrs"
592         test_mkdir $DIR/$tdir
593         test_mkdir $DIR/$tdir.new
594         touch $DIR/$tdir/$tfile
595         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
596         rsync -av -X $DIR/$tdir/ $DIR/$tdir.new ||
597                 error "rsync failed with xattrs enabled"
598 }
599 run_test 17k "symlinks: rsync with xattrs enabled"
600
601 test_17l() { # LU-279
602         [[ -z "$(which getfattr 2>/dev/null)" ]] &&
603                 skip "no getfattr command"
604
605         test_mkdir $DIR/$tdir
606         touch $DIR/$tdir/$tfile
607         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
608         for path in "$DIR/$tdir" "$DIR/$tdir/$tfile" "$DIR/$tdir/$tfile.lnk"; do
609                 # -h to not follow symlinks. -m '' to list all the xattrs.
610                 # grep to remove first line: '# file: $path'.
611                 for xattr in `getfattr -hm '' $path 2>/dev/null | grep -v '^#'`;
612                 do
613                         lgetxattr_size_check $path $xattr ||
614                                 error "lgetxattr_size_check $path $xattr failed"
615                 done
616         done
617 }
618 run_test 17l "Ensure lgetxattr's returned xattr size is consistent"
619
620 # LU-1540
621 test_17m() {
622         [ $PARALLEL == "yes" ] && skip "skip parallel run"
623         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
624         remote_mds_nodsh && skip "remote MDS with nodsh"
625         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
626         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
627                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
628
629         local short_sym="0123456789"
630         local wdir=$DIR/$tdir
631         local i
632
633         test_mkdir $wdir
634         long_sym=$short_sym
635         # create a long symlink file
636         for ((i = 0; i < 4; ++i)); do
637                 long_sym=${long_sym}${long_sym}
638         done
639
640         echo "create 512 short and long symlink files under $wdir"
641         for ((i = 0; i < 256; ++i)); do
642                 ln -sf ${long_sym}"a5a5" $wdir/long-$i
643                 ln -sf ${short_sym}"a5a5" $wdir/short-$i
644         done
645
646         echo "erase them"
647         rm -f $wdir/*
648         sync
649         wait_delete_completed
650
651         echo "recreate the 512 symlink files with a shorter string"
652         for ((i = 0; i < 512; ++i)); do
653                 # rewrite the symlink file with a shorter string
654                 ln -sf ${long_sym} $wdir/long-$i || error "long_sym failed"
655                 ln -sf ${short_sym} $wdir/short-$i || error "short_sym failed"
656         done
657
658         local mds_index=$(($($LFS getstripe -m $wdir) + 1))
659         local devname=$(mdsdevname $mds_index)
660
661         echo "stop and checking mds${mds_index}:"
662         # e2fsck should not return error
663         stop mds${mds_index}
664         run_e2fsck $(facet_active_host mds${mds_index}) $devname -n
665         rc=$?
666
667         start mds${mds_index} $devname $MDS_MOUNT_OPTS ||
668                 error "start mds${mds_index} failed"
669         df $MOUNT > /dev/null 2>&1
670         [ $rc -eq 0 ] ||
671                 error "e2fsck detected error for short/long symlink: rc=$rc"
672         rm -f $wdir/*
673 }
674 run_test 17m "run e2fsck against MDT which contains short/long symlink"
675
676 check_fs_consistency_17n() {
677         local mdt_index
678         local rc=0
679
680         # create/unlink in 17n only change 2 MDTs(MDT1/MDT2),
681         # so it only check MDT1/MDT2 instead of all of MDTs.
682         for mdt_index in 1 2; do
683                 local devname=$(mdsdevname $mdt_index)
684                 # e2fsck should not return error
685                 stop mds${mdt_index}
686                 run_e2fsck $(facet_active_host mds$mdt_index) $devname -n ||
687                         rc=$((rc + $?))
688
689                 start mds${mdt_index} $devname $MDS_MOUNT_OPTS ||
690                         error "mount mds$mdt_index failed"
691                 df $MOUNT > /dev/null 2>&1
692         done
693         return $rc
694 }
695
696 test_17n() {
697         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
698         [ $PARALLEL == "yes" ] && skip "skip parallel run"
699         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
700         remote_mds_nodsh && skip "remote MDS with nodsh"
701         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
702         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
703                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
704
705         local i
706
707         test_mkdir $DIR/$tdir
708         for ((i=0; i<10; i++)); do
709                 $LFS mkdir -i1 -c2 $DIR/$tdir/remote_dir_${i} ||
710                         error "create remote dir error $i"
711                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
712                         error "create files under remote dir failed $i"
713         done
714
715         check_fs_consistency_17n ||
716                 error "e2fsck report error after create files under remote dir"
717
718         for ((i = 0; i < 10; i++)); do
719                 rm -rf $DIR/$tdir/remote_dir_${i} ||
720                         error "destroy remote dir error $i"
721         done
722
723         check_fs_consistency_17n ||
724                 error "e2fsck report error after unlink files under remote dir"
725
726         [ $MDS1_VERSION -lt $(version_code 2.4.50) ] &&
727                 skip "lustre < 2.4.50 does not support migrate mv"
728
729         for ((i = 0; i < 10; i++)); do
730                 mkdir -p $DIR/$tdir/remote_dir_${i}
731                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
732                         error "create files under remote dir failed $i"
733                 $LFS migrate --mdt-index 1 $DIR/$tdir/remote_dir_${i} ||
734                         error "migrate remote dir error $i"
735         done
736         check_fs_consistency_17n || error "e2fsck report error after migration"
737
738         for ((i = 0; i < 10; i++)); do
739                 rm -rf $DIR/$tdir/remote_dir_${i} ||
740                         error "destroy remote dir error $i"
741         done
742
743         check_fs_consistency_17n || error "e2fsck report error after unlink"
744 }
745 run_test 17n "run e2fsck against master/slave MDT which contains remote dir"
746
747 test_17o() {
748         remote_mds_nodsh && skip "remote MDS with nodsh"
749         [ $MDS1_VERSION -lt $(version_code 2.3.64) ] &&
750                 skip "Need MDS version at least 2.3.64"
751
752         local wdir=$DIR/${tdir}o
753         local mdt_index
754         local rc=0
755
756         test_mkdir $wdir
757         touch $wdir/$tfile
758         mdt_index=$($LFS getstripe -m $wdir/$tfile)
759         mdt_index=$((mdt_index + 1))
760
761         cancel_lru_locks mdc
762         #fail mds will wait the failover finish then set
763         #following fail_loc to avoid interfer the recovery process.
764         fail mds${mdt_index}
765
766         #define OBD_FAIL_OSD_LMA_INCOMPAT 0x194
767         do_facet mds${mdt_index} lctl set_param fail_loc=0x194
768         ls -l $wdir/$tfile && rc=1
769         do_facet mds${mdt_index} lctl set_param fail_loc=0
770         [[ $rc -eq 0 ]] || error "stat file should fail"
771 }
772 run_test 17o "stat file with incompat LMA feature"
773
774 test_18() {
775         touch $DIR/$tfile || error "Failed to touch $DIR/$tfile: $?"
776         ls $DIR || error "Failed to ls $DIR: $?"
777 }
778 run_test 18 "touch .../f ; ls ... =============================="
779
780 test_19a() {
781         touch $DIR/$tfile
782         ls -l $DIR
783         rm $DIR/$tfile
784         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
785 }
786 run_test 19a "touch .../f19 ; ls -l ... ; rm .../f19 ==========="
787
788 test_19b() {
789         ls -l $DIR/$tfile && error "ls -l $tfile failed"|| true
790 }
791 run_test 19b "ls -l .../f19 (should return error) =============="
792
793 test_19c() {
794         [ $RUNAS_ID -eq $UID ] &&
795                 skip_env "RUNAS_ID = UID = $UID -- skipping"
796
797         $RUNAS touch $DIR/$tfile && error "create non-root file failed" || true
798 }
799 run_test 19c "$RUNAS touch .../f19 (should return error) =="
800
801 test_19d() {
802         cat $DIR/f19 && error || true
803 }
804 run_test 19d "cat .../f19 (should return error) =============="
805
806 test_20() {
807         touch $DIR/$tfile
808         rm $DIR/$tfile
809         touch $DIR/$tfile
810         rm $DIR/$tfile
811         touch $DIR/$tfile
812         rm $DIR/$tfile
813         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
814 }
815 run_test 20 "touch .../f ; ls -l ..."
816
817 test_21() {
818         test_mkdir $DIR/$tdir
819         [ -f $DIR/$tdir/dangle ] && rm -f $DIR/$tdir/dangle
820         ln -s dangle $DIR/$tdir/link
821         echo foo >> $DIR/$tdir/link
822         cat $DIR/$tdir/dangle
823         $CHECKSTAT -t link $DIR/$tdir/link || error "$tdir/link not a link"
824         $CHECKSTAT -f -t file $DIR/$tdir/link ||
825                 error "$tdir/link not linked to a file"
826 }
827 run_test 21 "write to dangling link"
828
829 test_22() {
830         local wdir=$DIR/$tdir
831         test_mkdir $wdir
832         chown $RUNAS_ID:$RUNAS_GID $wdir
833         (cd $wdir || error "cd $wdir failed";
834                 $RUNAS tar cf - /etc/hosts /etc/sysconfig/network |
835                 $RUNAS tar xf -)
836         ls -lR $wdir/etc || error "ls -lR $wdir/etc failed"
837         $CHECKSTAT -t dir $wdir/etc || error "checkstat -t dir failed"
838         $CHECKSTAT -u \#$RUNAS_ID -g \#$RUNAS_GID $wdir/etc ||
839                 error "checkstat -u failed"
840 }
841 run_test 22 "unpack tar archive as non-root user"
842
843 # was test_23
844 test_23a() {
845         test_mkdir $DIR/$tdir
846         local file=$DIR/$tdir/$tfile
847
848         openfile -f O_CREAT:O_EXCL $file || error "$file create failed"
849         openfile -f O_CREAT:O_EXCL $file &&
850                 error "$file recreate succeeded" || true
851 }
852 run_test 23a "O_CREAT|O_EXCL in subdir"
853
854 test_23b() { # bug 18988
855         test_mkdir $DIR/$tdir
856         local file=$DIR/$tdir/$tfile
857
858         rm -f $file
859         echo foo > $file || error "write filed"
860         echo bar >> $file || error "append filed"
861         $CHECKSTAT -s 8 $file || error "wrong size"
862         rm $file
863 }
864 run_test 23b "O_APPEND check"
865
866 # LU-9409, size with O_APPEND and tiny writes
867 test_23c() {
868         local file=$DIR/$tfile
869
870         # single dd
871         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800
872         $CHECKSTAT -s 6400 $file || error "wrong size, expected 6400"
873         rm -f $file
874
875         # racing tiny writes
876         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
877         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
878         wait
879         $CHECKSTAT -s 12800 $file || error "wrong size, expected 12800"
880         rm -f $file
881
882         #racing tiny & normal writes
883         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4096 count=4 &
884         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=100 &
885         wait
886         $CHECKSTAT -s 17184 $file || error "wrong size, expected 17184"
887         rm -f $file
888
889         #racing tiny & normal writes 2, ugly numbers
890         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4099 count=11 &
891         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=17 count=173 &
892         wait
893         $CHECKSTAT -s 48030 $file || error "wrong size, expected 48030"
894         rm -f $file
895 }
896 run_test 23c "O_APPEND size checks for tiny writes"
897
898 # LU-11069 file offset is correct after appending writes
899 test_23d() {
900         local file=$DIR/$tfile
901         local offset
902
903         echo CentaurHauls > $file
904         offset=$($MULTIOP $file oO_WRONLY:O_APPEND:w13Zp)
905         if ((offset != 26)); then
906                 error "wrong offset, expected 26, got '$offset'"
907         fi
908 }
909 run_test 23d "file offset is correct after appending writes"
910
911 # rename sanity
912 test_24a() {
913         echo '-- same directory rename'
914         test_mkdir $DIR/$tdir
915         touch $DIR/$tdir/$tfile.1
916         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
917         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
918 }
919 run_test 24a "rename file to non-existent target"
920
921 test_24b() {
922         test_mkdir $DIR/$tdir
923         touch $DIR/$tdir/$tfile.{1,2}
924         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
925         $CHECKSTAT -a $DIR/$tdir/$tfile.1 || error "$tfile.1 exists"
926         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
927 }
928 run_test 24b "rename file to existing target"
929
930 test_24c() {
931         test_mkdir $DIR/$tdir
932         test_mkdir $DIR/$tdir/d$testnum.1
933         mv $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
934         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
935         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
936 }
937 run_test 24c "rename directory to non-existent target"
938
939 test_24d() {
940         test_mkdir -c1 $DIR/$tdir
941         test_mkdir -c1 $DIR/$tdir/d$testnum.1
942         test_mkdir -c1 $DIR/$tdir/d$testnum.2
943         mrename $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
944         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
945         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
946 }
947 run_test 24d "rename directory to existing target"
948
949 test_24e() {
950         echo '-- cross directory renames --'
951         test_mkdir $DIR/R5a
952         test_mkdir $DIR/R5b
953         touch $DIR/R5a/f
954         mv $DIR/R5a/f $DIR/R5b/g
955         $CHECKSTAT -a $DIR/R5a/f || error "$DIR/R5a/f exists"
956         $CHECKSTAT -t file $DIR/R5b/g || error "$DIR/R5b/g not file type"
957 }
958 run_test 24e "touch .../R5a/f; rename .../R5a/f .../R5b/g ======"
959
960 test_24f() {
961         test_mkdir $DIR/R6a
962         test_mkdir $DIR/R6b
963         touch $DIR/R6a/f $DIR/R6b/g
964         mv $DIR/R6a/f $DIR/R6b/g
965         $CHECKSTAT -a $DIR/R6a/f || error "$DIR/R6a/f exists"
966         $CHECKSTAT -t file $DIR/R6b/g || error "$DIR/R6b/g not file type"
967 }
968 run_test 24f "touch .../R6a/f R6b/g; mv .../R6a/f .../R6b/g ===="
969
970 test_24g() {
971         test_mkdir $DIR/R7a
972         test_mkdir $DIR/R7b
973         test_mkdir $DIR/R7a/d
974         mv $DIR/R7a/d $DIR/R7b/e
975         $CHECKSTAT -a $DIR/R7a/d || error "$DIR/R7a/d exists"
976         $CHECKSTAT -t dir $DIR/R7b/e || error "$DIR/R7b/e not dir type"
977 }
978 run_test 24g "mkdir .../R7{a,b}/d; mv .../R7a/d .../R7b/e ======"
979
980 test_24h() {
981         test_mkdir -c1 $DIR/R8a
982         test_mkdir -c1 $DIR/R8b
983         test_mkdir -c1 $DIR/R8a/d
984         test_mkdir -c1 $DIR/R8b/e
985         mrename $DIR/R8a/d $DIR/R8b/e
986         $CHECKSTAT -a $DIR/R8a/d || error "$DIR/R8a/d exists"
987         $CHECKSTAT -t dir $DIR/R8b/e || error "$DIR/R8b/e not dir type"
988 }
989 run_test 24h "mkdir .../R8{a,b}/{d,e}; rename .../R8a/d .../R8b/e"
990
991 test_24i() {
992         echo "-- rename error cases"
993         test_mkdir $DIR/R9
994         test_mkdir $DIR/R9/a
995         touch $DIR/R9/f
996         mrename $DIR/R9/f $DIR/R9/a
997         $CHECKSTAT -t file $DIR/R9/f || error "$DIR/R9/f not file type"
998         $CHECKSTAT -t dir  $DIR/R9/a || error "$DIR/R9/a not dir type"
999         $CHECKSTAT -a $DIR/R9/a/f || error "$DIR/R9/a/f exists"
1000 }
1001 run_test 24i "rename file to dir error: touch f ; mkdir a ; rename f a"
1002
1003 test_24j() {
1004         test_mkdir $DIR/R10
1005         mrename $DIR/R10/f $DIR/R10/g
1006         $CHECKSTAT -t dir $DIR/R10 || error "$DIR/R10 not dir type"
1007         $CHECKSTAT -a $DIR/R10/f || error "$DIR/R10/f exists"
1008         $CHECKSTAT -a $DIR/R10/g || error "$DIR/R10/g exists"
1009 }
1010 run_test 24j "source does not exist ============================"
1011
1012 test_24k() {
1013         test_mkdir $DIR/R11a
1014         test_mkdir $DIR/R11a/d
1015         touch $DIR/R11a/f
1016         mv $DIR/R11a/f $DIR/R11a/d
1017         $CHECKSTAT -a $DIR/R11a/f || error "$DIR/R11a/f exists"
1018         $CHECKSTAT -t file $DIR/R11a/d/f || error "$DIR/R11a/d/f not file type"
1019 }
1020 run_test 24k "touch .../R11a/f; mv .../R11a/f .../R11a/d ======="
1021
1022 # bug 2429 - rename foo foo foo creates invalid file
1023 test_24l() {
1024         f="$DIR/f24l"
1025         $MULTIOP $f OcNs || error "rename of ${f} to itself failed"
1026 }
1027 run_test 24l "Renaming a file to itself ========================"
1028
1029 test_24m() {
1030         f="$DIR/f24m"
1031         $MULTIOP $f OcLN ${f}2 ${f}2 || error "link ${f}2 ${f}2 failed"
1032         # on ext3 this does not remove either the source or target files
1033         # though the "expected" operation would be to remove the source
1034         $CHECKSTAT -t file ${f} || error "${f} missing"
1035         $CHECKSTAT -t file ${f}2 || error "${f}2 missing"
1036 }
1037 run_test 24m "Renaming a file to a hard link to itself ========="
1038
1039 test_24n() {
1040     f="$DIR/f24n"
1041     # this stats the old file after it was renamed, so it should fail
1042     touch ${f}
1043     $CHECKSTAT ${f} || error "${f} missing"
1044     mv ${f} ${f}.rename
1045     $CHECKSTAT ${f}.rename || error "${f}.rename missing"
1046     $CHECKSTAT -a ${f} || error "${f} exists"
1047 }
1048 run_test 24n "Statting the old file after renaming (Posix rename 2)"
1049
1050 test_24o() {
1051         test_mkdir $DIR/$tdir
1052         rename_many -s random -v -n 10 $DIR/$tdir
1053 }
1054 run_test 24o "rename of files during htree split"
1055
1056 test_24p() {
1057         test_mkdir $DIR/R12a
1058         test_mkdir $DIR/R12b
1059         DIRINO=`ls -lid $DIR/R12a | awk '{ print $1 }'`
1060         mrename $DIR/R12a $DIR/R12b
1061         $CHECKSTAT -a $DIR/R12a || error "$DIR/R12a exists"
1062         $CHECKSTAT -t dir $DIR/R12b || error "$DIR/R12b not dir type"
1063         DIRINO2=`ls -lid $DIR/R12b | awk '{ print $1 }'`
1064         [ "$DIRINO" = "$DIRINO2" ] || error "R12a $DIRINO != R12b $DIRINO2"
1065 }
1066 run_test 24p "mkdir .../R12{a,b}; rename .../R12a .../R12b"
1067
1068 cleanup_multiop_pause() {
1069         trap 0
1070         kill -USR1 $MULTIPID
1071 }
1072
1073 test_24q() {
1074         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1075
1076         test_mkdir $DIR/R13a
1077         test_mkdir $DIR/R13b
1078         local DIRINO=$(ls -lid $DIR/R13a | awk '{ print $1 }')
1079         multiop_bg_pause $DIR/R13b D_c || error "multiop failed to start"
1080         MULTIPID=$!
1081
1082         trap cleanup_multiop_pause EXIT
1083         mrename $DIR/R13a $DIR/R13b
1084         $CHECKSTAT -a $DIR/R13a || error "R13a still exists"
1085         $CHECKSTAT -t dir $DIR/R13b || error "R13b does not exist"
1086         local DIRINO2=$(ls -lid $DIR/R13b | awk '{ print $1 }')
1087         [ "$DIRINO" = "$DIRINO2" ] || error "R13a $DIRINO != R13b $DIRINO2"
1088         cleanup_multiop_pause
1089         wait $MULTIPID || error "multiop close failed"
1090 }
1091 run_test 24q "mkdir .../R13{a,b}; open R13b rename R13a R13b ==="
1092
1093 test_24r() { #bug 3789
1094         test_mkdir $DIR/R14a
1095         test_mkdir $DIR/R14a/b
1096         mrename $DIR/R14a $DIR/R14a/b && error "rename to subdir worked!"
1097         $CHECKSTAT -t dir $DIR/R14a || error "$DIR/R14a missing"
1098         $CHECKSTAT -t dir $DIR/R14a/b || error "$DIR/R14a/b missing"
1099 }
1100 run_test 24r "mkdir .../R14a/b; rename .../R14a .../R14a/b ====="
1101
1102 test_24s() {
1103         test_mkdir $DIR/R15a
1104         test_mkdir $DIR/R15a/b
1105         test_mkdir $DIR/R15a/b/c
1106         mrename $DIR/R15a $DIR/R15a/b/c && error "rename to sub-subdir worked!"
1107         $CHECKSTAT -t dir $DIR/R15a || error "$DIR/R15a missing"
1108         $CHECKSTAT -t dir $DIR/R15a/b/c || error "$DIR/R15a/b/c missing"
1109 }
1110 run_test 24s "mkdir .../R15a/b/c; rename .../R15a .../R15a/b/c ="
1111 test_24t() {
1112         test_mkdir $DIR/R16a
1113         test_mkdir $DIR/R16a/b
1114         test_mkdir $DIR/R16a/b/c
1115         mrename $DIR/R16a/b/c $DIR/R16a && error "rename to sub-subdir worked!"
1116         $CHECKSTAT -t dir $DIR/R16a || error "$DIR/R16a missing"
1117         $CHECKSTAT -t dir $DIR/R16a/b/c || error "$DIR/R16a/b/c missing"
1118 }
1119 run_test 24t "mkdir .../R16a/b/c; rename .../R16a/b/c .../R16a ="
1120
1121 test_24u() { # bug12192
1122         $MULTIOP $DIR/$tfile C2w$((2048 * 1024))c || error "multiop failed"
1123         $CHECKSTAT -s $((2048 * 1024)) $DIR/$tfile || error "wrong file size"
1124 }
1125 run_test 24u "create stripe file"
1126
1127 simple_cleanup_common() {
1128         local rc=0
1129         trap 0
1130         [ -z "$DIR" ] || [ -z "$tdir" ] && return 0
1131
1132         local start=$SECONDS
1133         rm -rf $DIR/$tdir
1134         rc=$?
1135         wait_delete_completed
1136         echo "cleanup time $((SECONDS - start))"
1137         return $rc
1138 }
1139
1140 max_pages_per_rpc() {
1141         local mdtname="$(printf "MDT%04x" ${1:-0})"
1142         $LCTL get_param -n mdc.*$mdtname*.max_pages_per_rpc
1143 }
1144
1145 test_24v() {
1146         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1147
1148         local nrfiles=${COUNT:-100000}
1149         local fname="$DIR/$tdir/$tfile"
1150
1151         # Performance issue on ZFS see LU-4072 (c.f. LU-2887)
1152         [ "$mds1_FSTYPE" = "zfs" ] && nrfiles=${COUNT:-10000}
1153
1154         test_mkdir "$(dirname $fname)"
1155         # assume MDT0000 has the fewest inodes
1156         local stripes=$($LFS getdirstripe -c $(dirname $fname))
1157         local free_inodes=$(($(mdt_free_inodes 0) * stripes))
1158         [[ $free_inodes -lt $nrfiles ]] && nrfiles=$free_inodes
1159
1160         trap simple_cleanup_common EXIT
1161
1162         createmany -m "$fname" $nrfiles
1163
1164         cancel_lru_locks mdc
1165         lctl set_param mdc.*.stats clear
1166
1167         # was previously test_24D: LU-6101
1168         # readdir() returns correct number of entries after cursor reload
1169         local num_ls=$(ls $DIR/$tdir | wc -l)
1170         local num_uniq=$(ls $DIR/$tdir | sort -u | wc -l)
1171         local num_all=$(ls -a $DIR/$tdir | wc -l)
1172         if [ $num_ls -ne $nrfiles ] || [ $num_uniq -ne $nrfiles ] ||
1173                 [ $num_all -ne $((nrfiles + 2)) ]; then
1174                         error "Expected $nrfiles files, got $num_ls " \
1175                                 "($num_uniq unique $num_all .&..)"
1176         fi
1177         # LU-5 large readdir
1178         # dirent_size = 32 bytes for sizeof(struct lu_dirent) +
1179         #               N bytes for name (len($nrfiles) rounded to 8 bytes) +
1180         #               8 bytes for luda_type (4 bytes rounded to 8 bytes)
1181         # take into account of overhead in lu_dirpage header and end mark in
1182         # each page, plus one in rpc_num calculation.
1183         local dirent_size=$((32 + (${#tfile} | 7) + 1 + 8))
1184         local page_entries=$(((PAGE_SIZE - 24) / dirent_size))
1185         local mdt_idx=$($LFS getdirstripe -i $(dirname $fname))
1186         local rpc_pages=$(max_pages_per_rpc $mdt_idx)
1187         local rpc_max=$((nrfiles / (page_entries * rpc_pages) + stripes))
1188         local mds_readpage=$(calc_stats mdc.*.stats mds_readpage)
1189         echo "readpages: $mds_readpage rpc_max: $rpc_max"
1190         (( $mds_readpage < $rpc_max - 2 || $mds_readpage > $rpc_max + 1)) &&
1191                 error "large readdir doesn't take effect: " \
1192                       "$mds_readpage should be about $rpc_max"
1193
1194         simple_cleanup_common
1195 }
1196 run_test 24v "list large directory (test hash collision, b=17560)"
1197
1198 test_24w() { # bug21506
1199         SZ1=234852
1200         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=4096 || return 1
1201         dd if=/dev/zero bs=$SZ1 count=1 >> $DIR/$tfile || return 2
1202         dd if=$DIR/$tfile of=$DIR/${tfile}_left bs=1M skip=4097 || return 3
1203         SZ2=`ls -l $DIR/${tfile}_left | awk '{print $5}'`
1204         [[ "$SZ1" -eq "$SZ2" ]] ||
1205                 error "Error reading at the end of the file $tfile"
1206 }
1207 run_test 24w "Reading a file larger than 4Gb"
1208
1209 test_24x() {
1210         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1211         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1212         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1213                 skip "Need MDS version at least 2.7.56"
1214
1215         local MDTIDX=1
1216         local remote_dir=$DIR/$tdir/remote_dir
1217
1218         test_mkdir $DIR/$tdir
1219         $LFS mkdir -i $MDTIDX $remote_dir ||
1220                 error "create remote directory failed"
1221
1222         test_mkdir $DIR/$tdir/src_dir
1223         touch $DIR/$tdir/src_file
1224         test_mkdir $remote_dir/tgt_dir
1225         touch $remote_dir/tgt_file
1226
1227         mrename $DIR/$tdir/src_dir $remote_dir/tgt_dir ||
1228                 error "rename dir cross MDT failed!"
1229
1230         mrename $DIR/$tdir/src_file $remote_dir/tgt_file ||
1231                 error "rename file cross MDT failed!"
1232
1233         touch $DIR/$tdir/ln_file
1234         ln $DIR/$tdir/ln_file $remote_dir/ln_name ||
1235                 error "ln file cross MDT failed"
1236
1237         rm -rf $DIR/$tdir || error "Can not delete directories"
1238 }
1239 run_test 24x "cross MDT rename/link"
1240
1241 test_24y() {
1242         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1243         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1244
1245         local remote_dir=$DIR/$tdir/remote_dir
1246         local mdtidx=1
1247
1248         test_mkdir $DIR/$tdir
1249         $LFS mkdir -i $mdtidx $remote_dir ||
1250                 error "create remote directory failed"
1251
1252         test_mkdir $remote_dir/src_dir
1253         touch $remote_dir/src_file
1254         test_mkdir $remote_dir/tgt_dir
1255         touch $remote_dir/tgt_file
1256
1257         mrename $remote_dir/src_dir $remote_dir/tgt_dir ||
1258                 error "rename subdir in the same remote dir failed!"
1259
1260         mrename $remote_dir/src_file $remote_dir/tgt_file ||
1261                 error "rename files in the same remote dir failed!"
1262
1263         ln $remote_dir/tgt_file $remote_dir/tgt_file1 ||
1264                 error "link files in the same remote dir failed!"
1265
1266         rm -rf $DIR/$tdir || error "Can not delete directories"
1267 }
1268 run_test 24y "rename/link on the same dir should succeed"
1269
1270 test_24z() {
1271         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1272         [[ $MDS1_VERSION -lt $(version_code 2.12.51) ]] &&
1273                 skip "Need MDS version at least 2.12.51"
1274
1275         local index
1276
1277         for index in 0 1; do
1278                 $LFS mkdir -i $index $DIR/$tdir.$index || error "mkdir failed"
1279                 touch $DIR/$tdir.0/$tfile.$index || error "touch failed"
1280         done
1281
1282         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1 || error "mv $tfile.0 failed"
1283
1284         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.0)
1285         [ $index -eq 0 ] || error "$tfile.0 is on MDT$index"
1286
1287         local mdts=$(comma_list $(mdts_nodes))
1288
1289         do_nodes $mdts $LCTL set_param mdt.*.enable_remote_rename=0
1290         stack_trap "do_nodes $mdts $LCTL \
1291                 set_param mdt.*.enable_remote_rename=1" EXIT
1292
1293         mv $DIR/$tdir.0/$tfile.1 $DIR/$tdir.1 || error "mv $tfile.1 failed"
1294
1295         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.1)
1296         [ $index -eq 1 ] || error "$tfile.1 is on MDT$index"
1297 }
1298 run_test 24z "cross-MDT rename is done as cp"
1299
1300 test_24A() { # LU-3182
1301         local NFILES=5000
1302
1303         rm -rf $DIR/$tdir
1304         test_mkdir $DIR/$tdir
1305         trap simple_cleanup_common EXIT
1306         createmany -m $DIR/$tdir/$tfile $NFILES
1307         local t=$(ls $DIR/$tdir | wc -l)
1308         local u=$(ls $DIR/$tdir | sort -u | wc -l)
1309         local v=$(ls -ai $DIR/$tdir | sort -u | wc -l)
1310         if [ $t -ne $NFILES ] || [ $u -ne $NFILES ] ||
1311            [ $v -ne $((NFILES + 2)) ] ; then
1312                 error "Expected $NFILES files, got $t ($u unique $v .&..)"
1313         fi
1314
1315         simple_cleanup_common || error "Can not delete directories"
1316 }
1317 run_test 24A "readdir() returns correct number of entries."
1318
1319 test_24B() { # LU-4805
1320         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1321
1322         local count
1323
1324         test_mkdir $DIR/$tdir
1325         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
1326                 error "create striped dir failed"
1327
1328         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1329         [ $count -eq 2 ] || error "Expected 2, got $count"
1330
1331         touch $DIR/$tdir/striped_dir/a
1332
1333         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1334         [ $count -eq 3 ] || error "Expected 3, got $count"
1335
1336         touch $DIR/$tdir/striped_dir/.f
1337
1338         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1339         [ $count -eq 4 ] || error "Expected 4, got $count"
1340
1341         rm -rf $DIR/$tdir || error "Can not delete directories"
1342 }
1343 run_test 24B "readdir for striped dir return correct number of entries"
1344
1345 test_24C() {
1346         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1347
1348         mkdir $DIR/$tdir
1349         mkdir $DIR/$tdir/d0
1350         mkdir $DIR/$tdir/d1
1351
1352         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/d0/striped_dir ||
1353                 error "create striped dir failed"
1354
1355         cd $DIR/$tdir/d0/striped_dir
1356
1357         local d0_ino=$(ls -i -l -a $DIR/$tdir | grep "d0" | awk '{print $1}')
1358         local d1_ino=$(ls -i -l -a $DIR/$tdir | grep "d1" | awk '{print $1}')
1359         local parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1360
1361         [ "$d0_ino" = "$parent_ino" ] ||
1362                 error ".. wrong, expect $d0_ino, get $parent_ino"
1363
1364         mv $DIR/$tdir/d0/striped_dir $DIR/$tdir/d1/ ||
1365                 error "mv striped dir failed"
1366
1367         parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1368
1369         [ "$d1_ino" = "$parent_ino" ] ||
1370                 error ".. wrong after mv, expect $d1_ino, get $parent_ino"
1371 }
1372 run_test 24C "check .. in striped dir"
1373
1374 test_24E() {
1375         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
1376         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1377
1378         mkdir -p $DIR/$tdir
1379         mkdir $DIR/$tdir/src_dir
1380         $LFS mkdir -i 1 $DIR/$tdir/src_dir/src_child ||
1381                 error "create remote source failed"
1382
1383         touch $DIR/$tdir/src_dir/src_child/a
1384
1385         $LFS mkdir -i 2 $DIR/$tdir/tgt_dir ||
1386                 error "create remote target dir failed"
1387
1388         $LFS mkdir -i 3 $DIR/$tdir/tgt_dir/tgt_child ||
1389                 error "create remote target child failed"
1390
1391         mrename $DIR/$tdir/src_dir/src_child $DIR/$tdir/tgt_dir/tgt_child ||
1392                 error "rename dir cross MDT failed!"
1393
1394         find $DIR/$tdir
1395
1396         $CHECKSTAT -t dir $DIR/$tdir/src_dir/src_child &&
1397                 error "src_child still exists after rename"
1398
1399         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/tgt_child/a ||
1400                 error "missing file(a) after rename"
1401
1402         rm -rf $DIR/$tdir || error "Can not delete directories"
1403 }
1404 run_test 24E "cross MDT rename/link"
1405
1406 test_24F () {
1407         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
1408
1409         local repeats=1000
1410         [ "$SLOW" = "no" ] && repeats=100
1411
1412         mkdir -p $DIR/$tdir
1413
1414         echo "$repeats repeats"
1415         for ((i = 0; i < repeats; i++)); do
1416                 $LFS mkdir -i0 -c2 $DIR/$tdir/test || error "mkdir fails"
1417                 touch $DIR/$tdir/test/a || error "touch fails"
1418                 mkdir $DIR/$tdir/test/b || error "mkdir fails"
1419                 rm -rf $DIR/$tdir/test || error "rmdir fails"
1420         done
1421
1422         true
1423 }
1424 run_test 24F "hash order vs readdir (LU-11330)"
1425
1426 test_25a() {
1427         echo '== symlink sanity ============================================='
1428
1429         test_mkdir $DIR/d25
1430         ln -s d25 $DIR/s25
1431         touch $DIR/s25/foo ||
1432                 error "File creation in symlinked directory failed"
1433 }
1434 run_test 25a "create file in symlinked directory ==============="
1435
1436 test_25b() {
1437         [ ! -d $DIR/d25 ] && test_25a
1438         $CHECKSTAT -t file $DIR/s25/foo || error "$DIR/s25/foo not file type"
1439 }
1440 run_test 25b "lookup file in symlinked directory ==============="
1441
1442 test_26a() {
1443         test_mkdir $DIR/d26
1444         test_mkdir $DIR/d26/d26-2
1445         ln -s d26/d26-2 $DIR/s26
1446         touch $DIR/s26/foo || error "File creation failed"
1447 }
1448 run_test 26a "multiple component symlink ======================="
1449
1450 test_26b() {
1451         test_mkdir -p $DIR/$tdir/d26-2
1452         ln -s $tdir/d26-2/foo $DIR/s26-2
1453         touch $DIR/s26-2 || error "File creation failed"
1454 }
1455 run_test 26b "multiple component symlink at end of lookup ======"
1456
1457 test_26c() {
1458         test_mkdir $DIR/d26.2
1459         touch $DIR/d26.2/foo
1460         ln -s d26.2 $DIR/s26.2-1
1461         ln -s s26.2-1 $DIR/s26.2-2
1462         ln -s s26.2-2 $DIR/s26.2-3
1463         chmod 0666 $DIR/s26.2-3/foo
1464 }
1465 run_test 26c "chain of symlinks"
1466
1467 # recursive symlinks (bug 439)
1468 test_26d() {
1469         ln -s d26-3/foo $DIR/d26-3
1470 }
1471 run_test 26d "create multiple component recursive symlink"
1472
1473 test_26e() {
1474         [ ! -h $DIR/d26-3 ] && test_26d
1475         rm $DIR/d26-3
1476 }
1477 run_test 26e "unlink multiple component recursive symlink"
1478
1479 # recursive symlinks (bug 7022)
1480 test_26f() {
1481         test_mkdir $DIR/$tdir
1482         test_mkdir $DIR/$tdir/$tfile
1483         cd $DIR/$tdir/$tfile           || error "cd $DIR/$tdir/$tfile failed"
1484         test_mkdir -p lndir/bar1
1485         test_mkdir $DIR/$tdir/$tfile/$tfile
1486         cd $tfile                || error "cd $tfile failed"
1487         ln -s .. dotdot          || error "ln dotdot failed"
1488         ln -s dotdot/lndir lndir || error "ln lndir failed"
1489         cd $DIR/$tdir                 || error "cd $DIR/$tdir failed"
1490         output=`ls $tfile/$tfile/lndir/bar1`
1491         [ "$output" = bar1 ] && error "unexpected output"
1492         rm -r $tfile             || error "rm $tfile failed"
1493         $CHECKSTAT -a $DIR/$tfile || error "$tfile not gone"
1494 }
1495 run_test 26f "rm -r of a directory which has recursive symlink"
1496
1497 test_27a() {
1498         test_mkdir $DIR/$tdir
1499         $LFS getstripe $DIR/$tdir
1500         $LFS setstripe -c 1 $DIR/$tdir/$tfile || error "setstripe failed"
1501         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1502         cp /etc/hosts $DIR/$tdir/$tfile || error "Can't copy to one stripe file"
1503 }
1504 run_test 27a "one stripe file"
1505
1506 test_27b() {
1507         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1508
1509         test_mkdir $DIR/$tdir
1510         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1511         $LFS getstripe -c $DIR/$tdir/$tfile
1512         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
1513                 error "two-stripe file doesn't have two stripes"
1514
1515         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1516 }
1517 run_test 27b "create and write to two stripe file"
1518
1519 # 27c family tests specific striping, setstripe -o
1520 test_27ca() {
1521         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1522         test_mkdir -p $DIR/$tdir
1523         local osts="1"
1524
1525         $LFS setstripe -o $osts $DIR/$tdir/$tfile  || error "setstripe failed"
1526         $LFS getstripe -i $DIR/$tdir/$tfile
1527         [ $($LFS getstripe -i $DIR/$tdir/$tfile ) -eq $osts ] ||
1528                 error "stripe not on specified OST"
1529
1530         dd if=/dev/zero of=$DIR/$tdir/$tfile  bs=1M count=4 || error "dd failed"
1531 }
1532 run_test 27ca "one stripe on specified OST"
1533
1534 test_27cb() {
1535         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1536         test_mkdir -p $DIR/$tdir
1537         local osts="1,0"
1538         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1539         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1540         echo "$getstripe"
1541
1542         # Strip getstripe output to a space separated list of OSTs
1543         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1544                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1545         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1546                 error "stripes not on specified OSTs"
1547
1548         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1549 }
1550 run_test 27cb "two stripes on specified OSTs"
1551
1552 test_27cc() {
1553         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1554         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1555                 skip "server does not support overstriping"
1556
1557         test_mkdir -p $DIR/$tdir
1558         local osts="0,0"
1559         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1560         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1561         echo "$getstripe"
1562
1563         # Strip getstripe output to a space separated list of OSTs
1564         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1565                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1566         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1567                 error "stripes not on specified OSTs"
1568
1569         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1570 }
1571 run_test 27cc "two stripes on the same OST"
1572
1573 test_27cd() {
1574         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1575         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1576                 skip "server does not support overstriping"
1577         test_mkdir -p $DIR/$tdir
1578         local osts="0,1,1,0"
1579         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1580         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1581         echo "$getstripe"
1582
1583         # Strip getstripe output to a space separated list of OSTs
1584         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1585                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1586         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1587                 error "stripes not on specified OSTs"
1588
1589         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1590 }
1591 run_test 27cd "four stripes on two OSTs"
1592
1593 test_27ce() {
1594         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
1595                 skip_env "too many osts, skipping"
1596         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1597                 skip "server does not support overstriping"
1598         # We do one more stripe than we have OSTs
1599         [ $OSTCOUNT -ge 159 ] || large_xattr_enabled ||
1600                 skip_env "ea_inode feature disabled"
1601
1602         test_mkdir -p $DIR/$tdir
1603         local osts=""
1604         for i in $(seq 0 $OSTCOUNT);
1605         do
1606                 osts=$osts"0"
1607                 if [ $i -ne $OSTCOUNT ]; then
1608                         osts=$osts","
1609                 fi
1610         done
1611         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1612         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1613         echo "$getstripe"
1614
1615         # Strip getstripe output to a space separated list of OSTs
1616         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1617                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1618         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1619                 error "stripes not on specified OSTs"
1620
1621         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1622 }
1623 run_test 27ce "more stripes than OSTs with -o"
1624
1625 test_27d() {
1626         test_mkdir $DIR/$tdir
1627         $LFS setstripe -c 0 -i -1 -S 0 $DIR/$tdir/$tfile ||
1628                 error "setstripe failed"
1629         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1630         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1631 }
1632 run_test 27d "create file with default settings"
1633
1634 test_27e() {
1635         # LU-5839 adds check for existed layout before setting it
1636         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1637                 skip "Need MDS version at least 2.7.56"
1638
1639         test_mkdir $DIR/$tdir
1640         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1641         $LFS setstripe -c 2 $DIR/$tdir/$tfile && error "setstripe worked twice"
1642         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1643 }
1644 run_test 27e "setstripe existing file (should return error)"
1645
1646 test_27f() {
1647         test_mkdir $DIR/$tdir
1648         $LFS setstripe -S 100 -i 0 -c 1 $DIR/$tdir/$tfile &&
1649                 error "$LFS setstripe $DIR/$tdir/$tfile failed"
1650         $CHECKSTAT -t file $DIR/$tdir/$tfile &&
1651                 error "$CHECKSTAT -t file $DIR/$tdir/$tfile should fail"
1652         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1653         $LFS getstripe $DIR/$tdir/$tfile || error "$LFS getstripe failed"
1654 }
1655 run_test 27f "setstripe with bad stripe size (should return error)"
1656
1657 test_27g() {
1658         test_mkdir $DIR/$tdir
1659         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1660         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "no stripe info" ||
1661                 error "$DIR/$tdir/$tfile has object"
1662 }
1663 run_test 27g "$LFS getstripe with no objects"
1664
1665 test_27ga() {
1666         test_mkdir $DIR/$tdir
1667         touch $DIR/$tdir/$tfile || error "touch failed"
1668         ln -s bogus $DIR/$tdir/$tfile.2 || error "ln failed"
1669         $LFS getstripe -m $DIR/$tdir/$tfile $DIR/$tdir/$tfile.2
1670         local rc=$?
1671         (( rc == 2 )) || error "getstripe did not return ENOENT"
1672 }
1673 run_test 27ga "$LFS getstripe with missing file (should return error)"
1674
1675 test_27i() {
1676         test_mkdir $DIR/$tdir
1677         touch $DIR/$tdir/$tfile || error "touch failed"
1678         [[ $($LFS getstripe -c $DIR/$tdir/$tfile) -gt 0 ]] ||
1679                 error "missing objects"
1680 }
1681 run_test 27i "$LFS getstripe with some objects"
1682
1683 test_27j() {
1684         test_mkdir $DIR/$tdir
1685         $LFS setstripe -i $OSTCOUNT $DIR/$tdir/$tfile &&
1686                 error "setstripe failed" || true
1687 }
1688 run_test 27j "setstripe with bad stripe offset (should return error)"
1689
1690 test_27k() { # bug 2844
1691         test_mkdir $DIR/$tdir
1692         local file=$DIR/$tdir/$tfile
1693         local ll_max_blksize=$((4 * 1024 * 1024))
1694         $LFS setstripe -S 67108864 $file || error "setstripe failed"
1695         local blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1696         [ $blksize -le $ll_max_blksize ] || error "1:$blksize > $ll_max_blksize"
1697         dd if=/dev/zero of=$file bs=4k count=1
1698         blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1699         [ $blksize -le $ll_max_blksize ] || error "2:$blksize > $ll_max_blksize"
1700 }
1701 run_test 27k "limit i_blksize for broken user apps"
1702
1703 test_27l() {
1704         mcreate $DIR/$tfile || error "creating file"
1705         $RUNAS $LFS setstripe -c 1 $DIR/$tfile &&
1706                 error "setstripe should have failed" || true
1707 }
1708 run_test 27l "check setstripe permissions (should return error)"
1709
1710 test_27m() {
1711         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1712
1713         [ -n "$RCLIENTS" -o -n "$MOUNT_2" ] &&
1714                 skip_env "multiple clients -- skipping"
1715
1716         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
1717                    head -n1)
1718         if [[ $ORIGFREE -gt $MAXFREE ]]; then
1719                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
1720         fi
1721         trap simple_cleanup_common EXIT
1722         test_mkdir $DIR/$tdir
1723         $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.1
1724         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1024 count=$MAXFREE &&
1725                 error "dd should fill OST0"
1726         i=2
1727         while $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.$i; do
1728                 i=$((i + 1))
1729                 [ $i -gt 256 ] && break
1730         done
1731         i=$((i + 1))
1732         touch $DIR/$tdir/$tfile.$i
1733         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1734             awk '{print $1}'| grep -w "0") ] &&
1735                 error "OST0 was full but new created file still use it"
1736         i=$((i + 1))
1737         touch $DIR/$tdir/$tfile.$i
1738         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1739             awk '{print $1}'| grep -w "0") ] &&
1740                 error "OST0 was full but new created file still use it"
1741         simple_cleanup_common
1742 }
1743 run_test 27m "create file while OST0 was full"
1744
1745 # OSCs keep a NOSPC flag that will be reset after ~5s (qos_maxage)
1746 # if the OST isn't full anymore.
1747 reset_enospc() {
1748         local OSTIDX=${1:-""}
1749
1750         local list=$(comma_list $(osts_nodes))
1751         [ "$OSTIDX" ] && list=$(facet_host ost$((OSTIDX + 1)))
1752
1753         do_nodes $list lctl set_param fail_loc=0
1754         sync    # initiate all OST_DESTROYs from MDS to OST
1755         sleep_maxage
1756 }
1757
1758 exhaust_precreations() {
1759         local OSTIDX=$1
1760         local FAILLOC=$2
1761         local FAILIDX=${3:-$OSTIDX}
1762         local ofacet=ost$((OSTIDX + 1))
1763
1764         test_mkdir -p -c1 $DIR/$tdir
1765         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
1766         local mfacet=mds$((mdtidx + 1))
1767         echo OSTIDX=$OSTIDX MDTIDX=$mdtidx
1768
1769         local OST=$(ostname_from_index $OSTIDX)
1770
1771         # on the mdt's osc
1772         local mdtosc_proc1=$(get_mdtosc_proc_path $mfacet $OST)
1773         local last_id=$(do_facet $mfacet lctl get_param -n \
1774                         osp.$mdtosc_proc1.prealloc_last_id)
1775         local next_id=$(do_facet $mfacet lctl get_param -n \
1776                         osp.$mdtosc_proc1.prealloc_next_id)
1777
1778         local mdtosc_proc2=$(get_mdtosc_proc_path $mfacet)
1779         do_facet $mfacet lctl get_param osp.$mdtosc_proc2.prealloc*
1780
1781         test_mkdir -p $DIR/$tdir/${OST}
1782         $LFS setstripe -i $OSTIDX -c 1 $DIR/$tdir/${OST}
1783 #define OBD_FAIL_OST_ENOSPC              0x215
1784         do_facet $ofacet lctl set_param fail_val=$FAILIDX fail_loc=0x215
1785         echo "Creating to objid $last_id on ost $OST..."
1786         createmany -o $DIR/$tdir/${OST}/f $next_id $((last_id - next_id + 2))
1787         do_facet $mfacet lctl get_param osp.$mdtosc_proc2.prealloc*
1788         do_facet $ofacet lctl set_param fail_loc=$FAILLOC
1789         sleep_maxage
1790 }
1791
1792 exhaust_all_precreations() {
1793         local i
1794         for (( i=0; i < OSTCOUNT; i++ )) ; do
1795                 exhaust_precreations $i $1 -1
1796         done
1797 }
1798
1799 test_27n() {
1800         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1801         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1802         remote_mds_nodsh && skip "remote MDS with nodsh"
1803         remote_ost_nodsh && skip "remote OST with nodsh"
1804
1805         reset_enospc
1806         rm -f $DIR/$tdir/$tfile
1807         exhaust_precreations 0 0x80000215
1808         $LFS setstripe -c -1 $DIR/$tdir || error "setstripe failed"
1809         touch $DIR/$tdir/$tfile || error "touch failed"
1810         $LFS getstripe $DIR/$tdir/$tfile
1811         reset_enospc
1812 }
1813 run_test 27n "create file with some full OSTs"
1814
1815 test_27o() {
1816         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1817         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1818         remote_mds_nodsh && skip "remote MDS with nodsh"
1819         remote_ost_nodsh && skip "remote OST with nodsh"
1820
1821         reset_enospc
1822         rm -f $DIR/$tdir/$tfile
1823         exhaust_all_precreations 0x215
1824
1825         touch $DIR/$tdir/$tfile && error "able to create $DIR/$tdir/$tfile"
1826
1827         reset_enospc
1828         rm -rf $DIR/$tdir/*
1829 }
1830 run_test 27o "create file with all full OSTs (should error)"
1831
1832 test_27p() {
1833         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1834         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1835         remote_mds_nodsh && skip "remote MDS with nodsh"
1836         remote_ost_nodsh && skip "remote OST with nodsh"
1837
1838         reset_enospc
1839         rm -f $DIR/$tdir/$tfile
1840         test_mkdir $DIR/$tdir
1841
1842         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1843         $TRUNCATE $DIR/$tdir/$tfile 80000000 || error "truncate failed"
1844         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1845
1846         exhaust_precreations 0 0x80000215
1847         echo foo >> $DIR/$tdir/$tfile || error "append failed"
1848         $CHECKSTAT -s 80000004 $DIR/$tdir/$tfile || error "checkstat failed"
1849         $LFS getstripe $DIR/$tdir/$tfile
1850
1851         reset_enospc
1852 }
1853 run_test 27p "append to a truncated file with some full OSTs"
1854
1855 test_27q() {
1856         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1857         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1858         remote_mds_nodsh && skip "remote MDS with nodsh"
1859         remote_ost_nodsh && skip "remote OST with nodsh"
1860
1861         reset_enospc
1862         rm -f $DIR/$tdir/$tfile
1863
1864         test_mkdir $DIR/$tdir
1865         $MCREATE $DIR/$tdir/$tfile || error "mcreate $DIR/$tdir/$tfile failed"
1866         $TRUNCATE $DIR/$tdir/$tfile 80000000 ||
1867                 error "truncate $DIR/$tdir/$tfile failed"
1868         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1869
1870         exhaust_all_precreations 0x215
1871
1872         echo foo >> $DIR/$tdir/$tfile && error "append succeeded"
1873         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat 2 failed"
1874
1875         reset_enospc
1876 }
1877 run_test 27q "append to truncated file with all OSTs full (should error)"
1878
1879 test_27r() {
1880         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1881         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1882         remote_mds_nodsh && skip "remote MDS with nodsh"
1883         remote_ost_nodsh && skip "remote OST with nodsh"
1884
1885         reset_enospc
1886         rm -f $DIR/$tdir/$tfile
1887         exhaust_precreations 0 0x80000215
1888
1889         $LFS setstripe -i 0 -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1890
1891         reset_enospc
1892 }
1893 run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
1894
1895 test_27s() { # bug 10725
1896         test_mkdir $DIR/$tdir
1897         local stripe_size=$((4096 * 1024 * 1024))       # 2^32
1898         local stripe_count=0
1899         [ $OSTCOUNT -eq 1 ] || stripe_count=2
1900         $LFS setstripe -S $stripe_size -c $stripe_count $DIR/$tdir &&
1901                 error "stripe width >= 2^32 succeeded" || true
1902
1903 }
1904 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
1905
1906 test_27t() { # bug 10864
1907         WDIR=$(pwd)
1908         WLFS=$(which lfs)
1909         cd $DIR
1910         touch $tfile
1911         $WLFS getstripe $tfile
1912         cd $WDIR
1913 }
1914 run_test 27t "check that utils parse path correctly"
1915
1916 test_27u() { # bug 4900
1917         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1918         remote_mds_nodsh && skip "remote MDS with nodsh"
1919
1920         local index
1921         local list=$(comma_list $(mdts_nodes))
1922
1923 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
1924         do_nodes $list $LCTL set_param fail_loc=0x139
1925         test_mkdir -p $DIR/$tdir
1926         trap simple_cleanup_common EXIT
1927         createmany -o $DIR/$tdir/t- 1000
1928         do_nodes $list $LCTL set_param fail_loc=0
1929
1930         TLOG=$TMP/$tfile.getstripe
1931         $LFS getstripe $DIR/$tdir > $TLOG
1932         OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
1933         unlinkmany $DIR/$tdir/t- 1000
1934         trap 0
1935         [[ $OBJS -gt 0 ]] &&
1936                 error "$OBJS objects created on OST-0. See $TLOG" ||
1937                 rm -f $TLOG
1938 }
1939 run_test 27u "skip object creation on OSC w/o objects"
1940
1941 test_27v() { # bug 4900
1942         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1943         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1944         remote_mds_nodsh && skip "remote MDS with nodsh"
1945         remote_ost_nodsh && skip "remote OST with nodsh"
1946
1947         exhaust_all_precreations 0x215
1948         reset_enospc
1949
1950         $LFS setstripe -c 1 $DIR/$tdir         # 1 stripe / file
1951
1952         touch $DIR/$tdir/$tfile
1953         #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
1954         # all except ost1
1955         for (( i=1; i < OSTCOUNT; i++ )); do
1956                 do_facet ost$i lctl set_param fail_loc=0x705
1957         done
1958         local START=`date +%s`
1959         createmany -o $DIR/$tdir/$tfile 32
1960
1961         local FINISH=`date +%s`
1962         local TIMEOUT=`lctl get_param -n timeout`
1963         local PROCESS=$((FINISH - START))
1964         [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
1965                error "$FINISH - $START >= $TIMEOUT / 2"
1966         sleep $((TIMEOUT / 2 - PROCESS))
1967         reset_enospc
1968 }
1969 run_test 27v "skip object creation on slow OST"
1970
1971 test_27w() { # bug 10997
1972         test_mkdir $DIR/$tdir
1973         $LFS setstripe -S 65536 $DIR/$tdir/f0 || error "setstripe failed"
1974         [ $($LFS getstripe -S $DIR/$tdir/f0) -ne 65536 ] &&
1975                 error "stripe size $size != 65536" || true
1976         [ $($LFS getstripe -d $DIR/$tdir | grep -c "stripe_count") -eq 0 ] &&
1977                 error "$LFS getstripe -d $DIR/$tdir no 'stripe_count'" || true
1978 }
1979 run_test 27w "check $LFS setstripe -S and getstrip -d options"
1980
1981 test_27wa() {
1982         [[ $OSTCOUNT -lt 2 ]] &&
1983                 skip_env "skipping multiple stripe count/offset test"
1984
1985         test_mkdir $DIR/$tdir
1986         for i in $(seq 1 $OSTCOUNT); do
1987                 offset=$((i - 1))
1988                 $LFS setstripe -c $i -i $offset $DIR/$tdir/f$i ||
1989                         error "setstripe -c $i -i $offset failed"
1990                 count=$($LFS getstripe -c $DIR/$tdir/f$i)
1991                 index=$($LFS getstripe -i $DIR/$tdir/f$i)
1992                 [ $count -ne $i ] && error "stripe count $count != $i" || true
1993                 [ $index -ne $offset ] &&
1994                         error "stripe offset $index != $offset" || true
1995         done
1996 }
1997 run_test 27wa "check $LFS setstripe -c -i options"
1998
1999 test_27x() {
2000         remote_ost_nodsh && skip "remote OST with nodsh"
2001         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2002         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2003
2004         OFFSET=$(($OSTCOUNT - 1))
2005         OSTIDX=0
2006         local OST=$(ostname_from_index $OSTIDX)
2007
2008         test_mkdir $DIR/$tdir
2009         $LFS setstripe -c 1 $DIR/$tdir  # 1 stripe per file
2010         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 1
2011         sleep_maxage
2012         createmany -o $DIR/$tdir/$tfile $OSTCOUNT
2013         for i in $(seq 0 $OFFSET); do
2014                 [ $($LFS getstripe $DIR/$tdir/$tfile$i | grep -A 10 obdidx |
2015                         awk '{print $1}' | grep -w "$OSTIDX") ] &&
2016                 error "OST0 was degraded but new created file still use it"
2017         done
2018         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 0
2019 }
2020 run_test 27x "create files while OST0 is degraded"
2021
2022 test_27y() {
2023         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2024         remote_mds_nodsh && skip "remote MDS with nodsh"
2025         remote_ost_nodsh && skip "remote OST with nodsh"
2026         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2027
2028         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
2029         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
2030                 osp.$mdtosc.prealloc_last_id)
2031         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
2032                 osp.$mdtosc.prealloc_next_id)
2033         local fcount=$((last_id - next_id))
2034         [[ $fcount -eq 0 ]] && skip "not enough space on OST0"
2035         [[ $fcount -gt $OSTCOUNT ]] && fcount=$OSTCOUNT
2036
2037         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
2038                          awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
2039         local OST_DEACTIVE_IDX=-1
2040         local OSC
2041         local OSTIDX
2042         local OST
2043
2044         for OSC in $MDS_OSCS; do
2045                 OST=$(osc_to_ost $OSC)
2046                 OSTIDX=$(index_from_ostuuid $OST)
2047                 if [ $OST_DEACTIVE_IDX == -1 ]; then
2048                         OST_DEACTIVE_IDX=$OSTIDX
2049                 fi
2050                 if [ $OSTIDX != $OST_DEACTIVE_IDX ]; then
2051                         echo $OSC "is Deactivated:"
2052                         do_facet $SINGLEMDS lctl --device  %$OSC deactivate
2053                 fi
2054         done
2055
2056         OSTIDX=$(index_from_ostuuid $OST)
2057         test_mkdir $DIR/$tdir
2058         $LFS setstripe -c 1 $DIR/$tdir      # 1 stripe / file
2059
2060         for OSC in $MDS_OSCS; do
2061                 OST=$(osc_to_ost $OSC)
2062                 OSTIDX=$(index_from_ostuuid $OST)
2063                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2064                         echo $OST "is degraded:"
2065                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2066                                                 obdfilter.$OST.degraded=1
2067                 fi
2068         done
2069
2070         sleep_maxage
2071         createmany -o $DIR/$tdir/$tfile $fcount
2072
2073         for OSC in $MDS_OSCS; do
2074                 OST=$(osc_to_ost $OSC)
2075                 OSTIDX=$(index_from_ostuuid $OST)
2076                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2077                         echo $OST "is recovered from degraded:"
2078                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2079                                                 obdfilter.$OST.degraded=0
2080                 else
2081                         do_facet $SINGLEMDS lctl --device %$OSC activate
2082                 fi
2083         done
2084
2085         # all osp devices get activated, hence -1 stripe count restored
2086         local stripe_count=0
2087
2088         # sleep 2*lod_qos_maxage seconds waiting for lod qos to notice osp
2089         # devices get activated.
2090         sleep_maxage
2091         $LFS setstripe -c -1 $DIR/$tfile
2092         stripe_count=$($LFS getstripe -c $DIR/$tfile)
2093         rm -f $DIR/$tfile
2094         [ $stripe_count -ne $OSTCOUNT ] &&
2095                 error "Of $OSTCOUNT OSTs, only $stripe_count is available"
2096         return 0
2097 }
2098 run_test 27y "create files while OST0 is degraded and the rest inactive"
2099
2100 check_seq_oid()
2101 {
2102         log "check file $1"
2103
2104         lmm_count=$($LFS getstripe -c $1)
2105         lmm_seq=$($LFS getstripe -v $1 | awk '/lmm_seq/ { print $2 }')
2106         lmm_oid=$($LFS getstripe -v $1 | awk '/lmm_object_id/ { print $2 }')
2107
2108         local old_ifs="$IFS"
2109         IFS=$'[:]'
2110         fid=($($LFS path2fid $1))
2111         IFS="$old_ifs"
2112
2113         log "FID seq ${fid[1]}, oid ${fid[2]} ver ${fid[3]}"
2114         log "LOV seq $lmm_seq, oid $lmm_oid, count: $lmm_count"
2115
2116         # compare lmm_seq and lu_fid->f_seq
2117         [ $lmm_seq = ${fid[1]} ] || { error "SEQ mismatch"; return 1; }
2118         # compare lmm_object_id and lu_fid->oid
2119         [ $lmm_oid = ${fid[2]} ] || { error "OID mismatch"; return 2; }
2120
2121         # check the trusted.fid attribute of the OST objects of the file
2122         local have_obdidx=false
2123         local stripe_nr=0
2124         $LFS getstripe $1 | while read obdidx oid hex seq; do
2125                 # skip lines up to and including "obdidx"
2126                 [ -z "$obdidx" ] && break
2127                 [ "$obdidx" = "obdidx" ] && have_obdidx=true && continue
2128                 $have_obdidx || continue
2129
2130                 local ost=$((obdidx + 1))
2131                 local dev=$(ostdevname $ost)
2132                 local oid_hex
2133
2134                 log "want: stripe:$stripe_nr ost:$obdidx oid:$oid/$hex seq:$seq"
2135
2136                 seq=$(echo $seq | sed -e "s/^0x//g")
2137                 if [ $seq == 0 ] || [ $(facet_fstype ost$ost) == zfs ]; then
2138                         oid_hex=$(echo $oid)
2139                 else
2140                         oid_hex=$(echo $hex | sed -e "s/^0x//g")
2141                 fi
2142                 local obj_file="O/$seq/d$((oid %32))/$oid_hex"
2143
2144                 local ff=""
2145                 #
2146                 # Don't unmount/remount the OSTs if we don't need to do that.
2147                 # LU-2577 changes filter_fid to be smaller, so debugfs needs
2148                 # update too, until that use mount/ll_decode_filter_fid/mount.
2149                 # Re-enable when debugfs will understand new filter_fid.
2150                 #
2151                 if [ $(facet_fstype ost$ost) == ldiskfs ]; then
2152                         ff=$(do_facet ost$ost "$DEBUGFS -c -R 'stat $obj_file' \
2153                                 $dev 2>/dev/null" | grep "parent=")
2154                 fi
2155                 if [ -z "$ff" ]; then
2156                         stop ost$ost
2157                         mount_fstype ost$ost
2158                         ff=$(do_facet ost$ost $LL_DECODE_FILTER_FID \
2159                                 $(facet_mntpt ost$ost)/$obj_file)
2160                         unmount_fstype ost$ost
2161                         start ost$ost $dev $OST_MOUNT_OPTS
2162                         clients_up
2163                 fi
2164
2165                 [ -z "$ff" ] && error "$obj_file: no filter_fid info"
2166
2167                 echo "$ff" | sed -e 's#.*objid=#got: objid=#'
2168
2169                 # /mnt/O/0/d23/23: objid=23 seq=0 parent=[0x200000400:0x1e:0x1]
2170                 # fid: objid=23 seq=0 parent=[0x200000400:0x1e:0x0] stripe=1
2171                 #
2172                 # fid: parent=[0x200000400:0x1e:0x0] stripe=1 stripe_count=2 \
2173                 #       stripe_size=1048576 component_id=1 component_start=0 \
2174                 #       component_end=33554432
2175                 local ff_parent=$(sed -e 's/.*parent=.//' <<<$ff)
2176                 local ff_pseq=$(cut -d: -f1 <<<$ff_parent)
2177                 local ff_poid=$(cut -d: -f2 <<<$ff_parent)
2178                 local ff_pstripe
2179                 if grep -q 'stripe=' <<<$ff; then
2180                         ff_pstripe=$(sed -e 's/.*stripe=//' -e 's/ .*//' <<<$ff)
2181                 else
2182                         # $LL_DECODE_FILTER_FID does not print "stripe="; look
2183                         # into f_ver in this case.  See comment on ff_parent.
2184                         ff_pstripe=$(cut -d: -f3 <<<$ff_parent | sed -e 's/]//')
2185                 fi
2186
2187                 # compare lmm_seq and filter_fid->ff_parent.f_seq
2188                 [ $ff_pseq = $lmm_seq ] ||
2189                         error "FF parent SEQ $ff_pseq != $lmm_seq"
2190                 # compare lmm_object_id and filter_fid->ff_parent.f_oid
2191                 [ $ff_poid = $lmm_oid ] ||
2192                         error "FF parent OID $ff_poid != $lmm_oid"
2193                 (($ff_pstripe == $stripe_nr)) ||
2194                         error "FF stripe $ff_pstripe != $stripe_nr"
2195
2196                 stripe_nr=$((stripe_nr + 1))
2197                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2198                         continue
2199                 if grep -q 'stripe_count=' <<<$ff; then
2200                         local ff_scnt=$(sed -e 's/.*stripe_count=//' \
2201                                             -e 's/ .*//' <<<$ff)
2202                         [ $lmm_count = $ff_scnt ] ||
2203                                 error "FF stripe count $lmm_count != $ff_scnt"
2204                 fi
2205         done
2206 }
2207
2208 test_27z() {
2209         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2210         remote_ost_nodsh && skip "remote OST with nodsh"
2211
2212         test_mkdir $DIR/$tdir
2213         $LFS setstripe -c 1 -i 0 -S 64k $DIR/$tdir/$tfile-1 ||
2214                 { error "setstripe -c -1 failed"; return 1; }
2215         # We need to send a write to every object to get parent FID info set.
2216         # This _should_ also work for setattr, but does not currently.
2217         # touch $DIR/$tdir/$tfile-1 ||
2218         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
2219                 { error "dd $tfile-1 failed"; return 2; }
2220         $LFS setstripe -c -1 -i $((OSTCOUNT - 1)) -S 1M $DIR/$tdir/$tfile-2 ||
2221                 { error "setstripe -c -1 failed"; return 3; }
2222         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
2223                 { error "dd $tfile-2 failed"; return 4; }
2224
2225         # make sure write RPCs have been sent to OSTs
2226         sync; sleep 5; sync
2227
2228         check_seq_oid $DIR/$tdir/$tfile-1 || return 5
2229         check_seq_oid $DIR/$tdir/$tfile-2 || return 6
2230 }
2231 run_test 27z "check SEQ/OID on the MDT and OST filesystems"
2232
2233 test_27A() { # b=19102
2234         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2235
2236         save_layout_restore_at_exit $MOUNT
2237         $LFS setstripe -c 0 -i -1 -S 0 $MOUNT
2238         wait_update $HOSTNAME "$LFS getstripe -c $MOUNT | sed 's/  *//g'" "1" 20 ||
2239                 error "stripe count $($LFS getstripe -c $MOUNT) != 1"
2240         local default_size=$($LFS getstripe -S $MOUNT)
2241         local default_offset=$($LFS getstripe -i $MOUNT)
2242         local dsize=$(do_facet $SINGLEMDS \
2243                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
2244         [ $default_size -eq $dsize ] ||
2245                 error "stripe size $default_size != $dsize"
2246         [ $default_offset -eq -1 ] ||
2247                 error "stripe offset $default_offset != -1"
2248 }
2249 run_test 27A "check filesystem-wide default LOV EA values"
2250
2251 test_27B() { # LU-2523
2252         test_mkdir $DIR/$tdir
2253         rm -f $DIR/$tdir/f0 $DIR/$tdir/f1
2254         touch $DIR/$tdir/f0
2255         # open f1 with O_LOV_DELAY_CREATE
2256         # rename f0 onto f1
2257         # call setstripe ioctl on open file descriptor for f1
2258         # close
2259         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \
2260                 $DIR/$tdir/f0
2261
2262         rm -f $DIR/$tdir/f1
2263         # open f1 with O_LOV_DELAY_CREATE
2264         # unlink f1
2265         # call setstripe ioctl on open file descriptor for f1
2266         # close
2267         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c
2268
2269         # Allow multiop to fail in imitation of NFS's busted semantics.
2270         true
2271 }
2272 run_test 27B "call setstripe on open unlinked file/rename victim"
2273
2274 # 27C family tests full striping and overstriping
2275 test_27Ca() { #LU-2871
2276         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2277
2278         declare -a ost_idx
2279         local index
2280         local found
2281         local i
2282         local j
2283
2284         test_mkdir $DIR/$tdir
2285         cd $DIR/$tdir
2286         for i in $(seq 0 $((OSTCOUNT - 1))); do
2287                 # set stripe across all OSTs starting from OST$i
2288                 $LFS setstripe -i $i -c -1 $tfile$i
2289                 # get striping information
2290                 ost_idx=($($LFS getstripe $tfile$i |
2291                          tail -n $((OSTCOUNT + 1)) | awk '{print $1}'))
2292                 echo ${ost_idx[@]}
2293
2294                 # check the layout
2295                 [ ${#ost_idx[@]} -eq $OSTCOUNT ] ||
2296                         error "${#ost_idx[@]} != $OSTCOUNT"
2297
2298                 for index in $(seq 0 $((OSTCOUNT - 1))); do
2299                         found=0
2300                         for j in $(echo ${ost_idx[@]}); do
2301                                 if [ $index -eq $j ]; then
2302                                         found=1
2303                                         break
2304                                 fi
2305                         done
2306                         [ $found = 1 ] ||
2307                                 error "Can not find $index in ${ost_idx[@]}"
2308                 done
2309         done
2310 }
2311 run_test 27Ca "check full striping across all OSTs"
2312
2313 test_27Cb() {
2314         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2315                 skip "server does not support overstriping"
2316         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2317                 skip_env "too many osts, skipping"
2318
2319         test_mkdir -p $DIR/$tdir
2320         local setcount=$(($OSTCOUNT * 2))
2321         [ $setcount -ge 160 ] || large_xattr_enabled ||
2322                 skip_env "ea_inode feature disabled"
2323
2324         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2325                 error "setstripe failed"
2326
2327         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2328         [ $count -eq $setcount ] ||
2329                 error "stripe count $count, should be $setcount"
2330
2331         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2332                 error "overstriped should be set in pattern"
2333
2334         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2335                 error "dd failed"
2336 }
2337 run_test 27Cb "more stripes than OSTs with -C"
2338
2339 test_27Cc() {
2340         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2341                 skip "server does not support overstriping"
2342         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2343
2344         test_mkdir -p $DIR/$tdir
2345         local setcount=$(($OSTCOUNT - 1))
2346
2347         [ $setcount -ge 160 ] || large_xattr_enabled ||
2348                 skip_env "ea_inode feature disabled"
2349
2350         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2351                 error "setstripe failed"
2352
2353         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2354         [ $count -eq $setcount ] ||
2355                 error "stripe count $count, should be $setcount"
2356
2357         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" &&
2358                 error "overstriped should not be set in pattern"
2359
2360         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2361                 error "dd failed"
2362 }
2363 run_test 27Cc "fewer stripes than OSTs does not set overstriping"
2364
2365 test_27Cd() {
2366         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2367                 skip "server does not support overstriping"
2368         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2369         large_xattr_enabled || skip_env "ea_inode feature disabled"
2370
2371         test_mkdir -p $DIR/$tdir
2372         local setcount=$LOV_MAX_STRIPE_COUNT
2373
2374         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2375                 error "setstripe failed"
2376
2377         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2378         [ $count -eq $setcount ] ||
2379                 error "stripe count $count, should be $setcount"
2380
2381         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2382                 error "overstriped should be set in pattern"
2383
2384         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2385                 error "dd failed"
2386
2387         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2388 }
2389 run_test 27Cd "test maximum stripe count"
2390
2391 test_27Ce() {
2392         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2393                 skip "server does not support overstriping"
2394         test_mkdir -p $DIR/$tdir
2395
2396         pool_add $TESTNAME || error "Pool creation failed"
2397         pool_add_targets $TESTNAME 0 || error "pool_add_targets failed"
2398
2399         local setcount=8
2400
2401         $LFS setstripe  -C $setcount -p "$TESTNAME" $DIR/$tdir/$tfile ||
2402                 error "setstripe failed"
2403
2404         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2405         [ $count -eq $setcount ] ||
2406                 error "stripe count $count, should be $setcount"
2407
2408         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2409                 error "overstriped should be set in pattern"
2410
2411         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2412                 error "dd failed"
2413
2414         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2415 }
2416 run_test 27Ce "test pool with overstriping"
2417
2418 test_27Cf() {
2419         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2420                 skip "server does not support overstriping"
2421         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2422                 skip_env "too many osts, skipping"
2423
2424         test_mkdir -p $DIR/$tdir
2425
2426         local setcount=$(($OSTCOUNT * 2))
2427         [ $setcount -ge 160 ] || large_xattr_enabled ||
2428                 skip_env "ea_inode feature disabled"
2429
2430         $LFS setstripe  -C $setcount $DIR/$tdir/ ||
2431                 error "setstripe failed"
2432
2433         echo 1 > $DIR/$tdir/$tfile
2434
2435         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2436         [ $count -eq $setcount ] ||
2437                 error "stripe count $count, should be $setcount"
2438
2439         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2440                 error "overstriped should be set in pattern"
2441
2442         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2443                 error "dd failed"
2444
2445         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2446 }
2447 run_test 27Cf "test default inheritance with overstriping"
2448
2449 test_27D() {
2450         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2451         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2452         remote_mds_nodsh && skip "remote MDS with nodsh"
2453
2454         local POOL=${POOL:-testpool}
2455         local first_ost=0
2456         local last_ost=$(($OSTCOUNT - 1))
2457         local ost_step=1
2458         local ost_list=$(seq $first_ost $ost_step $last_ost)
2459         local ost_range="$first_ost $last_ost $ost_step"
2460
2461         if ! combined_mgs_mds ; then
2462                 mount_mgs_client
2463         fi
2464
2465         test_mkdir $DIR/$tdir
2466         pool_add $POOL || error "pool_add failed"
2467         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2468
2469         local skip27D
2470         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2471                 skip27D+="-s 29"
2472         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2473                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2474                         skip27D+=" -s 30,31"
2475         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code $SEL_VER) ] &&
2476                 skip27D+="-s 32"
2477         [[ ! $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ||
2478           $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2479                 skip27D+=" -s 32,33"
2480         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2481                 error "llapi_layout_test failed"
2482
2483         destroy_test_pools || error "destroy test pools failed"
2484
2485         if ! combined_mgs_mds ; then
2486                 umount_mgs_client
2487         fi
2488 }
2489 run_test 27D "validate llapi_layout API"
2490
2491 # Verify that default_easize is increased from its initial value after
2492 # accessing a widely striped file.
2493 test_27E() {
2494         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2495         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2496                 skip "client does not have LU-3338 fix"
2497
2498         # 72 bytes is the minimum space required to store striping
2499         # information for a file striped across one OST:
2500         # (sizeof(struct lov_user_md_v3) +
2501         #  sizeof(struct lov_user_ost_data_v1))
2502         local min_easize=72
2503         $LCTL set_param -n llite.*.default_easize $min_easize ||
2504                 error "lctl set_param failed"
2505         local easize=$($LCTL get_param -n llite.*.default_easize)
2506
2507         [ $easize -eq $min_easize ] ||
2508                 error "failed to set default_easize"
2509
2510         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2511                 error "setstripe failed"
2512         # In order to ensure stat() call actually talks to MDS we need to
2513         # do something drastic to this file to shake off all lock, e.g.
2514         # rename it (kills lookup lock forcing cache cleaning)
2515         mv $DIR/$tfile $DIR/${tfile}-1
2516         ls -l $DIR/${tfile}-1
2517         rm $DIR/${tfile}-1
2518
2519         easize=$($LCTL get_param -n llite.*.default_easize)
2520
2521         [ $easize -gt $min_easize ] ||
2522                 error "default_easize not updated"
2523 }
2524 run_test 27E "check that default extended attribute size properly increases"
2525
2526 test_27F() { # LU-5346/LU-7975
2527         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2528         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2529         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2530                 skip "Need MDS version at least 2.8.51"
2531         remote_ost_nodsh && skip "remote OST with nodsh"
2532
2533         test_mkdir $DIR/$tdir
2534         rm -f $DIR/$tdir/f0
2535         $LFS setstripe -c 2 $DIR/$tdir
2536
2537         # stop all OSTs to reproduce situation for LU-7975 ticket
2538         for num in $(seq $OSTCOUNT); do
2539                 stop ost$num
2540         done
2541
2542         # open/create f0 with O_LOV_DELAY_CREATE
2543         # truncate f0 to a non-0 size
2544         # close
2545         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2546
2547         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2548         # open/write it again to force delayed layout creation
2549         cat /etc/hosts > $DIR/$tdir/f0 &
2550         catpid=$!
2551
2552         # restart OSTs
2553         for num in $(seq $OSTCOUNT); do
2554                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2555                         error "ost$num failed to start"
2556         done
2557
2558         wait $catpid || error "cat failed"
2559
2560         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2561         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2562                 error "wrong stripecount"
2563
2564 }
2565 run_test 27F "Client resend delayed layout creation with non-zero size"
2566
2567 test_27G() { #LU-10629
2568         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2569                 skip "Need MDS version at least 2.11.51"
2570         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2571         remote_mds_nodsh && skip "remote MDS with nodsh"
2572         local POOL=${POOL:-testpool}
2573         local ostrange="0 0 1"
2574
2575         test_mkdir $DIR/$tdir
2576         pool_add $POOL || error "pool_add failed"
2577         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2578         $LFS setstripe -p $POOL $DIR/$tdir
2579
2580         local pool=$($LFS getstripe -p $DIR/$tdir)
2581
2582         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2583
2584         $LFS setstripe -d $DIR/$tdir
2585
2586         pool=$($LFS getstripe -p $DIR/$tdir)
2587
2588         rmdir $DIR/$tdir
2589
2590         [ -z "$pool" ] || error "'$pool' is not empty"
2591 }
2592 run_test 27G "Clear OST pool from stripe"
2593
2594 test_27H() {
2595         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2596                 skip "Need MDS version newer than 2.11.54"
2597         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2598         test_mkdir $DIR/$tdir
2599         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2600         touch $DIR/$tdir/$tfile
2601         $LFS getstripe -c $DIR/$tdir/$tfile
2602         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2603                 error "two-stripe file doesn't have two stripes"
2604
2605         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2606         $LFS getstripe -y $DIR/$tdir/$tfile
2607         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2608              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2609                 error "expected l_ost_idx: [02]$ not matched"
2610
2611         # make sure ost list has been cleared
2612         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2613         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2614                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2615         touch $DIR/$tdir/f3
2616         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2617 }
2618 run_test 27H "Set specific OSTs stripe"
2619
2620 test_27I() {
2621         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2622         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2623         local pool=$TESTNAME
2624         local ostrange="1 1 1"
2625
2626         save_layout_restore_at_exit $MOUNT
2627         $LFS setstripe -c 2 -i 0 $MOUNT
2628         pool_add $pool || error "pool_add failed"
2629         pool_add_targets $pool $ostrange || "pool_add_targets failed"
2630         test_mkdir $DIR/$tdir
2631         $LFS setstripe -p $pool $DIR/$tdir
2632         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2633         $LFS getstripe $DIR/$tdir/$tfile
2634 }
2635 run_test 27I "check that root dir striping does not break parent dir one"
2636
2637 test_27J() {
2638         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.51) ]] &&
2639                 skip "Need MDS version newer than 2.12.51"
2640
2641         test_mkdir $DIR/$tdir
2642         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2643         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2644
2645         # create foreign file (raw way)
2646         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2647                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2648
2649         # verify foreign file (raw way)
2650         parse_foreign_file -f $DIR/$tdir/$tfile |
2651                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2652                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2653         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2654                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2655         parse_foreign_file -f $DIR/$tdir/$tfile |
2656                 grep "lov_foreign_size: 73" ||
2657                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2658         parse_foreign_file -f $DIR/$tdir/$tfile |
2659                 grep "lov_foreign_type: 1" ||
2660                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2661         parse_foreign_file -f $DIR/$tdir/$tfile |
2662                 grep "lov_foreign_flags: 0x0000DA08" ||
2663                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2664         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2665                 grep "lov_foreign_value: 0x" |
2666                 sed -e 's/lov_foreign_value: 0x//')
2667         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2668         [[ $lov = ${lov2// /} ]] ||
2669                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2670
2671         # create foreign file (lfs + API)
2672         $LFS setstripe --foreign=daos --flags 0xda08 \
2673                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2674                 error "$DIR/$tdir/${tfile}2: create failed"
2675
2676         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2677                 grep "lfm_magic:.*0x0BD70BD0" ||
2678                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2679         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2680         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2681                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2682         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*daos" ||
2683                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2684         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2685                 grep "lfm_flags:.*0x0000DA08" ||
2686                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2687         $LFS getstripe $DIR/$tdir/${tfile}2 |
2688                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2689                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2690
2691         # modify striping should fail
2692         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2693                 error "$DIR/$tdir/$tfile: setstripe should fail"
2694         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2695                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2696
2697         # R/W should fail
2698         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2699         cat $DIR/$tdir/${tfile}2 &&
2700                 error "$DIR/$tdir/${tfile}2: read should fail"
2701         cat /etc/passwd > $DIR/$tdir/$tfile &&
2702                 error "$DIR/$tdir/$tfile: write should fail"
2703         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2704                 error "$DIR/$tdir/${tfile}2: write should fail"
2705
2706         # chmod should work
2707         chmod 222 $DIR/$tdir/$tfile ||
2708                 error "$DIR/$tdir/$tfile: chmod failed"
2709         chmod 222 $DIR/$tdir/${tfile}2 ||
2710                 error "$DIR/$tdir/${tfile}2: chmod failed"
2711
2712         # chown should work
2713         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2714                 error "$DIR/$tdir/$tfile: chown failed"
2715         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2716                 error "$DIR/$tdir/${tfile}2: chown failed"
2717
2718         # rename should work
2719         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2720                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2721         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2722                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2723
2724         #remove foreign file
2725         rm $DIR/$tdir/${tfile}.new ||
2726                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2727         rm $DIR/$tdir/${tfile}2.new ||
2728                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2729 }
2730 run_test 27J "basic ops on file with foreign LOV"
2731
2732 test_27K() {
2733         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.49) ]] &&
2734                 skip "Need MDS version newer than 2.12.49"
2735
2736         test_mkdir $DIR/$tdir
2737         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2738         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2739
2740         # create foreign dir (raw way)
2741         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2742                 error "create_foreign_dir FAILED"
2743
2744         # verify foreign dir (raw way)
2745         parse_foreign_dir -d $DIR/$tdir/$tdir |
2746                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2747                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2748         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2749                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2750         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2751                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2752         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_flags: 0$" ||
2753                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2754         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2755                 grep "lmv_foreign_value: 0x" |
2756                 sed 's/lmv_foreign_value: 0x//')
2757         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2758                 sed 's/ //g')
2759         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
2760
2761         # create foreign dir (lfs + API)
2762         $LFS mkdir --foreign=daos --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
2763                 $DIR/$tdir/${tdir}2 ||
2764                 error "$DIR/$tdir/${tdir}2: create failed"
2765
2766         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2767                 grep "lfm_magic:.*0x0CD50CD0" ||
2768                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
2769         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2770         # - sizeof(lfm_type) - sizeof(lfm_flags)
2771         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
2772                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
2773         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*daos" ||
2774                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
2775         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2776                 grep "lfm_flags:.*0x0000DA05" ||
2777                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
2778         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
2779                 grep "lfm_value.*${uuid1}@${uuid2}" ||
2780                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
2781
2782         # file create in dir should fail
2783         touch $DIR/$tdir/$tdir/$tfile && "$DIR/$tdir: file create should fail"
2784         touch $DIR/$tdir/${tdir}2/$tfile &&
2785                 "$DIR/${tdir}2: file create should fail"
2786
2787         # chmod should work
2788         chmod 777 $DIR/$tdir/$tdir ||
2789                 error "$DIR/$tdir: chmod failed"
2790         chmod 777 $DIR/$tdir/${tdir}2 ||
2791                 error "$DIR/${tdir}2: chmod failed"
2792
2793         # chown should work
2794         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
2795                 error "$DIR/$tdir: chown failed"
2796         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
2797                 error "$DIR/${tdir}2: chown failed"
2798
2799         # rename should work
2800         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
2801                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
2802         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
2803                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
2804
2805         #remove foreign dir
2806         rmdir $DIR/$tdir/${tdir}.new ||
2807                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
2808         rmdir $DIR/$tdir/${tdir}2.new ||
2809                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
2810 }
2811 run_test 27K "basic ops on dir with foreign LMV"
2812
2813 test_27L() {
2814         remote_mds_nodsh && skip "remote MDS with nodsh"
2815
2816         local POOL=${POOL:-$TESTNAME}
2817
2818         if ! combined_mgs_mds ; then
2819                 mount_mgs_client
2820                 trap umount_mgs_client EXIT
2821         fi
2822
2823         pool_add $POOL || error "pool_add failed"
2824
2825         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
2826                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
2827                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
2828 }
2829 run_test 27L "lfs pool_list gives correct pool name"
2830
2831 # createtest also checks that device nodes are created and
2832 # then visible correctly (#2091)
2833 test_28() { # bug 2091
2834         test_mkdir $DIR/d28
2835         $CREATETEST $DIR/d28/ct || error "createtest failed"
2836 }
2837 run_test 28 "create/mknod/mkdir with bad file types ============"
2838
2839 test_29() {
2840         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2841
2842         sync; sleep 1; sync # flush out any dirty pages from previous tests
2843         cancel_lru_locks
2844         test_mkdir $DIR/d29
2845         touch $DIR/d29/foo
2846         log 'first d29'
2847         ls -l $DIR/d29
2848
2849         declare -i LOCKCOUNTORIG=0
2850         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
2851                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
2852         done
2853         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
2854
2855         declare -i LOCKUNUSEDCOUNTORIG=0
2856         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
2857                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
2858         done
2859
2860         log 'second d29'
2861         ls -l $DIR/d29
2862         log 'done'
2863
2864         declare -i LOCKCOUNTCURRENT=0
2865         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
2866                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
2867         done
2868
2869         declare -i LOCKUNUSEDCOUNTCURRENT=0
2870         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
2871                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
2872         done
2873
2874         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
2875                 $LCTL set_param -n ldlm.dump_namespaces ""
2876                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
2877                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
2878                 log "dumped log to $TMP/test_29.dk (bug 5793)"
2879                 return 2
2880         fi
2881         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
2882                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
2883                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
2884                 log "dumped log to $TMP/test_29.dk (bug 5793)"
2885                 return 3
2886         fi
2887 }
2888 run_test 29 "IT_GETATTR regression  ============================"
2889
2890 test_30a() { # was test_30
2891         cp $(which ls) $DIR || cp /bin/ls $DIR
2892         $DIR/ls / || error "Can't execute binary from lustre"
2893         rm $DIR/ls
2894 }
2895 run_test 30a "execute binary from Lustre (execve) =============="
2896
2897 test_30b() {
2898         cp `which ls` $DIR || cp /bin/ls $DIR
2899         chmod go+rx $DIR/ls
2900         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
2901         rm $DIR/ls
2902 }
2903 run_test 30b "execute binary from Lustre as non-root ==========="
2904
2905 test_30c() { # b=22376
2906         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2907
2908         cp `which ls` $DIR || cp /bin/ls $DIR
2909         chmod a-rw $DIR/ls
2910         cancel_lru_locks mdc
2911         cancel_lru_locks osc
2912         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
2913         rm -f $DIR/ls
2914 }
2915 run_test 30c "execute binary from Lustre without read perms ===="
2916
2917 test_31a() {
2918         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
2919         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
2920 }
2921 run_test 31a "open-unlink file =================================="
2922
2923 test_31b() {
2924         touch $DIR/f31 || error "touch $DIR/f31 failed"
2925         ln $DIR/f31 $DIR/f31b || error "ln failed"
2926         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
2927         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
2928 }
2929 run_test 31b "unlink file with multiple links while open ======="
2930
2931 test_31c() {
2932         touch $DIR/f31 || error "touch $DIR/f31 failed"
2933         ln $DIR/f31 $DIR/f31c || error "ln failed"
2934         multiop_bg_pause $DIR/f31 O_uc ||
2935                 error "multiop_bg_pause for $DIR/f31 failed"
2936         MULTIPID=$!
2937         $MULTIOP $DIR/f31c Ouc
2938         kill -USR1 $MULTIPID
2939         wait $MULTIPID
2940 }
2941 run_test 31c "open-unlink file with multiple links ============="
2942
2943 test_31d() {
2944         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
2945         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
2946 }
2947 run_test 31d "remove of open directory ========================="
2948
2949 test_31e() { # bug 2904
2950         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
2951 }
2952 run_test 31e "remove of open non-empty directory ==============="
2953
2954 test_31f() { # bug 4554
2955         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2956
2957         set -vx
2958         test_mkdir $DIR/d31f
2959         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
2960         cp /etc/hosts $DIR/d31f
2961         ls -l $DIR/d31f
2962         $LFS getstripe $DIR/d31f/hosts
2963         multiop_bg_pause $DIR/d31f D_c || return 1
2964         MULTIPID=$!
2965
2966         rm -rv $DIR/d31f || error "first of $DIR/d31f"
2967         test_mkdir $DIR/d31f
2968         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
2969         cp /etc/hosts $DIR/d31f
2970         ls -l $DIR/d31f
2971         $LFS getstripe $DIR/d31f/hosts
2972         multiop_bg_pause $DIR/d31f D_c || return 1
2973         MULTIPID2=$!
2974
2975         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
2976         wait $MULTIPID || error "first opendir $MULTIPID failed"
2977
2978         sleep 6
2979
2980         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
2981         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
2982         set +vx
2983 }
2984 run_test 31f "remove of open directory with open-unlink file ==="
2985
2986 test_31g() {
2987         echo "-- cross directory link --"
2988         test_mkdir -c1 $DIR/${tdir}ga
2989         test_mkdir -c1 $DIR/${tdir}gb
2990         touch $DIR/${tdir}ga/f
2991         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
2992         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
2993         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
2994         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
2995         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
2996 }
2997 run_test 31g "cross directory link==============="
2998
2999 test_31h() {
3000         echo "-- cross directory link --"
3001         test_mkdir -c1 $DIR/${tdir}
3002         test_mkdir -c1 $DIR/${tdir}/dir
3003         touch $DIR/${tdir}/f
3004         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3005         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3006         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3007         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3008         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3009 }
3010 run_test 31h "cross directory link under child==============="
3011
3012 test_31i() {
3013         echo "-- cross directory link --"
3014         test_mkdir -c1 $DIR/$tdir
3015         test_mkdir -c1 $DIR/$tdir/dir
3016         touch $DIR/$tdir/dir/f
3017         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3018         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3019         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3020         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3021         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3022 }
3023 run_test 31i "cross directory link under parent==============="
3024
3025 test_31j() {
3026         test_mkdir -c1 -p $DIR/$tdir
3027         test_mkdir -c1 -p $DIR/$tdir/dir1
3028         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3029         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3030         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
3031         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
3032         return 0
3033 }
3034 run_test 31j "link for directory==============="
3035
3036 test_31k() {
3037         test_mkdir -c1 -p $DIR/$tdir
3038         touch $DIR/$tdir/s
3039         touch $DIR/$tdir/exist
3040         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
3041         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
3042         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
3043         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
3044         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
3045         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
3046         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
3047         return 0
3048 }
3049 run_test 31k "link to file: the same, non-existing, dir==============="
3050
3051 test_31m() {
3052         mkdir $DIR/d31m
3053         touch $DIR/d31m/s
3054         mkdir $DIR/d31m2
3055         touch $DIR/d31m2/exist
3056         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
3057         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
3058         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
3059         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
3060         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
3061         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
3062         return 0
3063 }
3064 run_test 31m "link to file: the same, non-existing, dir==============="
3065
3066 test_31n() {
3067         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3068         nlink=$(stat --format=%h $DIR/$tfile)
3069         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3070         local fd=$(free_fd)
3071         local cmd="exec $fd<$DIR/$tfile"
3072         eval $cmd
3073         cmd="exec $fd<&-"
3074         trap "eval $cmd" EXIT
3075         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3076         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3077         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3078         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3079         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3080         eval $cmd
3081 }
3082 run_test 31n "check link count of unlinked file"
3083
3084 link_one() {
3085         local tempfile=$(mktemp $1_XXXXXX)
3086         mlink $tempfile $1 2> /dev/null &&
3087                 echo "$BASHPID: link $tempfile to $1 succeeded"
3088         munlink $tempfile
3089 }
3090
3091 test_31o() { # LU-2901
3092         test_mkdir $DIR/$tdir
3093         for LOOP in $(seq 100); do
3094                 rm -f $DIR/$tdir/$tfile*
3095                 for THREAD in $(seq 8); do
3096                         link_one $DIR/$tdir/$tfile.$LOOP &
3097                 done
3098                 wait
3099                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3100                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3101                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3102                         break || true
3103         done
3104 }
3105 run_test 31o "duplicate hard links with same filename"
3106
3107 test_31p() {
3108         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3109
3110         test_mkdir $DIR/$tdir
3111         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3112         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3113
3114         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3115                 error "open unlink test1 failed"
3116         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3117                 error "open unlink test2 failed"
3118
3119         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3120                 error "test1 still exists"
3121         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3122                 error "test2 still exists"
3123 }
3124 run_test 31p "remove of open striped directory"
3125
3126 cleanup_test32_mount() {
3127         local rc=0
3128         trap 0
3129         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3130         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3131         losetup -d $loopdev || true
3132         rm -rf $DIR/$tdir
3133         return $rc
3134 }
3135
3136 test_32a() {
3137         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3138
3139         echo "== more mountpoints and symlinks ================="
3140         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3141         trap cleanup_test32_mount EXIT
3142         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3143         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3144                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3145         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3146                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3147         cleanup_test32_mount
3148 }
3149 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3150
3151 test_32b() {
3152         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3153
3154         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3155         trap cleanup_test32_mount EXIT
3156         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3157         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3158                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3159         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3160                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3161         cleanup_test32_mount
3162 }
3163 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3164
3165 test_32c() {
3166         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3167
3168         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3169         trap cleanup_test32_mount EXIT
3170         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3171         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3172                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3173         test_mkdir -p $DIR/$tdir/d2/test_dir
3174         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3175                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3176         cleanup_test32_mount
3177 }
3178 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3179
3180 test_32d() {
3181         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3182
3183         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3184         trap cleanup_test32_mount EXIT
3185         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3186         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3187                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3188         test_mkdir -p $DIR/$tdir/d2/test_dir
3189         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3190                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3191         cleanup_test32_mount
3192 }
3193 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3194
3195 test_32e() {
3196         rm -fr $DIR/$tdir
3197         test_mkdir -p $DIR/$tdir/tmp
3198         local tmp_dir=$DIR/$tdir/tmp
3199         ln -s $DIR/$tdir $tmp_dir/symlink11
3200         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3201         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3202         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3203 }
3204 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3205
3206 test_32f() {
3207         rm -fr $DIR/$tdir
3208         test_mkdir -p $DIR/$tdir/tmp
3209         local tmp_dir=$DIR/$tdir/tmp
3210         ln -s $DIR/$tdir $tmp_dir/symlink11
3211         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3212         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3213         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3214 }
3215 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3216
3217 test_32g() {
3218         local tmp_dir=$DIR/$tdir/tmp
3219         test_mkdir -p $tmp_dir
3220         test_mkdir $DIR/${tdir}2
3221         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3222         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3223         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3224         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3225         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3226         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3227 }
3228 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3229
3230 test_32h() {
3231         rm -fr $DIR/$tdir $DIR/${tdir}2
3232         tmp_dir=$DIR/$tdir/tmp
3233         test_mkdir -p $tmp_dir
3234         test_mkdir $DIR/${tdir}2
3235         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3236         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3237         ls $tmp_dir/symlink12 || error "listing symlink12"
3238         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3239 }
3240 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3241
3242 test_32i() {
3243         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3244
3245         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3246         trap cleanup_test32_mount EXIT
3247         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3248         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3249                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3250         touch $DIR/$tdir/test_file
3251         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
3252                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
3253         cleanup_test32_mount
3254 }
3255 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
3256
3257 test_32j() {
3258         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3259
3260         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3261         trap cleanup_test32_mount EXIT
3262         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3263         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3264                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3265         touch $DIR/$tdir/test_file
3266         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
3267                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
3268         cleanup_test32_mount
3269 }
3270 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
3271
3272 test_32k() {
3273         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3274
3275         rm -fr $DIR/$tdir
3276         trap cleanup_test32_mount EXIT
3277         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3278         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3279                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3280         test_mkdir -p $DIR/$tdir/d2
3281         touch $DIR/$tdir/d2/test_file || error "touch failed"
3282         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3283                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
3284         cleanup_test32_mount
3285 }
3286 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
3287
3288 test_32l() {
3289         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3290
3291         rm -fr $DIR/$tdir
3292         trap cleanup_test32_mount EXIT
3293         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3294         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3295                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3296         test_mkdir -p $DIR/$tdir/d2
3297         touch $DIR/$tdir/d2/test_file || error "touch failed"
3298         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3299                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
3300         cleanup_test32_mount
3301 }
3302 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
3303
3304 test_32m() {
3305         rm -fr $DIR/d32m
3306         test_mkdir -p $DIR/d32m/tmp
3307         TMP_DIR=$DIR/d32m/tmp
3308         ln -s $DIR $TMP_DIR/symlink11
3309         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3310         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
3311                 error "symlink11 not a link"
3312         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
3313                 error "symlink01 not a link"
3314 }
3315 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
3316
3317 test_32n() {
3318         rm -fr $DIR/d32n
3319         test_mkdir -p $DIR/d32n/tmp
3320         TMP_DIR=$DIR/d32n/tmp
3321         ln -s $DIR $TMP_DIR/symlink11
3322         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3323         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
3324         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
3325 }
3326 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
3327
3328 test_32o() {
3329         touch $DIR/$tfile
3330         test_mkdir -p $DIR/d32o/tmp
3331         TMP_DIR=$DIR/d32o/tmp
3332         ln -s $DIR/$tfile $TMP_DIR/symlink12
3333         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3334         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
3335                 error "symlink12 not a link"
3336         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
3337         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
3338                 error "$DIR/d32o/tmp/symlink12 not file type"
3339         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
3340                 error "$DIR/d32o/symlink02 not file type"
3341 }
3342 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
3343
3344 test_32p() {
3345         log 32p_1
3346         rm -fr $DIR/d32p
3347         log 32p_2
3348         rm -f $DIR/$tfile
3349         log 32p_3
3350         touch $DIR/$tfile
3351         log 32p_4
3352         test_mkdir -p $DIR/d32p/tmp
3353         log 32p_5
3354         TMP_DIR=$DIR/d32p/tmp
3355         log 32p_6
3356         ln -s $DIR/$tfile $TMP_DIR/symlink12
3357         log 32p_7
3358         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3359         log 32p_8
3360         cat $DIR/d32p/tmp/symlink12 ||
3361                 error "Can't open $DIR/d32p/tmp/symlink12"
3362         log 32p_9
3363         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
3364         log 32p_10
3365 }
3366 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
3367
3368 test_32q() {
3369         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3370
3371         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3372         trap cleanup_test32_mount EXIT
3373         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3374         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3375         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3376                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3377         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
3378         cleanup_test32_mount
3379 }
3380 run_test 32q "stat follows mountpoints in Lustre (should return error)"
3381
3382 test_32r() {
3383         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3384
3385         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3386         trap cleanup_test32_mount EXIT
3387         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3388         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3389         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3390                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3391         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
3392         cleanup_test32_mount
3393 }
3394 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
3395
3396 test_33aa() {
3397         rm -f $DIR/$tfile
3398         touch $DIR/$tfile
3399         chmod 444 $DIR/$tfile
3400         chown $RUNAS_ID $DIR/$tfile
3401         log 33_1
3402         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3403         log 33_2
3404 }
3405 run_test 33aa "write file with mode 444 (should return error)"
3406
3407 test_33a() {
3408         rm -fr $DIR/$tdir
3409         test_mkdir $DIR/$tdir
3410         chown $RUNAS_ID $DIR/$tdir
3411         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
3412                 error "$RUNAS create $tdir/$tfile failed"
3413         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
3414                 error "open RDWR" || true
3415 }
3416 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
3417
3418 test_33b() {
3419         rm -fr $DIR/$tdir
3420         test_mkdir $DIR/$tdir
3421         chown $RUNAS_ID $DIR/$tdir
3422         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
3423 }
3424 run_test 33b "test open file with malformed flags (No panic)"
3425
3426 test_33c() {
3427         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3428         remote_ost_nodsh && skip "remote OST with nodsh"
3429
3430         local ostnum
3431         local ostname
3432         local write_bytes
3433         local all_zeros
3434
3435         all_zeros=:
3436         rm -fr $DIR/$tdir
3437         test_mkdir $DIR/$tdir
3438         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
3439
3440         sync
3441         for ostnum in $(seq $OSTCOUNT); do
3442                 # test-framework's OST numbering is one-based, while Lustre's
3443                 # is zero-based
3444                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3445                 # Parsing llobdstat's output sucks; we could grep the /proc
3446                 # path, but that's likely to not be as portable as using the
3447                 # llobdstat utility.  So we parse lctl output instead.
3448                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3449                         obdfilter/$ostname/stats |
3450                         awk '/^write_bytes/ {print $7}' )
3451                 echo "baseline_write_bytes@$OSTnum/$ostname=$write_bytes"
3452                 if (( ${write_bytes:-0} > 0 ))
3453                 then
3454                         all_zeros=false
3455                         break;
3456                 fi
3457         done
3458
3459         $all_zeros || return 0
3460
3461         # Write four bytes
3462         echo foo > $DIR/$tdir/bar
3463         # Really write them
3464         sync
3465
3466         # Total up write_bytes after writing.  We'd better find non-zeros.
3467         for ostnum in $(seq $OSTCOUNT); do
3468                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3469                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3470                         obdfilter/$ostname/stats |
3471                         awk '/^write_bytes/ {print $7}' )
3472                 echo "write_bytes@$OSTnum/$ostname=$write_bytes"
3473                 if (( ${write_bytes:-0} > 0 ))
3474                 then
3475                         all_zeros=false
3476                         break;
3477                 fi
3478         done
3479
3480         if $all_zeros
3481         then
3482                 for ostnum in $(seq $OSTCOUNT); do
3483                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3484                         echo "Check that write_bytes is present in obdfilter/*/stats:"
3485                         do_facet ost$ostnum lctl get_param -n \
3486                                 obdfilter/$ostname/stats
3487                 done
3488                 error "OST not keeping write_bytes stats (b22312)"
3489         fi
3490 }
3491 run_test 33c "test llobdstat and write_bytes"
3492
3493 test_33d() {
3494         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
3495         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3496
3497         local MDTIDX=1
3498         local remote_dir=$DIR/$tdir/remote_dir
3499
3500         test_mkdir $DIR/$tdir
3501         $LFS mkdir -i $MDTIDX $remote_dir ||
3502                 error "create remote directory failed"
3503
3504         touch $remote_dir/$tfile
3505         chmod 444 $remote_dir/$tfile
3506         chown $RUNAS_ID $remote_dir/$tfile
3507
3508         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3509
3510         chown $RUNAS_ID $remote_dir
3511         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
3512                                         error "create" || true
3513         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
3514                                     error "open RDWR" || true
3515         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
3516 }
3517 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
3518
3519 test_33e() {
3520         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3521
3522         mkdir $DIR/$tdir
3523
3524         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3525         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3526         mkdir $DIR/$tdir/local_dir
3527
3528         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3529         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3530         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3531
3532         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3533                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
3534
3535         rmdir $DIR/$tdir/* || error "rmdir failed"
3536
3537         umask 777
3538         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3539         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3540         mkdir $DIR/$tdir/local_dir
3541
3542         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3543         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3544         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3545
3546         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3547                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
3548
3549         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
3550
3551         umask 000
3552         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3553         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3554         mkdir $DIR/$tdir/local_dir
3555
3556         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3557         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3558         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3559
3560         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3561                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
3562 }
3563 run_test 33e "mkdir and striped directory should have same mode"
3564
3565 cleanup_33f() {
3566         trap 0
3567         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
3568 }
3569
3570 test_33f() {
3571         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3572         remote_mds_nodsh && skip "remote MDS with nodsh"
3573
3574         mkdir $DIR/$tdir
3575         chmod go+rwx $DIR/$tdir
3576         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
3577         trap cleanup_33f EXIT
3578
3579         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
3580                 error "cannot create striped directory"
3581
3582         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
3583                 error "cannot create files in striped directory"
3584
3585         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
3586                 error "cannot remove files in striped directory"
3587
3588         $RUNAS rmdir $DIR/$tdir/striped_dir ||
3589                 error "cannot remove striped directory"
3590
3591         cleanup_33f
3592 }
3593 run_test 33f "nonroot user can create, access, and remove a striped directory"
3594
3595 test_33g() {
3596         mkdir -p $DIR/$tdir/dir2
3597
3598         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
3599         echo $err
3600         [[ $err =~ "exists" ]] || error "Not exists error"
3601 }
3602 run_test 33g "nonroot user create already existing root created file"
3603
3604 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
3605 test_34a() {
3606         rm -f $DIR/f34
3607         $MCREATE $DIR/f34 || error "mcreate failed"
3608         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3609                 error "getstripe failed"
3610         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
3611         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3612                 error "getstripe failed"
3613         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3614                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3615 }
3616 run_test 34a "truncate file that has not been opened ==========="
3617
3618 test_34b() {
3619         [ ! -f $DIR/f34 ] && test_34a
3620         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3621                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3622         $OPENFILE -f O_RDONLY $DIR/f34
3623         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3624                 error "getstripe failed"
3625         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3626                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3627 }
3628 run_test 34b "O_RDONLY opening file doesn't create objects ====="
3629
3630 test_34c() {
3631         [ ! -f $DIR/f34 ] && test_34a
3632         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3633                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3634         $OPENFILE -f O_RDWR $DIR/f34
3635         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
3636                 error "$LFS getstripe failed"
3637         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3638                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3639 }
3640 run_test 34c "O_RDWR opening file-with-size works =============="
3641
3642 test_34d() {
3643         [ ! -f $DIR/f34 ] && test_34a
3644         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
3645                 error "dd failed"
3646         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3647                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3648         rm $DIR/f34
3649 }
3650 run_test 34d "write to sparse file ============================="
3651
3652 test_34e() {
3653         rm -f $DIR/f34e
3654         $MCREATE $DIR/f34e || error "mcreate failed"
3655         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
3656         $CHECKSTAT -s 1000 $DIR/f34e ||
3657                 error "Size of $DIR/f34e not equal to 1000 bytes"
3658         $OPENFILE -f O_RDWR $DIR/f34e
3659         $CHECKSTAT -s 1000 $DIR/f34e ||
3660                 error "Size of $DIR/f34e not equal to 1000 bytes"
3661 }
3662 run_test 34e "create objects, some with size and some without =="
3663
3664 test_34f() { # bug 6242, 6243
3665         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3666
3667         SIZE34F=48000
3668         rm -f $DIR/f34f
3669         $MCREATE $DIR/f34f || error "mcreate failed"
3670         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
3671         dd if=$DIR/f34f of=$TMP/f34f
3672         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
3673         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
3674         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
3675         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
3676         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
3677 }
3678 run_test 34f "read from a file with no objects until EOF ======="
3679
3680 test_34g() {
3681         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3682
3683         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
3684                 error "dd failed"
3685         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
3686         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
3687                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
3688         cancel_lru_locks osc
3689         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
3690                 error "wrong size after lock cancel"
3691
3692         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
3693         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
3694                 error "expanding truncate failed"
3695         cancel_lru_locks osc
3696         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
3697                 error "wrong expanded size after lock cancel"
3698 }
3699 run_test 34g "truncate long file ==============================="
3700
3701 test_34h() {
3702         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3703
3704         local gid=10
3705         local sz=1000
3706
3707         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
3708         sync # Flush the cache so that multiop below does not block on cache
3709              # flush when getting the group lock
3710         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
3711         MULTIPID=$!
3712
3713         # Since just timed wait is not good enough, let's do a sync write
3714         # that way we are sure enough time for a roundtrip + processing
3715         # passed + 2 seconds of extra margin.
3716         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
3717         rm $DIR/${tfile}-1
3718         sleep 2
3719
3720         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
3721                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
3722                 kill -9 $MULTIPID
3723         fi
3724         wait $MULTIPID
3725         local nsz=`stat -c %s $DIR/$tfile`
3726         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
3727 }
3728 run_test 34h "ftruncate file under grouplock should not block"
3729
3730 test_35a() {
3731         cp /bin/sh $DIR/f35a
3732         chmod 444 $DIR/f35a
3733         chown $RUNAS_ID $DIR/f35a
3734         $RUNAS $DIR/f35a && error || true
3735         rm $DIR/f35a
3736 }
3737 run_test 35a "exec file with mode 444 (should return and not leak)"
3738
3739 test_36a() {
3740         rm -f $DIR/f36
3741         utime $DIR/f36 || error "utime failed for MDS"
3742 }
3743 run_test 36a "MDS utime check (mknod, utime)"
3744
3745 test_36b() {
3746         echo "" > $DIR/f36
3747         utime $DIR/f36 || error "utime failed for OST"
3748 }
3749 run_test 36b "OST utime check (open, utime)"
3750
3751 test_36c() {
3752         rm -f $DIR/d36/f36
3753         test_mkdir $DIR/d36
3754         chown $RUNAS_ID $DIR/d36
3755         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
3756 }
3757 run_test 36c "non-root MDS utime check (mknod, utime)"
3758
3759 test_36d() {
3760         [ ! -d $DIR/d36 ] && test_36c
3761         echo "" > $DIR/d36/f36
3762         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
3763 }
3764 run_test 36d "non-root OST utime check (open, utime)"
3765
3766 test_36e() {
3767         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
3768
3769         test_mkdir $DIR/$tdir
3770         touch $DIR/$tdir/$tfile
3771         $RUNAS utime $DIR/$tdir/$tfile &&
3772                 error "utime worked, expected failure" || true
3773 }
3774 run_test 36e "utime on non-owned file (should return error)"
3775
3776 subr_36fh() {
3777         local fl="$1"
3778         local LANG_SAVE=$LANG
3779         local LC_LANG_SAVE=$LC_LANG
3780         export LANG=C LC_LANG=C # for date language
3781
3782         DATESTR="Dec 20  2000"
3783         test_mkdir $DIR/$tdir
3784         lctl set_param fail_loc=$fl
3785         date; date +%s
3786         cp /etc/hosts $DIR/$tdir/$tfile
3787         sync & # write RPC generated with "current" inode timestamp, but delayed
3788         sleep 1
3789         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
3790         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
3791         cancel_lru_locks $OSC
3792         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
3793         date; date +%s
3794         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
3795                 echo "BEFORE: $LS_BEFORE" && \
3796                 echo "AFTER : $LS_AFTER" && \
3797                 echo "WANT  : $DATESTR" && \
3798                 error "$DIR/$tdir/$tfile timestamps changed" || true
3799
3800         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
3801 }
3802
3803 test_36f() {
3804         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3805
3806         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
3807         subr_36fh "0x80000214"
3808 }
3809 run_test 36f "utime on file racing with OST BRW write =========="
3810
3811 test_36g() {
3812         remote_ost_nodsh && skip "remote OST with nodsh"
3813         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3814         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
3815                 skip "Need MDS version at least 2.12.51"
3816
3817         local fmd_max_age
3818         local fmd
3819         local facet="ost1"
3820         local tgt="obdfilter"
3821
3822         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
3823
3824         test_mkdir $DIR/$tdir
3825         fmd_max_age=$(do_facet $facet \
3826                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
3827                 head -n 1")
3828
3829         echo "FMD max age: ${fmd_max_age}s"
3830         touch $DIR/$tdir/$tfile
3831         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
3832                 gawk '{cnt=cnt+$1}  END{print cnt}')
3833         echo "FMD before: $fmd"
3834         [[ $fmd == 0 ]] &&
3835                 error "FMD wasn't create by touch"
3836         sleep $((fmd_max_age + 12))
3837         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
3838                 gawk '{cnt=cnt+$1}  END{print cnt}')
3839         echo "FMD after: $fmd"
3840         [[ $fmd == 0 ]] ||
3841                 error "FMD wasn't expired by ping"
3842 }
3843 run_test 36g "FMD cache expiry ====================="
3844
3845 test_36h() {
3846         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3847
3848         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
3849         subr_36fh "0x80000227"
3850 }
3851 run_test 36h "utime on file racing with OST BRW write =========="
3852
3853 test_36i() {
3854         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3855
3856         test_mkdir $DIR/$tdir
3857         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
3858
3859         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
3860         local new_mtime=$((mtime + 200))
3861
3862         #change Modify time of striped dir
3863         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
3864                         error "change mtime failed"
3865
3866         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
3867
3868         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
3869 }
3870 run_test 36i "change mtime on striped directory"
3871
3872 # test_37 - duplicate with tests 32q 32r
3873
3874 test_38() {
3875         local file=$DIR/$tfile
3876         touch $file
3877         openfile -f O_DIRECTORY $file
3878         local RC=$?
3879         local ENOTDIR=20
3880         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
3881         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
3882 }
3883 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
3884
3885 test_39a() { # was test_39
3886         touch $DIR/$tfile
3887         touch $DIR/${tfile}2
3888 #       ls -l  $DIR/$tfile $DIR/${tfile}2
3889 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
3890 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
3891         sleep 2
3892         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
3893         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
3894                 echo "mtime"
3895                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
3896                 echo "atime"
3897                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
3898                 echo "ctime"
3899                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
3900                 error "O_TRUNC didn't change timestamps"
3901         fi
3902 }
3903 run_test 39a "mtime changed on create"
3904
3905 test_39b() {
3906         test_mkdir -c1 $DIR/$tdir
3907         cp -p /etc/passwd $DIR/$tdir/fopen
3908         cp -p /etc/passwd $DIR/$tdir/flink
3909         cp -p /etc/passwd $DIR/$tdir/funlink
3910         cp -p /etc/passwd $DIR/$tdir/frename
3911         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
3912
3913         sleep 1
3914         echo "aaaaaa" >> $DIR/$tdir/fopen
3915         echo "aaaaaa" >> $DIR/$tdir/flink
3916         echo "aaaaaa" >> $DIR/$tdir/funlink
3917         echo "aaaaaa" >> $DIR/$tdir/frename
3918
3919         local open_new=`stat -c %Y $DIR/$tdir/fopen`
3920         local link_new=`stat -c %Y $DIR/$tdir/flink`
3921         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
3922         local rename_new=`stat -c %Y $DIR/$tdir/frename`
3923
3924         cat $DIR/$tdir/fopen > /dev/null
3925         ln $DIR/$tdir/flink $DIR/$tdir/flink2
3926         rm -f $DIR/$tdir/funlink2
3927         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
3928
3929         for (( i=0; i < 2; i++ )) ; do
3930                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
3931                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
3932                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
3933                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
3934
3935                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
3936                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
3937                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
3938                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
3939
3940                 cancel_lru_locks $OSC
3941                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3942         done
3943 }
3944 run_test 39b "mtime change on open, link, unlink, rename  ======"
3945
3946 # this should be set to past
3947 TEST_39_MTIME=`date -d "1 year ago" +%s`
3948
3949 # bug 11063
3950 test_39c() {
3951         touch $DIR1/$tfile
3952         sleep 2
3953         local mtime0=`stat -c %Y $DIR1/$tfile`
3954
3955         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
3956         local mtime1=`stat -c %Y $DIR1/$tfile`
3957         [ "$mtime1" = $TEST_39_MTIME ] || \
3958                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
3959
3960         local d1=`date +%s`
3961         echo hello >> $DIR1/$tfile
3962         local d2=`date +%s`
3963         local mtime2=`stat -c %Y $DIR1/$tfile`
3964         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
3965                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
3966
3967         mv $DIR1/$tfile $DIR1/$tfile-1
3968
3969         for (( i=0; i < 2; i++ )) ; do
3970                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
3971                 [ "$mtime2" = "$mtime3" ] || \
3972                         error "mtime ($mtime2) changed (to $mtime3) on rename"
3973
3974                 cancel_lru_locks $OSC
3975                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3976         done
3977 }
3978 run_test 39c "mtime change on rename ==========================="
3979
3980 # bug 21114
3981 test_39d() {
3982         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3983
3984         touch $DIR1/$tfile
3985         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
3986
3987         for (( i=0; i < 2; i++ )) ; do
3988                 local mtime=`stat -c %Y $DIR1/$tfile`
3989                 [ $mtime = $TEST_39_MTIME ] || \
3990                         error "mtime($mtime) is not set to $TEST_39_MTIME"
3991
3992                 cancel_lru_locks $OSC
3993                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3994         done
3995 }
3996 run_test 39d "create, utime, stat =============================="
3997
3998 # bug 21114
3999 test_39e() {
4000         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4001
4002         touch $DIR1/$tfile
4003         local mtime1=`stat -c %Y $DIR1/$tfile`
4004
4005         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4006
4007         for (( i=0; i < 2; i++ )) ; do
4008                 local mtime2=`stat -c %Y $DIR1/$tfile`
4009                 [ $mtime2 = $TEST_39_MTIME ] || \
4010                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4011
4012                 cancel_lru_locks $OSC
4013                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4014         done
4015 }
4016 run_test 39e "create, stat, utime, stat ========================"
4017
4018 # bug 21114
4019 test_39f() {
4020         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4021
4022         touch $DIR1/$tfile
4023         mtime1=`stat -c %Y $DIR1/$tfile`
4024
4025         sleep 2
4026         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4027
4028         for (( i=0; i < 2; i++ )) ; do
4029                 local mtime2=`stat -c %Y $DIR1/$tfile`
4030                 [ $mtime2 = $TEST_39_MTIME ] || \
4031                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4032
4033                 cancel_lru_locks $OSC
4034                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4035         done
4036 }
4037 run_test 39f "create, stat, sleep, utime, stat ================="
4038
4039 # bug 11063
4040 test_39g() {
4041         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4042
4043         echo hello >> $DIR1/$tfile
4044         local mtime1=`stat -c %Y $DIR1/$tfile`
4045
4046         sleep 2
4047         chmod o+r $DIR1/$tfile
4048
4049         for (( i=0; i < 2; i++ )) ; do
4050                 local mtime2=`stat -c %Y $DIR1/$tfile`
4051                 [ "$mtime1" = "$mtime2" ] || \
4052                         error "lost mtime: $mtime2, should be $mtime1"
4053
4054                 cancel_lru_locks $OSC
4055                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4056         done
4057 }
4058 run_test 39g "write, chmod, stat ==============================="
4059
4060 # bug 11063
4061 test_39h() {
4062         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4063
4064         touch $DIR1/$tfile
4065         sleep 1
4066
4067         local d1=`date`
4068         echo hello >> $DIR1/$tfile
4069         local mtime1=`stat -c %Y $DIR1/$tfile`
4070
4071         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4072         local d2=`date`
4073         if [ "$d1" != "$d2" ]; then
4074                 echo "write and touch not within one second"
4075         else
4076                 for (( i=0; i < 2; i++ )) ; do
4077                         local mtime2=`stat -c %Y $DIR1/$tfile`
4078                         [ "$mtime2" = $TEST_39_MTIME ] || \
4079                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4080
4081                         cancel_lru_locks $OSC
4082                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4083                 done
4084         fi
4085 }
4086 run_test 39h "write, utime within one second, stat ============="
4087
4088 test_39i() {
4089         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4090
4091         touch $DIR1/$tfile
4092         sleep 1
4093
4094         echo hello >> $DIR1/$tfile
4095         local mtime1=`stat -c %Y $DIR1/$tfile`
4096
4097         mv $DIR1/$tfile $DIR1/$tfile-1
4098
4099         for (( i=0; i < 2; i++ )) ; do
4100                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4101
4102                 [ "$mtime1" = "$mtime2" ] || \
4103                         error "lost mtime: $mtime2, should be $mtime1"
4104
4105                 cancel_lru_locks $OSC
4106                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4107         done
4108 }
4109 run_test 39i "write, rename, stat =============================="
4110
4111 test_39j() {
4112         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4113
4114         start_full_debug_logging
4115         touch $DIR1/$tfile
4116         sleep 1
4117
4118         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
4119         lctl set_param fail_loc=0x80000412
4120         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
4121                 error "multiop failed"
4122         local multipid=$!
4123         local mtime1=`stat -c %Y $DIR1/$tfile`
4124
4125         mv $DIR1/$tfile $DIR1/$tfile-1
4126
4127         kill -USR1 $multipid
4128         wait $multipid || error "multiop close failed"
4129
4130         for (( i=0; i < 2; i++ )) ; do
4131                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4132                 [ "$mtime1" = "$mtime2" ] ||
4133                         error "mtime is lost on close: $mtime2, " \
4134                               "should be $mtime1"
4135
4136                 cancel_lru_locks $OSC
4137                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4138         done
4139         lctl set_param fail_loc=0
4140         stop_full_debug_logging
4141 }
4142 run_test 39j "write, rename, close, stat ======================="
4143
4144 test_39k() {
4145         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4146
4147         touch $DIR1/$tfile
4148         sleep 1
4149
4150         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
4151         local multipid=$!
4152         local mtime1=`stat -c %Y $DIR1/$tfile`
4153
4154         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4155
4156         kill -USR1 $multipid
4157         wait $multipid || error "multiop close failed"
4158
4159         for (( i=0; i < 2; i++ )) ; do
4160                 local mtime2=`stat -c %Y $DIR1/$tfile`
4161
4162                 [ "$mtime2" = $TEST_39_MTIME ] || \
4163                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
4164
4165                 cancel_lru_locks osc
4166                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4167         done
4168 }
4169 run_test 39k "write, utime, close, stat ========================"
4170
4171 # this should be set to future
4172 TEST_39_ATIME=`date -d "1 year" +%s`
4173
4174 test_39l() {
4175         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4176         remote_mds_nodsh && skip "remote MDS with nodsh"
4177
4178         local atime_diff=$(do_facet $SINGLEMDS \
4179                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4180         rm -rf $DIR/$tdir
4181         mkdir -p $DIR/$tdir
4182
4183         # test setting directory atime to future
4184         touch -a -d @$TEST_39_ATIME $DIR/$tdir
4185         local atime=$(stat -c %X $DIR/$tdir)
4186         [ "$atime" = $TEST_39_ATIME ] ||
4187                 error "atime is not set to future: $atime, $TEST_39_ATIME"
4188
4189         # test setting directory atime from future to now
4190         local now=$(date +%s)
4191         touch -a -d @$now $DIR/$tdir
4192
4193         atime=$(stat -c %X $DIR/$tdir)
4194         [ "$atime" -eq "$now"  ] ||
4195                 error "atime is not updated from future: $atime, $now"
4196
4197         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
4198         sleep 3
4199
4200         # test setting directory atime when now > dir atime + atime_diff
4201         local d1=$(date +%s)
4202         ls $DIR/$tdir
4203         local d2=$(date +%s)
4204         cancel_lru_locks mdc
4205         atime=$(stat -c %X $DIR/$tdir)
4206         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4207                 error "atime is not updated  : $atime, should be $d2"
4208
4209         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
4210         sleep 3
4211
4212         # test not setting directory atime when now < dir atime + atime_diff
4213         ls $DIR/$tdir
4214         cancel_lru_locks mdc
4215         atime=$(stat -c %X $DIR/$tdir)
4216         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4217                 error "atime is updated to $atime, should remain $d1<atime<$d2"
4218
4219         do_facet $SINGLEMDS \
4220                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4221 }
4222 run_test 39l "directory atime update ==========================="
4223
4224 test_39m() {
4225         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4226
4227         touch $DIR1/$tfile
4228         sleep 2
4229         local far_past_mtime=$(date -d "May 29 1953" +%s)
4230         local far_past_atime=$(date -d "Dec 17 1903" +%s)
4231
4232         touch -m -d @$far_past_mtime $DIR1/$tfile
4233         touch -a -d @$far_past_atime $DIR1/$tfile
4234
4235         for (( i=0; i < 2; i++ )) ; do
4236                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
4237                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
4238                         error "atime or mtime set incorrectly"
4239
4240                 cancel_lru_locks $OSC
4241                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4242         done
4243 }
4244 run_test 39m "test atime and mtime before 1970"
4245
4246 test_39n() { # LU-3832
4247         remote_mds_nodsh && skip "remote MDS with nodsh"
4248
4249         local atime_diff=$(do_facet $SINGLEMDS \
4250                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4251         local atime0
4252         local atime1
4253         local atime2
4254
4255         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
4256
4257         rm -rf $DIR/$tfile
4258         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
4259         atime0=$(stat -c %X $DIR/$tfile)
4260
4261         sleep 5
4262         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4263         atime1=$(stat -c %X $DIR/$tfile)
4264
4265         sleep 5
4266         cancel_lru_locks mdc
4267         cancel_lru_locks osc
4268         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4269         atime2=$(stat -c %X $DIR/$tfile)
4270
4271         do_facet $SINGLEMDS \
4272                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4273
4274         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
4275         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
4276 }
4277 run_test 39n "check that O_NOATIME is honored"
4278
4279 test_39o() {
4280         TESTDIR=$DIR/$tdir/$tfile
4281         [ -e $TESTDIR ] && rm -rf $TESTDIR
4282         mkdir -p $TESTDIR
4283         cd $TESTDIR
4284         links1=2
4285         ls
4286         mkdir a b
4287         ls
4288         links2=$(stat -c %h .)
4289         [ $(($links1 + 2)) != $links2 ] &&
4290                 error "wrong links count $(($links1 + 2)) != $links2"
4291         rmdir b
4292         links3=$(stat -c %h .)
4293         [ $(($links1 + 1)) != $links3 ] &&
4294                 error "wrong links count $links1 != $links3"
4295         return 0
4296 }
4297 run_test 39o "directory cached attributes updated after create"
4298
4299 test_39p() {
4300         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4301
4302         local MDTIDX=1
4303         TESTDIR=$DIR/$tdir/$tdir
4304         [ -e $TESTDIR ] && rm -rf $TESTDIR
4305         test_mkdir -p $TESTDIR
4306         cd $TESTDIR
4307         links1=2
4308         ls
4309         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
4310         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
4311         ls
4312         links2=$(stat -c %h .)
4313         [ $(($links1 + 2)) != $links2 ] &&
4314                 error "wrong links count $(($links1 + 2)) != $links2"
4315         rmdir remote_dir2
4316         links3=$(stat -c %h .)
4317         [ $(($links1 + 1)) != $links3 ] &&
4318                 error "wrong links count $links1 != $links3"
4319         return 0
4320 }
4321 run_test 39p "remote directory cached attributes updated after create ========"
4322
4323
4324 test_39q() { # LU-8041
4325         local testdir=$DIR/$tdir
4326         mkdir -p $testdir
4327         multiop_bg_pause $testdir D_c || error "multiop failed"
4328         local multipid=$!
4329         cancel_lru_locks mdc
4330         kill -USR1 $multipid
4331         local atime=$(stat -c %X $testdir)
4332         [ "$atime" -ne 0 ] || error "atime is zero"
4333 }
4334 run_test 39q "close won't zero out atime"
4335
4336 test_40() {
4337         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
4338         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
4339                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
4340         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
4341                 error "$tfile is not 4096 bytes in size"
4342 }
4343 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
4344
4345 test_41() {
4346         # bug 1553
4347         small_write $DIR/f41 18
4348 }
4349 run_test 41 "test small file write + fstat ====================="
4350
4351 count_ost_writes() {
4352         lctl get_param -n ${OSC}.*.stats |
4353                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
4354                         END { printf("%0.0f", writes) }'
4355 }
4356
4357 # decent default
4358 WRITEBACK_SAVE=500
4359 DIRTY_RATIO_SAVE=40
4360 MAX_DIRTY_RATIO=50
4361 BG_DIRTY_RATIO_SAVE=10
4362 MAX_BG_DIRTY_RATIO=25
4363
4364 start_writeback() {
4365         trap 0
4366         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
4367         # dirty_ratio, dirty_background_ratio
4368         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
4369                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
4370                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
4371                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
4372         else
4373                 # if file not here, we are a 2.4 kernel
4374                 kill -CONT `pidof kupdated`
4375         fi
4376 }
4377
4378 stop_writeback() {
4379         # setup the trap first, so someone cannot exit the test at the
4380         # exact wrong time and mess up a machine
4381         trap start_writeback EXIT
4382         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
4383         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
4384                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
4385                 sysctl -w vm.dirty_writeback_centisecs=0
4386                 sysctl -w vm.dirty_writeback_centisecs=0
4387                 # save and increase /proc/sys/vm/dirty_ratio
4388                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
4389                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
4390                 # save and increase /proc/sys/vm/dirty_background_ratio
4391                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
4392                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
4393         else
4394                 # if file not here, we are a 2.4 kernel
4395                 kill -STOP `pidof kupdated`
4396         fi
4397 }
4398
4399 # ensure that all stripes have some grant before we test client-side cache
4400 setup_test42() {
4401         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
4402                 dd if=/dev/zero of=$i bs=4k count=1
4403                 rm $i
4404         done
4405 }
4406
4407 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
4408 # file truncation, and file removal.
4409 test_42a() {
4410         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4411
4412         setup_test42
4413         cancel_lru_locks $OSC
4414         stop_writeback
4415         sync; sleep 1; sync # just to be safe
4416         BEFOREWRITES=`count_ost_writes`
4417         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
4418         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
4419         AFTERWRITES=`count_ost_writes`
4420         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
4421                 error "$BEFOREWRITES < $AFTERWRITES"
4422         start_writeback
4423 }
4424 run_test 42a "ensure that we don't flush on close"
4425
4426 test_42b() {
4427         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4428
4429         setup_test42
4430         cancel_lru_locks $OSC
4431         stop_writeback
4432         sync
4433         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
4434         BEFOREWRITES=$(count_ost_writes)
4435         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
4436         AFTERWRITES=$(count_ost_writes)
4437         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
4438                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
4439         fi
4440         BEFOREWRITES=$(count_ost_writes)
4441         sync || error "sync: $?"
4442         AFTERWRITES=$(count_ost_writes)
4443         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
4444                 error "$BEFOREWRITES < $AFTERWRITES on sync"
4445         fi
4446         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
4447         start_writeback
4448         return 0
4449 }
4450 run_test 42b "test destroy of file with cached dirty data ======"
4451
4452 # if these tests just want to test the effect of truncation,
4453 # they have to be very careful.  consider:
4454 # - the first open gets a {0,EOF}PR lock
4455 # - the first write conflicts and gets a {0, count-1}PW
4456 # - the rest of the writes are under {count,EOF}PW
4457 # - the open for truncate tries to match a {0,EOF}PR
4458 #   for the filesize and cancels the PWs.
4459 # any number of fixes (don't get {0,EOF} on open, match
4460 # composite locks, do smarter file size management) fix
4461 # this, but for now we want these tests to verify that
4462 # the cancellation with truncate intent works, so we
4463 # start the file with a full-file pw lock to match against
4464 # until the truncate.
4465 trunc_test() {
4466         test=$1
4467         file=$DIR/$test
4468         offset=$2
4469         cancel_lru_locks $OSC
4470         stop_writeback
4471         # prime the file with 0,EOF PW to match
4472         touch $file
4473         $TRUNCATE $file 0
4474         sync; sync
4475         # now the real test..
4476         dd if=/dev/zero of=$file bs=1024 count=100
4477         BEFOREWRITES=`count_ost_writes`
4478         $TRUNCATE $file $offset
4479         cancel_lru_locks $OSC
4480         AFTERWRITES=`count_ost_writes`
4481         start_writeback
4482 }
4483
4484 test_42c() {
4485         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4486
4487         trunc_test 42c 1024
4488         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
4489                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
4490         rm $file
4491 }
4492 run_test 42c "test partial truncate of file with cached dirty data"
4493
4494 test_42d() {
4495         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4496
4497         trunc_test 42d 0
4498         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
4499                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
4500         rm $file
4501 }
4502 run_test 42d "test complete truncate of file with cached dirty data"
4503
4504 test_42e() { # bug22074
4505         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4506
4507         local TDIR=$DIR/${tdir}e
4508         local pages=16 # hardcoded 16 pages, don't change it.
4509         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
4510         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
4511         local max_dirty_mb
4512         local warmup_files
4513
4514         test_mkdir $DIR/${tdir}e
4515         $LFS setstripe -c 1 $TDIR
4516         createmany -o $TDIR/f $files
4517
4518         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
4519
4520         # we assume that with $OSTCOUNT files, at least one of them will
4521         # be allocated on OST0.
4522         warmup_files=$((OSTCOUNT * max_dirty_mb))
4523         createmany -o $TDIR/w $warmup_files
4524
4525         # write a large amount of data into one file and sync, to get good
4526         # avail_grant number from OST.
4527         for ((i=0; i<$warmup_files; i++)); do
4528                 idx=$($LFS getstripe -i $TDIR/w$i)
4529                 [ $idx -ne 0 ] && continue
4530                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
4531                 break
4532         done
4533         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
4534         sync
4535         $LCTL get_param $proc_osc0/cur_dirty_bytes
4536         $LCTL get_param $proc_osc0/cur_grant_bytes
4537
4538         # create as much dirty pages as we can while not to trigger the actual
4539         # RPCs directly. but depends on the env, VFS may trigger flush during this
4540         # period, hopefully we are good.
4541         for ((i=0; i<$warmup_files; i++)); do
4542                 idx=$($LFS getstripe -i $TDIR/w$i)
4543                 [ $idx -ne 0 ] && continue
4544                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
4545         done
4546         $LCTL get_param $proc_osc0/cur_dirty_bytes
4547         $LCTL get_param $proc_osc0/cur_grant_bytes
4548
4549         # perform the real test
4550         $LCTL set_param $proc_osc0/rpc_stats 0
4551         for ((;i<$files; i++)); do
4552                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
4553                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
4554         done
4555         sync
4556         $LCTL get_param $proc_osc0/rpc_stats
4557
4558         local percent=0
4559         local have_ppr=false
4560         $LCTL get_param $proc_osc0/rpc_stats |
4561                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
4562                         # skip lines until we are at the RPC histogram data
4563                         [ "$PPR" == "pages" ] && have_ppr=true && continue
4564                         $have_ppr || continue
4565
4566                         # we only want the percent stat for < 16 pages
4567                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
4568
4569                         percent=$((percent + WPCT))
4570                         if [[ $percent -gt 15 ]]; then
4571                                 error "less than 16-pages write RPCs" \
4572                                       "$percent% > 15%"
4573                                 break
4574                         fi
4575                 done
4576         rm -rf $TDIR
4577 }
4578 run_test 42e "verify sub-RPC writes are not done synchronously"
4579
4580 test_43A() { # was test_43
4581         test_mkdir $DIR/$tdir
4582         cp -p /bin/ls $DIR/$tdir/$tfile
4583         $MULTIOP $DIR/$tdir/$tfile Ow_c &
4584         pid=$!
4585         # give multiop a chance to open
4586         sleep 1
4587
4588         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
4589         kill -USR1 $pid
4590 }
4591 run_test 43A "execution of file opened for write should return -ETXTBSY"
4592
4593 test_43a() {
4594         test_mkdir $DIR/$tdir
4595         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
4596         $DIR/$tdir/sleep 60 &
4597         SLEEP_PID=$!
4598         # Make sure exec of $tdir/sleep wins race with truncate
4599         sleep 1
4600         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
4601         kill $SLEEP_PID
4602 }
4603 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
4604
4605 test_43b() {
4606         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4607
4608         test_mkdir $DIR/$tdir
4609         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
4610         $DIR/$tdir/sleep 60 &
4611         SLEEP_PID=$!
4612         # Make sure exec of $tdir/sleep wins race with truncate
4613         sleep 1
4614         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
4615         kill $SLEEP_PID
4616 }
4617 run_test 43b "truncate of file being executed should return -ETXTBSY"
4618
4619 test_43c() {
4620         local testdir="$DIR/$tdir"
4621         test_mkdir $testdir
4622         cp $SHELL $testdir/
4623         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
4624                 ( cd $testdir && md5sum -c )
4625 }
4626 run_test 43c "md5sum of copy into lustre"
4627
4628 test_44A() { # was test_44
4629         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
4630
4631         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
4632         dd if=$DIR/f1 bs=4k count=1 > /dev/null
4633 }
4634 run_test 44A "zero length read from a sparse stripe"
4635
4636 test_44a() {
4637         local nstripe=$($LCTL lov_getconfig $DIR | grep default_stripe_count: |
4638                 awk '{ print $2 }')
4639         [ -z "$nstripe" ] && skip "can't get stripe info"
4640         [[ $nstripe -gt $OSTCOUNT ]] &&
4641                 skip "Wrong default_stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
4642
4643         local stride=$($LCTL lov_getconfig $DIR | grep default_stripe_size: |
4644                 awk '{ print $2 }')
4645         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
4646                 nstripe=$($LCTL lov_getconfig $DIR | grep obd_count: |
4647                         awk '{ print $2 }')
4648         fi
4649
4650         OFFSETS="0 $((stride/2)) $((stride-1))"
4651         for offset in $OFFSETS; do
4652                 for i in $(seq 0 $((nstripe-1))); do
4653                         local GLOBALOFFSETS=""
4654                         # size in Bytes
4655                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
4656                         local myfn=$DIR/d44a-$size
4657                         echo "--------writing $myfn at $size"
4658                         ll_sparseness_write $myfn $size ||
4659                                 error "ll_sparseness_write"
4660                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
4661                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
4662                                 error "ll_sparseness_verify $GLOBALOFFSETS"
4663
4664                         for j in $(seq 0 $((nstripe-1))); do
4665                                 # size in Bytes
4666                                 size=$((((j + $nstripe )*$stride + $offset)))
4667                                 ll_sparseness_write $myfn $size ||
4668                                         error "ll_sparseness_write"
4669                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
4670                         done
4671                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
4672                                 error "ll_sparseness_verify $GLOBALOFFSETS"
4673                         rm -f $myfn
4674                 done
4675         done
4676 }
4677 run_test 44a "test sparse pwrite ==============================="
4678
4679 dirty_osc_total() {
4680         tot=0
4681         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
4682                 tot=$(($tot + $d))
4683         done
4684         echo $tot
4685 }
4686 do_dirty_record() {
4687         before=`dirty_osc_total`
4688         echo executing "\"$*\""
4689         eval $*
4690         after=`dirty_osc_total`
4691         echo before $before, after $after
4692 }
4693 test_45() {
4694         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4695
4696         f="$DIR/f45"
4697         # Obtain grants from OST if it supports it
4698         echo blah > ${f}_grant
4699         stop_writeback
4700         sync
4701         do_dirty_record "echo blah > $f"
4702         [[ $before -eq $after ]] && error "write wasn't cached"
4703         do_dirty_record "> $f"
4704         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
4705         do_dirty_record "echo blah > $f"
4706         [[ $before -eq $after ]] && error "write wasn't cached"
4707         do_dirty_record "sync"
4708         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
4709         do_dirty_record "echo blah > $f"
4710         [[ $before -eq $after ]] && error "write wasn't cached"
4711         do_dirty_record "cancel_lru_locks osc"
4712         [[ $before -gt $after ]] ||
4713                 error "lock cancellation didn't lower dirty count"
4714         start_writeback
4715 }
4716 run_test 45 "osc io page accounting ============================"
4717
4718 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
4719 # test tickles a bug where re-dirtying a page was failing to be mapped to the
4720 # objects offset and an assert hit when an rpc was built with 1023's mapped
4721 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
4722 test_46() {
4723         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4724
4725         f="$DIR/f46"
4726         stop_writeback
4727         sync
4728         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
4729         sync
4730         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
4731         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
4732         sync
4733         start_writeback
4734 }
4735 run_test 46 "dirtying a previously written page ================"
4736
4737 # test_47 is removed "Device nodes check" is moved to test_28
4738
4739 test_48a() { # bug 2399
4740         [ "$mds1_FSTYPE" = "zfs" ] &&
4741         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
4742                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
4743
4744         test_mkdir $DIR/$tdir
4745         cd $DIR/$tdir
4746         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
4747         test_mkdir $DIR/$tdir
4748         touch foo || error "'touch foo' failed after recreating cwd"
4749         test_mkdir bar
4750         touch .foo || error "'touch .foo' failed after recreating cwd"
4751         test_mkdir .bar
4752         ls . > /dev/null || error "'ls .' failed after recreating cwd"
4753         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
4754         cd . || error "'cd .' failed after recreating cwd"
4755         mkdir . && error "'mkdir .' worked after recreating cwd"
4756         rmdir . && error "'rmdir .' worked after recreating cwd"
4757         ln -s . baz || error "'ln -s .' failed after recreating cwd"
4758         cd .. || error "'cd ..' failed after recreating cwd"
4759 }
4760 run_test 48a "Access renamed working dir (should return errors)="
4761
4762 test_48b() { # bug 2399
4763         rm -rf $DIR/$tdir
4764         test_mkdir $DIR/$tdir
4765         cd $DIR/$tdir
4766         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
4767         touch foo && error "'touch foo' worked after removing cwd"
4768         mkdir foo && error "'mkdir foo' worked after removing cwd"
4769         touch .foo && error "'touch .foo' worked after removing cwd"
4770         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
4771         ls . > /dev/null && error "'ls .' worked after removing cwd"
4772         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
4773         mkdir . && error "'mkdir .' worked after removing cwd"
4774         rmdir . && error "'rmdir .' worked after removing cwd"
4775         ln -s . foo && error "'ln -s .' worked after removing cwd"
4776         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
4777 }
4778 run_test 48b "Access removed working dir (should return errors)="
4779
4780 test_48c() { # bug 2350
4781         #lctl set_param debug=-1
4782         #set -vx
4783         rm -rf $DIR/$tdir
4784         test_mkdir -p $DIR/$tdir/dir
4785         cd $DIR/$tdir/dir
4786         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
4787         $TRACE touch foo && error "touch foo worked after removing cwd"
4788         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
4789         touch .foo && error "touch .foo worked after removing cwd"
4790         mkdir .foo && error "mkdir .foo worked after removing cwd"
4791         $TRACE ls . && error "'ls .' worked after removing cwd"
4792         $TRACE ls .. || error "'ls ..' failed after removing cwd"
4793         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
4794         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
4795         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
4796         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
4797 }
4798 run_test 48c "Access removed working subdir (should return errors)"
4799
4800 test_48d() { # bug 2350
4801         #lctl set_param debug=-1
4802         #set -vx
4803         rm -rf $DIR/$tdir
4804         test_mkdir -p $DIR/$tdir/dir
4805         cd $DIR/$tdir/dir
4806         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
4807         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
4808         $TRACE touch foo && error "'touch foo' worked after removing parent"
4809         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
4810         touch .foo && error "'touch .foo' worked after removing parent"
4811         mkdir .foo && error "mkdir .foo worked after removing parent"
4812         $TRACE ls . && error "'ls .' worked after removing parent"
4813         $TRACE ls .. && error "'ls ..' worked after removing parent"
4814         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
4815         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
4816         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
4817         true
4818 }
4819 run_test 48d "Access removed parent subdir (should return errors)"
4820
4821 test_48e() { # bug 4134
4822         #lctl set_param debug=-1
4823         #set -vx
4824         rm -rf $DIR/$tdir
4825         test_mkdir -p $DIR/$tdir/dir
4826         cd $DIR/$tdir/dir
4827         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
4828         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
4829         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
4830         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
4831         # On a buggy kernel addition of "touch foo" after cd .. will
4832         # produce kernel oops in lookup_hash_it
4833         touch ../foo && error "'cd ..' worked after recreate parent"
4834         cd $DIR
4835         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
4836 }
4837 run_test 48e "Access to recreated parent subdir (should return errors)"
4838
4839 test_49() { # LU-1030
4840         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4841         remote_ost_nodsh && skip "remote OST with nodsh"
4842
4843         # get ost1 size - lustre-OST0000
4844         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
4845                 awk '{ print $4 }')
4846         # write 800M at maximum
4847         [[ $ost1_size -lt 2 ]] && ost1_size=2
4848         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
4849
4850         $LFS setstripe -c 1 -i 0 $DIR/$tfile
4851         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
4852         local dd_pid=$!
4853
4854         # change max_pages_per_rpc while writing the file
4855         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
4856         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
4857         # loop until dd process exits
4858         while ps ax -opid | grep -wq $dd_pid; do
4859                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
4860                 sleep $((RANDOM % 5 + 1))
4861         done
4862         # restore original max_pages_per_rpc
4863         $LCTL set_param $osc1_mppc=$orig_mppc
4864         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
4865 }
4866 run_test 49 "Change max_pages_per_rpc won't break osc extent"
4867
4868 test_50() {
4869         # bug 1485
4870         test_mkdir $DIR/$tdir
4871         cd $DIR/$tdir
4872         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
4873 }
4874 run_test 50 "special situations: /proc symlinks  ==============="
4875
4876 test_51a() {    # was test_51
4877         # bug 1516 - create an empty entry right after ".." then split dir
4878         test_mkdir -c1 $DIR/$tdir
4879         touch $DIR/$tdir/foo
4880         $MCREATE $DIR/$tdir/bar
4881         rm $DIR/$tdir/foo
4882         createmany -m $DIR/$tdir/longfile 201
4883         FNUM=202
4884         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
4885                 $MCREATE $DIR/$tdir/longfile$FNUM
4886                 FNUM=$(($FNUM + 1))
4887                 echo -n "+"
4888         done
4889         echo
4890         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
4891 }
4892 run_test 51a "special situations: split htree with empty entry =="
4893
4894 cleanup_print_lfs_df () {
4895         trap 0
4896         $LFS df
4897         $LFS df -i
4898 }
4899
4900 test_51b() {
4901         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4902
4903         local dir=$DIR/$tdir
4904         local nrdirs=$((65536 + 100))
4905
4906         # cleanup the directory
4907         rm -fr $dir
4908
4909         test_mkdir -c1 $dir
4910
4911         $LFS df
4912         $LFS df -i
4913         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
4914         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
4915         [[ $numfree -lt $nrdirs ]] &&
4916                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
4917
4918         # need to check free space for the directories as well
4919         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
4920         numfree=$(( blkfree / $(fs_inode_ksize) ))
4921         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
4922
4923         trap cleanup_print_lfs_df EXIT
4924
4925         # create files
4926         createmany -d $dir/d $nrdirs || {
4927                 unlinkmany $dir/d $nrdirs
4928                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
4929         }
4930
4931         # really created :
4932         nrdirs=$(ls -U $dir | wc -l)
4933
4934         # unlink all but 100 subdirectories, then check it still works
4935         local left=100
4936         local delete=$((nrdirs - left))
4937
4938         $LFS df
4939         $LFS df -i
4940
4941         # for ldiskfs the nlink count should be 1, but this is OSD specific
4942         # and so this is listed for informational purposes only
4943         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
4944         unlinkmany -d $dir/d $delete ||
4945                 error "unlink of first $delete subdirs failed"
4946
4947         echo "nlink between: $(stat -c %h $dir)"
4948         local found=$(ls -U $dir | wc -l)
4949         [ $found -ne $left ] &&
4950                 error "can't find subdirs: found only $found, expected $left"
4951
4952         unlinkmany -d $dir/d $delete $left ||
4953                 error "unlink of second $left subdirs failed"
4954         # regardless of whether the backing filesystem tracks nlink accurately
4955         # or not, the nlink count shouldn't be more than "." and ".." here
4956         local after=$(stat -c %h $dir)
4957         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
4958                 echo "nlink after: $after"
4959
4960         cleanup_print_lfs_df
4961 }
4962 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
4963
4964 test_51d() {
4965         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4966         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
4967
4968         test_mkdir $DIR/$tdir
4969         createmany -o $DIR/$tdir/t- 1000
4970         $LFS getstripe $DIR/$tdir > $TMP/$tfile
4971         for N in $(seq 0 $((OSTCOUNT - 1))); do
4972                 OBJS[$N]=$(awk -vobjs=0 '($1 == '$N') { objs += 1 } \
4973                         END { printf("%0.0f", objs) }' $TMP/$tfile)
4974                 OBJS0[$N]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
4975                         '($1 == '$N') { objs += 1 } \
4976                         END { printf("%0.0f", objs) }')
4977                 log "OST$N has ${OBJS[$N]} objects, ${OBJS0[$N]} are index 0"
4978         done
4979         unlinkmany $DIR/$tdir/t- 1000
4980
4981         NLAST=0
4982         for N in $(seq 1 $((OSTCOUNT - 1))); do
4983                 [[ ${OBJS[$N]} -lt $((${OBJS[$NLAST]} - 20)) ]] &&
4984                         error "OST $N has less objects vs OST $NLAST" \
4985                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
4986                 [[ ${OBJS[$N]} -gt $((${OBJS[$NLAST]} + 20)) ]] &&
4987                         error "OST $N has less objects vs OST $NLAST" \
4988                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
4989
4990                 [[ ${OBJS0[$N]} -lt $((${OBJS0[$NLAST]} - 20)) ]] &&
4991                         error "OST $N has less #0 objects vs OST $NLAST" \
4992                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
4993                 [[ ${OBJS0[$N]} -gt $((${OBJS0[$NLAST]} + 20)) ]] &&
4994                         error "OST $N has less #0 objects vs OST $NLAST" \
4995                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
4996                 NLAST=$N
4997         done
4998         rm -f $TMP/$tfile
4999 }
5000 run_test 51d "check object distribution"
5001
5002 test_51e() {
5003         if [ "$mds1_FSTYPE" != ldiskfs ]; then
5004                 skip_env "ldiskfs only test"
5005         fi
5006
5007         test_mkdir -c1 $DIR/$tdir
5008         test_mkdir -c1 $DIR/$tdir/d0
5009
5010         touch $DIR/$tdir/d0/foo
5011         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
5012                 error "file exceed 65000 nlink limit!"
5013         unlinkmany $DIR/$tdir/d0/f- 65001
5014         return 0
5015 }
5016 run_test 51e "check file nlink limit"
5017
5018 test_51f() {
5019         test_mkdir $DIR/$tdir
5020
5021         local max=100000
5022         local ulimit_old=$(ulimit -n)
5023         local spare=20 # number of spare fd's for scripts/libraries, etc.
5024         local mdt=$($LFS getstripe -m $DIR/$tdir)
5025         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
5026
5027         echo "MDT$mdt numfree=$numfree, max=$max"
5028         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
5029         if [ $((numfree + spare)) -gt $ulimit_old ]; then
5030                 while ! ulimit -n $((numfree + spare)); do
5031                         numfree=$((numfree * 3 / 4))
5032                 done
5033                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
5034         else
5035                 echo "left ulimit at $ulimit_old"
5036         fi
5037
5038         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
5039                 unlinkmany $DIR/$tdir/f $numfree
5040                 error "create+open $numfree files in $DIR/$tdir failed"
5041         }
5042         ulimit -n $ulimit_old
5043
5044         # if createmany exits at 120s there will be fewer than $numfree files
5045         unlinkmany $DIR/$tdir/f $numfree || true
5046 }
5047 run_test 51f "check many open files limit"
5048
5049 test_52a() {
5050         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
5051         test_mkdir $DIR/$tdir
5052         touch $DIR/$tdir/foo
5053         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
5054         echo bar >> $DIR/$tdir/foo || error "append bar failed"
5055         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5056         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5057         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5058                                         error "link worked"
5059         echo foo >> $DIR/$tdir/foo || error "append foo failed"
5060         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5061         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
5062                                                      error "lsattr"
5063         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
5064         cp -r $DIR/$tdir $TMP/
5065         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
5066 }
5067 run_test 52a "append-only flag test (should return errors)"
5068
5069 test_52b() {
5070         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
5071         test_mkdir $DIR/$tdir
5072         touch $DIR/$tdir/foo
5073         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
5074         cat test > $DIR/$tdir/foo && error "cat test worked"
5075         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5076         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5077         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5078                                         error "link worked"
5079         echo foo >> $DIR/$tdir/foo && error "echo worked"
5080         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5081         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
5082         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
5083         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
5084                                                         error "lsattr"
5085         chattr -i $DIR/$tdir/foo || error "chattr failed"
5086
5087         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
5088 }
5089 run_test 52b "immutable flag test (should return errors) ======="
5090
5091 test_53() {
5092         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5093         remote_mds_nodsh && skip "remote MDS with nodsh"
5094         remote_ost_nodsh && skip "remote OST with nodsh"
5095
5096         local param
5097         local param_seq
5098         local ostname
5099         local mds_last
5100         local mds_last_seq
5101         local ost_last
5102         local ost_last_seq
5103         local ost_last_id
5104         local ostnum
5105         local node
5106         local found=false
5107         local support_last_seq=true
5108
5109         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
5110                 support_last_seq=false
5111
5112         # only test MDT0000
5113         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
5114         local value
5115         for value in $(do_facet $SINGLEMDS \
5116                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
5117                 param=$(echo ${value[0]} | cut -d "=" -f1)
5118                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
5119
5120                 if $support_last_seq; then
5121                         param_seq=$(echo $param |
5122                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
5123                         mds_last_seq=$(do_facet $SINGLEMDS \
5124                                        $LCTL get_param -n $param_seq)
5125                 fi
5126                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
5127
5128                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
5129                 node=$(facet_active_host ost$((ostnum+1)))
5130                 param="obdfilter.$ostname.last_id"
5131                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
5132                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
5133                         ost_last_id=$ost_last
5134
5135                         if $support_last_seq; then
5136                                 ost_last_id=$(echo $ost_last |
5137                                               awk -F':' '{print $2}' |
5138                                               sed -e "s/^0x//g")
5139                                 ost_last_seq=$(echo $ost_last |
5140                                                awk -F':' '{print $1}')
5141                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
5142                         fi
5143
5144                         if [[ $ost_last_id != $mds_last ]]; then
5145                                 error "$ost_last_id != $mds_last"
5146                         else
5147                                 found=true
5148                                 break
5149                         fi
5150                 done
5151         done
5152         $found || error "can not match last_seq/last_id for $mdtosc"
5153         return 0
5154 }
5155 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
5156
5157 test_54a() {
5158         perl -MSocket -e ';' || skip "no Socket perl module installed"
5159
5160         $SOCKETSERVER $DIR/socket ||
5161                 error "$SOCKETSERVER $DIR/socket failed: $?"
5162         $SOCKETCLIENT $DIR/socket ||
5163                 error "$SOCKETCLIENT $DIR/socket failed: $?"
5164         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
5165 }
5166 run_test 54a "unix domain socket test =========================="
5167
5168 test_54b() {
5169         f="$DIR/f54b"
5170         mknod $f c 1 3
5171         chmod 0666 $f
5172         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
5173 }
5174 run_test 54b "char device works in lustre ======================"
5175
5176 find_loop_dev() {
5177         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
5178         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
5179         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
5180
5181         for i in $(seq 3 7); do
5182                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
5183                 LOOPDEV=$LOOPBASE$i
5184                 LOOPNUM=$i
5185                 break
5186         done
5187 }
5188
5189 cleanup_54c() {
5190         local rc=0
5191         loopdev="$DIR/loop54c"
5192
5193         trap 0
5194         $UMOUNT $DIR/$tdir || rc=$?
5195         losetup -d $loopdev || true
5196         losetup -d $LOOPDEV || true
5197         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
5198         return $rc
5199 }
5200
5201 test_54c() {
5202         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5203
5204         loopdev="$DIR/loop54c"
5205
5206         find_loop_dev
5207         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
5208         trap cleanup_54c EXIT
5209         mknod $loopdev b 7 $LOOPNUM
5210         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
5211         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
5212         losetup $loopdev $DIR/$tfile ||
5213                 error "can't set up $loopdev for $DIR/$tfile"
5214         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
5215         test_mkdir $DIR/$tdir
5216         mount -t ext2 $loopdev $DIR/$tdir ||
5217                 error "error mounting $loopdev on $DIR/$tdir"
5218         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
5219                 error "dd write"
5220         df $DIR/$tdir
5221         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
5222                 error "dd read"
5223         cleanup_54c
5224 }
5225 run_test 54c "block device works in lustre ====================="
5226
5227 test_54d() {
5228         f="$DIR/f54d"
5229         string="aaaaaa"
5230         mknod $f p
5231         [ "$string" = $(echo $string > $f | cat $f) ] || error "$f != $string"
5232 }
5233 run_test 54d "fifo device works in lustre ======================"
5234
5235 test_54e() {
5236         f="$DIR/f54e"
5237         string="aaaaaa"
5238         cp -aL /dev/console $f
5239         echo $string > $f || error "echo $string to $f failed"
5240 }
5241 run_test 54e "console/tty device works in lustre ======================"
5242
5243 test_56a() {
5244         local numfiles=3
5245         local dir=$DIR/$tdir
5246
5247         rm -rf $dir
5248         test_mkdir -p $dir/dir
5249         for i in $(seq $numfiles); do
5250                 touch $dir/file$i
5251                 touch $dir/dir/file$i
5252         done
5253
5254         local numcomp=$($LFS getstripe --component-count $dir)
5255
5256         [[ $numcomp == 0 ]] && numcomp=1
5257
5258         # test lfs getstripe with --recursive
5259         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
5260
5261         [[ $filenum -eq $((numfiles * 2)) ]] ||
5262                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
5263         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
5264         [[ $filenum -eq $numfiles ]] ||
5265                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
5266         echo "$LFS getstripe showed obdidx or l_ost_idx"
5267
5268         # test lfs getstripe with file instead of dir
5269         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
5270         [[ $filenum -eq 1 ]] ||
5271                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
5272         echo "$LFS getstripe file1 passed"
5273
5274         #test lfs getstripe with --verbose
5275         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
5276         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5277                 error "$LFS getstripe --verbose $dir: "\
5278                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
5279         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
5280                 error "$LFS getstripe $dir: showed lmm_magic"
5281
5282         #test lfs getstripe with -v prints lmm_fid
5283         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
5284         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5285                 error "$LFS getstripe -v $dir: "\
5286                       "got $filenum want $((numfiles * numcomp)) lmm_fid"
5287         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
5288                 error "$LFS getstripe $dir: showed lmm_fid by default"
5289         echo "$LFS getstripe --verbose passed"
5290
5291         #check for FID information
5292         local fid1=$($LFS getstripe --fid $dir/file1)
5293         local fid2=$($LFS getstripe --verbose $dir/file1 |
5294                      awk '/lmm_fid: / { print $2; exit; }')
5295         local fid3=$($LFS path2fid $dir/file1)
5296
5297         [ "$fid1" != "$fid2" ] &&
5298                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
5299         [ "$fid1" != "$fid3" ] &&
5300                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
5301         echo "$LFS getstripe --fid passed"
5302
5303         #test lfs getstripe with --obd
5304         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
5305                 error "$LFS getstripe --obd wrong_uuid: should return error"
5306
5307         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5308
5309         local ostidx=1
5310         local obduuid=$(ostuuid_from_index $ostidx)
5311         local found=$($LFS getstripe -r --obd $obduuid $dir |
5312                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
5313
5314         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
5315         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
5316                 ((filenum--))
5317         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
5318                 ((filenum--))
5319
5320         [[ $found -eq $filenum ]] ||
5321                 error "$LFS getstripe --obd: found $found expect $filenum"
5322         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
5323                 sed '/^[         ]*'${ostidx}'[  ]/d' |
5324                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
5325                 error "$LFS getstripe --obd: should not show file on other obd"
5326         echo "$LFS getstripe --obd passed"
5327 }
5328 run_test 56a "check $LFS getstripe"
5329
5330 test_56b() {
5331         local dir=$DIR/$tdir
5332         local numdirs=3
5333
5334         test_mkdir $dir
5335         for i in $(seq $numdirs); do
5336                 test_mkdir $dir/dir$i
5337         done
5338
5339         # test lfs getdirstripe default mode is non-recursion, which is
5340         # different from lfs getstripe
5341         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
5342
5343         [[ $dircnt -eq 1 ]] ||
5344                 error "$LFS getdirstripe: found $dircnt, not 1"
5345         dircnt=$($LFS getdirstripe --recursive $dir |
5346                 grep -c lmv_stripe_count)
5347         [[ $dircnt -eq $((numdirs + 1)) ]] ||
5348                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
5349 }
5350 run_test 56b "check $LFS getdirstripe"
5351
5352 test_56c() {
5353         remote_ost_nodsh && skip "remote OST with nodsh"
5354
5355         local ost_idx=0
5356         local ost_name=$(ostname_from_index $ost_idx)
5357         local old_status=$(ost_dev_status $ost_idx)
5358
5359         [[ -z "$old_status" ]] ||
5360                 skip_env "OST $ost_name is in $old_status status"
5361
5362         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
5363         sleep_maxage
5364
5365         local new_status=$(ost_dev_status $ost_idx)
5366
5367         [[ "$new_status" = "D" ]] ||
5368                 error "OST $ost_name is in status of '$new_status', not 'D'"
5369
5370         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
5371         sleep_maxage
5372
5373         new_status=$(ost_dev_status $ost_idx)
5374         [[ -z "$new_status" ]] ||
5375                 error "OST $ost_name is in status of '$new_status', not ''"
5376 }
5377 run_test 56c "check 'lfs df' showing device status"
5378
5379 NUMFILES=3
5380 NUMDIRS=3
5381 setup_56() {
5382         local local_tdir="$1"
5383         local local_numfiles="$2"
5384         local local_numdirs="$3"
5385         local dir_params="$4"
5386         local dir_stripe_params="$5"
5387
5388         if [ ! -d "$local_tdir" ] ; then
5389                 test_mkdir -p $dir_stripe_params $local_tdir
5390                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
5391                 for i in $(seq $local_numfiles) ; do
5392                         touch $local_tdir/file$i
5393                 done
5394                 for i in $(seq $local_numdirs) ; do
5395                         test_mkdir $dir_stripe_params $local_tdir/dir$i
5396                         for j in $(seq $local_numfiles) ; do
5397                                 touch $local_tdir/dir$i/file$j
5398                         done
5399                 done
5400         fi
5401 }
5402
5403 setup_56_special() {
5404         local local_tdir=$1
5405         local local_numfiles=$2
5406         local local_numdirs=$3
5407
5408         setup_56 $local_tdir $local_numfiles $local_numdirs
5409
5410         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
5411                 for i in $(seq $local_numfiles) ; do
5412                         mknod $local_tdir/loop${i}b b 7 $i
5413                         mknod $local_tdir/null${i}c c 1 3
5414                         ln -s $local_tdir/file1 $local_tdir/link${i}
5415                 done
5416                 for i in $(seq $local_numdirs) ; do
5417                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
5418                         mknod $local_tdir/dir$i/null${i}c c 1 3
5419                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
5420                 done
5421         fi
5422 }
5423
5424 test_56g() {
5425         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5426         local expected=$(($NUMDIRS + 2))
5427
5428         setup_56 $dir $NUMFILES $NUMDIRS
5429
5430         # test lfs find with -name
5431         for i in $(seq $NUMFILES) ; do
5432                 local nums=$($LFS find -name "*$i" $dir | wc -l)
5433
5434                 [ $nums -eq $expected ] ||
5435                         error "lfs find -name '*$i' $dir wrong: "\
5436                               "found $nums, expected $expected"
5437         done
5438 }
5439 run_test 56g "check lfs find -name"
5440
5441 test_56h() {
5442         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5443         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
5444
5445         setup_56 $dir $NUMFILES $NUMDIRS
5446
5447         # test lfs find with ! -name
5448         for i in $(seq $NUMFILES) ; do
5449                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
5450
5451                 [ $nums -eq $expected ] ||
5452                         error "lfs find ! -name '*$i' $dir wrong: "\
5453                               "found $nums, expected $expected"
5454         done
5455 }
5456 run_test 56h "check lfs find ! -name"
5457
5458 test_56i() {
5459         local dir=$DIR/$tdir
5460
5461         test_mkdir $dir
5462
5463         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
5464         local out=$($cmd)
5465
5466         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
5467 }
5468 run_test 56i "check 'lfs find -ost UUID' skips directories"
5469
5470 test_56j() {
5471         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5472
5473         setup_56_special $dir $NUMFILES $NUMDIRS
5474
5475         local expected=$((NUMDIRS + 1))
5476         local cmd="$LFS find -type d $dir"
5477         local nums=$($cmd | wc -l)
5478
5479         [ $nums -eq $expected ] ||
5480                 error "'$cmd' wrong: found $nums, expected $expected"
5481 }
5482 run_test 56j "check lfs find -type d"
5483
5484 test_56k() {
5485         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5486
5487         setup_56_special $dir $NUMFILES $NUMDIRS
5488
5489         local expected=$(((NUMDIRS + 1) * NUMFILES))
5490         local cmd="$LFS find -type f $dir"
5491         local nums=$($cmd | wc -l)
5492
5493         [ $nums -eq $expected ] ||
5494                 error "'$cmd' wrong: found $nums, expected $expected"
5495 }
5496 run_test 56k "check lfs find -type f"
5497
5498 test_56l() {
5499         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5500
5501         setup_56_special $dir $NUMFILES $NUMDIRS
5502
5503         local expected=$((NUMDIRS + NUMFILES))
5504         local cmd="$LFS find -type b $dir"
5505         local nums=$($cmd | wc -l)
5506
5507         [ $nums -eq $expected ] ||
5508                 error "'$cmd' wrong: found $nums, expected $expected"
5509 }
5510 run_test 56l "check lfs find -type b"
5511
5512 test_56m() {
5513         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5514
5515         setup_56_special $dir $NUMFILES $NUMDIRS
5516
5517         local expected=$((NUMDIRS + NUMFILES))
5518         local cmd="$LFS find -type c $dir"
5519         local nums=$($cmd | wc -l)
5520         [ $nums -eq $expected ] ||
5521                 error "'$cmd' wrong: found $nums, expected $expected"
5522 }
5523 run_test 56m "check lfs find -type c"
5524
5525 test_56n() {
5526         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5527         setup_56_special $dir $NUMFILES $NUMDIRS
5528
5529         local expected=$((NUMDIRS + NUMFILES))
5530         local cmd="$LFS find -type l $dir"
5531         local nums=$($cmd | wc -l)
5532
5533         [ $nums -eq $expected ] ||
5534                 error "'$cmd' wrong: found $nums, expected $expected"
5535 }
5536 run_test 56n "check lfs find -type l"
5537
5538 test_56o() {
5539         local dir=$DIR/$tdir
5540
5541         setup_56 $dir $NUMFILES $NUMDIRS
5542         utime $dir/file1 > /dev/null || error "utime (1)"
5543         utime $dir/file2 > /dev/null || error "utime (2)"
5544         utime $dir/dir1 > /dev/null || error "utime (3)"
5545         utime $dir/dir2 > /dev/null || error "utime (4)"
5546         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
5547         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
5548
5549         local expected=4
5550         local nums=$($LFS find -mtime +0 $dir | wc -l)
5551
5552         [ $nums -eq $expected ] ||
5553                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
5554
5555         expected=12
5556         cmd="$LFS find -mtime 0 $dir"
5557         nums=$($cmd | wc -l)
5558         [ $nums -eq $expected ] ||
5559                 error "'$cmd' wrong: found $nums, expected $expected"
5560 }
5561 run_test 56o "check lfs find -mtime for old files"
5562
5563 test_56ob() {
5564         local dir=$DIR/$tdir
5565         local expected=1
5566         local count=0
5567
5568         # just to make sure there is something that won't be found
5569         test_mkdir $dir
5570         touch $dir/$tfile.now
5571
5572         for age in year week day hour min; do
5573                 count=$((count + 1))
5574
5575                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
5576                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
5577                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
5578
5579                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
5580                 local nums=$($cmd | wc -l)
5581                 [ $nums -eq $expected ] ||
5582                         error "'$cmd' wrong: found $nums, expected $expected"
5583
5584                 cmd="$LFS find $dir -atime $count${age:0:1}"
5585                 nums=$($cmd | wc -l)
5586                 [ $nums -eq $expected ] ||
5587                         error "'$cmd' wrong: found $nums, expected $expected"
5588         done
5589
5590         sleep 2
5591         cmd="$LFS find $dir -ctime +1s -type f"
5592         nums=$($cmd | wc -l)
5593         (( $nums == $count * 2 + 1)) ||
5594                 error "'$cmd' wrong: found $nums, expected $((expected*2+1))"
5595 }
5596 run_test 56ob "check lfs find -atime -mtime -ctime with units"
5597
5598 test_56p() {
5599         [ $RUNAS_ID -eq $UID ] &&
5600                 skip_env "RUNAS_ID = UID = $UID -- skipping"
5601
5602         local dir=$DIR/$tdir
5603
5604         setup_56 $dir $NUMFILES $NUMDIRS
5605         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
5606
5607         local expected=$NUMFILES
5608         local cmd="$LFS find -uid $RUNAS_ID $dir"
5609         local nums=$($cmd | wc -l)
5610
5611         [ $nums -eq $expected ] ||
5612                 error "'$cmd' wrong: found $nums, expected $expected"
5613
5614         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
5615         cmd="$LFS find ! -uid $RUNAS_ID $dir"
5616         nums=$($cmd | wc -l)
5617         [ $nums -eq $expected ] ||
5618                 error "'$cmd' wrong: found $nums, expected $expected"
5619 }
5620 run_test 56p "check lfs find -uid and ! -uid"
5621
5622 test_56q() {
5623         [ $RUNAS_ID -eq $UID ] &&
5624                 skip_env "RUNAS_ID = UID = $UID -- skipping"
5625
5626         local dir=$DIR/$tdir
5627
5628         setup_56 $dir $NUMFILES $NUMDIRS
5629         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
5630
5631         local expected=$NUMFILES
5632         local cmd="$LFS find -gid $RUNAS_GID $dir"
5633         local nums=$($cmd | wc -l)
5634
5635         [ $nums -eq $expected ] ||
5636                 error "'$cmd' wrong: found $nums, expected $expected"
5637
5638         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
5639         cmd="$LFS find ! -gid $RUNAS_GID $dir"
5640         nums=$($cmd | wc -l)
5641         [ $nums -eq $expected ] ||
5642                 error "'$cmd' wrong: found $nums, expected $expected"
5643 }
5644 run_test 56q "check lfs find -gid and ! -gid"
5645
5646 test_56r() {
5647         local dir=$DIR/$tdir
5648
5649         setup_56 $dir $NUMFILES $NUMDIRS
5650
5651         local expected=12
5652         local cmd="$LFS find -size 0 -type f $dir"
5653         local nums=$($cmd | wc -l)
5654
5655         [ $nums -eq $expected ] ||
5656                 error "'$cmd' wrong: found $nums, expected $expected"
5657         expected=0
5658         cmd="$LFS find ! -size 0 -type f $dir"
5659         nums=$($cmd | wc -l)
5660         [ $nums -eq $expected ] ||
5661                 error "'$cmd' wrong: found $nums, expected $expected"
5662         echo "test" > $dir/$tfile
5663         echo "test2" > $dir/$tfile.2 && sync
5664         expected=1
5665         cmd="$LFS find -size 5 -type f $dir"
5666         nums=$($cmd | wc -l)
5667         [ $nums -eq $expected ] ||
5668                 error "'$cmd' wrong: found $nums, expected $expected"
5669         expected=1
5670         cmd="$LFS find -size +5 -type f $dir"
5671         nums=$($cmd | wc -l)
5672         [ $nums -eq $expected ] ||
5673                 error "'$cmd' wrong: found $nums, expected $expected"
5674         expected=2
5675         cmd="$LFS find -size +0 -type f $dir"
5676         nums=$($cmd | wc -l)
5677         [ $nums -eq $expected ] ||
5678                 error "'$cmd' wrong: found $nums, expected $expected"
5679         expected=2
5680         cmd="$LFS find ! -size -5 -type f $dir"
5681         nums=$($cmd | wc -l)
5682         [ $nums -eq $expected ] ||
5683                 error "'$cmd' wrong: found $nums, expected $expected"
5684         expected=12
5685         cmd="$LFS find -size -5 -type f $dir"
5686         nums=$($cmd | wc -l)
5687         [ $nums -eq $expected ] ||
5688                 error "'$cmd' wrong: found $nums, expected $expected"
5689 }
5690 run_test 56r "check lfs find -size works"
5691
5692 test_56s() { # LU-611 #LU-9369
5693         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
5694
5695         local dir=$DIR/$tdir
5696         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
5697
5698         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
5699         for i in $(seq $NUMDIRS); do
5700                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
5701         done
5702
5703         local expected=$NUMDIRS
5704         local cmd="$LFS find -c $OSTCOUNT $dir"
5705         local nums=$($cmd | wc -l)
5706
5707         [ $nums -eq $expected ] || {
5708                 $LFS getstripe -R $dir
5709                 error "'$cmd' wrong: found $nums, expected $expected"
5710         }
5711
5712         expected=$((NUMDIRS + onestripe))
5713         cmd="$LFS find -stripe-count +0 -type f $dir"
5714         nums=$($cmd | wc -l)
5715         [ $nums -eq $expected ] || {
5716                 $LFS getstripe -R $dir
5717                 error "'$cmd' wrong: found $nums, expected $expected"
5718         }
5719
5720         expected=$onestripe
5721         cmd="$LFS find -stripe-count 1 -type f $dir"
5722         nums=$($cmd | wc -l)
5723         [ $nums -eq $expected ] || {
5724                 $LFS getstripe -R $dir
5725                 error "'$cmd' wrong: found $nums, expected $expected"
5726         }
5727
5728         cmd="$LFS find -stripe-count -2 -type f $dir"
5729         nums=$($cmd | wc -l)
5730         [ $nums -eq $expected ] || {
5731                 $LFS getstripe -R $dir
5732                 error "'$cmd' wrong: found $nums, expected $expected"
5733         }
5734
5735         expected=0
5736         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
5737         nums=$($cmd | wc -l)
5738         [ $nums -eq $expected ] || {
5739                 $LFS getstripe -R $dir
5740                 error "'$cmd' wrong: found $nums, expected $expected"
5741         }
5742 }
5743 run_test 56s "check lfs find -stripe-count works"
5744
5745 test_56t() { # LU-611 #LU-9369
5746         local dir=$DIR/$tdir
5747
5748         setup_56 $dir 0 $NUMDIRS
5749         for i in $(seq $NUMDIRS); do
5750                 $LFS setstripe -S 8M $dir/dir$i/$tfile
5751         done
5752
5753         local expected=$NUMDIRS
5754         local cmd="$LFS find -S 8M $dir"
5755         local nums=$($cmd | wc -l)
5756
5757         [ $nums -eq $expected ] || {
5758                 $LFS getstripe -R $dir
5759                 error "'$cmd' wrong: found $nums, expected $expected"
5760         }
5761         rm -rf $dir
5762
5763         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
5764
5765         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
5766
5767         expected=$(((NUMDIRS + 1) * NUMFILES))
5768         cmd="$LFS find -stripe-size 512k -type f $dir"
5769         nums=$($cmd | wc -l)
5770         [ $nums -eq $expected ] ||
5771                 error "'$cmd' wrong: found $nums, expected $expected"
5772
5773         cmd="$LFS find -stripe-size +320k -type f $dir"
5774         nums=$($cmd | wc -l)
5775         [ $nums -eq $expected ] ||
5776                 error "'$cmd' wrong: found $nums, expected $expected"
5777
5778         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
5779         cmd="$LFS find -stripe-size +200k -type f $dir"
5780         nums=$($cmd | wc -l)
5781         [ $nums -eq $expected ] ||
5782                 error "'$cmd' wrong: found $nums, expected $expected"
5783
5784         cmd="$LFS find -stripe-size -640k -type f $dir"
5785         nums=$($cmd | wc -l)
5786         [ $nums -eq $expected ] ||
5787                 error "'$cmd' wrong: found $nums, expected $expected"
5788
5789         expected=4
5790         cmd="$LFS find -stripe-size 256k -type f $dir"
5791         nums=$($cmd | wc -l)
5792         [ $nums -eq $expected ] ||
5793                 error "'$cmd' wrong: found $nums, expected $expected"
5794
5795         cmd="$LFS find -stripe-size -320k -type f $dir"
5796         nums=$($cmd | wc -l)
5797         [ $nums -eq $expected ] ||
5798                 error "'$cmd' wrong: found $nums, expected $expected"
5799
5800         expected=0
5801         cmd="$LFS find -stripe-size 1024k -type f $dir"
5802         nums=$($cmd | wc -l)
5803         [ $nums -eq $expected ] ||
5804                 error "'$cmd' wrong: found $nums, expected $expected"
5805 }
5806 run_test 56t "check lfs find -stripe-size works"
5807
5808 test_56u() { # LU-611
5809         local dir=$DIR/$tdir
5810
5811         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
5812
5813         if [[ $OSTCOUNT -gt 1 ]]; then
5814                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
5815                 onestripe=4
5816         else
5817                 onestripe=0
5818         fi
5819
5820         local expected=$(((NUMDIRS + 1) * NUMFILES))
5821         local cmd="$LFS find -stripe-index 0 -type f $dir"
5822         local nums=$($cmd | wc -l)
5823
5824         [ $nums -eq $expected ] ||
5825                 error "'$cmd' wrong: found $nums, expected $expected"
5826
5827         expected=$onestripe
5828         cmd="$LFS find -stripe-index 1 -type f $dir"
5829         nums=$($cmd | wc -l)
5830         [ $nums -eq $expected ] ||
5831                 error "'$cmd' wrong: found $nums, expected $expected"
5832
5833         cmd="$LFS find ! -stripe-index 0 -type f $dir"
5834         nums=$($cmd | wc -l)
5835         [ $nums -eq $expected ] ||
5836                 error "'$cmd' wrong: found $nums, expected $expected"
5837
5838         expected=0
5839         # This should produce an error and not return any files
5840         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
5841         nums=$($cmd 2>/dev/null | wc -l)
5842         [ $nums -eq $expected ] ||
5843                 error "'$cmd' wrong: found $nums, expected $expected"
5844
5845         if [[ $OSTCOUNT -gt 1 ]]; then
5846                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
5847                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
5848                 nums=$($cmd | wc -l)
5849                 [ $nums -eq $expected ] ||
5850                         error "'$cmd' wrong: found $nums, expected $expected"
5851         fi
5852 }
5853 run_test 56u "check lfs find -stripe-index works"
5854
5855 test_56v() {
5856         local mdt_idx=0
5857         local dir=$DIR/$tdir
5858
5859         setup_56 $dir $NUMFILES $NUMDIRS
5860
5861         UUID=$(mdtuuid_from_index $mdt_idx $dir)
5862         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
5863
5864         for file in $($LFS find -m $UUID $dir); do
5865                 file_midx=$($LFS getstripe -m $file)
5866                 [ $file_midx -eq $mdt_idx ] ||
5867                         error "lfs find -m $UUID != getstripe -m $file_midx"
5868         done
5869 }
5870 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
5871
5872 test_56w() {
5873         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5874         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5875
5876         local dir=$DIR/$tdir
5877
5878         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
5879
5880         local stripe_size=$($LFS getstripe -S -d $dir) ||
5881                 error "$LFS getstripe -S -d $dir failed"
5882         stripe_size=${stripe_size%% *}
5883
5884         local file_size=$((stripe_size * OSTCOUNT))
5885         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
5886         local required_space=$((file_num * file_size))
5887         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
5888                            head -n1)
5889         [[ $free_space -le $((required_space / 1024)) ]] &&
5890                 skip_env "need $required_space, have $free_space kbytes"
5891
5892         local dd_bs=65536
5893         local dd_count=$((file_size / dd_bs))
5894
5895         # write data into the files
5896         local i
5897         local j
5898         local file
5899
5900         for i in $(seq $NUMFILES); do
5901                 file=$dir/file$i
5902                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
5903                         error "write data into $file failed"
5904         done
5905         for i in $(seq $NUMDIRS); do
5906                 for j in $(seq $NUMFILES); do
5907                         file=$dir/dir$i/file$j
5908                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
5909                                 error "write data into $file failed"
5910                 done
5911         done
5912
5913         # $LFS_MIGRATE will fail if hard link migration is unsupported
5914         if [[ $(lustre_version_code mds1) -gt $(version_code 2.5.55) ]]; then
5915                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
5916                         error "creating links to $dir/dir1/file1 failed"
5917         fi
5918
5919         local expected=-1
5920
5921         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
5922
5923         # lfs_migrate file
5924         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
5925
5926         echo "$cmd"
5927         eval $cmd || error "$cmd failed"
5928
5929         check_stripe_count $dir/file1 $expected
5930
5931         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
5932         then
5933                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
5934                 # OST 1 if it is on OST 0. This file is small enough to
5935                 # be on only one stripe.
5936                 file=$dir/migr_1_ost
5937                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
5938                         error "write data into $file failed"
5939                 local obdidx=$($LFS getstripe -i $file)
5940                 local oldmd5=$(md5sum $file)
5941                 local newobdidx=0
5942
5943                 [[ $obdidx -eq 0 ]] && newobdidx=1
5944                 cmd="$LFS migrate -i $newobdidx $file"
5945                 echo $cmd
5946                 eval $cmd || error "$cmd failed"
5947
5948                 local realobdix=$($LFS getstripe -i $file)
5949                 local newmd5=$(md5sum $file)
5950
5951                 [[ $newobdidx -ne $realobdix ]] &&
5952                         error "new OST is different (was=$obdidx, "\
5953                               "wanted=$newobdidx, got=$realobdix)"
5954                 [[ "$oldmd5" != "$newmd5" ]] &&
5955                         error "md5sum differ: $oldmd5, $newmd5"
5956         fi
5957
5958         # lfs_migrate dir
5959         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
5960         echo "$cmd"
5961         eval $cmd || error "$cmd failed"
5962
5963         for j in $(seq $NUMFILES); do
5964                 check_stripe_count $dir/dir1/file$j $expected
5965         done
5966
5967         # lfs_migrate works with lfs find
5968         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
5969              $LFS_MIGRATE -y -c $expected"
5970         echo "$cmd"
5971         eval $cmd || error "$cmd failed"
5972
5973         for i in $(seq 2 $NUMFILES); do
5974                 check_stripe_count $dir/file$i $expected
5975         done
5976         for i in $(seq 2 $NUMDIRS); do
5977                 for j in $(seq $NUMFILES); do
5978                 check_stripe_count $dir/dir$i/file$j $expected
5979                 done
5980         done
5981 }
5982 run_test 56w "check lfs_migrate -c stripe_count works"
5983
5984 test_56wb() {
5985         local file1=$DIR/$tdir/file1
5986         local create_pool=false
5987         local initial_pool=$($LFS getstripe -p $DIR)
5988         local pool_list=()
5989         local pool=""
5990
5991         echo -n "Creating test dir..."
5992         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
5993         echo "done."
5994
5995         echo -n "Creating test file..."
5996         touch $file1 || error "cannot create file"
5997         echo "done."
5998
5999         echo -n "Detecting existing pools..."
6000         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
6001
6002         if [ ${#pool_list[@]} -gt 0 ]; then
6003                 echo "${pool_list[@]}"
6004                 for thispool in "${pool_list[@]}"; do
6005                         if [[ -z "$initial_pool" ||
6006                               "$initial_pool" != "$thispool" ]]; then
6007                                 pool="$thispool"
6008                                 echo "Using existing pool '$pool'"
6009                                 break
6010                         fi
6011                 done
6012         else
6013                 echo "none detected."
6014         fi
6015         if [ -z "$pool" ]; then
6016                 pool=${POOL:-testpool}
6017                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
6018                 echo -n "Creating pool '$pool'..."
6019                 create_pool=true
6020                 pool_add $pool &> /dev/null ||
6021                         error "pool_add failed"
6022                 echo "done."
6023
6024                 echo -n "Adding target to pool..."
6025                 pool_add_targets $pool 0 0 1 &> /dev/null ||
6026                         error "pool_add_targets failed"
6027                 echo "done."
6028         fi
6029
6030         echo -n "Setting pool using -p option..."
6031         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
6032                 error "migrate failed rc = $?"
6033         echo "done."
6034
6035         echo -n "Verifying test file is in pool after migrating..."
6036         [ "$($LFS getstripe -p $file1)" = $pool ] ||
6037                 error "file was not migrated to pool $pool"
6038         echo "done."
6039
6040         echo -n "Removing test file from pool '$pool'..."
6041         $LFS migrate $file1 &> /dev/null ||
6042                 error "cannot remove from pool"
6043         [ "$($LFS getstripe -p $file1)" ] &&
6044                 error "pool still set"
6045         echo "done."
6046
6047         echo -n "Setting pool using --pool option..."
6048         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
6049                 error "migrate failed rc = $?"
6050         echo "done."
6051
6052         # Clean up
6053         rm -f $file1
6054         if $create_pool; then
6055                 destroy_test_pools 2> /dev/null ||
6056                         error "destroy test pools failed"
6057         fi
6058 }
6059 run_test 56wb "check lfs_migrate pool support"
6060
6061 test_56wc() {
6062         local file1="$DIR/$tdir/file1"
6063
6064         echo -n "Creating test dir..."
6065         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
6066         local def_stripe_size=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
6067         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
6068                 error "cannot set stripe"
6069         echo "done"
6070
6071         echo -n "Setting initial stripe for test file..."
6072         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
6073                 error "cannot set stripe"
6074         [ $($LFS getstripe -S "$file1") -eq 524288 ] ||
6075                 error "stripe size not set"
6076         echo "done."
6077
6078         # File currently set to -S 512K -c 1
6079
6080         # Ensure -c and -S options are rejected when -R is set
6081         echo -n "Verifying incompatible options are detected..."
6082         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
6083                 error "incompatible -c and -R options not detected"
6084         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
6085                 error "incompatible -S and -R options not detected"
6086         echo "done."
6087
6088         # Ensure unrecognized options are passed through to 'lfs migrate'
6089         echo -n "Verifying -S option is passed through to lfs migrate..."
6090         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
6091                 error "migration failed"
6092         [ $($LFS getstripe -S "$file1") -eq 1048576 ] ||
6093                 error "file was not restriped"
6094         echo "done."
6095
6096         # File currently set to -S 1M -c 1
6097
6098         # Ensure long options are supported
6099         echo -n "Verifying long options supported..."
6100         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
6101                 error "long option without argument not supported"
6102         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
6103                 error "long option with argument not supported"
6104         [ $($LFS getstripe -S "$file1") -eq 524288 ] ||
6105                 error "file not restriped with --stripe-size option"
6106         echo "done."
6107
6108         # File currently set to -S 512K -c 1
6109
6110         if [ "$OSTCOUNT" -gt 1 ]; then
6111                 echo -n "Verifying explicit stripe count can be set..."
6112                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
6113                         error "migrate failed"
6114                 [ $($LFS getstripe -c "$file1") -eq 2 ] ||
6115                         error "file not restriped to explicit count"
6116                 echo "done."
6117         fi
6118
6119         # File currently set to -S 512K -c 1 or -S 512K -c 2
6120
6121         # Ensure parent striping is used if -R is set, and no stripe
6122         # count or size is specified
6123         echo -n "Setting stripe for parent directory..."
6124         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
6125                 error "cannot set stripe"
6126         echo "done."
6127
6128         echo -n "Verifying restripe option uses parent stripe settings..."
6129         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
6130                 error "migrate failed"
6131         [ $($LFS getstripe -S "$file1") -eq $def_stripe_size ] ||
6132                 error "file not restriped to parent settings"
6133         [ $($LFS getstripe -c "$file1") -eq 1 ] ||
6134                 error "file not restriped to parent settings"
6135         echo "done."
6136
6137         # File currently set to -S 1M -c 1
6138
6139         # Ensure striping is preserved if -R is not set, and no stripe
6140         # count or size is specified
6141         echo -n "Verifying striping size preserved when not specified..."
6142         local orig_stripe_size=$($LFS getstripe -S "$file1" 2>/dev/null)
6143         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
6144                 error "cannot set stripe on parent directory"
6145         $LFS_MIGRATE -y "$file1" &> /dev/null ||
6146                 error "migrate failed"
6147         [ $($LFS getstripe -S "$file1") -eq $orig_stripe_size ] ||
6148                 error "file was restriped"
6149         echo "done."
6150
6151         # Ensure file name properly detected when final option has no argument
6152         echo -n "Verifying file name properly detected..."
6153         $LFS_MIGRATE -y "$file1" &> /dev/null ||
6154                 error "file name interpreted as option argument"
6155         echo "done."
6156
6157         # Clean up
6158         rm -f "$file1"
6159 }
6160 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
6161
6162 test_56wd() {
6163         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6164
6165         local file1=$DIR/$tdir/file1
6166
6167         echo -n "Creating test dir..."
6168         test_mkdir $DIR/$tdir || error "cannot create dir"
6169         echo "done."
6170
6171         echo -n "Creating test file..."
6172         touch $file1
6173         echo "done."
6174
6175         # Ensure 'lfs migrate' will fail by using a non-existent option,
6176         # and make sure rsync is not called to recover
6177         echo -n "Make sure --no-rsync option works..."
6178         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
6179                 grep -q 'refusing to fall back to rsync' ||
6180                 error "rsync was called with --no-rsync set"
6181         echo "done."
6182
6183         # Ensure rsync is called without trying 'lfs migrate' first
6184         echo -n "Make sure --rsync option works..."
6185         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
6186                 grep -q 'falling back to rsync' &&
6187                 error "lfs migrate was called with --rsync set"
6188         echo "done."
6189
6190         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
6191         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
6192                 grep -q 'at the same time' ||
6193                 error "--rsync and --no-rsync accepted concurrently"
6194         echo "done."
6195
6196         # Clean up
6197         rm -f $file1
6198 }
6199 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
6200
6201 test_56x() {
6202         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6203         check_swap_layouts_support
6204
6205         local dir=$DIR/$tdir
6206         local ref1=/etc/passwd
6207         local file1=$dir/file1
6208
6209         test_mkdir $dir || error "creating dir $dir"
6210         $LFS setstripe -c 2 $file1
6211         cp $ref1 $file1
6212         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
6213         stripe=$($LFS getstripe -c $file1)
6214         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
6215         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
6216
6217         # clean up
6218         rm -f $file1
6219 }
6220 run_test 56x "lfs migration support"
6221
6222 test_56xa() {
6223         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6224         check_swap_layouts_support
6225
6226         local dir=$DIR/$tdir/$testnum
6227
6228         test_mkdir -p $dir
6229
6230         local ref1=/etc/passwd
6231         local file1=$dir/file1
6232
6233         $LFS setstripe -c 2 $file1
6234         cp $ref1 $file1
6235         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
6236
6237         local stripe=$($LFS getstripe -c $file1)
6238
6239         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
6240         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
6241
6242         # clean up
6243         rm -f $file1
6244 }
6245 run_test 56xa "lfs migration --block support"
6246
6247 check_migrate_links() {
6248         local dir="$1"
6249         local file1="$dir/file1"
6250         local begin="$2"
6251         local count="$3"
6252         local total_count=$(($begin + $count - 1))
6253         local symlink_count=10
6254         local uniq_count=10
6255
6256         if [ ! -f "$file1" ]; then
6257                 echo -n "creating initial file..."
6258                 $LFS setstripe -c 1 -S "512k" "$file1" ||
6259                         error "cannot setstripe initial file"
6260                 echo "done"
6261
6262                 echo -n "creating symlinks..."
6263                 for s in $(seq 1 $symlink_count); do
6264                         ln -s "$file1" "$dir/slink$s" ||
6265                                 error "cannot create symlinks"
6266                 done
6267                 echo "done"
6268
6269                 echo -n "creating nonlinked files..."
6270                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
6271                         error "cannot create nonlinked files"
6272                 echo "done"
6273         fi
6274
6275         # create hard links
6276         if [ ! -f "$dir/file$total_count" ]; then
6277                 echo -n "creating hard links $begin:$total_count..."
6278                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
6279                         /dev/null || error "cannot create hard links"
6280                 echo "done"
6281         fi
6282
6283         echo -n "checking number of hard links listed in xattrs..."
6284         local fid=$($LFS getstripe -F "$file1")
6285         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
6286
6287         echo "${#paths[*]}"
6288         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
6289                         skip "hard link list has unexpected size, skipping test"
6290         fi
6291         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
6292                         error "link names should exceed xattrs size"
6293         fi
6294
6295         echo -n "migrating files..."
6296         local migrate_out=$($LFS_MIGRATE -y -S '1m' $dir)
6297         local rc=$?
6298         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
6299         echo "done"
6300
6301         # make sure all links have been properly migrated
6302         echo -n "verifying files..."
6303         fid=$($LFS getstripe -F "$file1") ||
6304                 error "cannot get fid for file $file1"
6305         for i in $(seq 2 $total_count); do
6306                 local fid2=$($LFS getstripe -F $dir/file$i)
6307
6308                 [ "$fid2" == "$fid" ] ||
6309                         error "migrated hard link has mismatched FID"
6310         done
6311
6312         # make sure hard links were properly detected, and migration was
6313         # performed only once for the entire link set; nonlinked files should
6314         # also be migrated
6315         local actual=$(grep -c 'done' <<< "$migrate_out")
6316         local expected=$(($uniq_count + 1))
6317
6318         [ "$actual" -eq  "$expected" ] ||
6319                 error "hard links individually migrated ($actual != $expected)"
6320
6321         # make sure the correct number of hard links are present
6322         local hardlinks=$(stat -c '%h' "$file1")
6323
6324         [ $hardlinks -eq $total_count ] ||
6325                 error "num hard links $hardlinks != $total_count"
6326         echo "done"
6327
6328         return 0
6329 }
6330
6331 test_56xb() {
6332         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
6333                 skip "Need MDS version at least 2.10.55"
6334
6335         local dir="$DIR/$tdir"
6336
6337         test_mkdir "$dir" || error "cannot create dir $dir"
6338
6339         echo "testing lfs migrate mode when all links fit within xattrs"
6340         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
6341
6342         echo "testing rsync mode when all links fit within xattrs"
6343         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
6344
6345         echo "testing lfs migrate mode when all links do not fit within xattrs"
6346         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
6347
6348         echo "testing rsync mode when all links do not fit within xattrs"
6349         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
6350
6351
6352         # clean up
6353         rm -rf $dir
6354 }
6355 run_test 56xb "lfs migration hard link support"
6356
6357 test_56xc() {
6358         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6359
6360         local dir="$DIR/$tdir"
6361
6362         test_mkdir "$dir" || error "cannot create dir $dir"
6363
6364         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
6365         echo -n "Setting initial stripe for 20MB test file..."
6366         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
6367                 error "cannot setstripe 20MB file"
6368         echo "done"
6369         echo -n "Sizing 20MB test file..."
6370         truncate "$dir/20mb" 20971520 || error "cannot create 20MB test file"
6371         echo "done"
6372         echo -n "Verifying small file autostripe count is 1..."
6373         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
6374                 error "cannot migrate 20MB file"
6375         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
6376                 error "cannot get stripe for $dir/20mb"
6377         [ $stripe_count -eq 1 ] ||
6378                 error "unexpected stripe count $stripe_count for 20MB file"
6379         rm -f "$dir/20mb"
6380         echo "done"
6381
6382         # Test 2: File is small enough to fit within the available space on
6383         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
6384         # have at least an additional 1KB for each desired stripe for test 3
6385         echo -n "Setting stripe for 1GB test file..."
6386         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
6387         echo "done"
6388         echo -n "Sizing 1GB test file..."
6389         # File size is 1GB + 3KB
6390         truncate "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
6391         echo "done"
6392
6393         # need at least 512MB per OST for 1GB file to fit in 2 stripes
6394         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
6395         if (( avail > 524288 * OSTCOUNT )); then
6396                 echo -n "Migrating 1GB file..."
6397                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
6398                         error "cannot migrate 1GB file"
6399                 echo "done"
6400                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
6401                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
6402                         error "cannot getstripe for 1GB file"
6403                 [ $stripe_count -eq 2 ] ||
6404                         error "unexpected stripe count $stripe_count != 2"
6405                 echo "done"
6406         fi
6407
6408         # Test 3: File is too large to fit within the available space on
6409         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
6410         if [ $OSTCOUNT -ge 3 ]; then
6411                 # The required available space is calculated as
6412                 # file size (1GB + 3KB) / OST count (3).
6413                 local kb_per_ost=349526
6414
6415                 echo -n "Migrating 1GB file with limit..."
6416                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
6417                         error "cannot migrate 1GB file with limit"
6418                 echo "done"
6419
6420                 stripe_count=$($LFS getstripe -c "$dir/1gb")
6421                 echo -n "Verifying 1GB autostripe count with limited space..."
6422                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
6423                         error "unexpected stripe count $stripe_count (min 3)"
6424                 echo "done"
6425         fi
6426
6427         # clean up
6428         rm -rf $dir
6429 }
6430 run_test 56xc "lfs migration autostripe"
6431
6432 test_56y() {
6433         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
6434                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
6435
6436         local res=""
6437         local dir=$DIR/$tdir
6438         local f1=$dir/file1
6439         local f2=$dir/file2
6440
6441         test_mkdir -p $dir || error "creating dir $dir"
6442         touch $f1 || error "creating std file $f1"
6443         $MULTIOP $f2 H2c || error "creating released file $f2"
6444
6445         # a directory can be raid0, so ask only for files
6446         res=$($LFS find $dir -L raid0 -type f | wc -l)
6447         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
6448
6449         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
6450         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
6451
6452         # only files can be released, so no need to force file search
6453         res=$($LFS find $dir -L released)
6454         [[ $res == $f2 ]] || error "search released: found $res != $f2"
6455
6456         res=$($LFS find $dir -type f \! -L released)
6457         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
6458 }
6459 run_test 56y "lfs find -L raid0|released"
6460
6461 test_56z() { # LU-4824
6462         # This checks to make sure 'lfs find' continues after errors
6463         # There are two classes of errors that should be caught:
6464         # - If multiple paths are provided, all should be searched even if one
6465         #   errors out
6466         # - If errors are encountered during the search, it should not terminate
6467         #   early
6468         local dir=$DIR/$tdir
6469         local i
6470
6471         test_mkdir $dir
6472         for i in d{0..9}; do
6473                 test_mkdir $dir/$i
6474                 touch $dir/$i/$tfile
6475         done
6476         $LFS find $DIR/non_existent_dir $dir &&
6477                 error "$LFS find did not return an error"
6478         # Make a directory unsearchable. This should NOT be the last entry in
6479         # directory order.  Arbitrarily pick the 6th entry
6480         chmod 700 $($LFS find $dir -type d | sed '6!d')
6481
6482         $RUNAS $LFS find $DIR/non_existent $dir
6483         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
6484
6485         # The user should be able to see 10 directories and 9 files
6486         (( count == 19 )) ||
6487                 error "$LFS find found $count != 19 entries after error"
6488 }
6489 run_test 56z "lfs find should continue after an error"
6490
6491 test_56aa() { # LU-5937
6492         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
6493
6494         local dir=$DIR/$tdir
6495
6496         mkdir $dir
6497         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
6498
6499         createmany -o $dir/striped_dir/${tfile}- 1024
6500         local dirs=$($LFS find --size +8k $dir/)
6501
6502         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
6503 }
6504 run_test 56aa "lfs find --size under striped dir"
6505
6506 test_56ab() { # LU-10705
6507         test_mkdir $DIR/$tdir
6508         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
6509         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
6510         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
6511         # Flush writes to ensure valid blocks.  Need to be more thorough for
6512         # ZFS, since blocks are not allocated/returned to client immediately.
6513         sync_all_data
6514         wait_zfs_commit ost1 2
6515         cancel_lru_locks osc
6516         ls -ls $DIR/$tdir
6517
6518         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
6519
6520         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
6521
6522         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
6523         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
6524
6525         rm -f $DIR/$tdir/$tfile.[123]
6526 }
6527 run_test 56ab "lfs find --blocks"
6528
6529 test_56ba() {
6530         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
6531                 skip "Need MDS version at least 2.10.50"
6532
6533         # Create composite files with one component
6534         local dir=$DIR/$tdir
6535
6536         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
6537         # Create composite files with three components
6538         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
6539         # Create non-composite files
6540         createmany -o $dir/${tfile}- 10
6541
6542         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
6543
6544         [[ $nfiles == 10 ]] ||
6545                 error "lfs find -E 1M found $nfiles != 10 files"
6546
6547         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
6548         [[ $nfiles == 25 ]] ||
6549                 error "lfs find ! -E 1M found $nfiles != 25 files"
6550
6551         # All files have a component that starts at 0
6552         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
6553         [[ $nfiles == 35 ]] ||
6554                 error "lfs find --component-start 0 - $nfiles != 35 files"
6555
6556         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
6557         [[ $nfiles == 15 ]] ||
6558                 error "lfs find --component-start 2M - $nfiles != 15 files"
6559
6560         # All files created here have a componenet that does not starts at 2M
6561         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
6562         [[ $nfiles == 35 ]] ||
6563                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
6564
6565         # Find files with a specified number of components
6566         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
6567         [[ $nfiles == 15 ]] ||
6568                 error "lfs find --component-count 3 - $nfiles != 15 files"
6569
6570         # Remember non-composite files have a component count of zero
6571         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
6572         [[ $nfiles == 10 ]] ||
6573                 error "lfs find --component-count 0 - $nfiles != 10 files"
6574
6575         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
6576         [[ $nfiles == 20 ]] ||
6577                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
6578
6579         # All files have a flag called "init"
6580         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
6581         [[ $nfiles == 35 ]] ||
6582                 error "lfs find --component-flags init - $nfiles != 35 files"
6583
6584         # Multi-component files will have a component not initialized
6585         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
6586         [[ $nfiles == 15 ]] ||
6587                 error "lfs find !--component-flags init - $nfiles != 15 files"
6588
6589         rm -rf $dir
6590
6591 }
6592 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
6593
6594 test_56ca() {
6595         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
6596                 skip "Need MDS version at least 2.10.57"
6597
6598         local td=$DIR/$tdir
6599         local tf=$td/$tfile
6600         local dir
6601         local nfiles
6602         local cmd
6603         local i
6604         local j
6605
6606         # create mirrored directories and mirrored files
6607         mkdir $td || error "mkdir $td failed"
6608         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
6609         createmany -o $tf- 10 || error "create $tf- failed"
6610
6611         for i in $(seq 2); do
6612                 dir=$td/dir$i
6613                 mkdir $dir || error "mkdir $dir failed"
6614                 $LFS mirror create -N$((3 + i)) $dir ||
6615                         error "create mirrored dir $dir failed"
6616                 createmany -o $dir/$tfile- 10 ||
6617                         error "create $dir/$tfile- failed"
6618         done
6619
6620         # change the states of some mirrored files
6621         echo foo > $tf-6
6622         for i in $(seq 2); do
6623                 dir=$td/dir$i
6624                 for j in $(seq 4 9); do
6625                         echo foo > $dir/$tfile-$j
6626                 done
6627         done
6628
6629         # find mirrored files with specific mirror count
6630         cmd="$LFS find --mirror-count 3 --type f $td"
6631         nfiles=$($cmd | wc -l)
6632         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
6633
6634         cmd="$LFS find ! --mirror-count 3 --type f $td"
6635         nfiles=$($cmd | wc -l)
6636         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
6637
6638         cmd="$LFS find --mirror-count +2 --type f $td"
6639         nfiles=$($cmd | wc -l)
6640         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
6641
6642         cmd="$LFS find --mirror-count -6 --type f $td"
6643         nfiles=$($cmd | wc -l)
6644         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
6645
6646         # find mirrored files with specific file state
6647         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
6648         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
6649
6650         cmd="$LFS find --mirror-state=ro --type f $td"
6651         nfiles=$($cmd | wc -l)
6652         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
6653
6654         cmd="$LFS find ! --mirror-state=ro --type f $td"
6655         nfiles=$($cmd | wc -l)
6656         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
6657
6658         cmd="$LFS find --mirror-state=wp --type f $td"
6659         nfiles=$($cmd | wc -l)
6660         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
6661
6662         cmd="$LFS find ! --mirror-state=sp --type f $td"
6663         nfiles=$($cmd | wc -l)
6664         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
6665 }
6666 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
6667
6668 test_57a() {
6669         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6670         # note test will not do anything if MDS is not local
6671         if [ "$mds1_FSTYPE" != ldiskfs ]; then
6672                 skip_env "ldiskfs only test"
6673         fi
6674         remote_mds_nodsh && skip "remote MDS with nodsh"
6675
6676         local MNTDEV="osd*.*MDT*.mntdev"
6677         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
6678         [ -z "$DEV" ] && error "can't access $MNTDEV"
6679         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
6680                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
6681                         error "can't access $DEV"
6682                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
6683                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
6684                 rm $TMP/t57a.dump
6685         done
6686 }
6687 run_test 57a "verify MDS filesystem created with large inodes =="
6688
6689 test_57b() {
6690         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6691         if [ "$mds1_FSTYPE" != ldiskfs ]; then
6692                 skip_env "ldiskfs only test"
6693         fi
6694         remote_mds_nodsh && skip "remote MDS with nodsh"
6695
6696         local dir=$DIR/$tdir
6697         local filecount=100
6698         local file1=$dir/f1
6699         local fileN=$dir/f$filecount
6700
6701         rm -rf $dir || error "removing $dir"
6702         test_mkdir -c1 $dir
6703         local mdtidx=$($LFS getstripe -m $dir)
6704         local mdtname=MDT$(printf %04x $mdtidx)
6705         local facet=mds$((mdtidx + 1))
6706
6707         echo "mcreating $filecount files"
6708         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
6709
6710         # verify that files do not have EAs yet
6711         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
6712                 error "$file1 has an EA"
6713         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
6714                 error "$fileN has an EA"
6715
6716         sync
6717         sleep 1
6718         df $dir  #make sure we get new statfs data
6719         local mdsfree=$(do_facet $facet \
6720                         lctl get_param -n osd*.*$mdtname.kbytesfree)
6721         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
6722         local file
6723
6724         echo "opening files to create objects/EAs"
6725         for file in $(seq -f $dir/f%g 1 $filecount); do
6726                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
6727                         error "opening $file"
6728         done
6729
6730         # verify that files have EAs now
6731         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
6732         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
6733
6734         sleep 1  #make sure we get new statfs data
6735         df $dir
6736         local mdsfree2=$(do_facet $facet \
6737                          lctl get_param -n osd*.*$mdtname.kbytesfree)
6738         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
6739
6740         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
6741                 if [ "$mdsfree" != "$mdsfree2" ]; then
6742                         error "MDC before $mdcfree != after $mdcfree2"
6743                 else
6744                         echo "MDC before $mdcfree != after $mdcfree2"
6745                         echo "unable to confirm if MDS has large inodes"
6746                 fi
6747         fi
6748         rm -rf $dir
6749 }
6750 run_test 57b "default LOV EAs are stored inside large inodes ==="
6751
6752 test_58() {
6753         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6754         [ -z "$(which wiretest 2>/dev/null)" ] &&
6755                         skip_env "could not find wiretest"
6756
6757         wiretest
6758 }
6759 run_test 58 "verify cross-platform wire constants =============="
6760
6761 test_59() {
6762         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6763
6764         echo "touch 130 files"
6765         createmany -o $DIR/f59- 130
6766         echo "rm 130 files"
6767         unlinkmany $DIR/f59- 130
6768         sync
6769         # wait for commitment of removal
6770         wait_delete_completed
6771 }
6772 run_test 59 "verify cancellation of llog records async ========="
6773
6774 TEST60_HEAD="test_60 run $RANDOM"
6775 test_60a() {
6776         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6777         remote_mgs_nodsh && skip "remote MGS with nodsh"
6778         do_facet mgs "! which run-llog.sh &> /dev/null" &&
6779                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
6780                         skip_env "missing subtest run-llog.sh"
6781
6782         log "$TEST60_HEAD - from kernel mode"
6783         do_facet mgs "$LCTL dk > /dev/null"
6784         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
6785         do_facet mgs $LCTL dk > $TMP/$tfile
6786
6787         # LU-6388: test llog_reader
6788         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
6789         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
6790         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
6791                         skip_env "missing llog_reader"
6792         local fstype=$(facet_fstype mgs)
6793         [ $fstype != ldiskfs -a $fstype != zfs ] &&
6794                 skip_env "Only for ldiskfs or zfs type mgs"
6795
6796         local mntpt=$(facet_mntpt mgs)
6797         local mgsdev=$(mgsdevname 1)
6798         local fid_list
6799         local fid
6800         local rec_list
6801         local rec
6802         local rec_type
6803         local obj_file
6804         local path
6805         local seq
6806         local oid
6807         local pass=true
6808
6809         #get fid and record list
6810         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
6811                 tail -n 4))
6812         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
6813                 tail -n 4))
6814         #remount mgs as ldiskfs or zfs type
6815         stop mgs || error "stop mgs failed"
6816         mount_fstype mgs || error "remount mgs failed"
6817         for ((i = 0; i < ${#fid_list[@]}; i++)); do
6818                 fid=${fid_list[i]}
6819                 rec=${rec_list[i]}
6820                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
6821                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
6822                 oid=$((16#$oid))
6823
6824                 case $fstype in
6825                         ldiskfs )
6826                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
6827                         zfs )
6828                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
6829                 esac
6830                 echo "obj_file is $obj_file"
6831                 do_facet mgs $llog_reader $obj_file
6832
6833                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
6834                         awk '{ print $3 }' | sed -e "s/^type=//g")
6835                 if [ $rec_type != $rec ]; then
6836                         echo "FAILED test_60a wrong record type $rec_type," \
6837                               "should be $rec"
6838                         pass=false
6839                         break
6840                 fi
6841
6842                 #check obj path if record type is LLOG_LOGID_MAGIC
6843                 if [ "$rec" == "1064553b" ]; then
6844                         path=$(do_facet mgs $llog_reader $obj_file |
6845                                 grep "path=" | awk '{ print $NF }' |
6846                                 sed -e "s/^path=//g")
6847                         if [ $obj_file != $mntpt/$path ]; then
6848                                 echo "FAILED test_60a wrong obj path" \
6849                                       "$montpt/$path, should be $obj_file"
6850                                 pass=false
6851                                 break
6852                         fi
6853                 fi
6854         done
6855         rm -f $TMP/$tfile
6856         #restart mgs before "error", otherwise it will block the next test
6857         stop mgs || error "stop mgs failed"
6858         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
6859         $pass || error "test failed, see FAILED test_60a messages for specifics"
6860 }
6861 run_test 60a "llog_test run from kernel module and test llog_reader"
6862
6863 test_60b() { # bug 6411
6864         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6865
6866         dmesg > $DIR/$tfile
6867         LLOG_COUNT=$(do_facet mgs dmesg |
6868                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
6869                           /llog_[a-z]*.c:[0-9]/ {
6870                                 if (marker)
6871                                         from_marker++
6872                                 from_begin++
6873                           }
6874                           END {
6875                                 if (marker)
6876                                         print from_marker
6877                                 else
6878                                         print from_begin
6879                           }")
6880
6881         [[ $LLOG_COUNT -gt 120 ]] &&
6882                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
6883 }
6884 run_test 60b "limit repeated messages from CERROR/CWARN"
6885
6886 test_60c() {
6887         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6888
6889         echo "create 5000 files"
6890         createmany -o $DIR/f60c- 5000
6891 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
6892         lctl set_param fail_loc=0x80000137
6893         unlinkmany $DIR/f60c- 5000
6894         lctl set_param fail_loc=0
6895 }
6896 run_test 60c "unlink file when mds full"
6897
6898 test_60d() {
6899         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6900
6901         SAVEPRINTK=$(lctl get_param -n printk)
6902         # verify "lctl mark" is even working"
6903         MESSAGE="test message ID $RANDOM $$"
6904         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
6905         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
6906
6907         lctl set_param printk=0 || error "set lnet.printk failed"
6908         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
6909         MESSAGE="new test message ID $RANDOM $$"
6910         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
6911         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
6912         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
6913
6914         lctl set_param -n printk="$SAVEPRINTK"
6915 }
6916 run_test 60d "test printk console message masking"
6917
6918 test_60e() {
6919         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6920         remote_mds_nodsh && skip "remote MDS with nodsh"
6921
6922         touch $DIR/$tfile
6923 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
6924         do_facet mds1 lctl set_param fail_loc=0x15b
6925         rm $DIR/$tfile
6926 }
6927 run_test 60e "no space while new llog is being created"
6928
6929 test_60g() {
6930         local pid
6931         local i
6932
6933         test_mkdir -c $MDSCOUNT $DIR/$tdir
6934
6935         (
6936                 local index=0
6937                 while true; do
6938                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
6939                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
6940                                 2>/dev/null
6941                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
6942                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
6943                         index=$((index + 1))
6944                 done
6945         ) &
6946
6947         pid=$!
6948
6949         for i in {0..100}; do
6950                 # define OBD_FAIL_OSD_TXN_START    0x19a
6951                 local index=$((i % MDSCOUNT + 1))
6952
6953                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
6954                         > /dev/null
6955                 usleep 100
6956         done
6957
6958         kill -9 $pid
6959
6960         for i in $(seq $MDSCOUNT); do
6961                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
6962         done
6963
6964         mkdir $DIR/$tdir/new || error "mkdir failed"
6965         rmdir $DIR/$tdir/new || error "rmdir failed"
6966
6967         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
6968                 -t namespace
6969         for i in $(seq $MDSCOUNT); do
6970                 wait_update_facet mds$i "$LCTL get_param -n \
6971                         mdd.$(facet_svc mds$i).lfsck_namespace |
6972                         awk '/^status/ { print \\\$2 }'" "completed"
6973         done
6974
6975         ls -R $DIR/$tdir || error "ls failed"
6976         rm -rf $DIR/$tdir || error "rmdir failed"
6977 }
6978 run_test 60g "transaction abort won't cause MDT hung"
6979
6980 test_60h() {
6981         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
6982                 skip "Need MDS version at least 2.12.52"
6983         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
6984
6985         local f
6986
6987         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
6988         #define OBD_FAIL_MDS_STRIPE_FID          0x189
6989         for fail_loc in 0x80000188 0x80000189; do
6990                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
6991                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
6992                         error "mkdir $dir-$fail_loc failed"
6993                 for i in {0..10}; do
6994                         # create may fail on missing stripe
6995                         echo $i > $DIR/$tdir-$fail_loc/$i
6996                 done
6997                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
6998                         error "getdirstripe $tdir-$fail_loc failed"
6999                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
7000                         error "migrate $tdir-$fail_loc failed"
7001                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
7002                         error "getdirstripe $tdir-$fail_loc failed"
7003                 pushd $DIR/$tdir-$fail_loc
7004                 for f in *; do
7005                         echo $f | cmp $f - || error "$f data mismatch"
7006                 done
7007                 popd
7008                 rm -rf $DIR/$tdir-$fail_loc
7009         done
7010 }
7011 run_test 60h "striped directory with missing stripes can be accessed"
7012
7013 test_61a() {
7014         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7015
7016         f="$DIR/f61"
7017         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
7018         cancel_lru_locks osc
7019         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
7020         sync
7021 }
7022 run_test 61a "mmap() writes don't make sync hang ================"
7023
7024 test_61b() {
7025         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
7026 }
7027 run_test 61b "mmap() of unstriped file is successful"
7028
7029 # bug 2330 - insufficient obd_match error checking causes LBUG
7030 test_62() {
7031         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7032
7033         f="$DIR/f62"
7034         echo foo > $f
7035         cancel_lru_locks osc
7036         lctl set_param fail_loc=0x405
7037         cat $f && error "cat succeeded, expect -EIO"
7038         lctl set_param fail_loc=0
7039 }
7040 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
7041 # match every page all of the time.
7042 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
7043
7044 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
7045 # Though this test is irrelevant anymore, it helped to reveal some
7046 # other grant bugs (LU-4482), let's keep it.
7047 test_63a() {   # was test_63
7048         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7049
7050         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
7051
7052         for i in `seq 10` ; do
7053                 dd if=/dev/zero of=$DIR/f63 bs=8k &
7054                 sleep 5
7055                 kill $!
7056                 sleep 1
7057         done
7058
7059         rm -f $DIR/f63 || true
7060 }
7061 run_test 63a "Verify oig_wait interruption does not crash ======="
7062
7063 # bug 2248 - async write errors didn't return to application on sync
7064 # bug 3677 - async write errors left page locked
7065 test_63b() {
7066         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7067
7068         debugsave
7069         lctl set_param debug=-1
7070
7071         # ensure we have a grant to do async writes
7072         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
7073         rm $DIR/$tfile
7074
7075         sync    # sync lest earlier test intercept the fail_loc
7076
7077         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
7078         lctl set_param fail_loc=0x80000406
7079         $MULTIOP $DIR/$tfile Owy && \
7080                 error "sync didn't return ENOMEM"
7081         sync; sleep 2; sync     # do a real sync this time to flush page
7082         lctl get_param -n llite.*.dump_page_cache | grep locked && \
7083                 error "locked page left in cache after async error" || true
7084         debugrestore
7085 }
7086 run_test 63b "async write errors should be returned to fsync ==="
7087
7088 test_64a () {
7089         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7090
7091         df $DIR
7092         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur* | grep "[0-9]"
7093 }
7094 run_test 64a "verify filter grant calculations (in kernel) ====="
7095
7096 test_64b () {
7097         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7098
7099         sh oos.sh $MOUNT || error "oos.sh failed: $?"
7100 }
7101 run_test 64b "check out-of-space detection on client"
7102
7103 test_64c() {
7104         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
7105 }
7106 run_test 64c "verify grant shrink"
7107
7108 # this does exactly what osc_request.c:osc_announce_cached() does in
7109 # order to calculate max amount of grants to ask from server
7110 want_grant() {
7111         local tgt=$1
7112
7113         local nrpages=$($LCTL get_param -n osc.${tgt}.max_pages_per_rpc)
7114         local rpc_in_flight=$($LCTL get_param -n osc.${tgt}.max_rpcs_in_flight)
7115
7116         ((rpc_in_flight ++));
7117         nrpages=$((nrpages * rpc_in_flight))
7118
7119         local dirty_max_pages=$($LCTL get_param -n osc.${tgt}.max_dirty_mb)
7120
7121         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
7122
7123         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
7124         local undirty=$((nrpages * PAGE_SIZE))
7125
7126         local max_extent_pages
7127         max_extent_pages=$($LCTL get_param osc.${tgt}.import |
7128             grep grant_max_extent_size | awk '{print $2}')
7129         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
7130         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
7131         local grant_extent_tax
7132         grant_extent_tax=$($LCTL get_param osc.${tgt}.import |
7133             grep grant_extent_tax | awk '{print $2}')
7134
7135         undirty=$((undirty + nrextents * grant_extent_tax))
7136
7137         echo $undirty
7138 }
7139
7140 # this is size of unit for grant allocation. It should be equal to
7141 # what tgt_grant.c:tgt_grant_chunk() calculates
7142 grant_chunk() {
7143         local tgt=$1
7144         local max_brw_size
7145         local grant_extent_tax
7146
7147         max_brw_size=$($LCTL get_param osc.${tgt}.import |
7148             grep max_brw_size | awk '{print $2}')
7149
7150         grant_extent_tax=$($LCTL get_param osc.${tgt}.import |
7151             grep grant_extent_tax | awk '{print $2}')
7152
7153         echo $(((max_brw_size + grant_extent_tax) * 2))
7154 }
7155
7156 test_64d() {
7157         [ $OST1_VERSION -lt $(version_code 2.10.56) ] &&
7158                 skip "OST < 2.10.55 doesn't limit grants enough"
7159
7160         local tgt=$($LCTL dl | grep "0000-osc-[^mM]" | awk '{print $4}')
7161         local file=$DIR/$tfile
7162
7163         [[ $($LCTL get_param osc.${tgt}.import |
7164              grep "connect_flags:.*grant_param") ]] ||
7165                 skip "no grant_param connect flag"
7166
7167         local olddebug=$($LCTL get_param -n debug 2> /dev/null)
7168
7169         $LCTL set_param debug="$OLDDEBUG" 2> /dev/null || true
7170
7171         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
7172         stack_trap "rm -f $file" EXIT
7173
7174         $LFS setstripe $file -i 0 -c 1
7175         dd if=/dev/zero of=$file bs=1M count=1000 &
7176         ddpid=$!
7177
7178         while true
7179         do
7180                 local cur_grant=$($LCTL get_param -n osc.${tgt}.cur_grant_bytes)
7181                 if [[ $cur_grant -gt $max_cur_granted ]]
7182                 then
7183                         kill $ddpid
7184                         error "cur_grant $cur_grant > $max_cur_granted"
7185                 fi
7186                 kill -0 $ddpid
7187                 [[ $? -ne 0 ]] && break;
7188                 sleep 2
7189         done
7190
7191         rm -f $DIR/$tfile
7192         wait_delete_completed
7193         $LCTL set_param debug="$olddebug" 2> /dev/null || true
7194 }
7195 run_test 64d "check grant limit exceed"
7196
7197 # bug 1414 - set/get directories' stripe info
7198 test_65a() {
7199         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7200
7201         test_mkdir $DIR/$tdir
7202         touch $DIR/$tdir/f1
7203         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
7204 }
7205 run_test 65a "directory with no stripe info"
7206
7207 test_65b() {
7208         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7209
7210         test_mkdir $DIR/$tdir
7211         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
7212
7213         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
7214                                                 error "setstripe"
7215         touch $DIR/$tdir/f2
7216         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
7217 }
7218 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
7219
7220 test_65c() {
7221         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7222         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
7223
7224         test_mkdir $DIR/$tdir
7225         local stripesize=$($LFS getstripe -S $DIR/$tdir)
7226
7227         $LFS setstripe -S $((stripesize * 4)) -i 1 \
7228                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
7229         touch $DIR/$tdir/f3
7230         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
7231 }
7232 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
7233
7234 test_65d() {
7235         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7236
7237         test_mkdir $DIR/$tdir
7238         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
7239         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
7240
7241         if [[ $STRIPECOUNT -le 0 ]]; then
7242                 sc=1
7243         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
7244                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
7245                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
7246         else
7247                 sc=$(($STRIPECOUNT - 1))
7248         fi
7249         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
7250         touch $DIR/$tdir/f4 $DIR/$tdir/f5
7251         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
7252                 error "lverify failed"
7253 }
7254 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
7255
7256 test_65e() {
7257         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7258
7259         test_mkdir $DIR/$tdir
7260
7261         $LFS setstripe $DIR/$tdir || error "setstripe"
7262         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
7263                                         error "no stripe info failed"
7264         touch $DIR/$tdir/f6
7265         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
7266 }
7267 run_test 65e "directory setstripe defaults"
7268
7269 test_65f() {
7270         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7271
7272         test_mkdir $DIR/${tdir}f
7273         $RUNAS $LFS setstripe $DIR/${tdir}f &&
7274                 error "setstripe succeeded" || true
7275 }
7276 run_test 65f "dir setstripe permission (should return error) ==="
7277
7278 test_65g() {
7279         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7280
7281         test_mkdir $DIR/$tdir
7282         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
7283
7284         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
7285                 error "setstripe -S failed"
7286         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
7287         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
7288                 error "delete default stripe failed"
7289 }
7290 run_test 65g "directory setstripe -d"
7291
7292 test_65h() {
7293         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7294
7295         test_mkdir $DIR/$tdir
7296         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
7297
7298         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
7299                 error "setstripe -S failed"
7300         test_mkdir $DIR/$tdir/dd1
7301         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
7302                 error "stripe info inherit failed"
7303 }
7304 run_test 65h "directory stripe info inherit ===================="
7305
7306 test_65i() {
7307         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7308
7309         save_layout_restore_at_exit $MOUNT
7310
7311         # bug6367: set non-default striping on root directory
7312         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
7313
7314         # bug12836: getstripe on -1 default directory striping
7315         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
7316
7317         # bug12836: getstripe -v on -1 default directory striping
7318         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
7319
7320         # bug12836: new find on -1 default directory striping
7321         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
7322 }
7323 run_test 65i "various tests to set root directory striping"
7324
7325 test_65j() { # bug6367
7326         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7327
7328         sync; sleep 1
7329
7330         # if we aren't already remounting for each test, do so for this test
7331         if [ "$I_MOUNTED" = "yes" ]; then
7332                 cleanup || error "failed to unmount"
7333                 setup
7334         fi
7335
7336         save_layout_restore_at_exit $MOUNT
7337
7338         $LFS setstripe -d $MOUNT || error "setstripe failed"
7339 }
7340 run_test 65j "set default striping on root directory (bug 6367)="
7341
7342 cleanup_65k() {
7343         rm -rf $DIR/$tdir
7344         wait_delete_completed
7345         do_facet $SINGLEMDS "lctl set_param -n \
7346                 osp.$ost*MDT0000.max_create_count=$max_count"
7347         do_facet $SINGLEMDS "lctl set_param -n \
7348                 osp.$ost*MDT0000.create_count=$count"
7349         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
7350         echo $INACTIVE_OSC "is Activate"
7351
7352         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
7353 }
7354
7355 test_65k() { # bug11679
7356         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7357         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7358         remote_mds_nodsh && skip "remote MDS with nodsh"
7359
7360         local disable_precreate=true
7361         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
7362                 disable_precreate=false
7363
7364         echo "Check OST status: "
7365         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
7366                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
7367
7368         for OSC in $MDS_OSCS; do
7369                 echo $OSC "is active"
7370                 do_facet $SINGLEMDS lctl --device %$OSC activate
7371         done
7372
7373         for INACTIVE_OSC in $MDS_OSCS; do
7374                 local ost=$(osc_to_ost $INACTIVE_OSC)
7375                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
7376                                lov.*md*.target_obd |
7377                                awk -F: /$ost/'{ print $1 }' | head -n 1)
7378
7379                 mkdir -p $DIR/$tdir
7380                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
7381                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
7382
7383                 echo "Deactivate: " $INACTIVE_OSC
7384                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
7385
7386                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
7387                               osp.$ost*MDT0000.create_count")
7388                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
7389                                   osp.$ost*MDT0000.max_create_count")
7390                 $disable_precreate &&
7391                         do_facet $SINGLEMDS "lctl set_param -n \
7392                                 osp.$ost*MDT0000.max_create_count=0"
7393
7394                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
7395                         [ -f $DIR/$tdir/$idx ] && continue
7396                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
7397                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
7398                                 { cleanup_65k;
7399                                   error "setstripe $idx should succeed"; }
7400                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
7401                 done
7402                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
7403                 rmdir $DIR/$tdir
7404
7405                 do_facet $SINGLEMDS "lctl set_param -n \
7406                         osp.$ost*MDT0000.max_create_count=$max_count"
7407                 do_facet $SINGLEMDS "lctl set_param -n \
7408                         osp.$ost*MDT0000.create_count=$count"
7409                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
7410                 echo $INACTIVE_OSC "is Activate"
7411
7412                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
7413         done
7414 }
7415 run_test 65k "validate manual striping works properly with deactivated OSCs"
7416
7417 test_65l() { # bug 12836
7418         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7419
7420         test_mkdir -p $DIR/$tdir/test_dir
7421         $LFS setstripe -c -1 $DIR/$tdir/test_dir
7422         $LFS find -mtime -1 $DIR/$tdir >/dev/null
7423 }
7424 run_test 65l "lfs find on -1 stripe dir ========================"
7425
7426 test_65m() {
7427         local layout=$(save_layout $MOUNT)
7428         $RUNAS $LFS setstripe -c 2 $MOUNT && {
7429                 restore_layout $MOUNT $layout
7430                 error "setstripe should fail by non-root users"
7431         }
7432         true
7433 }
7434 run_test 65m "normal user can't set filesystem default stripe"
7435
7436 test_65n() {
7437         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
7438         [[ $(lustre_version_code $SINGLEMDS) -ge $(version_code 2.12.50) ]] ||
7439                 skip "Need MDS version at least 2.12.50"
7440         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
7441
7442         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
7443         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
7444         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
7445
7446         local root_layout=$(save_layout $MOUNT)
7447         stack_trap "restore_layout $MOUNT $root_layout" EXIT
7448
7449         # new subdirectory under root directory should not inherit
7450         # the default layout from root
7451         local dir1=$MOUNT/$tdir-1
7452         mkdir $dir1 || error "mkdir $dir1 failed"
7453         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
7454                 error "$dir1 shouldn't have LOV EA"
7455
7456         # delete the default layout on root directory
7457         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
7458
7459         local dir2=$MOUNT/$tdir-2
7460         mkdir $dir2 || error "mkdir $dir2 failed"
7461         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
7462                 error "$dir2 shouldn't have LOV EA"
7463
7464         # set a new striping pattern on root directory
7465         local def_stripe_size=$($LFS getstripe -S $MOUNT)
7466         local new_def_stripe_size=$((def_stripe_size * 2))
7467         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
7468                 error "set stripe size on $MOUNT failed"
7469
7470         # new file created in $dir2 should inherit the new stripe size from
7471         # the filesystem default
7472         local file2=$dir2/$tfile-2
7473         touch $file2 || error "touch $file2 failed"
7474
7475         local file2_stripe_size=$($LFS getstripe -S $file2)
7476         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
7477                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
7478
7479         local dir3=$MOUNT/$tdir-3
7480         mkdir $dir3 || error "mkdir $dir3 failed"
7481         ! getfattr -n trusted.lov $dir3 &> /dev/null ||
7482                 error "$dir3 shouldn't have LOV EA"
7483
7484         # set OST pool on root directory
7485         local pool=$TESTNAME
7486         pool_add $pool || error "add $pool failed"
7487         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
7488                 error "add targets to $pool failed"
7489
7490         $LFS setstripe -p $pool $MOUNT ||
7491                 error "set OST pool on $MOUNT failed"
7492
7493         # new file created in $dir3 should inherit the pool from
7494         # the filesystem default
7495         local file3=$dir3/$tfile-3
7496         touch $file3 || error "touch $file3 failed"
7497
7498         local file3_pool=$($LFS getstripe -p $file3)
7499         [[ "$file3_pool" = "$pool" ]] ||
7500                 error "$file3 didn't inherit OST pool $pool"
7501
7502         local dir4=$MOUNT/$tdir-4
7503         mkdir $dir4 || error "mkdir $dir4 failed"
7504         ! getfattr -n trusted.lov $dir4 &> /dev/null ||
7505                 error "$dir4 shouldn't have LOV EA"
7506
7507         # new file created in $dir4 should inherit the pool from
7508         # the filesystem default
7509         local file4=$dir4/$tfile-4
7510         touch $file4 || error "touch $file4 failed"
7511
7512         local file4_pool=$($LFS getstripe -p $file4)
7513         [[ "$file4_pool" = "$pool" ]] ||
7514                 error "$file4 didn't inherit OST pool $pool"
7515
7516         # new subdirectory under non-root directory should inherit
7517         # the default layout from its parent directory
7518         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
7519                 error "set directory layout on $dir4 failed"
7520
7521         local dir5=$dir4/$tdir-5
7522         mkdir $dir5 || error "mkdir $dir5 failed"
7523
7524         local dir4_layout=$(get_layout_param $dir4)
7525         local dir5_layout=$(get_layout_param $dir5)
7526         [[ "$dir4_layout" = "$dir5_layout" ]] ||
7527                 error "$dir5 should inherit the default layout from $dir4"
7528 }
7529 run_test 65n "don't inherit default layout from root for new subdirectories"
7530
7531 # bug 2543 - update blocks count on client
7532 test_66() {
7533         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7534
7535         COUNT=${COUNT:-8}
7536         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
7537         sync; sync_all_data; sync; sync_all_data
7538         cancel_lru_locks osc
7539         BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
7540         [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
7541 }
7542 run_test 66 "update inode blocks count on client ==============="
7543
7544 meminfo() {
7545         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
7546 }
7547
7548 swap_used() {
7549         swapon -s | awk '($1 == "'$1'") { print $4 }'
7550 }
7551
7552 # bug5265, obdfilter oa2dentry return -ENOENT
7553 # #define OBD_FAIL_SRV_ENOENT 0x217
7554 test_69() {
7555         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7556         remote_ost_nodsh && skip "remote OST with nodsh"
7557
7558         f="$DIR/$tfile"
7559         $LFS setstripe -c 1 -i 0 $f
7560
7561         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
7562
7563         do_facet ost1 lctl set_param fail_loc=0x217
7564         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
7565         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
7566
7567         do_facet ost1 lctl set_param fail_loc=0
7568         $DIRECTIO write $f 0 2 || error "write error"
7569
7570         cancel_lru_locks osc
7571         $DIRECTIO read $f 0 1 || error "read error"
7572
7573         do_facet ost1 lctl set_param fail_loc=0x217
7574         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
7575
7576         do_facet ost1 lctl set_param fail_loc=0
7577         rm -f $f
7578 }
7579 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
7580
7581 test_71() {
7582         test_mkdir $DIR/$tdir
7583         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
7584         sh rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
7585 }
7586 run_test 71 "Running dbench on lustre (don't segment fault) ===="
7587
7588 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
7589         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7590         [ "$RUNAS_ID" = "$UID" ] &&
7591                 skip_env "RUNAS_ID = UID = $UID -- skipping"
7592         # Check that testing environment is properly set up. Skip if not
7593         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
7594                 skip_env "User $RUNAS_ID does not exist - skipping"
7595
7596         touch $DIR/$tfile
7597         chmod 777 $DIR/$tfile
7598         chmod ug+s $DIR/$tfile
7599         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
7600                 error "$RUNAS dd $DIR/$tfile failed"
7601         # See if we are still setuid/sgid
7602         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
7603                 error "S/gid is not dropped on write"
7604         # Now test that MDS is updated too
7605         cancel_lru_locks mdc
7606         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
7607                 error "S/gid is not dropped on MDS"
7608         rm -f $DIR/$tfile
7609 }
7610 run_test 72a "Test that remove suid works properly (bug5695) ===="
7611
7612 test_72b() { # bug 24226 -- keep mode setting when size is not changing
7613         local perm
7614
7615         [ "$RUNAS_ID" = "$UID" ] &&
7616                 skip_env "RUNAS_ID = UID = $UID -- skipping"
7617         [ "$RUNAS_ID" -eq 0 ] &&
7618                 skip_env "RUNAS_ID = 0 -- skipping"
7619         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7620         # Check that testing environment is properly set up. Skip if not
7621         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
7622                 skip_env "User $RUNAS_ID does not exist - skipping"
7623
7624         touch $DIR/${tfile}-f{g,u}
7625         test_mkdir $DIR/${tfile}-dg
7626         test_mkdir $DIR/${tfile}-du
7627         chmod 770 $DIR/${tfile}-{f,d}{g,u}
7628         chmod g+s $DIR/${tfile}-{f,d}g
7629         chmod u+s $DIR/${tfile}-{f,d}u
7630         for perm in 777 2777 4777; do
7631                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
7632                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
7633                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
7634                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
7635         done
7636         true
7637 }
7638 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
7639
7640 # bug 3462 - multiple simultaneous MDC requests
7641 test_73() {
7642         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7643
7644         test_mkdir $DIR/d73-1
7645         test_mkdir $DIR/d73-2
7646         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
7647         pid1=$!
7648
7649         lctl set_param fail_loc=0x80000129
7650         $MULTIOP $DIR/d73-1/f73-2 Oc &
7651         sleep 1
7652         lctl set_param fail_loc=0
7653
7654         $MULTIOP $DIR/d73-2/f73-3 Oc &
7655         pid3=$!
7656
7657         kill -USR1 $pid1
7658         wait $pid1 || return 1
7659
7660         sleep 25
7661
7662         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
7663         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
7664         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
7665
7666         rm -rf $DIR/d73-*
7667 }
7668 run_test 73 "multiple MDC requests (should not deadlock)"
7669
7670 test_74a() { # bug 6149, 6184
7671         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7672
7673         touch $DIR/f74a
7674         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
7675         #
7676         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
7677         # will spin in a tight reconnection loop
7678         $LCTL set_param fail_loc=0x8000030e
7679         # get any lock that won't be difficult - lookup works.
7680         ls $DIR/f74a
7681         $LCTL set_param fail_loc=0
7682         rm -f $DIR/f74a
7683         true
7684 }
7685 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
7686
7687 test_74b() { # bug 13310
7688         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7689
7690         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
7691         #
7692         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
7693         # will spin in a tight reconnection loop
7694         $LCTL set_param fail_loc=0x8000030e
7695         # get a "difficult" lock
7696         touch $DIR/f74b
7697         $LCTL set_param fail_loc=0
7698         rm -f $DIR/f74b
7699         true
7700 }
7701 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
7702
7703 test_74c() {
7704         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7705
7706         #define OBD_FAIL_LDLM_NEW_LOCK
7707         $LCTL set_param fail_loc=0x319
7708         touch $DIR/$tfile && error "touch successful"
7709         $LCTL set_param fail_loc=0
7710         true
7711 }
7712 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
7713
7714 num_inodes() {
7715         awk '/lustre_inode_cache/ {print $2; exit}' /proc/slabinfo
7716 }
7717
7718 test_76() { # Now for bug 20433, added originally in bug 1443
7719         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7720
7721         local CPUS=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
7722
7723         cancel_lru_locks osc
7724         BEFORE_INODES=$(num_inodes)
7725         echo "before inodes: $BEFORE_INODES"
7726         local COUNT=1000
7727         [ "$SLOW" = "no" ] && COUNT=100
7728         for i in $(seq $COUNT); do
7729                 touch $DIR/$tfile
7730                 rm -f $DIR/$tfile
7731         done
7732         cancel_lru_locks osc
7733         AFTER_INODES=$(num_inodes)
7734         echo "after inodes: $AFTER_INODES"
7735         local wait=0
7736         while [[ $((AFTER_INODES-1*${CPUS:-1})) -gt $BEFORE_INODES ]]; do
7737                 sleep 2
7738                 AFTER_INODES=$(num_inodes)
7739                 wait=$((wait+2))
7740                 echo "wait $wait seconds inodes: $AFTER_INODES"
7741                 if [ $wait -gt 30 ]; then
7742                         error "inode slab grew from $BEFORE_INODES to $AFTER_INODES"
7743                 fi
7744         done
7745 }
7746 run_test 76 "confirm clients recycle inodes properly ===="
7747
7748
7749 export ORIG_CSUM=""
7750 set_checksums()
7751 {
7752         # Note: in sptlrpc modes which enable its own bulk checksum, the
7753         # original crc32_le bulk checksum will be automatically disabled,
7754         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
7755         # will be checked by sptlrpc code against sptlrpc bulk checksum.
7756         # In this case set_checksums() will not be no-op, because sptlrpc
7757         # bulk checksum will be enabled all through the test.
7758
7759         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
7760         lctl set_param -n osc.*.checksums $1
7761         return 0
7762 }
7763
7764 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
7765                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
7766 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
7767                              tr -d [] | head -n1)}
7768 set_checksum_type()
7769 {
7770         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
7771         rc=$?
7772         log "set checksum type to $1, rc = $rc"
7773         return $rc
7774 }
7775
7776 get_osc_checksum_type()
7777 {
7778         # arugment 1: OST name, like OST0000
7779         ost=$1
7780         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
7781                         sed 's/.*\[\(.*\)\].*/\1/g')
7782         rc=$?
7783         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
7784         echo $checksum_type
7785 }
7786
7787 F77_TMP=$TMP/f77-temp
7788 F77SZ=8
7789 setup_f77() {
7790         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
7791                 error "error writing to $F77_TMP"
7792 }
7793
7794 test_77a() { # bug 10889
7795         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7796         $GSS && skip_env "could not run with gss"
7797
7798         [ ! -f $F77_TMP ] && setup_f77
7799         set_checksums 1
7800         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
7801         set_checksums 0
7802         rm -f $DIR/$tfile
7803 }
7804 run_test 77a "normal checksum read/write operation"
7805
7806 test_77b() { # bug 10889
7807         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7808         $GSS && skip_env "could not run with gss"
7809
7810         [ ! -f $F77_TMP ] && setup_f77
7811         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
7812         $LCTL set_param fail_loc=0x80000409
7813         set_checksums 1
7814
7815         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
7816                 error "dd error: $?"
7817         $LCTL set_param fail_loc=0
7818
7819         for algo in $CKSUM_TYPES; do
7820                 cancel_lru_locks osc
7821                 set_checksum_type $algo
7822                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
7823                 $LCTL set_param fail_loc=0x80000408
7824                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
7825                 $LCTL set_param fail_loc=0
7826         done
7827         set_checksums 0
7828         set_checksum_type $ORIG_CSUM_TYPE
7829         rm -f $DIR/$tfile
7830 }
7831 run_test 77b "checksum error on client write, read"
7832
7833 cleanup_77c() {
7834         trap 0
7835         set_checksums 0
7836         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
7837         $check_ost &&
7838                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
7839         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
7840         $check_ost && [ -n "$ost_file_prefix" ] &&
7841                 do_facet ost1 rm -f ${ost_file_prefix}\*
7842 }
7843
7844 test_77c() {
7845         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7846         $GSS && skip_env "could not run with gss"
7847         remote_ost_nodsh && skip "remote OST with nodsh"
7848
7849         local bad1
7850         local osc_file_prefix
7851         local osc_file
7852         local check_ost=false
7853         local ost_file_prefix
7854         local ost_file
7855         local orig_cksum
7856         local dump_cksum
7857         local fid
7858
7859         # ensure corruption will occur on first OSS/OST
7860         $LFS setstripe -i 0 $DIR/$tfile
7861
7862         [ ! -f $F77_TMP ] && setup_f77
7863         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
7864                 error "dd write error: $?"
7865         fid=$($LFS path2fid $DIR/$tfile)
7866
7867         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
7868         then
7869                 check_ost=true
7870                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
7871                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
7872         else
7873                 echo "OSS do not support bulk pages dump upon error"
7874         fi
7875
7876         osc_file_prefix=$($LCTL get_param -n debug_path)
7877         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
7878
7879         trap cleanup_77c EXIT
7880
7881         set_checksums 1
7882         # enable bulk pages dump upon error on Client
7883         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
7884         # enable bulk pages dump upon error on OSS
7885         $check_ost &&
7886                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
7887
7888         # flush Client cache to allow next read to reach OSS
7889         cancel_lru_locks osc
7890
7891         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
7892         $LCTL set_param fail_loc=0x80000408
7893         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
7894         $LCTL set_param fail_loc=0
7895
7896         rm -f $DIR/$tfile
7897
7898         # check cksum dump on Client
7899         osc_file=$(ls ${osc_file_prefix}*)
7900         [ -n "$osc_file" ] || error "no checksum dump file on Client"
7901         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
7902         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
7903         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
7904         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
7905                      cksum)
7906         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
7907         [[ "$orig_cksum" == "$dump_cksum" ]] ||
7908                 error "dump content does not match on Client"
7909
7910         $check_ost || skip "No need to check cksum dump on OSS"
7911
7912         # check cksum dump on OSS
7913         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
7914         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
7915         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
7916         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
7917         [[ "$orig_cksum" == "$dump_cksum" ]] ||
7918                 error "dump content does not match on OSS"
7919
7920         cleanup_77c
7921 }
7922 run_test 77c "checksum error on client read with debug"
7923
7924 test_77d() { # bug 10889
7925         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7926         $GSS && skip_env "could not run with gss"
7927
7928         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
7929         $LCTL set_param fail_loc=0x80000409
7930         set_checksums 1
7931         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
7932                 error "direct write: rc=$?"
7933         $LCTL set_param fail_loc=0
7934         set_checksums 0
7935
7936         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
7937         $LCTL set_param fail_loc=0x80000408
7938         set_checksums 1
7939         cancel_lru_locks osc
7940         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
7941                 error "direct read: rc=$?"
7942         $LCTL set_param fail_loc=0
7943         set_checksums 0
7944 }
7945 run_test 77d "checksum error on OST direct write, read"
7946
7947 test_77f() { # bug 10889
7948         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7949         $GSS && skip_env "could not run with gss"
7950
7951         set_checksums 1
7952         for algo in $CKSUM_TYPES; do
7953                 cancel_lru_locks osc
7954                 set_checksum_type $algo
7955                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
7956                 $LCTL set_param fail_loc=0x409
7957                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
7958                         error "direct write succeeded"
7959                 $LCTL set_param fail_loc=0
7960         done
7961         set_checksum_type $ORIG_CSUM_TYPE
7962         set_checksums 0
7963 }
7964 run_test 77f "repeat checksum error on write (expect error)"
7965
7966 test_77g() { # bug 10889
7967         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7968         $GSS && skip_env "could not run with gss"
7969         remote_ost_nodsh && skip "remote OST with nodsh"
7970
7971         [ ! -f $F77_TMP ] && setup_f77
7972
7973         local file=$DIR/$tfile
7974         stack_trap "rm -f $file" EXIT
7975
7976         $LFS setstripe -c 1 -i 0 $file
7977         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
7978         do_facet ost1 lctl set_param fail_loc=0x8000021a
7979         set_checksums 1
7980         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
7981                 error "write error: rc=$?"
7982         do_facet ost1 lctl set_param fail_loc=0
7983         set_checksums 0
7984
7985         cancel_lru_locks osc
7986         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
7987         do_facet ost1 lctl set_param fail_loc=0x8000021b
7988         set_checksums 1
7989         cmp $F77_TMP $file || error "file compare failed"
7990         do_facet ost1 lctl set_param fail_loc=0
7991         set_checksums 0
7992 }
7993 run_test 77g "checksum error on OST write, read"
7994
7995 test_77k() { # LU-10906
7996         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7997         $GSS && skip_env "could not run with gss"
7998
7999         local cksum_param="osc.$FSNAME*.checksums"
8000         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
8001         local checksum
8002         local i
8003
8004         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
8005         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM" EXIT
8006         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM" \
8007                 EXIT
8008
8009         for i in 0 1; do
8010                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
8011                         error "failed to set checksum=$i on MGS"
8012                 wait_update $HOSTNAME "$get_checksum" $i
8013                 #remount
8014                 echo "remount client, checksum should be $i"
8015                 remount_client $MOUNT || "failed to remount client"
8016                 checksum=$(eval $get_checksum)
8017                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
8018         done
8019         # remove persistent param to avoid races with checksum mountopt below
8020         do_facet mgs $LCTL set_param -P -d $cksum_param ||
8021                 error "failed to delete checksum on MGS"
8022
8023         for opt in "checksum" "nochecksum"; do
8024                 #remount with mount option
8025                 echo "remount client with option $opt, checksum should be $i"
8026                 umount_client $MOUNT || "failed to umount client"
8027                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
8028                         "failed to mount client with option '$opt'"
8029                 checksum=$(eval $get_checksum)
8030                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
8031                 i=$((i - 1))
8032         done
8033
8034         remount_client $MOUNT || "failed to remount client"
8035 }
8036 run_test 77k "enable/disable checksum correctly"
8037
8038 test_77l() {
8039         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8040         $GSS && skip_env "could not run with gss"
8041
8042         set_checksums 1
8043         stack_trap "set_checksums $ORIG_CSUM" EXIT
8044         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
8045
8046         set_checksum_type invalid && error "unexpected success of invalid checksum type"
8047
8048         $LFS setstripe -c 1 -i 0 $DIR/$tfile
8049         for algo in $CKSUM_TYPES; do
8050                 set_checksum_type $algo || error "fail to set checksum type $algo"
8051                 osc_algo=$(get_osc_checksum_type OST0000)
8052                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
8053
8054                 # no locks, no reqs to let the connection idle
8055                 cancel_lru_locks osc
8056                 lru_resize_disable osc
8057                 wait_osc_import_state client ost1 IDLE
8058
8059                 # ensure ost1 is connected
8060                 stat $DIR/$tfile >/dev/null || error "can't stat"
8061                 wait_osc_import_state client ost1 FULL
8062
8063                 osc_algo=$(get_osc_checksum_type OST0000)
8064                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
8065         done
8066         return 0
8067 }
8068 run_test 77l "preferred checksum type is remembered after reconnected"
8069
8070 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
8071 rm -f $F77_TMP
8072 unset F77_TMP
8073
8074 cleanup_test_78() {
8075         trap 0
8076         rm -f $DIR/$tfile
8077 }
8078
8079 test_78() { # bug 10901
8080         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8081         remote_ost || skip_env "local OST"
8082
8083         NSEQ=5
8084         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
8085         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
8086         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
8087         echo "MemTotal: $MEMTOTAL"
8088
8089         # reserve 256MB of memory for the kernel and other running processes,
8090         # and then take 1/2 of the remaining memory for the read/write buffers.
8091         if [ $MEMTOTAL -gt 512 ] ;then
8092                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
8093         else
8094                 # for those poor memory-starved high-end clusters...
8095                 MEMTOTAL=$((MEMTOTAL / 2))
8096         fi
8097         echo "Mem to use for directio: $MEMTOTAL"
8098
8099         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
8100         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
8101         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
8102         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
8103                 head -n1)
8104         echo "Smallest OST: $SMALLESTOST"
8105         [[ $SMALLESTOST -lt 10240 ]] &&
8106                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
8107
8108         trap cleanup_test_78 EXIT
8109
8110         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
8111                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
8112
8113         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
8114         echo "File size: $F78SIZE"
8115         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
8116         for i in $(seq 1 $NSEQ); do
8117                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
8118                 echo directIO rdwr round $i of $NSEQ
8119                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
8120         done
8121
8122         cleanup_test_78
8123 }
8124 run_test 78 "handle large O_DIRECT writes correctly ============"
8125
8126 test_79() { # bug 12743
8127         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8128
8129         wait_delete_completed
8130
8131         BKTOTAL=$(calc_osc_kbytes kbytestotal)
8132         BKFREE=$(calc_osc_kbytes kbytesfree)
8133         BKAVAIL=$(calc_osc_kbytes kbytesavail)
8134
8135         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
8136         DFTOTAL=`echo $STRING | cut -d, -f1`
8137         DFUSED=`echo $STRING  | cut -d, -f2`
8138         DFAVAIL=`echo $STRING | cut -d, -f3`
8139         DFFREE=$(($DFTOTAL - $DFUSED))
8140
8141         ALLOWANCE=$((64 * $OSTCOUNT))
8142
8143         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
8144            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
8145                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
8146         fi
8147         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
8148            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
8149                 error "df free($DFFREE) mismatch OST free($BKFREE)"
8150         fi
8151         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
8152            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
8153                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
8154         fi
8155 }
8156 run_test 79 "df report consistency check ======================="
8157
8158 test_80() { # bug 10718
8159         remote_ost_nodsh && skip "remote OST with nodsh"
8160         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8161
8162         # relax strong synchronous semantics for slow backends like ZFS
8163         local soc="obdfilter.*.sync_on_lock_cancel"
8164         local soc_old=$(do_facet ost1 lctl get_param -n $soc | head -n1)
8165         local hosts=
8166         if [ "$soc_old" != "never" ] &&
8167                 [ "$ost1_FSTYPE" != "ldiskfs" ]; then
8168                         hosts=$(for host in $(seq -f "ost%g" 1 $OSTCOUNT); do
8169                                 facet_active_host $host; done | sort -u)
8170                         do_nodes $hosts lctl set_param $soc=never
8171         fi
8172
8173         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
8174         sync; sleep 1; sync
8175         local BEFORE=`date +%s`
8176         cancel_lru_locks osc
8177         local AFTER=`date +%s`
8178         local DIFF=$((AFTER-BEFORE))
8179         if [ $DIFF -gt 1 ] ; then
8180                 error "elapsed for 1M@1T = $DIFF"
8181         fi
8182
8183         [ -n "$hosts" ] && do_nodes $hosts lctl set_param $soc=$soc_old
8184
8185         rm -f $DIR/$tfile
8186 }
8187 run_test 80 "Page eviction is equally fast at high offsets too  ===="
8188
8189 test_81a() { # LU-456
8190         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8191         remote_ost_nodsh && skip "remote OST with nodsh"
8192
8193         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
8194         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
8195         do_facet ost1 lctl set_param fail_loc=0x80000228
8196
8197         # write should trigger a retry and success
8198         $LFS setstripe -i 0 -c 1 $DIR/$tfile
8199         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
8200         RC=$?
8201         if [ $RC -ne 0 ] ; then
8202                 error "write should success, but failed for $RC"
8203         fi
8204 }
8205 run_test 81a "OST should retry write when get -ENOSPC ==============="
8206
8207 test_81b() { # LU-456
8208         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8209         remote_ost_nodsh && skip "remote OST with nodsh"
8210
8211         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
8212         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
8213         do_facet ost1 lctl set_param fail_loc=0x228
8214
8215         # write should retry several times and return -ENOSPC finally
8216         $LFS setstripe -i 0 -c 1 $DIR/$tfile
8217         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
8218         RC=$?
8219         ENOSPC=28
8220         if [ $RC -ne $ENOSPC ] ; then
8221                 error "dd should fail for -ENOSPC, but succeed."
8222         fi
8223 }
8224 run_test 81b "OST should return -ENOSPC when retry still fails ======="
8225
8226 test_82() { # LU-1031
8227         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10
8228         local gid1=14091995
8229         local gid2=16022000
8230
8231         multiop_bg_pause $DIR/$tfile OG${gid1}_g${gid1}c || return 1
8232         local MULTIPID1=$!
8233         multiop_bg_pause $DIR/$tfile O_G${gid2}r10g${gid2}c || return 2
8234         local MULTIPID2=$!
8235         kill -USR1 $MULTIPID2
8236         sleep 2
8237         if [[ `ps h -o comm -p $MULTIPID2` == "" ]]; then
8238                 error "First grouplock does not block second one"
8239         else
8240                 echo "Second grouplock blocks first one"
8241         fi
8242         kill -USR1 $MULTIPID1
8243         wait $MULTIPID1
8244         wait $MULTIPID2
8245 }
8246 run_test 82 "Basic grouplock test"
8247
8248 test_99() {
8249         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
8250
8251         test_mkdir $DIR/$tdir.cvsroot
8252         chown $RUNAS_ID $DIR/$tdir.cvsroot
8253
8254         cd $TMP
8255         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
8256
8257         cd /etc/init.d
8258         # some versions of cvs import exit(1) when asked to import links or
8259         # files they can't read.  ignore those files.
8260         local toignore=$(find . -type l -printf '-I %f\n' -o \
8261                          ! -perm /4 -printf '-I %f\n')
8262         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
8263                 $tdir.reposname vtag rtag
8264
8265         cd $DIR
8266         test_mkdir $DIR/$tdir.reposname
8267         chown $RUNAS_ID $DIR/$tdir.reposname
8268         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
8269
8270         cd $DIR/$tdir.reposname
8271         $RUNAS touch foo99
8272         $RUNAS cvs add -m 'addmsg' foo99
8273         $RUNAS cvs update
8274         $RUNAS cvs commit -m 'nomsg' foo99
8275         rm -fr $DIR/$tdir.cvsroot
8276 }
8277 run_test 99 "cvs strange file/directory operations"
8278
8279 test_100() {
8280         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8281         [[ "$NETTYPE" =~ tcp ]] ||
8282                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
8283         remote_ost_nodsh && skip "remote OST with nodsh"
8284         remote_mds_nodsh && skip "remote MDS with nodsh"
8285         remote_servers ||
8286                 skip "useless for local single node setup"
8287
8288         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
8289                 [ "$PROT" != "tcp" ] && continue
8290                 RPORT=$(echo $REMOTE | cut -d: -f2)
8291                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
8292
8293                 rc=0
8294                 LPORT=`echo $LOCAL | cut -d: -f2`
8295                 if [ $LPORT -ge 1024 ]; then
8296                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
8297                         netstat -tna
8298                         error_exit "local: $LPORT > 1024, remote: $RPORT"
8299                 fi
8300         done
8301         [ "$rc" = 0 ] || error_exit "privileged port not found" )
8302 }
8303 run_test 100 "check local port using privileged port ==========="
8304
8305 function get_named_value()
8306 {
8307     local tag
8308
8309     tag=$1
8310     while read ;do
8311         line=$REPLY
8312         case $line in
8313         $tag*)
8314             echo $line | sed "s/^$tag[ ]*//"
8315             break
8316             ;;
8317         esac
8318     done
8319 }
8320
8321 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
8322                    awk '/^max_cached_mb/ { print $2 }')
8323
8324 cleanup_101a() {
8325         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
8326         trap 0
8327 }
8328
8329 test_101a() {
8330         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8331         [ $MDSCOUNT -ge 2 ] && skip_env "needs < 2 MDTs" #LU-4322
8332
8333         local s
8334         local discard
8335         local nreads=10000
8336         local cache_limit=32
8337
8338         $LCTL set_param -n osc.*-osc*.rpc_stats 0
8339         trap cleanup_101a EXIT
8340         $LCTL set_param -n llite.*.read_ahead_stats 0
8341         $LCTL set_param -n llite.*.max_cached_mb $cache_limit
8342
8343         #
8344         # randomly read 10000 of 64K chunks from file 3x 32MB in size
8345         #
8346         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
8347         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
8348
8349         discard=0
8350         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
8351                 get_named_value 'read but discarded' | cut -d" " -f1); do
8352                         discard=$(($discard + $s))
8353         done
8354         cleanup_101a
8355
8356         if [[ $(($discard * 10)) -gt $nreads ]]; then
8357                 $LCTL get_param osc.*-osc*.rpc_stats
8358                 $LCTL get_param llite.*.read_ahead_stats
8359                 error "too many ($discard) discarded pages"
8360         fi
8361         rm -f $DIR/$tfile || true
8362 }
8363 run_test 101a "check read-ahead for random reads"
8364
8365 setup_test101bc() {
8366         test_mkdir $DIR/$tdir
8367         local ssize=$1
8368         local FILE_LENGTH=$2
8369         STRIPE_OFFSET=0
8370
8371         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
8372
8373         local list=$(comma_list $(osts_nodes))
8374         set_osd_param $list '' read_cache_enable 0
8375         set_osd_param $list '' writethrough_cache_enable 0
8376
8377         trap cleanup_test101bc EXIT
8378         # prepare the read-ahead file
8379         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
8380
8381         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
8382                                 count=$FILE_SIZE_MB 2> /dev/null
8383
8384 }
8385
8386 cleanup_test101bc() {
8387         trap 0
8388         rm -rf $DIR/$tdir
8389         rm -f $DIR/$tfile
8390
8391         local list=$(comma_list $(osts_nodes))
8392         set_osd_param $list '' read_cache_enable 1
8393         set_osd_param $list '' writethrough_cache_enable 1
8394 }
8395
8396 calc_total() {
8397         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
8398 }
8399
8400 ra_check_101() {
8401         local READ_SIZE=$1
8402         local STRIPE_SIZE=$2
8403         local FILE_LENGTH=$3
8404         local RA_INC=1048576
8405         local STRIDE_LENGTH=$((STRIPE_SIZE/READ_SIZE))
8406         local discard_limit=$((((STRIDE_LENGTH - 1)*3/(STRIDE_LENGTH*OSTCOUNT))* \
8407                              (STRIDE_LENGTH*OSTCOUNT - STRIDE_LENGTH)))
8408         DISCARD=$($LCTL get_param -n llite.*.read_ahead_stats |
8409                         get_named_value 'read but discarded' |
8410                         cut -d" " -f1 | calc_total)
8411         if [[ $DISCARD -gt $discard_limit ]]; then
8412                 $LCTL get_param llite.*.read_ahead_stats
8413                 error "Too many ($DISCARD) discarded pages with size (${READ_SIZE})"
8414         else
8415                 echo "Read-ahead success for size ${READ_SIZE}"
8416         fi
8417 }
8418
8419 test_101b() {
8420         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8421         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8422
8423         local STRIPE_SIZE=1048576
8424         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
8425
8426         if [ $SLOW == "yes" ]; then
8427                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
8428         else
8429                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
8430         fi
8431
8432         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
8433
8434         # prepare the read-ahead file
8435         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
8436         cancel_lru_locks osc
8437         for BIDX in 2 4 8 16 32 64 128 256
8438         do
8439                 local BSIZE=$((BIDX*4096))
8440                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
8441                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
8442                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
8443                 $LCTL set_param -n llite.*.read_ahead_stats 0
8444                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
8445                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
8446                 cancel_lru_locks osc
8447                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
8448         done
8449         cleanup_test101bc
8450         true
8451 }
8452 run_test 101b "check stride-io mode read-ahead ================="
8453
8454 test_101c() {
8455         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8456
8457         local STRIPE_SIZE=1048576
8458         local FILE_LENGTH=$((STRIPE_SIZE*100))
8459         local nreads=10000
8460         local rsize=65536
8461         local osc_rpc_stats
8462
8463         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
8464
8465         cancel_lru_locks osc
8466         $LCTL set_param osc.*.rpc_stats 0
8467         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
8468         $LCTL get_param osc.*.rpc_stats
8469         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
8470                 local stats=$($LCTL get_param -n $osc_rpc_stats)
8471                 local lines=$(echo "$stats" | awk 'END {print NR;}')
8472                 local size
8473
8474                 if [ $lines -le 20 ]; then
8475                         echo "continue debug"
8476                         continue
8477                 fi
8478                 for size in 1 2 4 8; do
8479                         local rpc=$(echo "$stats" |
8480                                     awk '($1 == "'$size':") {print $2; exit; }')
8481                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
8482                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
8483                 done
8484                 echo "$osc_rpc_stats check passed!"
8485         done
8486         cleanup_test101bc
8487         true
8488 }
8489 run_test 101c "check stripe_size aligned read-ahead ================="
8490
8491 set_read_ahead() {
8492         $LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1
8493         $LCTL set_param -n llite.*.max_read_ahead_mb $1 > /dev/null 2>&1
8494 }
8495
8496 test_101d() {
8497         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8498
8499         local file=$DIR/$tfile
8500         local sz_MB=${FILESIZE_101d:-500}
8501         local ra_MB=${READAHEAD_MB:-40}
8502
8503         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
8504         [ $free_MB -lt $sz_MB ] &&
8505                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
8506
8507         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
8508         $LFS setstripe -c -1 $file || error "setstripe failed"
8509
8510         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
8511         echo Cancel LRU locks on lustre client to flush the client cache
8512         cancel_lru_locks osc
8513
8514         echo Disable read-ahead
8515         local old_READAHEAD=$(set_read_ahead 0)
8516
8517         echo Reading the test file $file with read-ahead disabled
8518         local raOFF=$(do_and_time "dd if=$file of=/dev/null bs=1M count=$sz_MB")
8519
8520         echo Cancel LRU locks on lustre client to flush the client cache
8521         cancel_lru_locks osc
8522         echo Enable read-ahead with ${ra_MB}MB
8523         set_read_ahead $ra_MB
8524
8525         echo Reading the test file $file with read-ahead enabled
8526         local raON=$(do_and_time "dd if=$file of=/dev/null bs=1M count=$sz_MB")
8527
8528         echo "read-ahead disabled time read $raOFF"
8529         echo "read-ahead enabled  time read $raON"
8530
8531         set_read_ahead $old_READAHEAD
8532         rm -f $file
8533         wait_delete_completed
8534
8535         [ $raOFF -le 1 ] || [ $raON -lt $raOFF ] ||
8536                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
8537 }
8538 run_test 101d "file read with and without read-ahead enabled"
8539
8540 test_101e() {
8541         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8542
8543         local file=$DIR/$tfile
8544         local size_KB=500  #KB
8545         local count=100
8546         local bsize=1024
8547
8548         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
8549         local need_KB=$((count * size_KB))
8550         [[ $free_KB -le $need_KB ]] &&
8551                 skip_env "Need free space $need_KB, have $free_KB"
8552
8553         echo "Creating $count ${size_KB}K test files"
8554         for ((i = 0; i < $count; i++)); do
8555                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
8556         done
8557
8558         echo "Cancel LRU locks on lustre client to flush the client cache"
8559         cancel_lru_locks $OSC
8560
8561         echo "Reset readahead stats"
8562         $LCTL set_param -n llite.*.read_ahead_stats 0
8563
8564         for ((i = 0; i < $count; i++)); do
8565                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
8566         done
8567
8568         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
8569                      get_named_value 'misses' | cut -d" " -f1 | calc_total)
8570
8571         for ((i = 0; i < $count; i++)); do
8572                 rm -rf $file.$i 2>/dev/null
8573         done
8574
8575         #10000 means 20% reads are missing in readahead
8576         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
8577 }
8578 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
8579
8580 test_101f() {
8581         which iozone || skip_env "no iozone installed"
8582
8583         local old_debug=$($LCTL get_param debug)
8584         old_debug=${old_debug#*=}
8585         $LCTL set_param debug="reada mmap"
8586
8587         # create a test file
8588         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
8589
8590         echo Cancel LRU locks on lustre client to flush the client cache
8591         cancel_lru_locks osc
8592
8593         echo Reset readahead stats
8594         $LCTL set_param -n llite.*.read_ahead_stats 0
8595
8596         echo mmap read the file with small block size
8597         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
8598                 > /dev/null 2>&1
8599
8600         echo checking missing pages
8601         $LCTL get_param llite.*.read_ahead_stats
8602         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
8603                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
8604
8605         $LCTL set_param debug="$old_debug"
8606         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
8607         rm -f $DIR/$tfile
8608 }
8609 run_test 101f "check mmap read performance"
8610
8611 test_101g_brw_size_test() {
8612         local mb=$1
8613         local pages=$((mb * 1048576 / PAGE_SIZE))
8614         local file=$DIR/$tfile
8615
8616         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
8617                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
8618         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
8619                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
8620                         return 2
8621         done
8622
8623         stack_trap "rm -f $file" EXIT
8624         $LCTL set_param -n osc.*.rpc_stats=0
8625
8626         # 10 RPCs should be enough for the test
8627         local count=10
8628         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
8629                 { error "dd write ${mb} MB blocks failed"; return 3; }
8630         cancel_lru_locks osc
8631         dd of=/dev/null if=$file bs=${mb}M count=$count ||
8632                 { error "dd write ${mb} MB blocks failed"; return 4; }
8633
8634         # calculate number of full-sized read and write RPCs
8635         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
8636                 sed -n '/pages per rpc/,/^$/p' |
8637                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
8638                 END { print reads,writes }'))
8639         [ ${rpcs[0]} -ne $count ] && error "${rpcs[0]} != $count read RPCs" &&
8640                 return 5
8641         [ ${rpcs[1]} -ne $count ] && error "${rpcs[1]} != $count write RPCs" &&
8642                 return 6
8643
8644         return 0
8645 }
8646
8647 test_101g() {
8648         remote_ost_nodsh && skip "remote OST with nodsh"
8649
8650         local rpcs
8651         local osts=$(get_facets OST)
8652         local list=$(comma_list $(osts_nodes))
8653         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
8654         local brw_size="obdfilter.*.brw_size"
8655
8656         $LFS setstripe -i 0 -c 1 $DIR/$tfile
8657
8658         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
8659
8660         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
8661                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
8662                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
8663            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
8664                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
8665                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
8666
8667                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
8668                         suffix="M"
8669
8670                 if [[ $orig_mb -lt 16 ]]; then
8671                         save_lustre_params $osts "$brw_size" > $p
8672                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
8673                                 error "set 16MB RPC size failed"
8674
8675                         echo "remount client to enable new RPC size"
8676                         remount_client $MOUNT || error "remount_client failed"
8677                 fi
8678
8679                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
8680                 # should be able to set brw_size=12, but no rpc_stats for that
8681                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
8682         fi
8683
8684         test_101g_brw_size_test 4 || error "4MB RPC test failed"
8685
8686         if [[ $orig_mb -lt 16 ]]; then
8687                 restore_lustre_params < $p
8688                 remount_client $MOUNT || error "remount_client restore failed"
8689         fi
8690
8691         rm -f $p $DIR/$tfile
8692 }
8693 run_test 101g "Big bulk(4/16 MiB) readahead"
8694
8695 test_101h() {
8696         $LFS setstripe -i 0 -c 1 $DIR/$tfile
8697
8698         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
8699                 error "dd 70M file failed"
8700         echo Cancel LRU locks on lustre client to flush the client cache
8701         cancel_lru_locks osc
8702
8703         echo "Reset readahead stats"
8704         $LCTL set_param -n llite.*.read_ahead_stats 0
8705
8706         echo "Read 10M of data but cross 64M bundary"
8707         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
8708         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
8709                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
8710         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
8711         rm -f $p $DIR/$tfile
8712 }
8713 run_test 101h "Readahead should cover current read window"
8714
8715 setup_test102() {
8716         test_mkdir $DIR/$tdir
8717         chown $RUNAS_ID $DIR/$tdir
8718         STRIPE_SIZE=65536
8719         STRIPE_OFFSET=1
8720         STRIPE_COUNT=$OSTCOUNT
8721         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
8722
8723         trap cleanup_test102 EXIT
8724         cd $DIR
8725         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
8726         cd $DIR/$tdir
8727         for num in 1 2 3 4; do
8728                 for count in $(seq 1 $STRIPE_COUNT); do
8729                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
8730                                 local size=`expr $STRIPE_SIZE \* $num`
8731                                 local file=file"$num-$idx-$count"
8732                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
8733                         done
8734                 done
8735         done
8736
8737         cd $DIR
8738         $1 tar cf $TMP/f102.tar $tdir --xattrs
8739 }
8740
8741 cleanup_test102() {
8742         trap 0
8743         rm -f $TMP/f102.tar
8744         rm -rf $DIR/d0.sanity/d102
8745 }
8746
8747 test_102a() {
8748         [ "$UID" != 0 ] && skip "must run as root"
8749         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
8750                 skip_env "must have user_xattr"
8751
8752         [ -z "$(which setfattr 2>/dev/null)" ] &&
8753                 skip_env "could not find setfattr"
8754
8755         local testfile=$DIR/$tfile
8756
8757         touch $testfile
8758         echo "set/get xattr..."
8759         setfattr -n trusted.name1 -v value1 $testfile ||
8760                 error "setfattr -n trusted.name1=value1 $testfile failed"
8761         getfattr -n trusted.name1 $testfile 2> /dev/null |
8762           grep "trusted.name1=.value1" ||
8763                 error "$testfile missing trusted.name1=value1"
8764
8765         setfattr -n user.author1 -v author1 $testfile ||
8766                 error "setfattr -n user.author1=author1 $testfile failed"
8767         getfattr -n user.author1 $testfile 2> /dev/null |
8768           grep "user.author1=.author1" ||
8769                 error "$testfile missing trusted.author1=author1"
8770
8771         echo "listxattr..."
8772         setfattr -n trusted.name2 -v value2 $testfile ||
8773                 error "$testfile unable to set trusted.name2"
8774         setfattr -n trusted.name3 -v value3 $testfile ||
8775                 error "$testfile unable to set trusted.name3"
8776         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
8777             grep "trusted.name" | wc -l) -eq 3 ] ||
8778                 error "$testfile missing 3 trusted.name xattrs"
8779
8780         setfattr -n user.author2 -v author2 $testfile ||
8781                 error "$testfile unable to set user.author2"
8782         setfattr -n user.author3 -v author3 $testfile ||
8783                 error "$testfile unable to set user.author3"
8784         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
8785             grep "user.author" | wc -l) -eq 3 ] ||
8786                 error "$testfile missing 3 user.author xattrs"
8787
8788         echo "remove xattr..."
8789         setfattr -x trusted.name1 $testfile ||
8790                 error "$testfile error deleting trusted.name1"
8791         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
8792                 error "$testfile did not delete trusted.name1 xattr"
8793
8794         setfattr -x user.author1 $testfile ||
8795                 error "$testfile error deleting user.author1"
8796         echo "set lustre special xattr ..."
8797         $LFS setstripe -c1 $testfile
8798         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
8799                 awk -F "=" '/trusted.lov/ { print $2 }' )
8800         setfattr -n "trusted.lov" -v $lovea $testfile ||
8801                 error "$testfile doesn't ignore setting trusted.lov again"
8802         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
8803                 error "$testfile allow setting invalid trusted.lov"
8804         rm -f $testfile
8805 }
8806 run_test 102a "user xattr test =================================="
8807
8808 test_102b() {
8809         [ -z "$(which setfattr 2>/dev/null)" ] &&
8810                 skip_env "could not find setfattr"
8811         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8812
8813         # b10930: get/set/list trusted.lov xattr
8814         echo "get/set/list trusted.lov xattr ..."
8815         local testfile=$DIR/$tfile
8816         $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
8817                 error "setstripe failed"
8818         local STRIPECOUNT=$($LFS getstripe -c $testfile) ||
8819                 error "getstripe failed"
8820         getfattr -d -m "^trusted" $testfile 2>/dev/null | grep "trusted.lov" ||
8821                 error "can't get trusted.lov from $testfile"
8822
8823         local testfile2=${testfile}2
8824         local value=$(getfattr -n trusted.lov $testfile 2>/dev/null |
8825                         grep "trusted.lov" | sed -e 's/[^=]\+=//')
8826
8827         $MCREATE $testfile2
8828         setfattr -n trusted.lov -v $value $testfile2
8829         local stripe_size=$($LFS getstripe -S $testfile2)
8830         local stripe_count=$($LFS getstripe -c $testfile2)
8831         [[ $stripe_size -eq 65536 ]] ||
8832                 error "stripe size $stripe_size != 65536"
8833         [[ $stripe_count -eq $STRIPECOUNT ]] ||
8834                 error "stripe count $stripe_count != $STRIPECOUNT"
8835         rm -f $DIR/$tfile
8836 }
8837 run_test 102b "getfattr/setfattr for trusted.lov EAs ============"
8838
8839 test_102c() {
8840         [ -z "$(which setfattr 2>/dev/null)" ] &&
8841                 skip_env "could not find setfattr"
8842         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8843
8844         # b10930: get/set/list lustre.lov xattr
8845         echo "get/set/list lustre.lov xattr ..."
8846         test_mkdir $DIR/$tdir
8847         chown $RUNAS_ID $DIR/$tdir
8848         local testfile=$DIR/$tdir/$tfile
8849         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
8850                 error "setstripe failed"
8851         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
8852                 error "getstripe failed"
8853         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
8854         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
8855
8856         local testfile2=${testfile}2
8857         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
8858                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
8859
8860         $RUNAS $MCREATE $testfile2
8861         $RUNAS setfattr -n lustre.lov -v $value $testfile2
8862         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
8863         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
8864         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
8865         [ $stripe_count -eq $STRIPECOUNT ] ||
8866                 error "stripe count $stripe_count != $STRIPECOUNT"
8867 }
8868 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
8869
8870 compare_stripe_info1() {
8871         local stripe_index_all_zero=true
8872
8873         for num in 1 2 3 4; do
8874                 for count in $(seq 1 $STRIPE_COUNT); do
8875                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
8876                                 local size=$((STRIPE_SIZE * num))
8877                                 local file=file"$num-$offset-$count"
8878                                 stripe_size=$($LFS getstripe -S $PWD/$file)
8879                                 [[ $stripe_size -ne $size ]] &&
8880                                     error "$file: size $stripe_size != $size"
8881                                 stripe_count=$($LFS getstripe -c $PWD/$file)
8882                                 # allow fewer stripes to be created, ORI-601
8883                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
8884                                     error "$file: count $stripe_count != $count"
8885                                 stripe_index=$($LFS getstripe -i $PWD/$file)
8886                                 [[ $stripe_index -ne 0 ]] &&
8887                                         stripe_index_all_zero=false
8888                         done
8889                 done
8890         done
8891         $stripe_index_all_zero &&
8892                 error "all files are being extracted starting from OST index 0"
8893         return 0
8894 }
8895
8896 have_xattrs_include() {
8897         tar --help | grep -q xattrs-include &&
8898                 echo --xattrs-include="lustre.*"
8899 }
8900
8901 test_102d() {
8902         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8903         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8904
8905         XINC=$(have_xattrs_include)
8906         setup_test102
8907         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
8908         cd $DIR/$tdir/$tdir
8909         compare_stripe_info1
8910 }
8911 run_test 102d "tar restore stripe info from tarfile,not keep osts"
8912
8913 test_102f() {
8914         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8915         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8916
8917         XINC=$(have_xattrs_include)
8918         setup_test102
8919         test_mkdir $DIR/$tdir.restore
8920         cd $DIR
8921         tar cf - --xattrs $tdir | tar xf - \
8922                 -C $DIR/$tdir.restore --xattrs $XINC
8923         cd $DIR/$tdir.restore/$tdir
8924         compare_stripe_info1
8925 }
8926 run_test 102f "tar copy files, not keep osts"
8927
8928 grow_xattr() {
8929         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
8930                 skip "must have user_xattr"
8931         [ -z "$(which setfattr 2>/dev/null)" ] &&
8932                 skip_env "could not find setfattr"
8933         [ -z "$(which getfattr 2>/dev/null)" ] &&
8934                 skip_env "could not find getfattr"
8935
8936         local xsize=${1:-1024}  # in bytes
8937         local file=$DIR/$tfile
8938         local value="$(generate_string $xsize)"
8939         local xbig=trusted.big
8940         local toobig=$2
8941
8942         touch $file
8943         log "save $xbig on $file"
8944         if [ -z "$toobig" ]
8945         then
8946                 setfattr -n $xbig -v $value $file ||
8947                         error "saving $xbig on $file failed"
8948         else
8949                 setfattr -n $xbig -v $value $file &&
8950                         error "saving $xbig on $file succeeded"
8951                 return 0
8952         fi
8953
8954         local orig=$(get_xattr_value $xbig $file)
8955         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
8956
8957         local xsml=trusted.sml
8958         log "save $xsml on $file"
8959         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
8960
8961         local new=$(get_xattr_value $xbig $file)
8962         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
8963
8964         log "grow $xsml on $file"
8965         setfattr -n $xsml -v "$value" $file ||
8966                 error "growing $xsml on $file failed"
8967
8968         new=$(get_xattr_value $xbig $file)
8969         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
8970         log "$xbig still valid after growing $xsml"
8971
8972         rm -f $file
8973 }
8974
8975 test_102h() { # bug 15777
8976         grow_xattr 1024
8977 }
8978 run_test 102h "grow xattr from inside inode to external block"
8979
8980 test_102ha() {
8981         large_xattr_enabled || skip_env "ea_inode feature disabled"
8982
8983         echo "setting xattr of max xattr size: $(max_xattr_size)"
8984         grow_xattr $(max_xattr_size)
8985
8986         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
8987         echo "This should fail:"
8988         grow_xattr $(($(max_xattr_size) + 10)) 1
8989 }
8990 run_test 102ha "grow xattr from inside inode to external inode"
8991
8992 test_102i() { # bug 17038
8993         [ -z "$(which getfattr 2>/dev/null)" ] &&
8994                 skip "could not find getfattr"
8995
8996         touch $DIR/$tfile
8997         ln -s $DIR/$tfile $DIR/${tfile}link
8998         getfattr -n trusted.lov $DIR/$tfile ||
8999                 error "lgetxattr on $DIR/$tfile failed"
9000         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
9001                 grep -i "no such attr" ||
9002                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
9003         rm -f $DIR/$tfile $DIR/${tfile}link
9004 }
9005 run_test 102i "lgetxattr test on symbolic link ============"
9006
9007 test_102j() {
9008         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9009         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9010
9011         XINC=$(have_xattrs_include)
9012         setup_test102 "$RUNAS"
9013         chown $RUNAS_ID $DIR/$tdir
9014         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
9015         cd $DIR/$tdir/$tdir
9016         compare_stripe_info1 "$RUNAS"
9017 }
9018 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
9019
9020 test_102k() {
9021         [ -z "$(which setfattr 2>/dev/null)" ] &&
9022                 skip "could not find setfattr"
9023
9024         touch $DIR/$tfile
9025         # b22187 just check that does not crash for regular file.
9026         setfattr -n trusted.lov $DIR/$tfile
9027         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
9028         local test_kdir=$DIR/$tdir
9029         test_mkdir $test_kdir
9030         local default_size=$($LFS getstripe -S $test_kdir)
9031         local default_count=$($LFS getstripe -c $test_kdir)
9032         local default_offset=$($LFS getstripe -i $test_kdir)
9033         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
9034                 error 'dir setstripe failed'
9035         setfattr -n trusted.lov $test_kdir
9036         local stripe_size=$($LFS getstripe -S $test_kdir)
9037         local stripe_count=$($LFS getstripe -c $test_kdir)
9038         local stripe_offset=$($LFS getstripe -i $test_kdir)
9039         [ $stripe_size -eq $default_size ] ||
9040                 error "stripe size $stripe_size != $default_size"
9041         [ $stripe_count -eq $default_count ] ||
9042                 error "stripe count $stripe_count != $default_count"
9043         [ $stripe_offset -eq $default_offset ] ||
9044                 error "stripe offset $stripe_offset != $default_offset"
9045         rm -rf $DIR/$tfile $test_kdir
9046 }
9047 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
9048
9049 test_102l() {
9050         [ -z "$(which getfattr 2>/dev/null)" ] &&
9051                 skip "could not find getfattr"
9052
9053         # LU-532 trusted. xattr is invisible to non-root
9054         local testfile=$DIR/$tfile
9055
9056         touch $testfile
9057
9058         echo "listxattr as user..."
9059         chown $RUNAS_ID $testfile
9060         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
9061             grep -q "trusted" &&
9062                 error "$testfile trusted xattrs are user visible"
9063
9064         return 0;
9065 }
9066 run_test 102l "listxattr size test =================================="
9067
9068 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
9069         local path=$DIR/$tfile
9070         touch $path
9071
9072         listxattr_size_check $path || error "listattr_size_check $path failed"
9073 }
9074 run_test 102m "Ensure listxattr fails on small bufffer ========"
9075
9076 cleanup_test102
9077
9078 getxattr() { # getxattr path name
9079         # Return the base64 encoding of the value of xattr name on path.
9080         local path=$1
9081         local name=$2
9082
9083         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
9084         # file: $path
9085         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
9086         #
9087         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
9088
9089         getfattr --absolute-names --encoding=base64 --name=$name $path |
9090                 awk -F= -v name=$name '$1 == name {
9091                         print substr($0, index($0, "=") + 1);
9092         }'
9093 }
9094
9095 test_102n() { # LU-4101 mdt: protect internal xattrs
9096         [ -z "$(which setfattr 2>/dev/null)" ] &&
9097                 skip "could not find setfattr"
9098         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
9099         then
9100                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
9101         fi
9102
9103         local file0=$DIR/$tfile.0
9104         local file1=$DIR/$tfile.1
9105         local xattr0=$TMP/$tfile.0
9106         local xattr1=$TMP/$tfile.1
9107         local namelist="lov lma lmv link fid version som hsm"
9108         local name
9109         local value
9110
9111         rm -rf $file0 $file1 $xattr0 $xattr1
9112         touch $file0 $file1
9113
9114         # Get 'before' xattrs of $file1.
9115         getfattr --absolute-names --dump --match=- $file1 > $xattr0
9116
9117         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
9118                 namelist+=" lfsck_namespace"
9119         for name in $namelist; do
9120                 # Try to copy xattr from $file0 to $file1.
9121                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
9122
9123                 setfattr --name=trusted.$name --value="$value" $file1 ||
9124                         error "setxattr 'trusted.$name' failed"
9125
9126                 # Try to set a garbage xattr.
9127                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
9128
9129                 if [[ x$name == "xlov" ]]; then
9130                         setfattr --name=trusted.lov --value="$value" $file1 &&
9131                         error "setxattr invalid 'trusted.lov' success"
9132                 else
9133                         setfattr --name=trusted.$name --value="$value" $file1 ||
9134                                 error "setxattr invalid 'trusted.$name' failed"
9135                 fi
9136
9137                 # Try to remove the xattr from $file1. We don't care if this
9138                 # appears to succeed or fail, we just don't want there to be
9139                 # any changes or crashes.
9140                 setfattr --remove=$trusted.$name $file1 2> /dev/null
9141         done
9142
9143         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
9144         then
9145                 name="lfsck_ns"
9146                 # Try to copy xattr from $file0 to $file1.
9147                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
9148
9149                 setfattr --name=trusted.$name --value="$value" $file1 ||
9150                         error "setxattr 'trusted.$name' failed"
9151
9152                 # Try to set a garbage xattr.
9153                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
9154
9155                 setfattr --name=trusted.$name --value="$value" $file1 ||
9156                         error "setxattr 'trusted.$name' failed"
9157
9158                 # Try to remove the xattr from $file1. We don't care if this
9159                 # appears to succeed or fail, we just don't want there to be
9160                 # any changes or crashes.
9161                 setfattr --remove=$trusted.$name $file1 2> /dev/null
9162         fi
9163
9164         # Get 'after' xattrs of file1.
9165         getfattr --absolute-names --dump --match=- $file1 > $xattr1
9166
9167         if ! diff $xattr0 $xattr1; then
9168                 error "before and after xattrs of '$file1' differ"
9169         fi
9170
9171         rm -rf $file0 $file1 $xattr0 $xattr1
9172
9173         return 0
9174 }
9175 run_test 102n "silently ignore setxattr on internal trusted xattrs"
9176
9177 test_102p() { # LU-4703 setxattr did not check ownership
9178         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
9179                 skip "MDS needs to be at least 2.5.56"
9180
9181         local testfile=$DIR/$tfile
9182
9183         touch $testfile
9184
9185         echo "setfacl as user..."
9186         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
9187         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
9188
9189         echo "setfattr as user..."
9190         setfacl -m "u:$RUNAS_ID:---" $testfile
9191         $RUNAS setfattr -x system.posix_acl_access $testfile
9192         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
9193 }
9194 run_test 102p "check setxattr(2) correctly fails without permission"
9195
9196 test_102q() {
9197         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
9198                 skip "MDS needs to be at least 2.6.92"
9199
9200         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
9201 }
9202 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
9203
9204 test_102r() {
9205         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
9206                 skip "MDS needs to be at least 2.6.93"
9207
9208         touch $DIR/$tfile || error "touch"
9209         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
9210         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
9211         rm $DIR/$tfile || error "rm"
9212
9213         #normal directory
9214         mkdir -p $DIR/$tdir || error "mkdir"
9215         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
9216         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
9217         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
9218                 error "$testfile error deleting user.author1"
9219         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
9220                 grep "user.$(basename $tdir)" &&
9221                 error "$tdir did not delete user.$(basename $tdir)"
9222         rmdir $DIR/$tdir || error "rmdir"
9223
9224         #striped directory
9225         test_mkdir $DIR/$tdir
9226         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
9227         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
9228         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
9229                 error "$testfile error deleting user.author1"
9230         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
9231                 grep "user.$(basename $tdir)" &&
9232                 error "$tdir did not delete user.$(basename $tdir)"
9233         rmdir $DIR/$tdir || error "rm striped dir"
9234 }
9235 run_test 102r "set EAs with empty values"
9236
9237 test_102s() {
9238         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
9239                 skip "MDS needs to be at least 2.11.52"
9240
9241         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
9242
9243         save_lustre_params client "llite.*.xattr_cache" > $save
9244
9245         for cache in 0 1; do
9246                 lctl set_param llite.*.xattr_cache=$cache
9247
9248                 rm -f $DIR/$tfile
9249                 touch $DIR/$tfile || error "touch"
9250                 for prefix in lustre security system trusted user; do
9251                         # Note getxattr() may fail with 'Operation not
9252                         # supported' or 'No such attribute' depending
9253                         # on prefix and cache.
9254                         getfattr -n $prefix.n102s $DIR/$tfile &&
9255                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
9256                 done
9257         done
9258
9259         restore_lustre_params < $save
9260 }
9261 run_test 102s "getting nonexistent xattrs should fail"
9262
9263 test_102t() {
9264         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
9265                 skip "MDS needs to be at least 2.11.52"
9266
9267         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
9268
9269         save_lustre_params client "llite.*.xattr_cache" > $save
9270
9271         for cache in 0 1; do
9272                 lctl set_param llite.*.xattr_cache=$cache
9273
9274                 for buf_size in 0 256; do
9275                         rm -f $DIR/$tfile
9276                         touch $DIR/$tfile || error "touch"
9277                         setfattr -n user.multiop $DIR/$tfile
9278                         $MULTIOP $DIR/$tfile oa$buf_size ||
9279                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
9280                 done
9281         done
9282
9283         restore_lustre_params < $save
9284 }
9285 run_test 102t "zero length xattr values handled correctly"
9286
9287 run_acl_subtest()
9288 {
9289     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
9290     return $?
9291 }
9292
9293 test_103a() {
9294         [ "$UID" != 0 ] && skip "must run as root"
9295         $GSS && skip_env "could not run under gss"
9296         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
9297                 skip_env "must have acl enabled"
9298         [ -z "$(which setfacl 2>/dev/null)" ] &&
9299                 skip_env "could not find setfacl"
9300         remote_mds_nodsh && skip "remote MDS with nodsh"
9301
9302         gpasswd -a daemon bin                           # LU-5641
9303         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
9304
9305         declare -a identity_old
9306
9307         for num in $(seq $MDSCOUNT); do
9308                 switch_identity $num true || identity_old[$num]=$?
9309         done
9310
9311         SAVE_UMASK=$(umask)
9312         umask 0022
9313         mkdir -p $DIR/$tdir
9314         cd $DIR/$tdir
9315
9316         echo "performing cp ..."
9317         run_acl_subtest cp || error "run_acl_subtest cp failed"
9318         echo "performing getfacl-noacl..."
9319         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
9320         echo "performing misc..."
9321         run_acl_subtest misc || error  "misc test failed"
9322         echo "performing permissions..."
9323         run_acl_subtest permissions || error "permissions failed"
9324         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
9325         if [ $MDS1_VERSION -gt $(version_code 2.8.55) ] ||
9326                 { [ $MDS1_VERSION -lt $(version_code 2.6) ] &&
9327                         [ $MDS1_VERSION -ge $(version_code 2.5.29) ]; }
9328         then
9329                 echo "performing permissions xattr..."
9330                 run_acl_subtest permissions_xattr ||
9331                         error "permissions_xattr failed"
9332         fi
9333         echo "performing setfacl..."
9334         run_acl_subtest setfacl || error  "setfacl test failed"
9335
9336         # inheritance test got from HP
9337         echo "performing inheritance..."
9338         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
9339         chmod +x make-tree || error "chmod +x failed"
9340         run_acl_subtest inheritance || error "inheritance test failed"
9341         rm -f make-tree
9342
9343         echo "LU-974 ignore umask when acl is enabled..."
9344         run_acl_subtest 974 || error "LU-974 umask test failed"
9345         if [ $MDSCOUNT -ge 2 ]; then
9346                 run_acl_subtest 974_remote ||
9347                         error "LU-974 umask test failed under remote dir"
9348         fi
9349
9350         echo "LU-2561 newly created file is same size as directory..."
9351         if [ "$mds1_FSTYPE" != "zfs" ]; then
9352                 run_acl_subtest 2561 || error "LU-2561 test failed"
9353         else
9354                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
9355         fi
9356
9357         run_acl_subtest 4924 || error "LU-4924 test failed"
9358
9359         cd $SAVE_PWD
9360         umask $SAVE_UMASK
9361
9362         for num in $(seq $MDSCOUNT); do
9363                 if [ "${identity_old[$num]}" = 1 ]; then
9364                         switch_identity $num false || identity_old[$num]=$?
9365                 fi
9366         done
9367 }
9368 run_test 103a "acl test"
9369
9370 test_103b() {
9371         declare -a pids
9372         local U
9373
9374         for U in {0..511}; do
9375                 {
9376                 local O=$(printf "%04o" $U)
9377
9378                 umask $(printf "%04o" $((511 ^ $O)))
9379                 $LFS setstripe -c 1 $DIR/$tfile.s$O
9380                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
9381
9382                 (( $S == ($O & 0666) )) ||
9383                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
9384
9385                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
9386                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
9387                 (( $S == ($O & 0666) )) ||
9388                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
9389
9390                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
9391                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
9392                 (( $S == ($O & 0666) )) ||
9393                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
9394                 rm -f $DIR/$tfile.[smp]$0
9395                 } &
9396                 local pid=$!
9397
9398                 # limit the concurrently running threads to 64. LU-11878
9399                 local idx=$((U % 64))
9400                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
9401                 pids[idx]=$pid
9402         done
9403         wait
9404 }
9405 run_test 103b "umask lfs setstripe"
9406
9407 test_103c() {
9408         mkdir -p $DIR/$tdir
9409         cp -rp $DIR/$tdir $DIR/$tdir.bak
9410
9411         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
9412                 error "$DIR/$tdir shouldn't contain default ACL"
9413         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
9414                 error "$DIR/$tdir.bak shouldn't contain default ACL"
9415         true
9416 }
9417 run_test 103c "'cp -rp' won't set empty acl"
9418
9419 test_104a() {
9420         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9421
9422         touch $DIR/$tfile
9423         lfs df || error "lfs df failed"
9424         lfs df -ih || error "lfs df -ih failed"
9425         lfs df -h $DIR || error "lfs df -h $DIR failed"
9426         lfs df -i $DIR || error "lfs df -i $DIR failed"
9427         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
9428         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
9429
9430         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
9431         lctl --device %$OSC deactivate
9432         lfs df || error "lfs df with deactivated OSC failed"
9433         lctl --device %$OSC activate
9434         # wait the osc back to normal
9435         wait_osc_import_ready client ost
9436
9437         lfs df || error "lfs df with reactivated OSC failed"
9438         rm -f $DIR/$tfile
9439 }
9440 run_test 104a "lfs df [-ih] [path] test ========================="
9441
9442 test_104b() {
9443         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9444         [ $RUNAS_ID -eq $UID ] &&
9445                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9446
9447         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
9448                         grep "Permission denied" | wc -l)))
9449         if [ $denied_cnt -ne 0 ]; then
9450                 error "lfs check servers test failed"
9451         fi
9452 }
9453 run_test 104b "$RUNAS lfs check servers test ===================="
9454
9455 test_105a() {
9456         # doesn't work on 2.4 kernels
9457         touch $DIR/$tfile
9458         if $(flock_is_enabled); then
9459                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
9460         else
9461                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
9462         fi
9463         rm -f $DIR/$tfile
9464 }
9465 run_test 105a "flock when mounted without -o flock test ========"
9466
9467 test_105b() {
9468         touch $DIR/$tfile
9469         if $(flock_is_enabled); then
9470                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
9471         else
9472                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
9473         fi
9474         rm -f $DIR/$tfile
9475 }
9476 run_test 105b "fcntl when mounted without -o flock test ========"
9477
9478 test_105c() {
9479         touch $DIR/$tfile
9480         if $(flock_is_enabled); then
9481                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
9482         else
9483                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
9484         fi
9485         rm -f $DIR/$tfile
9486 }
9487 run_test 105c "lockf when mounted without -o flock test"
9488
9489 test_105d() { # bug 15924
9490         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9491
9492         test_mkdir $DIR/$tdir
9493         flock_is_enabled || skip_env "mount w/o flock enabled"
9494         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
9495         $LCTL set_param fail_loc=0x80000315
9496         flocks_test 2 $DIR/$tdir
9497 }
9498 run_test 105d "flock race (should not freeze) ========"
9499
9500 test_105e() { # bug 22660 && 22040
9501         flock_is_enabled || skip_env "mount w/o flock enabled"
9502
9503         touch $DIR/$tfile
9504         flocks_test 3 $DIR/$tfile
9505 }
9506 run_test 105e "Two conflicting flocks from same process"
9507
9508 test_106() { #bug 10921
9509         test_mkdir $DIR/$tdir
9510         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
9511         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
9512 }
9513 run_test 106 "attempt exec of dir followed by chown of that dir"
9514
9515 test_107() {
9516         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9517
9518         CDIR=`pwd`
9519         local file=core
9520
9521         cd $DIR
9522         rm -f $file
9523
9524         local save_pattern=$(sysctl -n kernel.core_pattern)
9525         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
9526         sysctl -w kernel.core_pattern=$file
9527         sysctl -w kernel.core_uses_pid=0
9528
9529         ulimit -c unlimited
9530         sleep 60 &
9531         SLEEPPID=$!
9532
9533         sleep 1
9534
9535         kill -s 11 $SLEEPPID
9536         wait $SLEEPPID
9537         if [ -e $file ]; then
9538                 size=`stat -c%s $file`
9539                 [ $size -eq 0 ] && error "Fail to create core file $file"
9540         else
9541                 error "Fail to create core file $file"
9542         fi
9543         rm -f $file
9544         sysctl -w kernel.core_pattern=$save_pattern
9545         sysctl -w kernel.core_uses_pid=$save_uses_pid
9546         cd $CDIR
9547 }
9548 run_test 107 "Coredump on SIG"
9549
9550 test_110() {
9551         test_mkdir $DIR/$tdir
9552         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
9553         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
9554                 error "mkdir with 256 char should fail, but did not"
9555         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
9556                 error "create with 255 char failed"
9557         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
9558                 error "create with 256 char should fail, but did not"
9559
9560         ls -l $DIR/$tdir
9561         rm -rf $DIR/$tdir
9562 }
9563 run_test 110 "filename length checking"
9564
9565 #
9566 # Purpose: To verify dynamic thread (OSS) creation.
9567 #
9568 test_115() {
9569         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9570         remote_ost_nodsh && skip "remote OST with nodsh"
9571
9572         # Lustre does not stop service threads once they are started.
9573         # Reset number of running threads to default.
9574         stopall
9575         setupall
9576
9577         local OSTIO_pre
9578         local save_params="$TMP/sanity-$TESTNAME.parameters"
9579
9580         # Get ll_ost_io count before I/O
9581         OSTIO_pre=$(do_facet ost1 \
9582                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
9583         # Exit if lustre is not running (ll_ost_io not running).
9584         [ -z "$OSTIO_pre" ] && error "no OSS threads"
9585
9586         echo "Starting with $OSTIO_pre threads"
9587         local thread_max=$((OSTIO_pre * 2))
9588         local rpc_in_flight=$((thread_max * 2))
9589         # Number of I/O Process proposed to be started.
9590         local nfiles
9591         local facets=$(get_facets OST)
9592
9593         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
9594         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
9595
9596         # Set in_flight to $rpc_in_flight
9597         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
9598                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
9599         nfiles=${rpc_in_flight}
9600         # Set ost thread_max to $thread_max
9601         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
9602
9603         # 5 Minutes should be sufficient for max number of OSS
9604         # threads(thread_max) to be created.
9605         local timeout=300
9606
9607         # Start I/O.
9608         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
9609         test_mkdir $DIR/$tdir
9610         for i in $(seq $nfiles); do
9611                 local file=$DIR/$tdir/${tfile}-$i
9612                 $LFS setstripe -c -1 -i 0 $file
9613                 ($WTL $file $timeout)&
9614         done
9615
9616         # I/O Started - Wait for thread_started to reach thread_max or report
9617         # error if thread_started is more than thread_max.
9618         echo "Waiting for thread_started to reach thread_max"
9619         local thread_started=0
9620         local end_time=$((SECONDS + timeout))
9621
9622         while [ $SECONDS -le $end_time ] ; do
9623                 echo -n "."
9624                 # Get ost i/o thread_started count.
9625                 thread_started=$(do_facet ost1 \
9626                         "$LCTL get_param \
9627                         ost.OSS.ost_io.threads_started | cut -d= -f2")
9628                 # Break out if thread_started is equal/greater than thread_max
9629                 if [[ $thread_started -ge $thread_max ]]; then
9630                         echo ll_ost_io thread_started $thread_started, \
9631                                 equal/greater than thread_max $thread_max
9632                         break
9633                 fi
9634                 sleep 1
9635         done
9636
9637         # Cleanup - We have the numbers, Kill i/o jobs if running.
9638         jobcount=($(jobs -p))
9639         for i in $(seq 0 $((${#jobcount[@]}-1)))
9640         do
9641                 kill -9 ${jobcount[$i]}
9642                 if [ $? -ne 0 ] ; then
9643                         echo Warning: \
9644                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
9645                 fi
9646         done
9647
9648         # Cleanup files left by WTL binary.
9649         for i in $(seq $nfiles); do
9650                 local file=$DIR/$tdir/${tfile}-$i
9651                 rm -rf $file
9652                 if [ $? -ne 0 ] ; then
9653                         echo "Warning: Failed to delete file $file"
9654                 fi
9655         done
9656
9657         restore_lustre_params <$save_params
9658         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
9659
9660         # Error out if no new thread has started or Thread started is greater
9661         # than thread max.
9662         if [[ $thread_started -le $OSTIO_pre ||
9663                         $thread_started -gt $thread_max ]]; then
9664                 error "ll_ost_io: thread_started $thread_started" \
9665                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
9666                       "No new thread started or thread started greater " \
9667                       "than thread_max."
9668         fi
9669 }
9670 run_test 115 "verify dynamic thread creation===================="
9671
9672 free_min_max () {
9673         wait_delete_completed
9674         AVAIL=($(lctl get_param -n osc.*[oO][sS][cC]-[^M]*.kbytesavail))
9675         echo "OST kbytes available: ${AVAIL[@]}"
9676         MAXV=${AVAIL[0]}
9677         MAXI=0
9678         MINV=${AVAIL[0]}
9679         MINI=0
9680         for ((i = 0; i < ${#AVAIL[@]}; i++)); do
9681                 #echo OST $i: ${AVAIL[i]}kb
9682                 if [[ ${AVAIL[i]} -gt $MAXV ]]; then
9683                         MAXV=${AVAIL[i]}
9684                         MAXI=$i
9685                 fi
9686                 if [[ ${AVAIL[i]} -lt $MINV ]]; then
9687                         MINV=${AVAIL[i]}
9688                         MINI=$i
9689                 fi
9690         done
9691         echo "Min free space: OST $MINI: $MINV"
9692         echo "Max free space: OST $MAXI: $MAXV"
9693 }
9694
9695 test_116a() { # was previously test_116()
9696         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9697         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9698         remote_mds_nodsh && skip "remote MDS with nodsh"
9699
9700         echo -n "Free space priority "
9701         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
9702                 head -n1
9703         declare -a AVAIL
9704         free_min_max
9705
9706         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
9707         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
9708         trap simple_cleanup_common EXIT
9709
9710         # Check if we need to generate uneven OSTs
9711         test_mkdir -p $DIR/$tdir/OST${MINI}
9712         local FILL=$((MINV / 4))
9713         local DIFF=$((MAXV - MINV))
9714         local DIFF2=$((DIFF * 100 / MINV))
9715
9716         local threshold=$(do_facet $SINGLEMDS \
9717                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
9718         threshold=${threshold%%%}
9719         echo -n "Check for uneven OSTs: "
9720         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
9721
9722         if [[ $DIFF2 -gt $threshold ]]; then
9723                 echo "ok"
9724                 echo "Don't need to fill OST$MINI"
9725         else
9726                 # generate uneven OSTs. Write 2% over the QOS threshold value
9727                 echo "no"
9728                 DIFF=$((threshold - DIFF2 + 2))
9729                 DIFF2=$((MINV * DIFF / 100))
9730                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
9731                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
9732                         error "setstripe failed"
9733                 DIFF=$((DIFF2 / 2048))
9734                 i=0
9735                 while [ $i -lt $DIFF ]; do
9736                         i=$((i + 1))
9737                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
9738                                 bs=2M count=1 2>/dev/null
9739                         echo -n .
9740                 done
9741                 echo .
9742                 sync
9743                 sleep_maxage
9744                 free_min_max
9745         fi
9746
9747         DIFF=$((MAXV - MINV))
9748         DIFF2=$((DIFF * 100 / MINV))
9749         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
9750         if [ $DIFF2 -gt $threshold ]; then
9751                 echo "ok"
9752         else
9753                 echo "failed - QOS mode won't be used"
9754                 simple_cleanup_common
9755                 skip "QOS imbalance criteria not met"
9756         fi
9757
9758         MINI1=$MINI
9759         MINV1=$MINV
9760         MAXI1=$MAXI
9761         MAXV1=$MAXV
9762
9763         # now fill using QOS
9764         $LFS setstripe -c 1 $DIR/$tdir
9765         FILL=$((FILL / 200))
9766         if [ $FILL -gt 600 ]; then
9767                 FILL=600
9768         fi
9769         echo "writing $FILL files to QOS-assigned OSTs"
9770         i=0
9771         while [ $i -lt $FILL ]; do
9772                 i=$((i + 1))
9773                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
9774                         count=1 2>/dev/null
9775                 echo -n .
9776         done
9777         echo "wrote $i 200k files"
9778         sync
9779         sleep_maxage
9780
9781         echo "Note: free space may not be updated, so measurements might be off"
9782         free_min_max
9783         DIFF2=$((MAXV - MINV))
9784         echo "free space delta: orig $DIFF final $DIFF2"
9785         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
9786         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
9787         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
9788         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
9789         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
9790         if [[ $DIFF -gt 0 ]]; then
9791                 FILL=$((DIFF2 * 100 / DIFF - 100))
9792                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
9793         fi
9794
9795         # Figure out which files were written where
9796         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
9797                awk '/'$MINI1': / {print $2; exit}')
9798         echo $UUID
9799         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
9800         echo "$MINC files created on smaller OST $MINI1"
9801         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
9802                awk '/'$MAXI1': / {print $2; exit}')
9803         echo $UUID
9804         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
9805         echo "$MAXC files created on larger OST $MAXI1"
9806         if [[ $MINC -gt 0 ]]; then
9807                 FILL=$((MAXC * 100 / MINC - 100))
9808                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
9809         fi
9810         [[ $MAXC -gt $MINC ]] ||
9811                 error_ignore LU-9 "stripe QOS didn't balance free space"
9812         simple_cleanup_common
9813 }
9814 run_test 116a "stripe QOS: free space balance ==================="
9815
9816 test_116b() { # LU-2093
9817         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9818         remote_mds_nodsh && skip "remote MDS with nodsh"
9819
9820 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
9821         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
9822                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
9823         [ -z "$old_rr" ] && skip "no QOS"
9824         do_facet $SINGLEMDS lctl set_param \
9825                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
9826         mkdir -p $DIR/$tdir
9827         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
9828         createmany -o $DIR/$tdir/f- 20 || error "can't create"
9829         do_facet $SINGLEMDS lctl set_param fail_loc=0
9830         rm -rf $DIR/$tdir
9831         do_facet $SINGLEMDS lctl set_param \
9832                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
9833 }
9834 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
9835
9836 test_117() # bug 10891
9837 {
9838         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9839
9840         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
9841         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
9842         lctl set_param fail_loc=0x21e
9843         > $DIR/$tfile || error "truncate failed"
9844         lctl set_param fail_loc=0
9845         echo "Truncate succeeded."
9846         rm -f $DIR/$tfile
9847 }
9848 run_test 117 "verify osd extend =========="
9849
9850 NO_SLOW_RESENDCOUNT=4
9851 export OLD_RESENDCOUNT=""
9852 set_resend_count () {
9853         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
9854         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
9855         lctl set_param -n $PROC_RESENDCOUNT $1
9856         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
9857 }
9858
9859 # for reduce test_118* time (b=14842)
9860 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
9861
9862 # Reset async IO behavior after error case
9863 reset_async() {
9864         FILE=$DIR/reset_async
9865
9866         # Ensure all OSCs are cleared
9867         $LFS setstripe -c -1 $FILE
9868         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
9869         sync
9870         rm $FILE
9871 }
9872
9873 test_118a() #bug 11710
9874 {
9875         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9876
9877         reset_async
9878
9879         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9880         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9881         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
9882
9883         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9884                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9885                 return 1;
9886         fi
9887         rm -f $DIR/$tfile
9888 }
9889 run_test 118a "verify O_SYNC works =========="
9890
9891 test_118b()
9892 {
9893         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9894         remote_ost_nodsh && skip "remote OST with nodsh"
9895
9896         reset_async
9897
9898         #define OBD_FAIL_SRV_ENOENT 0x217
9899         set_nodes_failloc "$(osts_nodes)" 0x217
9900         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9901         RC=$?
9902         set_nodes_failloc "$(osts_nodes)" 0
9903         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9904         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9905                     grep -c writeback)
9906
9907         if [[ $RC -eq 0 ]]; then
9908                 error "Must return error due to dropped pages, rc=$RC"
9909                 return 1;
9910         fi
9911
9912         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9913                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9914                 return 1;
9915         fi
9916
9917         echo "Dirty pages not leaked on ENOENT"
9918
9919         # Due to the above error the OSC will issue all RPCs syncronously
9920         # until a subsequent RPC completes successfully without error.
9921         $MULTIOP $DIR/$tfile Ow4096yc
9922         rm -f $DIR/$tfile
9923
9924         return 0
9925 }
9926 run_test 118b "Reclaim dirty pages on fatal error =========="
9927
9928 test_118c()
9929 {
9930         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9931
9932         # for 118c, restore the original resend count, LU-1940
9933         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
9934                                 set_resend_count $OLD_RESENDCOUNT
9935         remote_ost_nodsh && skip "remote OST with nodsh"
9936
9937         reset_async
9938
9939         #define OBD_FAIL_OST_EROFS               0x216
9940         set_nodes_failloc "$(osts_nodes)" 0x216
9941
9942         # multiop should block due to fsync until pages are written
9943         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
9944         MULTIPID=$!
9945         sleep 1
9946
9947         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
9948                 error "Multiop failed to block on fsync, pid=$MULTIPID"
9949         fi
9950
9951         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9952                     grep -c writeback)
9953         if [[ $WRITEBACK -eq 0 ]]; then
9954                 error "No page in writeback, writeback=$WRITEBACK"
9955         fi
9956
9957         set_nodes_failloc "$(osts_nodes)" 0
9958         wait $MULTIPID
9959         RC=$?
9960         if [[ $RC -ne 0 ]]; then
9961                 error "Multiop fsync failed, rc=$RC"
9962         fi
9963
9964         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9965         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9966                     grep -c writeback)
9967         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9968                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9969         fi
9970
9971         rm -f $DIR/$tfile
9972         echo "Dirty pages flushed via fsync on EROFS"
9973         return 0
9974 }
9975 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
9976
9977 # continue to use small resend count to reduce test_118* time (b=14842)
9978 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
9979
9980 test_118d()
9981 {
9982         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9983         remote_ost_nodsh && skip "remote OST with nodsh"
9984
9985         reset_async
9986
9987         #define OBD_FAIL_OST_BRW_PAUSE_BULK
9988         set_nodes_failloc "$(osts_nodes)" 0x214
9989         # multiop should block due to fsync until pages are written
9990         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
9991         MULTIPID=$!
9992         sleep 1
9993
9994         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
9995                 error "Multiop failed to block on fsync, pid=$MULTIPID"
9996         fi
9997
9998         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9999                     grep -c writeback)
10000         if [[ $WRITEBACK -eq 0 ]]; then
10001                 error "No page in writeback, writeback=$WRITEBACK"
10002         fi
10003
10004         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
10005         set_nodes_failloc "$(osts_nodes)" 0
10006
10007         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10008         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10009                     grep -c writeback)
10010         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10011                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10012         fi
10013
10014         rm -f $DIR/$tfile
10015         echo "Dirty pages gaurenteed flushed via fsync"
10016         return 0
10017 }
10018 run_test 118d "Fsync validation inject a delay of the bulk =========="
10019
10020 test_118f() {
10021         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10022
10023         reset_async
10024
10025         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
10026         lctl set_param fail_loc=0x8000040a
10027
10028         # Should simulate EINVAL error which is fatal
10029         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10030         RC=$?
10031         if [[ $RC -eq 0 ]]; then
10032                 error "Must return error due to dropped pages, rc=$RC"
10033         fi
10034
10035         lctl set_param fail_loc=0x0
10036
10037         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
10038         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10039         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10040                     grep -c writeback)
10041         if [[ $LOCKED -ne 0 ]]; then
10042                 error "Locked pages remain in cache, locked=$LOCKED"
10043         fi
10044
10045         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10046                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10047         fi
10048
10049         rm -f $DIR/$tfile
10050         echo "No pages locked after fsync"
10051
10052         reset_async
10053         return 0
10054 }
10055 run_test 118f "Simulate unrecoverable OSC side error =========="
10056
10057 test_118g() {
10058         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10059
10060         reset_async
10061
10062         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
10063         lctl set_param fail_loc=0x406
10064
10065         # simulate local -ENOMEM
10066         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10067         RC=$?
10068
10069         lctl set_param fail_loc=0
10070         if [[ $RC -eq 0 ]]; then
10071                 error "Must return error due to dropped pages, rc=$RC"
10072         fi
10073
10074         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
10075         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10076         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10077                         grep -c writeback)
10078         if [[ $LOCKED -ne 0 ]]; then
10079                 error "Locked pages remain in cache, locked=$LOCKED"
10080         fi
10081
10082         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10083                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10084         fi
10085
10086         rm -f $DIR/$tfile
10087         echo "No pages locked after fsync"
10088
10089         reset_async
10090         return 0
10091 }
10092 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
10093
10094 test_118h() {
10095         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10096         remote_ost_nodsh && skip "remote OST with nodsh"
10097
10098         reset_async
10099
10100         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
10101         set_nodes_failloc "$(osts_nodes)" 0x20e
10102         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
10103         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10104         RC=$?
10105
10106         set_nodes_failloc "$(osts_nodes)" 0
10107         if [[ $RC -eq 0 ]]; then
10108                 error "Must return error due to dropped pages, rc=$RC"
10109         fi
10110
10111         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
10112         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10113         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10114                     grep -c writeback)
10115         if [[ $LOCKED -ne 0 ]]; then
10116                 error "Locked pages remain in cache, locked=$LOCKED"
10117         fi
10118
10119         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10120                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10121         fi
10122
10123         rm -f $DIR/$tfile
10124         echo "No pages locked after fsync"
10125
10126         return 0
10127 }
10128 run_test 118h "Verify timeout in handling recoverables errors  =========="
10129
10130 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
10131
10132 test_118i() {
10133         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10134         remote_ost_nodsh && skip "remote OST with nodsh"
10135
10136         reset_async
10137
10138         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
10139         set_nodes_failloc "$(osts_nodes)" 0x20e
10140
10141         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
10142         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
10143         PID=$!
10144         sleep 5
10145         set_nodes_failloc "$(osts_nodes)" 0
10146
10147         wait $PID
10148         RC=$?
10149         if [[ $RC -ne 0 ]]; then
10150                 error "got error, but should be not, rc=$RC"
10151         fi
10152
10153         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
10154         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10155         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
10156         if [[ $LOCKED -ne 0 ]]; then
10157                 error "Locked pages remain in cache, locked=$LOCKED"
10158         fi
10159
10160         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10161                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10162         fi
10163
10164         rm -f $DIR/$tfile
10165         echo "No pages locked after fsync"
10166
10167         return 0
10168 }
10169 run_test 118i "Fix error before timeout in recoverable error  =========="
10170
10171 [ "$SLOW" = "no" ] && set_resend_count 4
10172
10173 test_118j() {
10174         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10175         remote_ost_nodsh && skip "remote OST with nodsh"
10176
10177         reset_async
10178
10179         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
10180         set_nodes_failloc "$(osts_nodes)" 0x220
10181
10182         # return -EIO from OST
10183         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10184         RC=$?
10185         set_nodes_failloc "$(osts_nodes)" 0x0
10186         if [[ $RC -eq 0 ]]; then
10187                 error "Must return error due to dropped pages, rc=$RC"
10188         fi
10189
10190         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
10191         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10192         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
10193         if [[ $LOCKED -ne 0 ]]; then
10194                 error "Locked pages remain in cache, locked=$LOCKED"
10195         fi
10196
10197         # in recoverable error on OST we want resend and stay until it finished
10198         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10199                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10200         fi
10201
10202         rm -f $DIR/$tfile
10203         echo "No pages locked after fsync"
10204
10205         return 0
10206 }
10207 run_test 118j "Simulate unrecoverable OST side error =========="
10208
10209 test_118k()
10210 {
10211         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10212         remote_ost_nodsh && skip "remote OSTs with nodsh"
10213
10214         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
10215         set_nodes_failloc "$(osts_nodes)" 0x20e
10216         test_mkdir $DIR/$tdir
10217
10218         for ((i=0;i<10;i++)); do
10219                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
10220                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
10221                 SLEEPPID=$!
10222                 sleep 0.500s
10223                 kill $SLEEPPID
10224                 wait $SLEEPPID
10225         done
10226
10227         set_nodes_failloc "$(osts_nodes)" 0
10228         rm -rf $DIR/$tdir
10229 }
10230 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
10231
10232 test_118l() # LU-646
10233 {
10234         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10235
10236         test_mkdir $DIR/$tdir
10237         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
10238         rm -rf $DIR/$tdir
10239 }
10240 run_test 118l "fsync dir"
10241
10242 test_118m() # LU-3066
10243 {
10244         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10245
10246         test_mkdir $DIR/$tdir
10247         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
10248         rm -rf $DIR/$tdir
10249 }
10250 run_test 118m "fdatasync dir ========="
10251
10252 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
10253
10254 test_118n()
10255 {
10256         local begin
10257         local end
10258
10259         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10260         remote_ost_nodsh && skip "remote OSTs with nodsh"
10261
10262         # Sleep to avoid a cached response.
10263         #define OBD_STATFS_CACHE_SECONDS 1
10264         sleep 2
10265
10266         # Inject a 10 second delay in the OST_STATFS handler.
10267         #define OBD_FAIL_OST_STATFS_DELAY 0x242
10268         set_nodes_failloc "$(osts_nodes)" 0x242
10269
10270         begin=$SECONDS
10271         stat --file-system $MOUNT > /dev/null
10272         end=$SECONDS
10273
10274         set_nodes_failloc "$(osts_nodes)" 0
10275
10276         if ((end - begin > 20)); then
10277             error "statfs took $((end - begin)) seconds, expected 10"
10278         fi
10279 }
10280 run_test 118n "statfs() sends OST_STATFS requests in parallel"
10281
10282 test_119a() # bug 11737
10283 {
10284         BSIZE=$((512 * 1024))
10285         directio write $DIR/$tfile 0 1 $BSIZE
10286         # We ask to read two blocks, which is more than a file size.
10287         # directio will indicate an error when requested and actual
10288         # sizes aren't equeal (a normal situation in this case) and
10289         # print actual read amount.
10290         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
10291         if [ "$NOB" != "$BSIZE" ]; then
10292                 error "read $NOB bytes instead of $BSIZE"
10293         fi
10294         rm -f $DIR/$tfile
10295 }
10296 run_test 119a "Short directIO read must return actual read amount"
10297
10298 test_119b() # bug 11737
10299 {
10300         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10301
10302         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
10303         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
10304         sync
10305         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
10306                 error "direct read failed"
10307         rm -f $DIR/$tfile
10308 }
10309 run_test 119b "Sparse directIO read must return actual read amount"
10310
10311 test_119c() # bug 13099
10312 {
10313         BSIZE=1048576
10314         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
10315         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
10316         rm -f $DIR/$tfile
10317 }
10318 run_test 119c "Testing for direct read hitting hole"
10319
10320 test_119d() # bug 15950
10321 {
10322         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10323
10324         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
10325         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
10326         BSIZE=1048576
10327         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
10328         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
10329         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
10330         lctl set_param fail_loc=0x40d
10331         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
10332         pid_dio=$!
10333         sleep 1
10334         cat $DIR/$tfile > /dev/null &
10335         lctl set_param fail_loc=0
10336         pid_reads=$!
10337         wait $pid_dio
10338         log "the DIO writes have completed, now wait for the reads (should not block very long)"
10339         sleep 2
10340         [ -n "`ps h -p $pid_reads -o comm`" ] && \
10341         error "the read rpcs have not completed in 2s"
10342         rm -f $DIR/$tfile
10343         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
10344 }
10345 run_test 119d "The DIO path should try to send a new rpc once one is completed"
10346
10347 test_120a() {
10348         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10349         remote_mds_nodsh && skip "remote MDS with nodsh"
10350         test_mkdir -i0 -c1 $DIR/$tdir
10351         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10352                 skip_env "no early lock cancel on server"
10353
10354         lru_resize_disable mdc
10355         lru_resize_disable osc
10356         cancel_lru_locks mdc
10357         # asynchronous object destroy at MDT could cause bl ast to client
10358         cancel_lru_locks osc
10359
10360         stat $DIR/$tdir > /dev/null
10361         can1=$(do_facet mds1 \
10362                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10363                awk '/ldlm_cancel/ {print $2}')
10364         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10365                awk '/ldlm_bl_callback/ {print $2}')
10366         test_mkdir -i0 -c1 $DIR/$tdir/d1
10367         can2=$(do_facet mds1 \
10368                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10369                awk '/ldlm_cancel/ {print $2}')
10370         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10371                awk '/ldlm_bl_callback/ {print $2}')
10372         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
10373         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
10374         lru_resize_enable mdc
10375         lru_resize_enable osc
10376 }
10377 run_test 120a "Early Lock Cancel: mkdir test"
10378
10379 test_120b() {
10380         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10381         remote_mds_nodsh && skip "remote MDS with nodsh"
10382         test_mkdir $DIR/$tdir
10383         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10384                 skip_env "no early lock cancel on server"
10385
10386         lru_resize_disable mdc
10387         lru_resize_disable osc
10388         cancel_lru_locks mdc
10389         stat $DIR/$tdir > /dev/null
10390         can1=$(do_facet $SINGLEMDS \
10391                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10392                awk '/ldlm_cancel/ {print $2}')
10393         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10394                awk '/ldlm_bl_callback/ {print $2}')
10395         touch $DIR/$tdir/f1
10396         can2=$(do_facet $SINGLEMDS \
10397                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10398                awk '/ldlm_cancel/ {print $2}')
10399         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10400                awk '/ldlm_bl_callback/ {print $2}')
10401         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
10402         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
10403         lru_resize_enable mdc
10404         lru_resize_enable osc
10405 }
10406 run_test 120b "Early Lock Cancel: create test"
10407
10408 test_120c() {
10409         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10410         remote_mds_nodsh && skip "remote MDS with nodsh"
10411         test_mkdir -i0 -c1 $DIR/$tdir
10412         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10413                 skip "no early lock cancel on server"
10414
10415         lru_resize_disable mdc
10416         lru_resize_disable osc
10417         test_mkdir -i0 -c1 $DIR/$tdir/d1
10418         test_mkdir -i0 -c1 $DIR/$tdir/d2
10419         touch $DIR/$tdir/d1/f1
10420         cancel_lru_locks mdc
10421         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
10422         can1=$(do_facet mds1 \
10423                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10424                awk '/ldlm_cancel/ {print $2}')
10425         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10426                awk '/ldlm_bl_callback/ {print $2}')
10427         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
10428         can2=$(do_facet mds1 \
10429                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10430                awk '/ldlm_cancel/ {print $2}')
10431         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10432                awk '/ldlm_bl_callback/ {print $2}')
10433         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
10434         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
10435         lru_resize_enable mdc
10436         lru_resize_enable osc
10437 }
10438 run_test 120c "Early Lock Cancel: link test"
10439
10440 test_120d() {
10441         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10442         remote_mds_nodsh && skip "remote MDS with nodsh"
10443         test_mkdir -i0 -c1 $DIR/$tdir
10444         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10445                 skip_env "no early lock cancel on server"
10446
10447         lru_resize_disable mdc
10448         lru_resize_disable osc
10449         touch $DIR/$tdir
10450         cancel_lru_locks mdc
10451         stat $DIR/$tdir > /dev/null
10452         can1=$(do_facet mds1 \
10453                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10454                awk '/ldlm_cancel/ {print $2}')
10455         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10456                awk '/ldlm_bl_callback/ {print $2}')
10457         chmod a+x $DIR/$tdir
10458         can2=$(do_facet mds1 \
10459                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10460                awk '/ldlm_cancel/ {print $2}')
10461         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10462                awk '/ldlm_bl_callback/ {print $2}')
10463         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
10464         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
10465         lru_resize_enable mdc
10466         lru_resize_enable osc
10467 }
10468 run_test 120d "Early Lock Cancel: setattr test"
10469
10470 test_120e() {
10471         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10472         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10473                 skip_env "no early lock cancel on server"
10474         remote_mds_nodsh && skip "remote MDS with nodsh"
10475
10476         local dlmtrace_set=false
10477
10478         test_mkdir -i0 -c1 $DIR/$tdir
10479         lru_resize_disable mdc
10480         lru_resize_disable osc
10481         ! $LCTL get_param debug | grep -q dlmtrace &&
10482                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
10483         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
10484         cancel_lru_locks mdc
10485         cancel_lru_locks osc
10486         dd if=$DIR/$tdir/f1 of=/dev/null
10487         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
10488         # XXX client can not do early lock cancel of OST lock
10489         # during unlink (LU-4206), so cancel osc lock now.
10490         sleep 2
10491         cancel_lru_locks osc
10492         can1=$(do_facet mds1 \
10493                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10494                awk '/ldlm_cancel/ {print $2}')
10495         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10496                awk '/ldlm_bl_callback/ {print $2}')
10497         unlink $DIR/$tdir/f1
10498         sleep 5
10499         can2=$(do_facet mds1 \
10500                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10501                awk '/ldlm_cancel/ {print $2}')
10502         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10503                awk '/ldlm_bl_callback/ {print $2}')
10504         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
10505                 $LCTL dk $TMP/cancel.debug.txt
10506         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
10507                 $LCTL dk $TMP/blocking.debug.txt
10508         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
10509         lru_resize_enable mdc
10510         lru_resize_enable osc
10511 }
10512 run_test 120e "Early Lock Cancel: unlink test"
10513
10514 test_120f() {
10515         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10516         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10517                 skip_env "no early lock cancel on server"
10518         remote_mds_nodsh && skip "remote MDS with nodsh"
10519
10520         test_mkdir -i0 -c1 $DIR/$tdir
10521         lru_resize_disable mdc
10522         lru_resize_disable osc
10523         test_mkdir -i0 -c1 $DIR/$tdir/d1
10524         test_mkdir -i0 -c1 $DIR/$tdir/d2
10525         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
10526         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
10527         cancel_lru_locks mdc
10528         cancel_lru_locks osc
10529         dd if=$DIR/$tdir/d1/f1 of=/dev/null
10530         dd if=$DIR/$tdir/d2/f2 of=/dev/null
10531         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
10532         # XXX client can not do early lock cancel of OST lock
10533         # during rename (LU-4206), so cancel osc lock now.
10534         sleep 2
10535         cancel_lru_locks osc
10536         can1=$(do_facet mds1 \
10537                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10538                awk '/ldlm_cancel/ {print $2}')
10539         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10540                awk '/ldlm_bl_callback/ {print $2}')
10541         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
10542         sleep 5
10543         can2=$(do_facet mds1 \
10544                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10545                awk '/ldlm_cancel/ {print $2}')
10546         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10547                awk '/ldlm_bl_callback/ {print $2}')
10548         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
10549         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
10550         lru_resize_enable mdc
10551         lru_resize_enable osc
10552 }
10553 run_test 120f "Early Lock Cancel: rename test"
10554
10555 test_120g() {
10556         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10557         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10558                 skip_env "no early lock cancel on server"
10559         remote_mds_nodsh && skip "remote MDS with nodsh"
10560
10561         lru_resize_disable mdc
10562         lru_resize_disable osc
10563         count=10000
10564         echo create $count files
10565         test_mkdir $DIR/$tdir
10566         cancel_lru_locks mdc
10567         cancel_lru_locks osc
10568         t0=$(date +%s)
10569
10570         can0=$(do_facet $SINGLEMDS \
10571                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10572                awk '/ldlm_cancel/ {print $2}')
10573         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10574                awk '/ldlm_bl_callback/ {print $2}')
10575         createmany -o $DIR/$tdir/f $count
10576         sync
10577         can1=$(do_facet $SINGLEMDS \
10578                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10579                awk '/ldlm_cancel/ {print $2}')
10580         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10581                awk '/ldlm_bl_callback/ {print $2}')
10582         t1=$(date +%s)
10583         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
10584         echo rm $count files
10585         rm -r $DIR/$tdir
10586         sync
10587         can2=$(do_facet $SINGLEMDS \
10588                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10589                awk '/ldlm_cancel/ {print $2}')
10590         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10591                awk '/ldlm_bl_callback/ {print $2}')
10592         t2=$(date +%s)
10593         echo total: $count removes in $((t2-t1))
10594         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
10595         sleep 2
10596         # wait for commitment of removal
10597         lru_resize_enable mdc
10598         lru_resize_enable osc
10599 }
10600 run_test 120g "Early Lock Cancel: performance test"
10601
10602 test_121() { #bug #10589
10603         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10604
10605         rm -rf $DIR/$tfile
10606         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
10607 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
10608         lctl set_param fail_loc=0x310
10609         cancel_lru_locks osc > /dev/null
10610         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
10611         lctl set_param fail_loc=0
10612         [[ $reads -eq $writes ]] ||
10613                 error "read $reads blocks, must be $writes blocks"
10614 }
10615 run_test 121 "read cancel race ========="
10616
10617 test_123a() { # was test 123, statahead(bug 11401)
10618         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10619
10620         SLOWOK=0
10621         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
10622                 log "testing UP system. Performance may be lower than expected."
10623                 SLOWOK=1
10624         fi
10625
10626         rm -rf $DIR/$tdir
10627         test_mkdir $DIR/$tdir
10628         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
10629         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
10630         MULT=10
10631         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
10632                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
10633
10634                 max=`lctl get_param -n llite.*.statahead_max | head -n 1`
10635                 lctl set_param -n llite.*.statahead_max 0
10636                 lctl get_param llite.*.statahead_max
10637                 cancel_lru_locks mdc
10638                 cancel_lru_locks osc
10639                 stime=`date +%s`
10640                 time ls -l $DIR/$tdir | wc -l
10641                 etime=`date +%s`
10642                 delta=$((etime - stime))
10643                 log "ls $i files without statahead: $delta sec"
10644                 lctl set_param llite.*.statahead_max=$max
10645
10646                 swrong=`lctl get_param -n llite.*.statahead_stats | grep "statahead wrong:" | awk '{print $3}'`
10647                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
10648                 cancel_lru_locks mdc
10649                 cancel_lru_locks osc
10650                 stime=`date +%s`
10651                 time ls -l $DIR/$tdir | wc -l
10652                 etime=`date +%s`
10653                 delta_sa=$((etime - stime))
10654                 log "ls $i files with statahead: $delta_sa sec"
10655                 lctl get_param -n llite.*.statahead_stats
10656                 ewrong=`lctl get_param -n llite.*.statahead_stats | grep "statahead wrong:" | awk '{print $3}'`
10657
10658                 [[ $swrong -lt $ewrong ]] &&
10659                         log "statahead was stopped, maybe too many locks held!"
10660                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
10661
10662                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
10663                     max=`lctl get_param -n llite.*.statahead_max | head -n 1`
10664                     lctl set_param -n llite.*.statahead_max 0
10665                     lctl get_param llite.*.statahead_max
10666                     cancel_lru_locks mdc
10667                     cancel_lru_locks osc
10668                     stime=`date +%s`
10669                     time ls -l $DIR/$tdir | wc -l
10670                     etime=`date +%s`
10671                     delta=$((etime - stime))
10672                     log "ls $i files again without statahead: $delta sec"
10673                     lctl set_param llite.*.statahead_max=$max
10674                     if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
10675                         if [  $SLOWOK -eq 0 ]; then
10676                                 error "ls $i files is slower with statahead!"
10677                         else
10678                                 log "ls $i files is slower with statahead!"
10679                         fi
10680                         break
10681                     fi
10682                 fi
10683
10684                 [ $delta -gt 20 ] && break
10685                 [ $delta -gt 8 ] && MULT=$((50 / delta))
10686                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
10687         done
10688         log "ls done"
10689
10690         stime=`date +%s`
10691         rm -r $DIR/$tdir
10692         sync
10693         etime=`date +%s`
10694         delta=$((etime - stime))
10695         log "rm -r $DIR/$tdir/: $delta seconds"
10696         log "rm done"
10697         lctl get_param -n llite.*.statahead_stats
10698 }
10699 run_test 123a "verify statahead work"
10700
10701 test_123b () { # statahead(bug 15027)
10702         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10703
10704         test_mkdir $DIR/$tdir
10705         createmany -o $DIR/$tdir/$tfile-%d 1000
10706
10707         cancel_lru_locks mdc
10708         cancel_lru_locks osc
10709
10710 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
10711         lctl set_param fail_loc=0x80000803
10712         ls -lR $DIR/$tdir > /dev/null
10713         log "ls done"
10714         lctl set_param fail_loc=0x0
10715         lctl get_param -n llite.*.statahead_stats
10716         rm -r $DIR/$tdir
10717         sync
10718
10719 }
10720 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
10721
10722 test_124a() {
10723         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10724         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
10725                 skip_env "no lru resize on server"
10726
10727         local NR=2000
10728
10729         test_mkdir $DIR/$tdir
10730
10731         log "create $NR files at $DIR/$tdir"
10732         createmany -o $DIR/$tdir/f $NR ||
10733                 error "failed to create $NR files in $DIR/$tdir"
10734
10735         cancel_lru_locks mdc
10736         ls -l $DIR/$tdir > /dev/null
10737
10738         local NSDIR=""
10739         local LRU_SIZE=0
10740         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
10741                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
10742                 LRU_SIZE=$($LCTL get_param -n $PARAM)
10743                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
10744                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
10745                         log "NSDIR=$NSDIR"
10746                         log "NS=$(basename $NSDIR)"
10747                         break
10748                 fi
10749         done
10750
10751         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
10752                 skip "Not enough cached locks created!"
10753         fi
10754         log "LRU=$LRU_SIZE"
10755
10756         local SLEEP=30
10757
10758         # We know that lru resize allows one client to hold $LIMIT locks
10759         # for 10h. After that locks begin to be killed by client.
10760         local MAX_HRS=10
10761         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
10762         log "LIMIT=$LIMIT"
10763         if [ $LIMIT -lt $LRU_SIZE ]; then
10764                 skip "Limit is too small $LIMIT"
10765         fi
10766
10767         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
10768         # killing locks. Some time was spent for creating locks. This means
10769         # that up to the moment of sleep finish we must have killed some of
10770         # them (10-100 locks). This depends on how fast ther were created.
10771         # Many of them were touched in almost the same moment and thus will
10772         # be killed in groups.
10773         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE))
10774
10775         # Use $LRU_SIZE_B here to take into account real number of locks
10776         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
10777         local LRU_SIZE_B=$LRU_SIZE
10778         log "LVF=$LVF"
10779         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
10780         log "OLD_LVF=$OLD_LVF"
10781         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
10782
10783         # Let's make sure that we really have some margin. Client checks
10784         # cached locks every 10 sec.
10785         SLEEP=$((SLEEP+20))
10786         log "Sleep ${SLEEP} sec"
10787         local SEC=0
10788         while ((SEC<$SLEEP)); do
10789                 echo -n "..."
10790                 sleep 5
10791                 SEC=$((SEC+5))
10792                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
10793                 echo -n "$LRU_SIZE"
10794         done
10795         echo ""
10796         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
10797         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
10798
10799         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
10800                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
10801                 unlinkmany $DIR/$tdir/f $NR
10802                 return
10803         }
10804
10805         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
10806         log "unlink $NR files at $DIR/$tdir"
10807         unlinkmany $DIR/$tdir/f $NR
10808 }
10809 run_test 124a "lru resize ======================================="
10810
10811 get_max_pool_limit()
10812 {
10813         local limit=$($LCTL get_param \
10814                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
10815         local max=0
10816         for l in $limit; do
10817                 if [[ $l -gt $max ]]; then
10818                         max=$l
10819                 fi
10820         done
10821         echo $max
10822 }
10823
10824 test_124b() {
10825         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10826         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
10827                 skip_env "no lru resize on server"
10828
10829         LIMIT=$(get_max_pool_limit)
10830
10831         NR=$(($(default_lru_size)*20))
10832         if [[ $NR -gt $LIMIT ]]; then
10833                 log "Limit lock number by $LIMIT locks"
10834                 NR=$LIMIT
10835         fi
10836
10837         IFree=$(mdsrate_inodes_available)
10838         if [ $IFree -lt $NR ]; then
10839                 log "Limit lock number by $IFree inodes"
10840                 NR=$IFree
10841         fi
10842
10843         lru_resize_disable mdc
10844         test_mkdir -p $DIR/$tdir/disable_lru_resize
10845
10846         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
10847         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
10848         cancel_lru_locks mdc
10849         stime=`date +%s`
10850         PID=""
10851         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
10852         PID="$PID $!"
10853         sleep 2
10854         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
10855         PID="$PID $!"
10856         sleep 2
10857         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
10858         PID="$PID $!"
10859         wait $PID
10860         etime=`date +%s`
10861         nolruresize_delta=$((etime-stime))
10862         log "ls -la time: $nolruresize_delta seconds"
10863         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
10864         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
10865
10866         lru_resize_enable mdc
10867         test_mkdir -p $DIR/$tdir/enable_lru_resize
10868
10869         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
10870         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
10871         cancel_lru_locks mdc
10872         stime=`date +%s`
10873         PID=""
10874         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
10875         PID="$PID $!"
10876         sleep 2
10877         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
10878         PID="$PID $!"
10879         sleep 2
10880         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
10881         PID="$PID $!"
10882         wait $PID
10883         etime=`date +%s`
10884         lruresize_delta=$((etime-stime))
10885         log "ls -la time: $lruresize_delta seconds"
10886         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
10887
10888         if [ $lruresize_delta -gt $nolruresize_delta ]; then
10889                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
10890         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
10891                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
10892         else
10893                 log "lru resize performs the same with no lru resize"
10894         fi
10895         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
10896 }
10897 run_test 124b "lru resize (performance test) ======================="
10898
10899 test_124c() {
10900         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10901         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
10902                 skip_env "no lru resize on server"
10903
10904         # cache ununsed locks on client
10905         local nr=100
10906         cancel_lru_locks mdc
10907         test_mkdir $DIR/$tdir
10908         createmany -o $DIR/$tdir/f $nr ||
10909                 error "failed to create $nr files in $DIR/$tdir"
10910         ls -l $DIR/$tdir > /dev/null
10911
10912         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
10913         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
10914         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
10915         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
10916         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
10917
10918         # set lru_max_age to 1 sec
10919         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
10920         echo "sleep $((recalc_p * 2)) seconds..."
10921         sleep $((recalc_p * 2))
10922
10923         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
10924         # restore lru_max_age
10925         $LCTL set_param -n $nsdir.lru_max_age $max_age
10926         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
10927         unlinkmany $DIR/$tdir/f $nr
10928 }
10929 run_test 124c "LRUR cancel very aged locks"
10930
10931 test_124d() {
10932         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10933         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
10934                 skip_env "no lru resize on server"
10935
10936         # cache ununsed locks on client
10937         local nr=100
10938
10939         lru_resize_disable mdc
10940         stack_trap "lru_resize_enable mdc" EXIT
10941
10942         cancel_lru_locks mdc
10943
10944         # asynchronous object destroy at MDT could cause bl ast to client
10945         test_mkdir $DIR/$tdir
10946         createmany -o $DIR/$tdir/f $nr ||
10947                 error "failed to create $nr files in $DIR/$tdir"
10948         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
10949
10950         ls -l $DIR/$tdir > /dev/null
10951
10952         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
10953         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
10954         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
10955         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
10956
10957         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
10958
10959         # set lru_max_age to 1 sec
10960         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
10961         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
10962
10963         echo "sleep $((recalc_p * 2)) seconds..."
10964         sleep $((recalc_p * 2))
10965
10966         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
10967
10968         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
10969 }
10970 run_test 124d "cancel very aged locks if lru-resize diasbaled"
10971
10972 test_125() { # 13358
10973         $LCTL get_param -n llite.*.client_type | grep -q local ||
10974                 skip "must run as local client"
10975         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
10976                 skip_env "must have acl enabled"
10977         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
10978
10979         test_mkdir $DIR/$tdir
10980         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
10981         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
10982         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
10983 }
10984 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
10985
10986 test_126() { # bug 12829/13455
10987         $GSS && skip_env "must run as gss disabled"
10988         $LCTL get_param -n llite.*.client_type | grep -q local ||
10989                 skip "must run as local client"
10990         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
10991
10992         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
10993         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
10994         rm -f $DIR/$tfile
10995         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
10996 }
10997 run_test 126 "check that the fsgid provided by the client is taken into account"
10998
10999 test_127a() { # bug 15521
11000         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11001
11002         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
11003         $LCTL set_param osc.*.stats=0
11004         FSIZE=$((2048 * 1024))
11005         dd if=/dev/zero of=$DIR/$tfile bs=$FSIZE count=1
11006         cancel_lru_locks osc
11007         dd if=$DIR/$tfile of=/dev/null bs=$FSIZE
11008
11009         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/${tfile}.tmp
11010         while read NAME COUNT SAMP UNIT MIN MAX SUM SUMSQ; do
11011                 echo "got $COUNT $NAME"
11012                 [ ! $MIN ] && error "Missing min value for $NAME proc entry"
11013                 eval $NAME=$COUNT || error "Wrong proc format"
11014
11015                 case $NAME in
11016                         read_bytes|write_bytes)
11017                         [ $MIN -lt 4096 ] && error "min is too small: $MIN"
11018                         [ $MIN -gt $FSIZE ] && error "min is too big: $MIN"
11019                         [ $MAX -lt 4096 ] && error "max is too small: $MAX"
11020                         [ $MAX -gt $FSIZE ] && error "max is too big: $MAX"
11021                         [ $SUM -ne $FSIZE ] && error "sum is wrong: $SUM"
11022                         [ $SUMSQ -lt $(((FSIZE /4096) * (4096 * 4096))) ] &&
11023                                 error "sumsquare is too small: $SUMSQ"
11024                         [ $SUMSQ -gt $((FSIZE * FSIZE)) ] &&
11025                                 error "sumsquare is too big: $SUMSQ"
11026                         ;;
11027                         *) ;;
11028                 esac
11029         done < $DIR/${tfile}.tmp
11030
11031         #check that we actually got some stats
11032         [ "$read_bytes" ] || error "Missing read_bytes stats"
11033         [ "$write_bytes" ] || error "Missing write_bytes stats"
11034         [ "$read_bytes" != 0 ] || error "no read done"
11035         [ "$write_bytes" != 0 ] || error "no write done"
11036 }
11037 run_test 127a "verify the client stats are sane"
11038
11039 test_127b() { # bug LU-333
11040         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11041         local name count samp unit min max sum sumsq
11042
11043         $LCTL set_param llite.*.stats=0
11044
11045         # perform 2 reads and writes so MAX is different from SUM.
11046         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
11047         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
11048         cancel_lru_locks osc
11049         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
11050         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
11051
11052         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
11053         while read name count samp unit min max sum sumsq; do
11054                 echo "got $count $name"
11055                 eval $name=$count || error "Wrong proc format"
11056
11057                 case $name in
11058                 read_bytes)
11059                         [ $count -ne 2 ] && error "count is not 2: $count"
11060                         [ $min -ne $PAGE_SIZE ] &&
11061                                 error "min is not $PAGE_SIZE: $min"
11062                         [ $max -ne $PAGE_SIZE ] &&
11063                                 error "max is incorrect: $max"
11064                         [ $sum -ne $((PAGE_SIZE * 2)) ] &&
11065                                 error "sum is wrong: $sum"
11066                         ;;
11067                 write_bytes)
11068                         [ $count -ne 2 ] && error "count is not 2: $count"
11069                         [ $min -ne $PAGE_SIZE ] &&
11070                                 error "min is not $PAGE_SIZE: $min"
11071                         [ $max -ne $PAGE_SIZE ] &&
11072                                 error "max is incorrect: $max"
11073                         [ $sum -ne $((PAGE_SIZE * 2)) ] &&
11074                                 error "sum is wrong: $sum"
11075                         ;;
11076                 *) ;;
11077                 esac
11078         done < $TMP/$tfile.tmp
11079
11080         #check that we actually got some stats
11081         [ "$read_bytes" ] || error "Missing read_bytes stats"
11082         [ "$write_bytes" ] || error "Missing write_bytes stats"
11083         [ "$read_bytes" != 0 ] || error "no read done"
11084         [ "$write_bytes" != 0 ] || error "no write done"
11085
11086         rm -f $TMP/${tfile}.tmp
11087 }
11088 run_test 127b "verify the llite client stats are sane"
11089
11090 test_127c() { # LU-12394
11091         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
11092         local size
11093         local bsize
11094         local reads
11095         local writes
11096         local count
11097
11098         $LCTL set_param llite.*.extents_stats=1
11099         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
11100
11101         # Use two stripes so there is enough space in default config
11102         $LFS setstripe -c 2 $DIR/$tfile
11103
11104         # Extent stats start at 0-4K and go in power of two buckets
11105         # LL_HIST_START = 12 --> 2^12 = 4K
11106         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
11107         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
11108         # small configs
11109         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
11110                 do
11111                 # Write and read, 2x each, second time at a non-zero offset
11112                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
11113                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
11114                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
11115                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
11116                 rm -f $DIR/$tfile
11117         done
11118
11119         $LCTL get_param llite.*.extents_stats
11120
11121         count=2
11122         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
11123                 do
11124                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
11125                                 grep -m 1 $bsize)
11126                 reads=$(echo $bucket | awk '{print $5}')
11127                 writes=$(echo $bucket | awk '{print $9}')
11128                 [ "$reads" -eq $count ] ||
11129                         error "$reads reads in < $bsize bucket, expect $count"
11130                 [ "$writes" -eq $count ] ||
11131                         error "$writes writes in < $bsize bucket, expect $count"
11132         done
11133
11134         # Test mmap write and read
11135         $LCTL set_param llite.*.extents_stats=c
11136         size=512
11137         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
11138         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
11139         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
11140
11141         $LCTL get_param llite.*.extents_stats
11142
11143         count=$(((size*1024) / PAGE_SIZE))
11144
11145         bsize=$((2 * PAGE_SIZE / 1024))K
11146
11147         bucket=$($LCTL get_param -n llite.*.extents_stats |
11148                         grep -m 1 $bsize)
11149         reads=$(echo $bucket | awk '{print $5}')
11150         writes=$(echo $bucket | awk '{print $9}')
11151         # mmap writes fault in the page first, creating an additonal read
11152         [ "$reads" -eq $((2 * count)) ] ||
11153                 error "$reads reads in < $bsize bucket, expect $count"
11154         [ "$writes" -eq $count ] ||
11155                 error "$writes writes in < $bsize bucket, expect $count"
11156 }
11157 run_test 127c "test llite extent stats with regular & mmap i/o"
11158
11159 test_128() { # bug 15212
11160         touch $DIR/$tfile
11161         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
11162                 find $DIR/$tfile
11163                 find $DIR/$tfile
11164         EOF
11165
11166         result=$(grep error $TMP/$tfile.log)
11167         rm -f $DIR/$tfile $TMP/$tfile.log
11168         [ -z "$result" ] ||
11169                 error "consecutive find's under interactive lfs failed"
11170 }
11171 run_test 128 "interactive lfs for 2 consecutive find's"
11172
11173 set_dir_limits () {
11174         local mntdev
11175         local canondev
11176         local node
11177
11178         local ldproc=/proc/fs/ldiskfs
11179         local facets=$(get_facets MDS)
11180
11181         for facet in ${facets//,/ }; do
11182                 canondev=$(ldiskfs_canon \
11183                            *.$(convert_facet2label $facet).mntdev $facet)
11184                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
11185                         ldproc=/sys/fs/ldiskfs
11186                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
11187                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
11188         done
11189 }
11190
11191 check_mds_dmesg() {
11192         local facets=$(get_facets MDS)
11193         for facet in ${facets//,/ }; do
11194                 do_facet $facet "dmesg | tail -3 | grep -q $1" && return 0
11195         done
11196         return 1
11197 }
11198
11199 test_129() {
11200         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11201         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
11202                 skip "Need MDS version with at least 2.5.56"
11203         if [ "$mds1_FSTYPE" != ldiskfs ]; then
11204                 skip_env "ldiskfs only test"
11205         fi
11206         remote_mds_nodsh && skip "remote MDS with nodsh"
11207
11208         local ENOSPC=28
11209         local EFBIG=27
11210         local has_warning=false
11211
11212         rm -rf $DIR/$tdir
11213         mkdir -p $DIR/$tdir
11214
11215         # block size of mds1
11216         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 5))
11217         set_dir_limits $maxsize $maxsize
11218         local dirsize=$(stat -c%s "$DIR/$tdir")
11219         local nfiles=0
11220         while [[ $dirsize -le $maxsize ]]; do
11221                 $MULTIOP $DIR/$tdir/file_base_$nfiles Oc
11222                 rc=$?
11223                 if ! $has_warning; then
11224                         check_mds_dmesg '"is approaching"' && has_warning=true
11225                 fi
11226                 # check two errors:
11227                 # ENOSPC for new ext4 max_dir_size (kernel commit df981d03ee)
11228                 # EFBIG for previous versions included in ldiskfs series
11229                 if [ $rc -eq $EFBIG ] || [ $rc -eq $ENOSPC ]; then
11230                         set_dir_limits 0 0
11231                         echo "return code $rc received as expected"
11232
11233                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
11234                                 error_exit "create failed w/o dir size limit"
11235
11236                         check_mds_dmesg '"has reached"' ||
11237                                 error_exit "reached message should be output"
11238
11239                         [ $has_warning = "false" ] &&
11240                                 error_exit "warning message should be output"
11241
11242                         dirsize=$(stat -c%s "$DIR/$tdir")
11243
11244                         [[ $dirsize -ge $maxsize ]] && return 0
11245                         error_exit "current dir size $dirsize, " \
11246                                    "previous limit $maxsize"
11247                 elif [ $rc -ne 0 ]; then
11248                         set_dir_limits 0 0
11249                         error_exit "return $rc received instead of expected " \
11250                                    "$EFBIG or $ENOSPC, files in dir $dirsize"
11251                 fi
11252                 nfiles=$((nfiles + 1))
11253                 dirsize=$(stat -c%s "$DIR/$tdir")
11254         done
11255
11256         set_dir_limits 0 0
11257         error "exceeded dir size limit $maxsize($MDSCOUNT) : $dirsize bytes"
11258 }
11259 run_test 129 "test directory size limit ========================"
11260
11261 OLDIFS="$IFS"
11262 cleanup_130() {
11263         trap 0
11264         IFS="$OLDIFS"
11265 }
11266
11267 test_130a() {
11268         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
11269         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
11270
11271         trap cleanup_130 EXIT RETURN
11272
11273         local fm_file=$DIR/$tfile
11274         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
11275         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
11276                 error "dd failed for $fm_file"
11277
11278         # LU-1795: test filefrag/FIEMAP once, even if unsupported
11279         filefrag -ves $fm_file
11280         RC=$?
11281         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
11282                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
11283         [ $RC != 0 ] && error "filefrag $fm_file failed"
11284
11285         filefrag_op=$(filefrag -ve -k $fm_file |
11286                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
11287         lun=$($LFS getstripe -i $fm_file)
11288
11289         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
11290         IFS=$'\n'
11291         tot_len=0
11292         for line in $filefrag_op
11293         do
11294                 frag_lun=`echo $line | cut -d: -f5`
11295                 ext_len=`echo $line | cut -d: -f4`
11296                 if (( $frag_lun != $lun )); then
11297                         cleanup_130
11298                         error "FIEMAP on 1-stripe file($fm_file) failed"
11299                         return
11300                 fi
11301                 (( tot_len += ext_len ))
11302         done
11303
11304         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
11305                 cleanup_130
11306                 error "FIEMAP on 1-stripe file($fm_file) failed;"
11307                 return
11308         fi
11309
11310         cleanup_130
11311
11312         echo "FIEMAP on single striped file succeeded"
11313 }
11314 run_test 130a "FIEMAP (1-stripe file)"
11315
11316 test_130b() {
11317         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
11318
11319         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
11320         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
11321
11322         trap cleanup_130 EXIT RETURN
11323
11324         local fm_file=$DIR/$tfile
11325         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
11326                         error "setstripe on $fm_file"
11327         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
11328                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
11329
11330         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
11331                 error "dd failed on $fm_file"
11332
11333         filefrag -ves $fm_file || error "filefrag $fm_file failed"
11334         filefrag_op=$(filefrag -ve -k $fm_file |
11335                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
11336
11337         last_lun=$(echo $filefrag_op | cut -d: -f5 |
11338                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11339
11340         IFS=$'\n'
11341         tot_len=0
11342         num_luns=1
11343         for line in $filefrag_op
11344         do
11345                 frag_lun=$(echo $line | cut -d: -f5 |
11346                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11347                 ext_len=$(echo $line | cut -d: -f4)
11348                 if (( $frag_lun != $last_lun )); then
11349                         if (( tot_len != 1024 )); then
11350                                 cleanup_130
11351                                 error "FIEMAP on $fm_file failed; returned " \
11352                                 "len $tot_len for OST $last_lun instead of 1024"
11353                                 return
11354                         else
11355                                 (( num_luns += 1 ))
11356                                 tot_len=0
11357                         fi
11358                 fi
11359                 (( tot_len += ext_len ))
11360                 last_lun=$frag_lun
11361         done
11362         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
11363                 cleanup_130
11364                 error "FIEMAP on $fm_file failed; returned wrong number of " \
11365                         "luns or wrong len for OST $last_lun"
11366                 return
11367         fi
11368
11369         cleanup_130
11370
11371         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
11372 }
11373 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
11374
11375 test_130c() {
11376         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11377
11378         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
11379         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
11380
11381         trap cleanup_130 EXIT RETURN
11382
11383         local fm_file=$DIR/$tfile
11384         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
11385         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
11386                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
11387
11388         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
11389                         error "dd failed on $fm_file"
11390
11391         filefrag -ves $fm_file || error "filefrag $fm_file failed"
11392         filefrag_op=$(filefrag -ve -k $fm_file |
11393                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
11394
11395         last_lun=$(echo $filefrag_op | cut -d: -f5 |
11396                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11397
11398         IFS=$'\n'
11399         tot_len=0
11400         num_luns=1
11401         for line in $filefrag_op
11402         do
11403                 frag_lun=$(echo $line | cut -d: -f5 |
11404                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11405                 ext_len=$(echo $line | cut -d: -f4)
11406                 if (( $frag_lun != $last_lun )); then
11407                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
11408                         if (( logical != 512 )); then
11409                                 cleanup_130
11410                                 error "FIEMAP on $fm_file failed; returned " \
11411                                 "logical start for lun $logical instead of 512"
11412                                 return
11413                         fi
11414                         if (( tot_len != 512 )); then
11415                                 cleanup_130
11416                                 error "FIEMAP on $fm_file failed; returned " \
11417                                 "len $tot_len for OST $last_lun instead of 1024"
11418                                 return
11419                         else
11420                                 (( num_luns += 1 ))
11421                                 tot_len=0
11422                         fi
11423                 fi
11424                 (( tot_len += ext_len ))
11425                 last_lun=$frag_lun
11426         done
11427         if (( num_luns != 2 || tot_len != 512 )); then
11428                 cleanup_130
11429                 error "FIEMAP on $fm_file failed; returned wrong number of " \
11430                         "luns or wrong len for OST $last_lun"
11431                 return
11432         fi
11433
11434         cleanup_130
11435
11436         echo "FIEMAP on 2-stripe file with hole succeeded"
11437 }
11438 run_test 130c "FIEMAP (2-stripe file with hole)"
11439
11440 test_130d() {
11441         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
11442
11443         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
11444         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
11445
11446         trap cleanup_130 EXIT RETURN
11447
11448         local fm_file=$DIR/$tfile
11449         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
11450                         error "setstripe on $fm_file"
11451         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
11452                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
11453
11454         local actual_stripe_count=$($LFS getstripe -c $fm_file)
11455         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
11456                 error "dd failed on $fm_file"
11457
11458         filefrag -ves $fm_file || error "filefrag $fm_file failed"
11459         filefrag_op=$(filefrag -ve -k $fm_file |
11460                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
11461
11462         last_lun=$(echo $filefrag_op | cut -d: -f5 |
11463                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11464
11465         IFS=$'\n'
11466         tot_len=0
11467         num_luns=1
11468         for line in $filefrag_op
11469         do
11470                 frag_lun=$(echo $line | cut -d: -f5 |
11471                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11472                 ext_len=$(echo $line | cut -d: -f4)
11473                 if (( $frag_lun != $last_lun )); then
11474                         if (( tot_len != 1024 )); then
11475                                 cleanup_130
11476                                 error "FIEMAP on $fm_file failed; returned " \
11477                                 "len $tot_len for OST $last_lun instead of 1024"
11478                                 return
11479                         else
11480                                 (( num_luns += 1 ))
11481                                 tot_len=0
11482                         fi
11483                 fi
11484                 (( tot_len += ext_len ))
11485                 last_lun=$frag_lun
11486         done
11487         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
11488                 cleanup_130
11489                 error "FIEMAP on $fm_file failed; returned wrong number of " \
11490                         "luns or wrong len for OST $last_lun"
11491                 return
11492         fi
11493
11494         cleanup_130
11495
11496         echo "FIEMAP on N-stripe file succeeded"
11497 }
11498 run_test 130d "FIEMAP (N-stripe file)"
11499
11500 test_130e() {
11501         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11502
11503         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
11504         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
11505
11506         trap cleanup_130 EXIT RETURN
11507
11508         local fm_file=$DIR/$tfile
11509         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
11510         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
11511                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
11512
11513         NUM_BLKS=512
11514         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
11515         for ((i = 0; i < $NUM_BLKS; i++))
11516         do
11517                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) conv=notrunc > /dev/null 2>&1
11518         done
11519
11520         filefrag -ves $fm_file || error "filefrag $fm_file failed"
11521         filefrag_op=$(filefrag -ve -k $fm_file |
11522                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
11523
11524         last_lun=$(echo $filefrag_op | cut -d: -f5 |
11525                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11526
11527         IFS=$'\n'
11528         tot_len=0
11529         num_luns=1
11530         for line in $filefrag_op
11531         do
11532                 frag_lun=$(echo $line | cut -d: -f5 |
11533                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11534                 ext_len=$(echo $line | cut -d: -f4)
11535                 if (( $frag_lun != $last_lun )); then
11536                         if (( tot_len != $EXPECTED_LEN )); then
11537                                 cleanup_130
11538                                 error "FIEMAP on $fm_file failed; returned " \
11539                                 "len $tot_len for OST $last_lun instead " \
11540                                 "of $EXPECTED_LEN"
11541                                 return
11542                         else
11543                                 (( num_luns += 1 ))
11544                                 tot_len=0
11545                         fi
11546                 fi
11547                 (( tot_len += ext_len ))
11548                 last_lun=$frag_lun
11549         done
11550         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
11551                 cleanup_130
11552                 error "FIEMAP on $fm_file failed; returned wrong number " \
11553                         "of luns or wrong len for OST $last_lun"
11554                 return
11555         fi
11556
11557         cleanup_130
11558
11559         echo "FIEMAP with continuation calls succeeded"
11560 }
11561 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
11562
11563 test_130f() {
11564         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
11565         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
11566
11567         local fm_file=$DIR/$tfile
11568         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
11569                 error "multiop create with lov_delay_create on $fm_file"
11570
11571         filefrag -ves $fm_file || error "filefrag $fm_file failed"
11572         filefrag_extents=$(filefrag -vek $fm_file |
11573                            awk '/extents? found/ { print $2 }')
11574         if [[ "$filefrag_extents" != "0" ]]; then
11575                 error "FIEMAP on $fm_file failed; " \
11576                       "returned $filefrag_extents expected 0"
11577         fi
11578
11579         rm -f $fm_file
11580 }
11581 run_test 130f "FIEMAP (unstriped file)"
11582
11583 # Test for writev/readv
11584 test_131a() {
11585         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
11586                 error "writev test failed"
11587         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
11588                 error "readv failed"
11589         rm -f $DIR/$tfile
11590 }
11591 run_test 131a "test iov's crossing stripe boundary for writev/readv"
11592
11593 test_131b() {
11594         local fsize=$((524288 + 1048576 + 1572864))
11595         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
11596                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
11597                         error "append writev test failed"
11598
11599         ((fsize += 1572864 + 1048576))
11600         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
11601                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
11602                         error "append writev test failed"
11603         rm -f $DIR/$tfile
11604 }
11605 run_test 131b "test append writev"
11606
11607 test_131c() {
11608         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
11609         error "NOT PASS"
11610 }
11611 run_test 131c "test read/write on file w/o objects"
11612
11613 test_131d() {
11614         rwv -f $DIR/$tfile -w -n 1 1572864
11615         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
11616         if [ "$NOB" != 1572864 ]; then
11617                 error "Short read filed: read $NOB bytes instead of 1572864"
11618         fi
11619         rm -f $DIR/$tfile
11620 }
11621 run_test 131d "test short read"
11622
11623 test_131e() {
11624         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
11625         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
11626         error "read hitting hole failed"
11627         rm -f $DIR/$tfile
11628 }
11629 run_test 131e "test read hitting hole"
11630
11631 check_stats() {
11632         local facet=$1
11633         local op=$2
11634         local want=${3:-0}
11635         local res
11636
11637         case $facet in
11638         mds*) res=$(do_facet $facet \
11639                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
11640                  ;;
11641         ost*) res=$(do_facet $facet \
11642                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
11643                  ;;
11644         *) error "Wrong facet '$facet'" ;;
11645         esac
11646         [ "$res" ] || error "The counter for $op on $facet was not incremented"
11647         # if the argument $3 is zero, it means any stat increment is ok.
11648         if [[ $want -gt 0 ]]; then
11649                 local count=$(echo $res | awk '{ print $2 }')
11650                 [[ $count -ne $want ]] &&
11651                         error "The $op counter on $facet is $count, not $want"
11652         fi
11653 }
11654
11655 test_133a() {
11656         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11657         remote_ost_nodsh && skip "remote OST with nodsh"
11658         remote_mds_nodsh && skip "remote MDS with nodsh"
11659         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
11660                 skip_env "MDS doesn't support rename stats"
11661
11662         local testdir=$DIR/${tdir}/stats_testdir
11663
11664         mkdir -p $DIR/${tdir}
11665
11666         # clear stats.
11667         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
11668         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
11669
11670         # verify mdt stats first.
11671         mkdir ${testdir} || error "mkdir failed"
11672         check_stats $SINGLEMDS "mkdir" 1
11673         touch ${testdir}/${tfile} || error "touch failed"
11674         check_stats $SINGLEMDS "open" 1
11675         check_stats $SINGLEMDS "close" 1
11676         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
11677                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
11678                 check_stats $SINGLEMDS "mknod" 2
11679         }
11680         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
11681         check_stats $SINGLEMDS "unlink" 1
11682         rm -f ${testdir}/${tfile} || error "file remove failed"
11683         check_stats $SINGLEMDS "unlink" 2
11684
11685         # remove working dir and check mdt stats again.
11686         rmdir ${testdir} || error "rmdir failed"
11687         check_stats $SINGLEMDS "rmdir" 1
11688
11689         local testdir1=$DIR/${tdir}/stats_testdir1
11690         mkdir -p ${testdir}
11691         mkdir -p ${testdir1}
11692         touch ${testdir1}/test1
11693         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
11694         check_stats $SINGLEMDS "crossdir_rename" 1
11695
11696         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
11697         check_stats $SINGLEMDS "samedir_rename" 1
11698
11699         rm -rf $DIR/${tdir}
11700 }
11701 run_test 133a "Verifying MDT stats ========================================"
11702
11703 test_133b() {
11704         local res
11705
11706         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11707         remote_ost_nodsh && skip "remote OST with nodsh"
11708         remote_mds_nodsh && skip "remote MDS with nodsh"
11709
11710         local testdir=$DIR/${tdir}/stats_testdir
11711
11712         mkdir -p ${testdir} || error "mkdir failed"
11713         touch ${testdir}/${tfile} || error "touch failed"
11714         cancel_lru_locks mdc
11715
11716         # clear stats.
11717         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
11718         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
11719
11720         # extra mdt stats verification.
11721         chmod 444 ${testdir}/${tfile} || error "chmod failed"
11722         check_stats $SINGLEMDS "setattr" 1
11723         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
11724         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
11725         then            # LU-1740
11726                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
11727                 check_stats $SINGLEMDS "getattr" 1
11728         fi
11729         rm -rf $DIR/${tdir}
11730
11731         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
11732         # so the check below is not reliable
11733         [ $MDSCOUNT -eq 1 ] || return 0
11734
11735         # Sleep to avoid a cached response.
11736         #define OBD_STATFS_CACHE_SECONDS 1
11737         sleep 2
11738         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
11739         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
11740         $LFS df || error "lfs failed"
11741         check_stats $SINGLEMDS "statfs" 1
11742
11743         # check aggregated statfs (LU-10018)
11744         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
11745                 return 0
11746         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
11747                 return 0
11748         sleep 2
11749         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
11750         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
11751         df $DIR
11752         check_stats $SINGLEMDS "statfs" 1
11753
11754         # We want to check that the client didn't send OST_STATFS to
11755         # ost1 but the MDT also uses OST_STATFS for precreate. So some
11756         # extra care is needed here.
11757         if remote_mds; then
11758                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
11759                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
11760
11761                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
11762                 [ "$res" ] && error "OST got STATFS"
11763         fi
11764
11765         return 0
11766 }
11767 run_test 133b "Verifying extra MDT stats =================================="
11768
11769 test_133c() {
11770         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11771         remote_ost_nodsh && skip "remote OST with nodsh"
11772         remote_mds_nodsh && skip "remote MDS with nodsh"
11773
11774         local testdir=$DIR/$tdir/stats_testdir
11775
11776         test_mkdir -p $testdir
11777
11778         # verify obdfilter stats.
11779         $LFS setstripe -c 1 -i 0 $testdir/$tfile
11780         sync
11781         cancel_lru_locks osc
11782         wait_delete_completed
11783
11784         # clear stats.
11785         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
11786         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
11787
11788         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
11789                 error "dd failed"
11790         sync
11791         cancel_lru_locks osc
11792         check_stats ost1 "write" 1
11793
11794         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
11795         check_stats ost1 "read" 1
11796
11797         > $testdir/$tfile || error "truncate failed"
11798         check_stats ost1 "punch" 1
11799
11800         rm -f $testdir/$tfile || error "file remove failed"
11801         wait_delete_completed
11802         check_stats ost1 "destroy" 1
11803
11804         rm -rf $DIR/$tdir
11805 }
11806 run_test 133c "Verifying OST stats ========================================"
11807
11808 order_2() {
11809         local value=$1
11810         local orig=$value
11811         local order=1
11812
11813         while [ $value -ge 2 ]; do
11814                 order=$((order*2))
11815                 value=$((value/2))
11816         done
11817
11818         if [ $orig -gt $order ]; then
11819                 order=$((order*2))
11820         fi
11821         echo $order
11822 }
11823
11824 size_in_KMGT() {
11825     local value=$1
11826     local size=('K' 'M' 'G' 'T');
11827     local i=0
11828     local size_string=$value
11829
11830     while [ $value -ge 1024 ]; do
11831         if [ $i -gt 3 ]; then
11832             #T is the biggest unit we get here, if that is bigger,
11833             #just return XXXT
11834             size_string=${value}T
11835             break
11836         fi
11837         value=$((value >> 10))
11838         if [ $value -lt 1024 ]; then
11839             size_string=${value}${size[$i]}
11840             break
11841         fi
11842         i=$((i + 1))
11843     done
11844
11845     echo $size_string
11846 }
11847
11848 get_rename_size() {
11849         local size=$1
11850         local context=${2:-.}
11851         local sample=$(do_facet $SINGLEMDS $LCTL \
11852                 get_param mdt.$FSNAME-MDT0000.rename_stats |
11853                 grep -A1 $context |
11854                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
11855         echo $sample
11856 }
11857
11858 test_133d() {
11859         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11860         remote_ost_nodsh && skip "remote OST with nodsh"
11861         remote_mds_nodsh && skip "remote MDS with nodsh"
11862         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
11863                 skip_env "MDS doesn't support rename stats"
11864
11865         local testdir1=$DIR/${tdir}/stats_testdir1
11866         local testdir2=$DIR/${tdir}/stats_testdir2
11867         mkdir -p $DIR/${tdir}
11868
11869         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
11870
11871         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
11872         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
11873
11874         createmany -o $testdir1/test 512 || error "createmany failed"
11875
11876         # check samedir rename size
11877         mv ${testdir1}/test0 ${testdir1}/test_0
11878
11879         local testdir1_size=$(ls -l $DIR/${tdir} |
11880                 awk '/stats_testdir1/ {print $5}')
11881         local testdir2_size=$(ls -l $DIR/${tdir} |
11882                 awk '/stats_testdir2/ {print $5}')
11883
11884         testdir1_size=$(order_2 $testdir1_size)
11885         testdir2_size=$(order_2 $testdir2_size)
11886
11887         testdir1_size=$(size_in_KMGT $testdir1_size)
11888         testdir2_size=$(size_in_KMGT $testdir2_size)
11889
11890         echo "source rename dir size: ${testdir1_size}"
11891         echo "target rename dir size: ${testdir2_size}"
11892
11893         local cmd="do_facet $SINGLEMDS $LCTL "
11894         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
11895
11896         eval $cmd || error "$cmd failed"
11897         local samedir=$($cmd | grep 'same_dir')
11898         local same_sample=$(get_rename_size $testdir1_size)
11899         [ -z "$samedir" ] && error "samedir_rename_size count error"
11900         [[ $same_sample -eq 1 ]] ||
11901                 error "samedir_rename_size error $same_sample"
11902         echo "Check same dir rename stats success"
11903
11904         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
11905
11906         # check crossdir rename size
11907         mv ${testdir1}/test_0 ${testdir2}/test_0
11908
11909         testdir1_size=$(ls -l $DIR/${tdir} |
11910                 awk '/stats_testdir1/ {print $5}')
11911         testdir2_size=$(ls -l $DIR/${tdir} |
11912                 awk '/stats_testdir2/ {print $5}')
11913
11914         testdir1_size=$(order_2 $testdir1_size)
11915         testdir2_size=$(order_2 $testdir2_size)
11916
11917         testdir1_size=$(size_in_KMGT $testdir1_size)
11918         testdir2_size=$(size_in_KMGT $testdir2_size)
11919
11920         echo "source rename dir size: ${testdir1_size}"
11921         echo "target rename dir size: ${testdir2_size}"
11922
11923         eval $cmd || error "$cmd failed"
11924         local crossdir=$($cmd | grep 'crossdir')
11925         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
11926         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
11927         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
11928         [[ $src_sample -eq 1 ]] ||
11929                 error "crossdir_rename_size error $src_sample"
11930         [[ $tgt_sample -eq 1 ]] ||
11931                 error "crossdir_rename_size error $tgt_sample"
11932         echo "Check cross dir rename stats success"
11933         rm -rf $DIR/${tdir}
11934 }
11935 run_test 133d "Verifying rename_stats ========================================"
11936
11937 test_133e() {
11938         remote_mds_nodsh && skip "remote MDS with nodsh"
11939         remote_ost_nodsh && skip "remote OST with nodsh"
11940         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11941
11942         local testdir=$DIR/${tdir}/stats_testdir
11943         local ctr f0 f1 bs=32768 count=42 sum
11944
11945         mkdir -p ${testdir} || error "mkdir failed"
11946
11947         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
11948
11949         for ctr in {write,read}_bytes; do
11950                 sync
11951                 cancel_lru_locks osc
11952
11953                 do_facet ost1 $LCTL set_param -n \
11954                         "obdfilter.*.exports.clear=clear"
11955
11956                 if [ $ctr = write_bytes ]; then
11957                         f0=/dev/zero
11958                         f1=${testdir}/${tfile}
11959                 else
11960                         f0=${testdir}/${tfile}
11961                         f1=/dev/null
11962                 fi
11963
11964                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
11965                         error "dd failed"
11966                 sync
11967                 cancel_lru_locks osc
11968
11969                 sum=$(do_facet ost1 $LCTL get_param \
11970                         "obdfilter.*.exports.*.stats" |
11971                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
11972                                 $1 == ctr { sum += $7 }
11973                                 END { printf("%0.0f", sum) }')
11974
11975                 if ((sum != bs * count)); then
11976                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
11977                 fi
11978         done
11979
11980         rm -rf $DIR/${tdir}
11981 }
11982 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
11983
11984 proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
11985
11986 # Some versions of find (4.5.11, 4.5.14) included in CentOS 7.3-7.5 do
11987 # not honor the -ignore_readdir_race option correctly. So we call
11988 # error_ignore() rather than error() in these cases. See LU-11152.
11989 error_133() {
11990         if (find --version; do_facet mds1 find --version) |
11991                 grep -q '\b4\.5\.1[1-4]\b'; then
11992                 error_ignore LU-11152 "$@"
11993         else
11994                 error "$@"
11995         fi
11996 }
11997
11998 test_133f() {
11999         # First without trusting modes.
12000         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
12001         echo "proc_dirs='$proc_dirs'"
12002         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
12003         find $proc_dirs -exec cat '{}' \; &> /dev/null
12004
12005         # Second verifying readability.
12006         $LCTL get_param -R '*' &> /dev/null
12007
12008         # Verifing writability with badarea_io.
12009         find $proc_dirs \
12010                 -ignore_readdir_race \
12011                 -type f \
12012                 -not -name force_lbug \
12013                 -not -name changelog_mask \
12014                 -exec badarea_io '{}' \; ||
12015                         error_133 "find $proc_dirs failed"
12016 }
12017 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
12018
12019 test_133g() {
12020         remote_mds_nodsh && skip "remote MDS with nodsh"
12021         remote_ost_nodsh && skip "remote OST with nodsh"
12022
12023         # eventually, this can also be replaced with "lctl get_param -R",
12024         # but not until that option is always available on the server
12025         local facet
12026         for facet in mds1 ost1; do
12027                 [ $(lustre_version_code $facet) -le $(version_code 2.5.54) ] &&
12028                         skip_noexit "Too old lustre on $facet"
12029                 local facet_proc_dirs=$(do_facet $facet \
12030                                         \\\ls -d $proc_regexp 2>/dev/null)
12031                 echo "${facet}_proc_dirs='$facet_proc_dirs'"
12032                 [ -z "$facet_proc_dirs" ] && error "no proc_dirs on $facet"
12033                 do_facet $facet find $facet_proc_dirs \
12034                         ! -name req_history \
12035                         -exec cat '{}' \\\; &> /dev/null
12036
12037                 do_facet $facet find $facet_proc_dirs \
12038                         ! -name req_history \
12039                         -type f \
12040                         -exec cat '{}' \\\; &> /dev/null ||
12041                                 error "proc file read failed"
12042
12043                 do_facet $facet find $facet_proc_dirs \
12044                         -ignore_readdir_race \
12045                         -type f \
12046                         -not -name force_lbug \
12047                         -not -name changelog_mask \
12048                         -exec badarea_io '{}' \\\; ||
12049                                 error_133 "$facet find $facet_proc_dirs failed"
12050         done
12051
12052         # remount the FS in case writes/reads /proc break the FS
12053         cleanup || error "failed to unmount"
12054         setup || error "failed to setup"
12055         true
12056 }
12057 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
12058
12059 test_133h() {
12060         remote_mds_nodsh && skip "remote MDS with nodsh"
12061         remote_ost_nodsh && skip "remote OST with nodsh"
12062         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
12063                 skip "Need MDS version at least 2.9.54"
12064
12065         local facet
12066
12067         for facet in client mds1 ost1; do
12068                 local facet_proc_dirs=$(do_facet $facet \
12069                                         \\\ls -d $proc_regexp 2> /dev/null)
12070                 [ -z "$facet_proc_dirs" ] && error "no proc_dirs on $facet"
12071                 echo "${facet}_proc_dirs='$facet_proc_dirs'"
12072                 # Get the list of files that are missing the terminating newline
12073                 local missing=($(do_facet $facet \
12074                         find ${facet_proc_dirs} -type f \|              \
12075                                 while read F\; do                       \
12076                                         awk -v FS='\v' -v RS='\v\v'     \
12077                                         "'END { if(NR>0 &&              \
12078                                         \\\$NF !~ /.*\\\n\$/)           \
12079                                                 print FILENAME}'"       \
12080                                         '\$F'\;                         \
12081                                 done 2>/dev/null))
12082                 [ ${#missing[*]} -eq 0 ] ||
12083                         error "files do not end with newline: ${missing[*]}"
12084         done
12085 }
12086 run_test 133h "Proc files should end with newlines"
12087
12088 test_134a() {
12089         remote_mds_nodsh && skip "remote MDS with nodsh"
12090         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
12091                 skip "Need MDS version at least 2.7.54"
12092
12093         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
12094         cancel_lru_locks mdc
12095
12096         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
12097         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12098         [ $unused -eq 0 ] || error "$unused locks are not cleared"
12099
12100         local nr=1000
12101         createmany -o $DIR/$tdir/f $nr ||
12102                 error "failed to create $nr files in $DIR/$tdir"
12103         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12104
12105         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
12106         do_facet mds1 $LCTL set_param fail_loc=0x327
12107         do_facet mds1 $LCTL set_param fail_val=500
12108         touch $DIR/$tdir/m
12109
12110         echo "sleep 10 seconds ..."
12111         sleep 10
12112         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
12113
12114         do_facet mds1 $LCTL set_param fail_loc=0
12115         do_facet mds1 $LCTL set_param fail_val=0
12116         [ $lck_cnt -lt $unused ] ||
12117                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
12118
12119         rm $DIR/$tdir/m
12120         unlinkmany $DIR/$tdir/f $nr
12121 }
12122 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
12123
12124 test_134b() {
12125         remote_mds_nodsh && skip "remote MDS with nodsh"
12126         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
12127                 skip "Need MDS version at least 2.7.54"
12128
12129         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
12130         cancel_lru_locks mdc
12131
12132         local low_wm=$(do_facet mds1 $LCTL get_param -n \
12133                         ldlm.lock_reclaim_threshold_mb)
12134         # disable reclaim temporarily
12135         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
12136
12137         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
12138         do_facet mds1 $LCTL set_param fail_loc=0x328
12139         do_facet mds1 $LCTL set_param fail_val=500
12140
12141         $LCTL set_param debug=+trace
12142
12143         local nr=600
12144         createmany -o $DIR/$tdir/f $nr &
12145         local create_pid=$!
12146
12147         echo "Sleep $TIMEOUT seconds ..."
12148         sleep $TIMEOUT
12149         if ! ps -p $create_pid  > /dev/null 2>&1; then
12150                 do_facet mds1 $LCTL set_param fail_loc=0
12151                 do_facet mds1 $LCTL set_param fail_val=0
12152                 do_facet mds1 $LCTL set_param \
12153                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
12154                 error "createmany finished incorrectly!"
12155         fi
12156         do_facet mds1 $LCTL set_param fail_loc=0
12157         do_facet mds1 $LCTL set_param fail_val=0
12158         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
12159         wait $create_pid || return 1
12160
12161         unlinkmany $DIR/$tdir/f $nr
12162 }
12163 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
12164
12165 test_140() { #bug-17379
12166         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12167
12168         test_mkdir $DIR/$tdir
12169         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
12170         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
12171
12172         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
12173         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
12174         local i=0
12175         while i=$((i + 1)); do
12176                 test_mkdir $i
12177                 cd $i || error "Changing to $i"
12178                 ln -s ../stat stat || error "Creating stat symlink"
12179                 # Read the symlink until ELOOP present,
12180                 # not LBUGing the system is considered success,
12181                 # we didn't overrun the stack.
12182                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
12183                 if [ $ret -ne 0 ]; then
12184                         if [ $ret -eq 40 ]; then
12185                                 break  # -ELOOP
12186                         else
12187                                 error "Open stat symlink"
12188                                         return
12189                         fi
12190                 fi
12191         done
12192         i=$((i - 1))
12193         echo "The symlink depth = $i"
12194         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
12195                 error "Invalid symlink depth"
12196
12197         # Test recursive symlink
12198         ln -s symlink_self symlink_self
12199         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
12200         echo "open symlink_self returns $ret"
12201         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
12202 }
12203 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
12204
12205 test_150() {
12206         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12207
12208         local TF="$TMP/$tfile"
12209
12210         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
12211         cp $TF $DIR/$tfile
12212         cancel_lru_locks $OSC
12213         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
12214         remount_client $MOUNT
12215         df -P $MOUNT
12216         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
12217
12218         $TRUNCATE $TF 6000
12219         $TRUNCATE $DIR/$tfile 6000
12220         cancel_lru_locks $OSC
12221         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
12222
12223         echo "12345" >>$TF
12224         echo "12345" >>$DIR/$tfile
12225         cancel_lru_locks $OSC
12226         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
12227
12228         echo "12345" >>$TF
12229         echo "12345" >>$DIR/$tfile
12230         cancel_lru_locks $OSC
12231         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
12232
12233         rm -f $TF
12234         true
12235 }
12236 run_test 150 "truncate/append tests"
12237
12238 #LU-2902 roc_hit was not able to read all values from lproc
12239 function roc_hit_init() {
12240         local list=$(comma_list $(osts_nodes))
12241         local dir=$DIR/$tdir-check
12242         local file=$dir/$tfile
12243         local BEFORE
12244         local AFTER
12245         local idx
12246
12247         test_mkdir $dir
12248         #use setstripe to do a write to every ost
12249         for i in $(seq 0 $((OSTCOUNT-1))); do
12250                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
12251                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
12252                 idx=$(printf %04x $i)
12253                 BEFORE=$(get_osd_param $list *OST*$idx stats |
12254                         awk '$1 == "cache_access" {sum += $7}
12255                                 END { printf("%0.0f", sum) }')
12256
12257                 cancel_lru_locks osc
12258                 cat $file >/dev/null
12259
12260                 AFTER=$(get_osd_param $list *OST*$idx stats |
12261                         awk '$1 == "cache_access" {sum += $7}
12262                                 END { printf("%0.0f", sum) }')
12263
12264                 echo BEFORE:$BEFORE AFTER:$AFTER
12265                 if ! let "AFTER - BEFORE == 4"; then
12266                         rm -rf $dir
12267                         error "roc_hit is not safe to use"
12268                 fi
12269                 rm $file
12270         done
12271
12272         rm -rf $dir
12273 }
12274
12275 function roc_hit() {
12276         local list=$(comma_list $(osts_nodes))
12277         echo $(get_osd_param $list '' stats |
12278                 awk '$1 == "cache_hit" {sum += $7}
12279                         END { printf("%0.0f", sum) }')
12280 }
12281
12282 function set_cache() {
12283         local on=1
12284
12285         if [ "$2" == "off" ]; then
12286                 on=0;
12287         fi
12288         local list=$(comma_list $(osts_nodes))
12289         set_osd_param $list '' $1_cache_enable $on
12290
12291         cancel_lru_locks osc
12292 }
12293
12294 test_151() {
12295         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12296         remote_ost_nodsh && skip "remote OST with nodsh"
12297
12298         local CPAGES=3
12299         local list=$(comma_list $(osts_nodes))
12300
12301         # check whether obdfilter is cache capable at all
12302         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
12303                 skip "not cache-capable obdfilter"
12304         fi
12305
12306         # check cache is enabled on all obdfilters
12307         if get_osd_param $list '' read_cache_enable | grep 0; then
12308                 skip "oss cache is disabled"
12309         fi
12310
12311         set_osd_param $list '' writethrough_cache_enable 1
12312
12313         # check write cache is enabled on all obdfilters
12314         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
12315                 skip "oss write cache is NOT enabled"
12316         fi
12317
12318         roc_hit_init
12319
12320         #define OBD_FAIL_OBD_NO_LRU  0x609
12321         do_nodes $list $LCTL set_param fail_loc=0x609
12322
12323         # pages should be in the case right after write
12324         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
12325                 error "dd failed"
12326
12327         local BEFORE=$(roc_hit)
12328         cancel_lru_locks osc
12329         cat $DIR/$tfile >/dev/null
12330         local AFTER=$(roc_hit)
12331
12332         do_nodes $list $LCTL set_param fail_loc=0
12333
12334         if ! let "AFTER - BEFORE == CPAGES"; then
12335                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12336         fi
12337
12338         # the following read invalidates the cache
12339         cancel_lru_locks osc
12340         set_osd_param $list '' read_cache_enable 0
12341         cat $DIR/$tfile >/dev/null
12342
12343         # now data shouldn't be found in the cache
12344         BEFORE=$(roc_hit)
12345         cancel_lru_locks osc
12346         cat $DIR/$tfile >/dev/null
12347         AFTER=$(roc_hit)
12348         if let "AFTER - BEFORE != 0"; then
12349                 error "IN CACHE: before: $BEFORE, after: $AFTER"
12350         fi
12351
12352         set_osd_param $list '' read_cache_enable 1
12353         rm -f $DIR/$tfile
12354 }
12355 run_test 151 "test cache on oss and controls ==============================="
12356
12357 test_152() {
12358         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12359
12360         local TF="$TMP/$tfile"
12361
12362         # simulate ENOMEM during write
12363 #define OBD_FAIL_OST_NOMEM      0x226
12364         lctl set_param fail_loc=0x80000226
12365         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
12366         cp $TF $DIR/$tfile
12367         sync || error "sync failed"
12368         lctl set_param fail_loc=0
12369
12370         # discard client's cache
12371         cancel_lru_locks osc
12372
12373         # simulate ENOMEM during read
12374         lctl set_param fail_loc=0x80000226
12375         cmp $TF $DIR/$tfile || error "cmp failed"
12376         lctl set_param fail_loc=0
12377
12378         rm -f $TF
12379 }
12380 run_test 152 "test read/write with enomem ============================"
12381
12382 test_153() {
12383         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
12384 }
12385 run_test 153 "test if fdatasync does not crash ======================="
12386
12387 dot_lustre_fid_permission_check() {
12388         local fid=$1
12389         local ffid=$MOUNT/.lustre/fid/$fid
12390         local test_dir=$2
12391
12392         echo "stat fid $fid"
12393         stat $ffid > /dev/null || error "stat $ffid failed."
12394         echo "touch fid $fid"
12395         touch $ffid || error "touch $ffid failed."
12396         echo "write to fid $fid"
12397         cat /etc/hosts > $ffid || error "write $ffid failed."
12398         echo "read fid $fid"
12399         diff /etc/hosts $ffid || error "read $ffid failed."
12400         echo "append write to fid $fid"
12401         cat /etc/hosts >> $ffid || error "append write $ffid failed."
12402         echo "rename fid $fid"
12403         mv $ffid $test_dir/$tfile.1 &&
12404                 error "rename $ffid to $tfile.1 should fail."
12405         touch $test_dir/$tfile.1
12406         mv $test_dir/$tfile.1 $ffid &&
12407                 error "rename $tfile.1 to $ffid should fail."
12408         rm -f $test_dir/$tfile.1
12409         echo "truncate fid $fid"
12410         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
12411         echo "link fid $fid"
12412         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
12413         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
12414                 echo "setfacl fid $fid"
12415                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
12416                 echo "getfacl fid $fid"
12417                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
12418         fi
12419         echo "unlink fid $fid"
12420         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
12421         echo "mknod fid $fid"
12422         mknod $ffid c 1 3 && error "mknod $ffid should fail."
12423
12424         fid=[0xf00000400:0x1:0x0]
12425         ffid=$MOUNT/.lustre/fid/$fid
12426
12427         echo "stat non-exist fid $fid"
12428         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
12429         echo "write to non-exist fid $fid"
12430         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
12431         echo "link new fid $fid"
12432         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
12433
12434         mkdir -p $test_dir/$tdir
12435         touch $test_dir/$tdir/$tfile
12436         fid=$($LFS path2fid $test_dir/$tdir)
12437         rc=$?
12438         [ $rc -ne 0 ] &&
12439                 error "error: could not get fid for $test_dir/$dir/$tfile."
12440
12441         ffid=$MOUNT/.lustre/fid/$fid
12442
12443         echo "ls $fid"
12444         ls $ffid > /dev/null || error "ls $ffid failed."
12445         echo "touch $fid/$tfile.1"
12446         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
12447
12448         echo "touch $MOUNT/.lustre/fid/$tfile"
12449         touch $MOUNT/.lustre/fid/$tfile && \
12450                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
12451
12452         echo "setxattr to $MOUNT/.lustre/fid"
12453         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
12454
12455         echo "listxattr for $MOUNT/.lustre/fid"
12456         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
12457
12458         echo "delxattr from $MOUNT/.lustre/fid"
12459         setfattr -x trusted.name1 $MOUNT/.lustre/fid
12460
12461         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
12462         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
12463                 error "touch invalid fid should fail."
12464
12465         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
12466         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
12467                 error "touch non-normal fid should fail."
12468
12469         echo "rename $tdir to $MOUNT/.lustre/fid"
12470         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
12471                 error "rename to $MOUNT/.lustre/fid should fail."
12472
12473         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
12474         then            # LU-3547
12475                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
12476                 local new_obf_mode=777
12477
12478                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
12479                 chmod $new_obf_mode $DIR/.lustre/fid ||
12480                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
12481
12482                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
12483                 [ $obf_mode -eq $new_obf_mode ] ||
12484                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
12485
12486                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
12487                 chmod $old_obf_mode $DIR/.lustre/fid ||
12488                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
12489         fi
12490
12491         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
12492         fid=$($LFS path2fid $test_dir/$tfile-2)
12493
12494         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
12495         then # LU-5424
12496                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
12497                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
12498                         error "create lov data thru .lustre failed"
12499         fi
12500         echo "cp /etc/passwd $test_dir/$tfile-2"
12501         cp /etc/passwd $test_dir/$tfile-2 ||
12502                 error "copy to $test_dir/$tfile-2 failed."
12503         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
12504         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
12505                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
12506
12507         rm -rf $test_dir/tfile.lnk
12508         rm -rf $test_dir/$tfile-2
12509 }
12510
12511 test_154A() {
12512         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
12513                 skip "Need MDS version at least 2.4.1"
12514
12515         local tf=$DIR/$tfile
12516         touch $tf
12517
12518         local fid=$($LFS path2fid $tf)
12519         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
12520
12521         # check that we get the same pathname back
12522         local found=$($LFS fid2path $MOUNT "$fid")
12523         [ -z "$found" ] && error "fid2path unable to get '$fid' path"
12524         [ "$found" == "$tf" ] ||
12525                 error "fid2path($fid=path2fid($tf)) = $found != $tf"
12526 }
12527 run_test 154A "lfs path2fid and fid2path basic checks"
12528
12529 test_154B() {
12530         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
12531                 skip "Need MDS version at least 2.4.1"
12532
12533         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
12534         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
12535         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
12536         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
12537
12538         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
12539         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
12540
12541         # check that we get the same pathname
12542         echo "PFID: $PFID, name: $name"
12543         local FOUND=$($LFS fid2path $MOUNT "$PFID")
12544         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
12545         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
12546                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
12547
12548         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
12549 }
12550 run_test 154B "verify the ll_decode_linkea tool"
12551
12552 test_154a() {
12553         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12554         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
12555         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
12556                 skip "Need MDS version at least 2.2.51"
12557         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
12558
12559         cp /etc/hosts $DIR/$tfile
12560
12561         fid=$($LFS path2fid $DIR/$tfile)
12562         rc=$?
12563         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
12564
12565         dot_lustre_fid_permission_check "$fid" $DIR ||
12566                 error "dot lustre permission check $fid failed"
12567
12568         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
12569
12570         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
12571
12572         touch $MOUNT/.lustre/file &&
12573                 error "creation is not allowed under .lustre"
12574
12575         mkdir $MOUNT/.lustre/dir &&
12576                 error "mkdir is not allowed under .lustre"
12577
12578         rm -rf $DIR/$tfile
12579 }
12580 run_test 154a "Open-by-FID"
12581
12582 test_154b() {
12583         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12584         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
12585         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
12586         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
12587                 skip "Need MDS version at least 2.2.51"
12588
12589         local remote_dir=$DIR/$tdir/remote_dir
12590         local MDTIDX=1
12591         local rc=0
12592
12593         mkdir -p $DIR/$tdir
12594         $LFS mkdir -i $MDTIDX $remote_dir ||
12595                 error "create remote directory failed"
12596
12597         cp /etc/hosts $remote_dir/$tfile
12598
12599         fid=$($LFS path2fid $remote_dir/$tfile)
12600         rc=$?
12601         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
12602
12603         dot_lustre_fid_permission_check "$fid" $remote_dir ||
12604                 error "dot lustre permission check $fid failed"
12605         rm -rf $DIR/$tdir
12606 }
12607 run_test 154b "Open-by-FID for remote directory"
12608
12609 test_154c() {
12610         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
12611                 skip "Need MDS version at least 2.4.1"
12612
12613         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
12614         local FID1=$($LFS path2fid $DIR/$tfile.1)
12615         local FID2=$($LFS path2fid $DIR/$tfile.2)
12616         local FID3=$($LFS path2fid $DIR/$tfile.3)
12617
12618         local N=1
12619         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
12620                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
12621                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
12622                 local want=FID$N
12623                 [ "$FID" = "${!want}" ] ||
12624                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
12625                 N=$((N + 1))
12626         done
12627
12628         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
12629         do
12630                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
12631                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
12632                 N=$((N + 1))
12633         done
12634 }
12635 run_test 154c "lfs path2fid and fid2path multiple arguments"
12636
12637 test_154d() {
12638         remote_mds_nodsh && skip "remote MDS with nodsh"
12639         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
12640                 skip "Need MDS version at least 2.5.53"
12641
12642         if remote_mds; then
12643                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
12644         else
12645                 nid="0@lo"
12646         fi
12647         local proc_ofile="mdt.*.exports.'$nid'.open_files"
12648         local fd
12649         local cmd
12650
12651         rm -f $DIR/$tfile
12652         touch $DIR/$tfile
12653
12654         local fid=$($LFS path2fid $DIR/$tfile)
12655         # Open the file
12656         fd=$(free_fd)
12657         cmd="exec $fd<$DIR/$tfile"
12658         eval $cmd
12659         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
12660         echo "$fid_list" | grep "$fid"
12661         rc=$?
12662
12663         cmd="exec $fd>/dev/null"
12664         eval $cmd
12665         if [ $rc -ne 0 ]; then
12666                 error "FID $fid not found in open files list $fid_list"
12667         fi
12668 }
12669 run_test 154d "Verify open file fid"
12670
12671 test_154e()
12672 {
12673         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
12674                 skip "Need MDS version at least 2.6.50"
12675
12676         if ls -a $MOUNT | grep -q '^\.lustre$'; then
12677                 error ".lustre returned by readdir"
12678         fi
12679 }
12680 run_test 154e ".lustre is not returned by readdir"
12681
12682 test_154f() {
12683         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
12684
12685         # create parent directory on a single MDT to avoid cross-MDT hardlinks
12686         test_mkdir -p -c1 $DIR/$tdir/d
12687         # test dirs inherit from its stripe
12688         mkdir -p $DIR/$tdir/d/foo1 || error "mkdir error"
12689         mkdir -p $DIR/$tdir/d/foo2 || error "mkdir error"
12690         cp /etc/hosts $DIR/$tdir/d/foo1/$tfile
12691         ln $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/link
12692         touch $DIR/f
12693
12694         # get fid of parents
12695         local FID0=$($LFS path2fid $DIR/$tdir/d)
12696         local FID1=$($LFS path2fid $DIR/$tdir/d/foo1)
12697         local FID2=$($LFS path2fid $DIR/$tdir/d/foo2)
12698         local FID3=$($LFS path2fid $DIR)
12699
12700         # check that path2fid --parents returns expected <parent_fid>/name
12701         # 1) test for a directory (single parent)
12702         local parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1)
12703         [ "$parent" == "$FID0/foo1" ] ||
12704                 error "expected parent: $FID0/foo1, got: $parent"
12705
12706         # 2) test for a file with nlink > 1 (multiple parents)
12707         parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1/$tfile)
12708         echo "$parent" | grep -F "$FID1/$tfile" ||
12709                 error "$FID1/$tfile not returned in parent list"
12710         echo "$parent" | grep -F "$FID2/link" ||
12711                 error "$FID2/link not returned in parent list"
12712
12713         # 3) get parent by fid
12714         local file_fid=$($LFS path2fid $DIR/$tdir/d/foo1/$tfile)
12715         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
12716         echo "$parent" | grep -F "$FID1/$tfile" ||
12717                 error "$FID1/$tfile not returned in parent list (by fid)"
12718         echo "$parent" | grep -F "$FID2/link" ||
12719                 error "$FID2/link not returned in parent list (by fid)"
12720
12721         # 4) test for entry in root directory
12722         parent=$($LFS path2fid --parents $DIR/f)
12723         echo "$parent" | grep -F "$FID3/f" ||
12724                 error "$FID3/f not returned in parent list"
12725
12726         # 5) test it on root directory
12727         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
12728                 error "$MOUNT should not have parents"
12729
12730         # enable xattr caching and check that linkea is correctly updated
12731         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
12732         save_lustre_params client "llite.*.xattr_cache" > $save
12733         lctl set_param llite.*.xattr_cache 1
12734
12735         # 6.1) linkea update on rename
12736         mv $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/$tfile.moved
12737
12738         # get parents by fid
12739         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
12740         # foo1 should no longer be returned in parent list
12741         echo "$parent" | grep -F "$FID1" &&
12742                 error "$FID1 should no longer be in parent list"
12743         # the new path should appear
12744         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
12745                 error "$FID2/$tfile.moved is not in parent list"
12746
12747         # 6.2) linkea update on unlink
12748         rm -f $DIR/$tdir/d/foo2/link
12749         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
12750         # foo2/link should no longer be returned in parent list
12751         echo "$parent" | grep -F "$FID2/link" &&
12752                 error "$FID2/link should no longer be in parent list"
12753         true
12754
12755         rm -f $DIR/f
12756         restore_lustre_params < $save
12757         rm -f $save
12758 }
12759 run_test 154f "get parent fids by reading link ea"
12760
12761 test_154g()
12762 {
12763         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
12764         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
12765            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
12766                 skip "Need MDS version at least 2.6.92"
12767
12768         mkdir -p $DIR/$tdir
12769         llapi_fid_test -d $DIR/$tdir
12770 }
12771 run_test 154g "various llapi FID tests"
12772
12773 test_155_small_load() {
12774     local temp=$TMP/$tfile
12775     local file=$DIR/$tfile
12776
12777     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
12778         error "dd of=$temp bs=6096 count=1 failed"
12779     cp $temp $file
12780     cancel_lru_locks $OSC
12781     cmp $temp $file || error "$temp $file differ"
12782
12783     $TRUNCATE $temp 6000
12784     $TRUNCATE $file 6000
12785     cmp $temp $file || error "$temp $file differ (truncate1)"
12786
12787     echo "12345" >>$temp
12788     echo "12345" >>$file
12789     cmp $temp $file || error "$temp $file differ (append1)"
12790
12791     echo "12345" >>$temp
12792     echo "12345" >>$file
12793     cmp $temp $file || error "$temp $file differ (append2)"
12794
12795     rm -f $temp $file
12796     true
12797 }
12798
12799 test_155_big_load() {
12800         remote_ost_nodsh && skip "remote OST with nodsh"
12801
12802         local temp=$TMP/$tfile
12803         local file=$DIR/$tfile
12804
12805         free_min_max
12806         local cache_size=$(do_facet ost$((MAXI+1)) \
12807                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
12808         local large_file_size=$((cache_size * 2))
12809
12810         echo "OSS cache size: $cache_size KB"
12811         echo "Large file size: $large_file_size KB"
12812
12813         [ $MAXV -le $large_file_size ] &&
12814                 skip_env "max available OST size needs > $large_file_size KB"
12815
12816         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
12817
12818         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
12819                 error "dd of=$temp bs=$large_file_size count=1k failed"
12820         cp $temp $file
12821         ls -lh $temp $file
12822         cancel_lru_locks osc
12823         cmp $temp $file || error "$temp $file differ"
12824
12825         rm -f $temp $file
12826         true
12827 }
12828
12829 save_writethrough() {
12830         local facets=$(get_facets OST)
12831
12832         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
12833 }
12834
12835 test_155a() {
12836         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12837
12838         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12839
12840         save_writethrough $p
12841
12842         set_cache read on
12843         set_cache writethrough on
12844         test_155_small_load
12845         restore_lustre_params < $p
12846         rm -f $p
12847 }
12848 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
12849
12850 test_155b() {
12851         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12852
12853         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12854
12855         save_writethrough $p
12856
12857         set_cache read on
12858         set_cache writethrough off
12859         test_155_small_load
12860         restore_lustre_params < $p
12861         rm -f $p
12862 }
12863 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
12864
12865 test_155c() {
12866         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12867
12868         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12869
12870         save_writethrough $p
12871
12872         set_cache read off
12873         set_cache writethrough on
12874         test_155_small_load
12875         restore_lustre_params < $p
12876         rm -f $p
12877 }
12878 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
12879
12880 test_155d() {
12881         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12882
12883         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12884
12885         save_writethrough $p
12886
12887         set_cache read off
12888         set_cache writethrough off
12889         test_155_small_load
12890         restore_lustre_params < $p
12891         rm -f $p
12892 }
12893 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
12894
12895 test_155e() {
12896         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12897
12898         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12899
12900         save_writethrough $p
12901
12902         set_cache read on
12903         set_cache writethrough on
12904         test_155_big_load
12905         restore_lustre_params < $p
12906         rm -f $p
12907 }
12908 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
12909
12910 test_155f() {
12911         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12912
12913         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12914
12915         save_writethrough $p
12916
12917         set_cache read on
12918         set_cache writethrough off
12919         test_155_big_load
12920         restore_lustre_params < $p
12921         rm -f $p
12922 }
12923 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
12924
12925 test_155g() {
12926         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12927
12928         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12929
12930         save_writethrough $p
12931
12932         set_cache read off
12933         set_cache writethrough on
12934         test_155_big_load
12935         restore_lustre_params < $p
12936         rm -f $p
12937 }
12938 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
12939
12940 test_155h() {
12941         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12942
12943         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12944
12945         save_writethrough $p
12946
12947         set_cache read off
12948         set_cache writethrough off
12949         test_155_big_load
12950         restore_lustre_params < $p
12951         rm -f $p
12952 }
12953 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
12954
12955 test_156() {
12956         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12957         remote_ost_nodsh && skip "remote OST with nodsh"
12958         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
12959                 skip "stats not implemented on old servers"
12960         [ "$ost1_FSTYPE" = "zfs" ] &&
12961                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
12962
12963         local CPAGES=3
12964         local BEFORE
12965         local AFTER
12966         local file="$DIR/$tfile"
12967         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12968
12969         save_writethrough $p
12970         roc_hit_init
12971
12972         log "Turn on read and write cache"
12973         set_cache read on
12974         set_cache writethrough on
12975
12976         log "Write data and read it back."
12977         log "Read should be satisfied from the cache."
12978         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
12979         BEFORE=$(roc_hit)
12980         cancel_lru_locks osc
12981         cat $file >/dev/null
12982         AFTER=$(roc_hit)
12983         if ! let "AFTER - BEFORE == CPAGES"; then
12984                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12985         else
12986                 log "cache hits:: before: $BEFORE, after: $AFTER"
12987         fi
12988
12989         log "Read again; it should be satisfied from the cache."
12990         BEFORE=$AFTER
12991         cancel_lru_locks osc
12992         cat $file >/dev/null
12993         AFTER=$(roc_hit)
12994         if ! let "AFTER - BEFORE == CPAGES"; then
12995                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12996         else
12997                 log "cache hits:: before: $BEFORE, after: $AFTER"
12998         fi
12999
13000         log "Turn off the read cache and turn on the write cache"
13001         set_cache read off
13002         set_cache writethrough on
13003
13004         log "Read again; it should be satisfied from the cache."
13005         BEFORE=$(roc_hit)
13006         cancel_lru_locks osc
13007         cat $file >/dev/null
13008         AFTER=$(roc_hit)
13009         if ! let "AFTER - BEFORE == CPAGES"; then
13010                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
13011         else
13012                 log "cache hits:: before: $BEFORE, after: $AFTER"
13013         fi
13014
13015         log "Read again; it should not be satisfied from the cache."
13016         BEFORE=$AFTER
13017         cancel_lru_locks osc
13018         cat $file >/dev/null
13019         AFTER=$(roc_hit)
13020         if ! let "AFTER - BEFORE == 0"; then
13021                 error "IN CACHE: before: $BEFORE, after: $AFTER"
13022         else
13023                 log "cache hits:: before: $BEFORE, after: $AFTER"
13024         fi
13025
13026         log "Write data and read it back."
13027         log "Read should be satisfied from the cache."
13028         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
13029         BEFORE=$(roc_hit)
13030         cancel_lru_locks osc
13031         cat $file >/dev/null
13032         AFTER=$(roc_hit)
13033         if ! let "AFTER - BEFORE == CPAGES"; then
13034                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
13035         else
13036                 log "cache hits:: before: $BEFORE, after: $AFTER"
13037         fi
13038
13039         log "Read again; it should not be satisfied from the cache."
13040         BEFORE=$AFTER
13041         cancel_lru_locks osc
13042         cat $file >/dev/null
13043         AFTER=$(roc_hit)
13044         if ! let "AFTER - BEFORE == 0"; then
13045                 error "IN CACHE: before: $BEFORE, after: $AFTER"
13046         else
13047                 log "cache hits:: before: $BEFORE, after: $AFTER"
13048         fi
13049
13050         log "Turn off read and write cache"
13051         set_cache read off
13052         set_cache writethrough off
13053
13054         log "Write data and read it back"
13055         log "It should not be satisfied from the cache."
13056         rm -f $file
13057         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
13058         cancel_lru_locks osc
13059         BEFORE=$(roc_hit)
13060         cat $file >/dev/null
13061         AFTER=$(roc_hit)
13062         if ! let "AFTER - BEFORE == 0"; then
13063                 error_ignore bz20762 "IN CACHE: before: $BEFORE, after: $AFTER"
13064         else
13065                 log "cache hits:: before: $BEFORE, after: $AFTER"
13066         fi
13067
13068         log "Turn on the read cache and turn off the write cache"
13069         set_cache read on
13070         set_cache writethrough off
13071
13072         log "Write data and read it back"
13073         log "It should not be satisfied from the cache."
13074         rm -f $file
13075         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
13076         BEFORE=$(roc_hit)
13077         cancel_lru_locks osc
13078         cat $file >/dev/null
13079         AFTER=$(roc_hit)
13080         if ! let "AFTER - BEFORE == 0"; then
13081                 error_ignore bz20762 "IN CACHE: before: $BEFORE, after: $AFTER"
13082         else
13083                 log "cache hits:: before: $BEFORE, after: $AFTER"
13084         fi
13085
13086         log "Read again; it should be satisfied from the cache."
13087         BEFORE=$(roc_hit)
13088         cancel_lru_locks osc
13089         cat $file >/dev/null
13090         AFTER=$(roc_hit)
13091         if ! let "AFTER - BEFORE == CPAGES"; then
13092                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
13093         else
13094                 log "cache hits:: before: $BEFORE, after: $AFTER"
13095         fi
13096
13097         restore_lustre_params < $p
13098         rm -f $p $file
13099 }
13100 run_test 156 "Verification of tunables"
13101
13102 test_160a() {
13103         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13104         remote_mds_nodsh && skip "remote MDS with nodsh"
13105         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
13106                 skip "Need MDS version at least 2.2.0"
13107
13108         changelog_register || error "changelog_register failed"
13109         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
13110         changelog_users $SINGLEMDS | grep -q $cl_user ||
13111                 error "User $cl_user not found in changelog_users"
13112
13113         # change something
13114         test_mkdir -p $DIR/$tdir/pics/2008/zachy
13115         changelog_clear 0 || error "changelog_clear failed"
13116         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
13117         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
13118         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
13119         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
13120         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
13121         rm $DIR/$tdir/pics/desktop.jpg
13122
13123         changelog_dump | tail -10
13124
13125         echo "verifying changelog mask"
13126         changelog_chmask "-MKDIR"
13127         changelog_chmask "-CLOSE"
13128
13129         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
13130         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
13131
13132         changelog_chmask "+MKDIR"
13133         changelog_chmask "+CLOSE"
13134
13135         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
13136         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
13137
13138         changelog_dump | tail -10
13139         MKDIRS=$(changelog_dump | grep -c "MKDIR")
13140         CLOSES=$(changelog_dump | grep -c "CLOSE")
13141         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
13142         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
13143
13144         # verify contents
13145         echo "verifying target fid"
13146         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
13147         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
13148         [ "$fidc" == "$fidf" ] ||
13149                 error "changelog '$tfile' fid $fidc != file fid $fidf"
13150         echo "verifying parent fid"
13151         # The FID returned from the Changelog may be the directory shard on
13152         # a different MDT, and not the FID returned by path2fid on the parent.
13153         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
13154         # since this is what will matter when recreating this file in the tree.
13155         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
13156         local pathp=$($LFS fid2path $MOUNT "$fidp")
13157         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
13158                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
13159
13160         echo "getting records for $cl_user"
13161         changelog_users $SINGLEMDS
13162         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
13163         local nclr=3
13164         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
13165                 error "changelog_clear failed"
13166         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
13167         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
13168         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
13169                 error "user index expect $user_rec1 + $nclr != $user_rec2"
13170
13171         local min0_rec=$(changelog_users $SINGLEMDS |
13172                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
13173         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
13174                           awk '{ print $1; exit; }')
13175
13176         changelog_dump | tail -n 5
13177         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
13178         [ $first_rec == $((min0_rec + 1)) ] ||
13179                 error "first index should be $min0_rec + 1 not $first_rec"
13180
13181         # LU-3446 changelog index reset on MDT restart
13182         local cur_rec1=$(changelog_users $SINGLEMDS |
13183                          awk '/^current.index:/ { print $NF }')
13184         changelog_clear 0 ||
13185                 error "clear all changelog records for $cl_user failed"
13186         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
13187         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
13188                 error "Fail to start $SINGLEMDS"
13189         local cur_rec2=$(changelog_users $SINGLEMDS |
13190                          awk '/^current.index:/ { print $NF }')
13191         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
13192         [ $cur_rec1 == $cur_rec2 ] ||
13193                 error "current index should be $cur_rec1 not $cur_rec2"
13194
13195         echo "verifying users from this test are deregistered"
13196         changelog_deregister || error "changelog_deregister failed"
13197         changelog_users $SINGLEMDS | grep -q $cl_user &&
13198                 error "User '$cl_user' still in changelog_users"
13199
13200         # lctl get_param -n mdd.*.changelog_users
13201         # current index: 144
13202         # ID    index (idle seconds)
13203         # cl3   144 (2)
13204         if ! changelog_users $SINGLEMDS | grep "^cl"; then
13205                 # this is the normal case where all users were deregistered
13206                 # make sure no new records are added when no users are present
13207                 local last_rec1=$(changelog_users $SINGLEMDS |
13208                                   awk '/^current.index:/ { print $NF }')
13209                 touch $DIR/$tdir/chloe
13210                 local last_rec2=$(changelog_users $SINGLEMDS |
13211                                   awk '/^current.index:/ { print $NF }')
13212                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
13213                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
13214         else
13215                 # any changelog users must be leftovers from a previous test
13216                 changelog_users $SINGLEMDS
13217                 echo "other changelog users; can't verify off"
13218         fi
13219 }
13220 run_test 160a "changelog sanity"
13221
13222 test_160b() { # LU-3587
13223         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13224         remote_mds_nodsh && skip "remote MDS with nodsh"
13225         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
13226                 skip "Need MDS version at least 2.2.0"
13227
13228         changelog_register || error "changelog_register failed"
13229         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
13230         changelog_users $SINGLEMDS | grep -q $cl_user ||
13231                 error "User '$cl_user' not found in changelog_users"
13232
13233         local longname1=$(str_repeat a 255)
13234         local longname2=$(str_repeat b 255)
13235
13236         cd $DIR
13237         echo "creating very long named file"
13238         touch $longname1 || error "create of '$longname1' failed"
13239         echo "renaming very long named file"
13240         mv $longname1 $longname2
13241
13242         changelog_dump | grep RENME | tail -n 5
13243         rm -f $longname2
13244 }
13245 run_test 160b "Verify that very long rename doesn't crash in changelog"
13246
13247 test_160c() {
13248         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13249         remote_mds_nodsh && skip "remote MDS with nodsh"
13250
13251         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
13252                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
13253                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
13254                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
13255
13256         local rc=0
13257
13258         # Registration step
13259         changelog_register || error "changelog_register failed"
13260
13261         rm -rf $DIR/$tdir
13262         mkdir -p $DIR/$tdir
13263         $MCREATE $DIR/$tdir/foo_160c
13264         changelog_chmask "-TRUNC"
13265         $TRUNCATE $DIR/$tdir/foo_160c 200
13266         changelog_chmask "+TRUNC"
13267         $TRUNCATE $DIR/$tdir/foo_160c 199
13268         changelog_dump | tail -n 5
13269         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
13270         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
13271 }
13272 run_test 160c "verify that changelog log catch the truncate event"
13273
13274 test_160d() {
13275         remote_mds_nodsh && skip "remote MDS with nodsh"
13276         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
13277         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13278         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
13279                 skip "Need MDS version at least 2.7.60"
13280
13281         # Registration step
13282         changelog_register || error "changelog_register failed"
13283
13284         mkdir -p $DIR/$tdir/migrate_dir
13285         changelog_clear 0 || error "changelog_clear failed"
13286
13287         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
13288         changelog_dump | tail -n 5
13289         local migrates=$(changelog_dump | grep -c "MIGRT")
13290         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
13291 }
13292 run_test 160d "verify that changelog log catch the migrate event"
13293
13294 test_160e() {
13295         remote_mds_nodsh && skip "remote MDS with nodsh"
13296
13297         # Create a user
13298         changelog_register || error "changelog_register failed"
13299
13300         # Delete a future user (expect fail)
13301         local MDT0=$(facet_svc $SINGLEMDS)
13302         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
13303         local rc=$?
13304
13305         if [ $rc -eq 0 ]; then
13306                 error "Deleted non-existant user cl77"
13307         elif [ $rc -ne 2 ]; then
13308                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
13309         fi
13310
13311         # Clear to a bad index (1 billion should be safe)
13312         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
13313         rc=$?
13314
13315         if [ $rc -eq 0 ]; then
13316                 error "Successfully cleared to invalid CL index"
13317         elif [ $rc -ne 22 ]; then
13318                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
13319         fi
13320 }
13321 run_test 160e "changelog negative testing (should return errors)"
13322
13323 test_160f() {
13324         remote_mds_nodsh && skip "remote MDS with nodsh" && return
13325         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
13326                 skip "Need MDS version at least 2.10.56"
13327
13328         local mdts=$(comma_list $(mdts_nodes))
13329
13330         # Create a user
13331         changelog_register || error "first changelog_register failed"
13332         changelog_register || error "second changelog_register failed"
13333         local cl_users
13334         declare -A cl_user1
13335         declare -A cl_user2
13336         local user_rec1
13337         local user_rec2
13338         local i
13339
13340         # generate some changelog records to accumulate on each MDT
13341         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "test_mkdir $tdir failed"
13342         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
13343                 error "create $DIR/$tdir/$tfile failed"
13344
13345         # check changelogs have been generated
13346         local nbcl=$(changelog_dump | wc -l)
13347         [[ $nbcl -eq 0 ]] && error "no changelogs found"
13348
13349         for param in "changelog_max_idle_time=10" \
13350                      "changelog_gc=1" \
13351                      "changelog_min_gc_interval=2" \
13352                      "changelog_min_free_cat_entries=3"; do
13353                 local MDT0=$(facet_svc $SINGLEMDS)
13354                 local var="${param%=*}"
13355                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
13356
13357                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
13358                 do_nodes $mdts $LCTL set_param mdd.*.$param
13359         done
13360
13361         # force cl_user2 to be idle (1st part)
13362         sleep 9
13363
13364         # simulate changelog catalog almost full
13365         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
13366         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
13367
13368         for i in $(seq $MDSCOUNT); do
13369                 cl_users=(${CL_USERS[mds$i]})
13370                 cl_user1[mds$i]="${cl_users[0]}"
13371                 cl_user2[mds$i]="${cl_users[1]}"
13372
13373                 [ -n "${cl_user1[mds$i]}" ] ||
13374                         error "mds$i: no user registered"
13375                 [ -n "${cl_user2[mds$i]}" ] ||
13376                         error "mds$i: only ${cl_user2[mds$i]} is registered"
13377
13378                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13379                 [ -n "$user_rec1" ] ||
13380                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13381                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
13382                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13383                 [ -n "$user_rec2" ] ||
13384                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13385                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
13386                      "$user_rec1 + 2 == $user_rec2"
13387                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
13388                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
13389                               "$user_rec1 + 2, but is $user_rec2"
13390                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
13391                 [ -n "$user_rec2" ] ||
13392                         error "mds$i: User ${cl_user2[mds$i]} not registered"
13393                 [ $user_rec1 == $user_rec2 ] ||
13394                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
13395                               "$user_rec1, but is $user_rec2"
13396         done
13397
13398         # force cl_user2 to be idle (2nd part) and to reach
13399         # changelog_max_idle_time
13400         sleep 2
13401
13402         # generate one more changelog to trigger fail_loc
13403         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
13404                 error "create $DIR/$tdir/${tfile}bis failed"
13405
13406         # ensure gc thread is done
13407         for i in $(mdts_nodes); do
13408                 wait_update $i \
13409                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
13410                         error "$i: GC-thread not done"
13411         done
13412
13413         local first_rec
13414         for i in $(seq $MDSCOUNT); do
13415                 # check cl_user1 still registered
13416                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
13417                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13418                 # check cl_user2 unregistered
13419                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
13420                         error "mds$i: User ${cl_user2[mds$i]} still registered"
13421
13422                 # check changelogs are present and starting at $user_rec1 + 1
13423                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13424                 [ -n "$user_rec1" ] ||
13425                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13426                 first_rec=$($LFS changelog $(facet_svc mds$i) |
13427                             awk '{ print $1; exit; }')
13428
13429                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
13430                 [ $((user_rec1 + 1)) == $first_rec ] ||
13431                         error "mds$i: first index should be $user_rec1 + 1, " \
13432                               "but is $first_rec"
13433         done
13434 }
13435 run_test 160f "changelog garbage collect (timestamped users)"
13436
13437 test_160g() {
13438         remote_mds_nodsh && skip "remote MDS with nodsh"
13439         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
13440                 skip "Need MDS version at least 2.10.56"
13441
13442         local mdts=$(comma_list $(mdts_nodes))
13443
13444         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
13445         do_nodes $mdts $LCTL set_param fail_loc=0x1314
13446
13447         # Create a user
13448         changelog_register || error "first changelog_register failed"
13449         changelog_register || error "second changelog_register failed"
13450         local cl_users
13451         declare -A cl_user1
13452         declare -A cl_user2
13453         local user_rec1
13454         local user_rec2
13455         local i
13456
13457         # generate some changelog records to accumulate on each MDT
13458         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
13459         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
13460                 error "create $DIR/$tdir/$tfile failed"
13461
13462         # check changelogs have been generated
13463         local nbcl=$(changelog_dump | wc -l)
13464         [[ $nbcl -eq 0 ]] && error "no changelogs found"
13465
13466         # reduce the max_idle_indexes value to make sure we exceed it
13467         max_ndx=$((nbcl / 2 - 1))
13468
13469         for param in "changelog_max_idle_indexes=$max_ndx" \
13470                      "changelog_gc=1" \
13471                      "changelog_min_gc_interval=2" \
13472                      "changelog_min_free_cat_entries=3"; do
13473                 local MDT0=$(facet_svc $SINGLEMDS)
13474                 local var="${param%=*}"
13475                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
13476
13477                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
13478                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
13479                         error "unable to set mdd.*.$param"
13480         done
13481
13482         # simulate changelog catalog almost full
13483         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
13484         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
13485
13486         for i in $(seq $MDSCOUNT); do
13487                 cl_users=(${CL_USERS[mds$i]})
13488                 cl_user1[mds$i]="${cl_users[0]}"
13489                 cl_user2[mds$i]="${cl_users[1]}"
13490
13491                 [ -n "${cl_user1[mds$i]}" ] ||
13492                         error "mds$i: no user registered"
13493                 [ -n "${cl_user2[mds$i]}" ] ||
13494                         error "mds$i: only ${cl_user1[mds$i]} is registered"
13495
13496                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13497                 [ -n "$user_rec1" ] ||
13498                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13499                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
13500                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13501                 [ -n "$user_rec2" ] ||
13502                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13503                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
13504                      "$user_rec1 + 2 == $user_rec2"
13505                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
13506                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
13507                               "$user_rec1 + 2, but is $user_rec2"
13508                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
13509                 [ -n "$user_rec2" ] ||
13510                         error "mds$i: User ${cl_user2[mds$i]} not registered"
13511                 [ $user_rec1 == $user_rec2 ] ||
13512                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
13513                               "$user_rec1, but is $user_rec2"
13514         done
13515
13516         # ensure we are past the previous changelog_min_gc_interval set above
13517         sleep 2
13518
13519         # generate one more changelog to trigger fail_loc
13520         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
13521                 error "create $DIR/$tdir/${tfile}bis failed"
13522
13523         # ensure gc thread is done
13524         for i in $(mdts_nodes); do
13525                 wait_update $i \
13526                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
13527                         error "$i: GC-thread not done"
13528         done
13529
13530         local first_rec
13531         for i in $(seq $MDSCOUNT); do
13532                 # check cl_user1 still registered
13533                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
13534                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13535                 # check cl_user2 unregistered
13536                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
13537                         error "mds$i: User ${cl_user2[mds$i]} still registered"
13538
13539                 # check changelogs are present and starting at $user_rec1 + 1
13540                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13541                 [ -n "$user_rec1" ] ||
13542                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13543                 first_rec=$($LFS changelog $(facet_svc mds$i) |
13544                             awk '{ print $1; exit; }')
13545
13546                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
13547                 [ $((user_rec1 + 1)) == $first_rec ] ||
13548                         error "mds$i: first index should be $user_rec1 + 1, " \
13549                               "but is $first_rec"
13550         done
13551 }
13552 run_test 160g "changelog garbage collect (old users)"
13553
13554 test_160h() {
13555         remote_mds_nodsh && skip "remote MDS with nodsh" && return
13556         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
13557                 skip "Need MDS version at least 2.10.56"
13558
13559         local mdts=$(comma_list $(mdts_nodes))
13560
13561         # Create a user
13562         changelog_register || error "first changelog_register failed"
13563         changelog_register || error "second changelog_register failed"
13564         local cl_users
13565         declare -A cl_user1
13566         declare -A cl_user2
13567         local user_rec1
13568         local user_rec2
13569         local i
13570
13571         # generate some changelog records to accumulate on each MDT
13572         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "test_mkdir $tdir failed"
13573         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
13574                 error "create $DIR/$tdir/$tfile failed"
13575
13576         # check changelogs have been generated
13577         local nbcl=$(changelog_dump | wc -l)
13578         [[ $nbcl -eq 0 ]] && error "no changelogs found"
13579
13580         for param in "changelog_max_idle_time=10" \
13581                      "changelog_gc=1" \
13582                      "changelog_min_gc_interval=2"; do
13583                 local MDT0=$(facet_svc $SINGLEMDS)
13584                 local var="${param%=*}"
13585                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
13586
13587                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
13588                 do_nodes $mdts $LCTL set_param mdd.*.$param
13589         done
13590
13591         # force cl_user2 to be idle (1st part)
13592         sleep 9
13593
13594         for i in $(seq $MDSCOUNT); do
13595                 cl_users=(${CL_USERS[mds$i]})
13596                 cl_user1[mds$i]="${cl_users[0]}"
13597                 cl_user2[mds$i]="${cl_users[1]}"
13598
13599                 [ -n "${cl_user1[mds$i]}" ] ||
13600                         error "mds$i: no user registered"
13601                 [ -n "${cl_user2[mds$i]}" ] ||
13602                         error "mds$i: only ${cl_user2[mds$i]} is registered"
13603
13604                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13605                 [ -n "$user_rec1" ] ||
13606                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13607                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
13608                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13609                 [ -n "$user_rec2" ] ||
13610                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13611                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
13612                      "$user_rec1 + 2 == $user_rec2"
13613                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
13614                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
13615                               "$user_rec1 + 2, but is $user_rec2"
13616                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
13617                 [ -n "$user_rec2" ] ||
13618                         error "mds$i: User ${cl_user2[mds$i]} not registered"
13619                 [ $user_rec1 == $user_rec2 ] ||
13620                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
13621                               "$user_rec1, but is $user_rec2"
13622         done
13623
13624         # force cl_user2 to be idle (2nd part) and to reach
13625         # changelog_max_idle_time
13626         sleep 2
13627
13628         # force each GC-thread start and block then
13629         # one per MDT/MDD, set fail_val accordingly
13630         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
13631         do_nodes $mdts $LCTL set_param fail_loc=0x1316
13632
13633         # generate more changelogs to trigger fail_loc
13634         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
13635                 error "create $DIR/$tdir/${tfile}bis failed"
13636
13637         # stop MDT to stop GC-thread, should be done in back-ground as it will
13638         # block waiting for the thread to be released and exit
13639         declare -A stop_pids
13640         for i in $(seq $MDSCOUNT); do
13641                 stop mds$i &
13642                 stop_pids[mds$i]=$!
13643         done
13644
13645         for i in $(mdts_nodes); do
13646                 local facet
13647                 local nb=0
13648                 local facets=$(facets_up_on_host $i)
13649
13650                 for facet in ${facets//,/ }; do
13651                         if [[ $facet == mds* ]]; then
13652                                 nb=$((nb + 1))
13653                         fi
13654                 done
13655                 # ensure each MDS's gc threads are still present and all in "R"
13656                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
13657                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
13658                         error "$i: expected $nb GC-thread"
13659                 wait_update $i \
13660                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
13661                         "R" 20 ||
13662                         error "$i: GC-thread not found in R-state"
13663                 # check umounts of each MDT on MDS have reached kthread_stop()
13664                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
13665                         error "$i: expected $nb umount"
13666                 wait_update $i \
13667                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
13668                         error "$i: umount not found in D-state"
13669         done
13670
13671         # release all GC-threads
13672         do_nodes $mdts $LCTL set_param fail_loc=0
13673
13674         # wait for MDT stop to complete
13675         for i in $(seq $MDSCOUNT); do
13676                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
13677         done
13678
13679         # XXX
13680         # may try to check if any orphan changelog records are present
13681         # via ldiskfs/zfs and llog_reader...
13682
13683         # re-start/mount MDTs
13684         for i in $(seq $MDSCOUNT); do
13685                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
13686                         error "Fail to start mds$i"
13687         done
13688
13689         local first_rec
13690         for i in $(seq $MDSCOUNT); do
13691                 # check cl_user1 still registered
13692                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
13693                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13694                 # check cl_user2 unregistered
13695                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
13696                         error "mds$i: User ${cl_user2[mds$i]} still registered"
13697
13698                 # check changelogs are present and starting at $user_rec1 + 1
13699                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13700                 [ -n "$user_rec1" ] ||
13701                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13702                 first_rec=$($LFS changelog $(facet_svc mds$i) |
13703                             awk '{ print $1; exit; }')
13704
13705                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
13706                 [ $((user_rec1 + 1)) == $first_rec ] ||
13707                         error "mds$i: first index should be $user_rec1 + 1, " \
13708                               "but is $first_rec"
13709         done
13710 }
13711 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
13712               "during mount"
13713
13714 test_160i() {
13715
13716         local mdts=$(comma_list $(mdts_nodes))
13717
13718         changelog_register || error "first changelog_register failed"
13719
13720         # generate some changelog records to accumulate on each MDT
13721         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
13722         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
13723                 error "create $DIR/$tdir/$tfile failed"
13724
13725         # check changelogs have been generated
13726         local nbcl=$(changelog_dump | wc -l)
13727         [[ $nbcl -eq 0 ]] && error "no changelogs found"
13728
13729         # simulate race between register and unregister
13730         # XXX as fail_loc is set per-MDS, with DNE configs the race
13731         # simulation will only occur for one MDT per MDS and for the
13732         # others the normal race scenario will take place
13733         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
13734         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
13735         do_nodes $mdts $LCTL set_param fail_val=1
13736
13737         # unregister 1st user
13738         changelog_deregister &
13739         local pid1=$!
13740         # wait some time for deregister work to reach race rdv
13741         sleep 2
13742         # register 2nd user
13743         changelog_register || error "2nd user register failed"
13744
13745         wait $pid1 || error "1st user deregister failed"
13746
13747         local i
13748         local last_rec
13749         declare -A LAST_REC
13750         for i in $(seq $MDSCOUNT); do
13751                 if changelog_users mds$i | grep "^cl"; then
13752                         # make sure new records are added with one user present
13753                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
13754                                           awk '/^current.index:/ { print $NF }')
13755                 else
13756                         error "mds$i has no user registered"
13757                 fi
13758         done
13759
13760         # generate more changelog records to accumulate on each MDT
13761         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
13762                 error "create $DIR/$tdir/${tfile}bis failed"
13763
13764         for i in $(seq $MDSCOUNT); do
13765                 last_rec=$(changelog_users $SINGLEMDS |
13766                            awk '/^current.index:/ { print $NF }')
13767                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
13768                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
13769                         error "changelogs are off on mds$i"
13770         done
13771 }
13772 run_test 160i "changelog user register/unregister race"
13773
13774 test_160j() {
13775         remote_mds_nodsh && skip "remote MDS with nodsh"
13776         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
13777                 skip "Need MDS version at least 2.12.56"
13778
13779         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
13780
13781         changelog_register || error "first changelog_register failed"
13782
13783         # generate some changelog
13784         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
13785         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
13786                 error "create $DIR/$tdir/${tfile}bis failed"
13787
13788         # open the changelog device
13789         exec 3>/dev/changelog-$FSNAME-MDT0000
13790         exec 4</dev/changelog-$FSNAME-MDT0000
13791
13792         # umount the first lustre mount
13793         umount $MOUNT
13794
13795         # read changelog
13796         cat <&4 >/dev/null || error "read changelog failed"
13797
13798         # clear changelog
13799         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
13800         changelog_users $SINGLEMDS | grep -q $cl_user ||
13801                 error "User $cl_user not found in changelog_users"
13802
13803         printf 'clear:'$cl_user':0' >&3
13804
13805         # close
13806         exec 3>&-
13807         exec 4<&-
13808
13809         # cleanup
13810         changelog_deregister || error "changelog_deregister failed"
13811
13812         umount $MOUNT2
13813         mount_client $MOUNT || error "mount_client on $MOUNT failed"
13814 }
13815 run_test 160j "client can be umounted  while its chanangelog is being used"
13816
13817 test_161a() {
13818         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13819
13820         test_mkdir -c1 $DIR/$tdir
13821         cp /etc/hosts $DIR/$tdir/$tfile
13822         test_mkdir -c1 $DIR/$tdir/foo1
13823         test_mkdir -c1 $DIR/$tdir/foo2
13824         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
13825         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
13826         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
13827         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
13828         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
13829         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
13830                 $LFS fid2path $DIR $FID
13831                 error "bad link ea"
13832         fi
13833         # middle
13834         rm $DIR/$tdir/foo2/zachary
13835         # last
13836         rm $DIR/$tdir/foo2/thor
13837         # first
13838         rm $DIR/$tdir/$tfile
13839         # rename
13840         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
13841         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
13842                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
13843         rm $DIR/$tdir/foo2/maggie
13844
13845         # overflow the EA
13846         local longname=$tfile.avg_len_is_thirty_two_
13847         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
13848                 error_noexit 'failed to unlink many hardlinks'" EXIT
13849         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
13850                 error "failed to hardlink many files"
13851         links=$($LFS fid2path $DIR $FID | wc -l)
13852         echo -n "${links}/1000 links in link EA"
13853         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
13854 }
13855 run_test 161a "link ea sanity"
13856
13857 test_161b() {
13858         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13859         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
13860
13861         local MDTIDX=1
13862         local remote_dir=$DIR/$tdir/remote_dir
13863
13864         mkdir -p $DIR/$tdir
13865         $LFS mkdir -i $MDTIDX $remote_dir ||
13866                 error "create remote directory failed"
13867
13868         cp /etc/hosts $remote_dir/$tfile
13869         mkdir -p $remote_dir/foo1
13870         mkdir -p $remote_dir/foo2
13871         ln $remote_dir/$tfile $remote_dir/foo1/sofia
13872         ln $remote_dir/$tfile $remote_dir/foo2/zachary
13873         ln $remote_dir/$tfile $remote_dir/foo1/luna
13874         ln $remote_dir/$tfile $remote_dir/foo2/thor
13875
13876         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
13877                      tr -d ']')
13878         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
13879                 $LFS fid2path $DIR $FID
13880                 error "bad link ea"
13881         fi
13882         # middle
13883         rm $remote_dir/foo2/zachary
13884         # last
13885         rm $remote_dir/foo2/thor
13886         # first
13887         rm $remote_dir/$tfile
13888         # rename
13889         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
13890         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
13891         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
13892                 $LFS fid2path $DIR $FID
13893                 error "bad link rename"
13894         fi
13895         rm $remote_dir/foo2/maggie
13896
13897         # overflow the EA
13898         local longname=filename_avg_len_is_thirty_two_
13899         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
13900                 error "failed to hardlink many files"
13901         links=$($LFS fid2path $DIR $FID | wc -l)
13902         echo -n "${links}/1000 links in link EA"
13903         [[ ${links} -gt 60 ]] ||
13904                 error "expected at least 60 links in link EA"
13905         unlinkmany $remote_dir/foo2/$longname 1000 ||
13906         error "failed to unlink many hardlinks"
13907 }
13908 run_test 161b "link ea sanity under remote directory"
13909
13910 test_161c() {
13911         remote_mds_nodsh && skip "remote MDS with nodsh"
13912         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13913         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
13914                 skip "Need MDS version at least 2.1.5"
13915
13916         # define CLF_RENAME_LAST 0x0001
13917         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
13918         changelog_register || error "changelog_register failed"
13919
13920         rm -rf $DIR/$tdir
13921         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
13922         touch $DIR/$tdir/foo_161c
13923         touch $DIR/$tdir/bar_161c
13924         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
13925         changelog_dump | grep RENME | tail -n 5
13926         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
13927         changelog_clear 0 || error "changelog_clear failed"
13928         if [ x$flags != "x0x1" ]; then
13929                 error "flag $flags is not 0x1"
13930         fi
13931
13932         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
13933         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
13934         touch $DIR/$tdir/foo_161c
13935         touch $DIR/$tdir/bar_161c
13936         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
13937         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
13938         changelog_dump | grep RENME | tail -n 5
13939         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
13940         changelog_clear 0 || error "changelog_clear failed"
13941         if [ x$flags != "x0x0" ]; then
13942                 error "flag $flags is not 0x0"
13943         fi
13944         echo "rename overwrite a target having nlink > 1," \
13945                 "changelog record has flags of $flags"
13946
13947         # rename doesn't overwrite a target (changelog flag 0x0)
13948         touch $DIR/$tdir/foo_161c
13949         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
13950         changelog_dump | grep RENME | tail -n 5
13951         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
13952         changelog_clear 0 || error "changelog_clear failed"
13953         if [ x$flags != "x0x0" ]; then
13954                 error "flag $flags is not 0x0"
13955         fi
13956         echo "rename doesn't overwrite a target," \
13957                 "changelog record has flags of $flags"
13958
13959         # define CLF_UNLINK_LAST 0x0001
13960         # unlink a file having nlink = 1 (changelog flag 0x1)
13961         rm -f $DIR/$tdir/foo2_161c
13962         changelog_dump | grep UNLNK | tail -n 5
13963         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
13964         changelog_clear 0 || error "changelog_clear failed"
13965         if [ x$flags != "x0x1" ]; then
13966                 error "flag $flags is not 0x1"
13967         fi
13968         echo "unlink a file having nlink = 1," \
13969                 "changelog record has flags of $flags"
13970
13971         # unlink a file having nlink > 1 (changelog flag 0x0)
13972         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
13973         rm -f $DIR/$tdir/foobar_161c
13974         changelog_dump | grep UNLNK | tail -n 5
13975         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
13976         changelog_clear 0 || error "changelog_clear failed"
13977         if [ x$flags != "x0x0" ]; then
13978                 error "flag $flags is not 0x0"
13979         fi
13980         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
13981 }
13982 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
13983
13984 test_161d() {
13985         remote_mds_nodsh && skip "remote MDS with nodsh"
13986         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
13987
13988         local pid
13989         local fid
13990
13991         changelog_register || error "changelog_register failed"
13992
13993         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
13994         # interfer with $MOUNT/.lustre/fid/ access
13995         mkdir $DIR/$tdir
13996         [[ $? -eq 0 ]] || error "mkdir failed"
13997
13998         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
13999         $LCTL set_param fail_loc=0x8000140c
14000         # 5s pause
14001         $LCTL set_param fail_val=5
14002
14003         # create file
14004         echo foofoo > $DIR/$tdir/$tfile &
14005         pid=$!
14006
14007         # wait for create to be delayed
14008         sleep 2
14009
14010         ps -p $pid
14011         [[ $? -eq 0 ]] || error "create should be blocked"
14012
14013         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
14014         stack_trap "rm -f $tempfile"
14015         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
14016         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
14017         # some delay may occur during ChangeLog publishing and file read just
14018         # above, that could allow file write to happen finally
14019         [[ -s $tempfile ]] && echo "file should be empty"
14020
14021         $LCTL set_param fail_loc=0
14022
14023         wait $pid
14024         [[ $? -eq 0 ]] || error "create failed"
14025 }
14026 run_test 161d "create with concurrent .lustre/fid access"
14027
14028 check_path() {
14029         local expected="$1"
14030         shift
14031         local fid="$2"
14032
14033         local path
14034         path=$($LFS fid2path "$@")
14035         local rc=$?
14036
14037         if [ $rc -ne 0 ]; then
14038                 error "path looked up of '$expected' failed: rc=$rc"
14039         elif [ "$path" != "$expected" ]; then
14040                 error "path looked up '$path' instead of '$expected'"
14041         else
14042                 echo "FID '$fid' resolves to path '$path' as expected"
14043         fi
14044 }
14045
14046 test_162a() { # was test_162
14047         test_mkdir -p -c1 $DIR/$tdir/d2
14048         touch $DIR/$tdir/d2/$tfile
14049         touch $DIR/$tdir/d2/x1
14050         touch $DIR/$tdir/d2/x2
14051         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
14052         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
14053         # regular file
14054         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
14055         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
14056
14057         # softlink
14058         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
14059         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
14060         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
14061
14062         # softlink to wrong file
14063         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
14064         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
14065         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
14066
14067         # hardlink
14068         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
14069         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
14070         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
14071         # fid2path dir/fsname should both work
14072         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
14073         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
14074
14075         # hardlink count: check that there are 2 links
14076         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
14077         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
14078
14079         # hardlink indexing: remove the first link
14080         rm $DIR/$tdir/d2/p/q/r/hlink
14081         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
14082 }
14083 run_test 162a "path lookup sanity"
14084
14085 test_162b() {
14086         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14087         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
14088
14089         mkdir $DIR/$tdir
14090         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
14091                                 error "create striped dir failed"
14092
14093         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
14094                                         tail -n 1 | awk '{print $2}')
14095         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
14096
14097         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
14098         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
14099
14100         # regular file
14101         for ((i=0;i<5;i++)); do
14102                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
14103                         error "get fid for f$i failed"
14104                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
14105
14106                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
14107                         error "get fid for d$i failed"
14108                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
14109         done
14110
14111         return 0
14112 }
14113 run_test 162b "striped directory path lookup sanity"
14114
14115 # LU-4239: Verify fid2path works with paths 100 or more directories deep
14116 test_162c() {
14117         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
14118                 skip "Need MDS version at least 2.7.51"
14119
14120         local lpath=$tdir.local
14121         local rpath=$tdir.remote
14122
14123         test_mkdir $DIR/$lpath
14124         test_mkdir $DIR/$rpath
14125
14126         for ((i = 0; i <= 101; i++)); do
14127                 lpath="$lpath/$i"
14128                 mkdir $DIR/$lpath
14129                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
14130                         error "get fid for local directory $DIR/$lpath failed"
14131                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
14132
14133                 rpath="$rpath/$i"
14134                 test_mkdir $DIR/$rpath
14135                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
14136                         error "get fid for remote directory $DIR/$rpath failed"
14137                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
14138         done
14139
14140         return 0
14141 }
14142 run_test 162c "fid2path works with paths 100 or more directories deep"
14143
14144 test_169() {
14145         # do directio so as not to populate the page cache
14146         log "creating a 10 Mb file"
14147         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
14148         log "starting reads"
14149         dd if=$DIR/$tfile of=/dev/null bs=4096 &
14150         log "truncating the file"
14151         $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
14152         log "killing dd"
14153         kill %+ || true # reads might have finished
14154         echo "wait until dd is finished"
14155         wait
14156         log "removing the temporary file"
14157         rm -rf $DIR/$tfile || error "tmp file removal failed"
14158 }
14159 run_test 169 "parallel read and truncate should not deadlock"
14160
14161 test_170() {
14162         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14163
14164         $LCTL clear     # bug 18514
14165         $LCTL debug_daemon start $TMP/${tfile}_log_good
14166         touch $DIR/$tfile
14167         $LCTL debug_daemon stop
14168         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
14169                 error "sed failed to read log_good"
14170
14171         $LCTL debug_daemon start $TMP/${tfile}_log_good
14172         rm -rf $DIR/$tfile
14173         $LCTL debug_daemon stop
14174
14175         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
14176                error "lctl df log_bad failed"
14177
14178         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
14179         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
14180
14181         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
14182         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
14183
14184         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
14185                 error "bad_line good_line1 good_line2 are empty"
14186
14187         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
14188         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
14189         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
14190
14191         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
14192         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
14193         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
14194
14195         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
14196                 error "bad_line_new good_line_new are empty"
14197
14198         local expected_good=$((good_line1 + good_line2*2))
14199
14200         rm -f $TMP/${tfile}*
14201         # LU-231, short malformed line may not be counted into bad lines
14202         if [ $bad_line -ne $bad_line_new ] &&
14203                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
14204                 error "expected $bad_line bad lines, but got $bad_line_new"
14205                 return 1
14206         fi
14207
14208         if [ $expected_good -ne $good_line_new ]; then
14209                 error "expected $expected_good good lines, but got $good_line_new"
14210                 return 2
14211         fi
14212         true
14213 }
14214 run_test 170 "test lctl df to handle corrupted log ====================="
14215
14216 test_171() { # bug20592
14217         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14218
14219         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
14220         $LCTL set_param fail_loc=0x50e
14221         $LCTL set_param fail_val=3000
14222         multiop_bg_pause $DIR/$tfile O_s || true
14223         local MULTIPID=$!
14224         kill -USR1 $MULTIPID
14225         # cause log dump
14226         sleep 3
14227         wait $MULTIPID
14228         if dmesg | grep "recursive fault"; then
14229                 error "caught a recursive fault"
14230         fi
14231         $LCTL set_param fail_loc=0
14232         true
14233 }
14234 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
14235
14236 # it would be good to share it with obdfilter-survey/iokit-libecho code
14237 setup_obdecho_osc () {
14238         local rc=0
14239         local ost_nid=$1
14240         local obdfilter_name=$2
14241         echo "Creating new osc for $obdfilter_name on $ost_nid"
14242         # make sure we can find loopback nid
14243         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
14244
14245         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
14246                            ${obdfilter_name}_osc_UUID || rc=2; }
14247         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
14248                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
14249         return $rc
14250 }
14251
14252 cleanup_obdecho_osc () {
14253         local obdfilter_name=$1
14254         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
14255         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
14256         return 0
14257 }
14258
14259 obdecho_test() {
14260         local OBD=$1
14261         local node=$2
14262         local pages=${3:-64}
14263         local rc=0
14264         local id
14265
14266         local count=10
14267         local obd_size=$(get_obd_size $node $OBD)
14268         local page_size=$(get_page_size $node)
14269         if [[ -n "$obd_size" ]]; then
14270                 local new_count=$((obd_size / (pages * page_size / 1024)))
14271                 [[ $new_count -ge $count ]] || count=$new_count
14272         fi
14273
14274         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
14275         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
14276                            rc=2; }
14277         if [ $rc -eq 0 ]; then
14278             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
14279             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
14280         fi
14281         echo "New object id is $id"
14282         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
14283                            rc=4; }
14284         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
14285                            "test_brw $count w v $pages $id" || rc=4; }
14286         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
14287                            rc=4; }
14288         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
14289                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
14290         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
14291                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
14292         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
14293         return $rc
14294 }
14295
14296 test_180a() {
14297         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14298
14299         if ! module_loaded obdecho; then
14300                 load_module obdecho/obdecho &&
14301                         stack_trap "rmmod obdecho" EXIT ||
14302                         error "unable to load obdecho on client"
14303         fi
14304
14305         local osc=$($LCTL dl | grep -v mdt | awk '$3 == "osc" {print $4; exit}')
14306         local host=$($LCTL get_param -n osc.$osc.import |
14307                      awk '/current_connection:/ { print $2 }' )
14308         local target=$($LCTL get_param -n osc.$osc.import |
14309                        awk '/target:/ { print $2 }' )
14310         target=${target%_UUID}
14311
14312         if [ -n "$target" ]; then
14313                 setup_obdecho_osc $host $target &&
14314                         stack_trap "cleanup_obdecho_osc $target" EXIT ||
14315                         { error "obdecho setup failed with $?"; return; }
14316
14317                 obdecho_test ${target}_osc client ||
14318                         error "obdecho_test failed on ${target}_osc"
14319         else
14320                 $LCTL get_param osc.$osc.import
14321                 error "there is no osc.$osc.import target"
14322         fi
14323 }
14324 run_test 180a "test obdecho on osc"
14325
14326 test_180b() {
14327         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14328         remote_ost_nodsh && skip "remote OST with nodsh"
14329
14330         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
14331                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
14332                 error "failed to load module obdecho"
14333
14334         local target=$(do_facet ost1 $LCTL dl |
14335                        awk '/obdfilter/ { print $4; exit; }')
14336
14337         if [ -n "$target" ]; then
14338                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
14339         else
14340                 do_facet ost1 $LCTL dl
14341                 error "there is no obdfilter target on ost1"
14342         fi
14343 }
14344 run_test 180b "test obdecho directly on obdfilter"
14345
14346 test_180c() { # LU-2598
14347         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14348         remote_ost_nodsh && skip "remote OST with nodsh"
14349         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
14350                 skip "Need MDS version at least 2.4.0"
14351
14352         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
14353                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
14354                 error "failed to load module obdecho"
14355
14356         local target=$(do_facet ost1 $LCTL dl |
14357                        awk '/obdfilter/ { print $4; exit; }')
14358
14359         if [ -n "$target" ]; then
14360                 local pages=16384 # 64MB bulk I/O RPC size
14361
14362                 obdecho_test "$target" ost1 "$pages" ||
14363                         error "obdecho_test with pages=$pages failed with $?"
14364         else
14365                 do_facet ost1 $LCTL dl
14366                 error "there is no obdfilter target on ost1"
14367         fi
14368 }
14369 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
14370
14371 test_181() { # bug 22177
14372         test_mkdir $DIR/$tdir
14373         # create enough files to index the directory
14374         createmany -o $DIR/$tdir/foobar 4000
14375         # print attributes for debug purpose
14376         lsattr -d .
14377         # open dir
14378         multiop_bg_pause $DIR/$tdir D_Sc || return 1
14379         MULTIPID=$!
14380         # remove the files & current working dir
14381         unlinkmany $DIR/$tdir/foobar 4000
14382         rmdir $DIR/$tdir
14383         kill -USR1 $MULTIPID
14384         wait $MULTIPID
14385         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
14386         return 0
14387 }
14388 run_test 181 "Test open-unlinked dir ========================"
14389
14390 test_182() {
14391         local fcount=1000
14392         local tcount=10
14393
14394         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
14395
14396         $LCTL set_param mdc.*.rpc_stats=clear
14397
14398         for (( i = 0; i < $tcount; i++ )) ; do
14399                 mkdir $DIR/$tdir/$i
14400         done
14401
14402         for (( i = 0; i < $tcount; i++ )) ; do
14403                 createmany -o $DIR/$tdir/$i/f- $fcount &
14404         done
14405         wait
14406
14407         for (( i = 0; i < $tcount; i++ )) ; do
14408                 unlinkmany $DIR/$tdir/$i/f- $fcount &
14409         done
14410         wait
14411
14412         $LCTL get_param mdc.*.rpc_stats
14413
14414         rm -rf $DIR/$tdir
14415 }
14416 run_test 182 "Test parallel modify metadata operations ================"
14417
14418 test_183() { # LU-2275
14419         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14420         remote_mds_nodsh && skip "remote MDS with nodsh"
14421         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
14422                 skip "Need MDS version at least 2.3.56"
14423
14424         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
14425         echo aaa > $DIR/$tdir/$tfile
14426
14427 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
14428         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
14429
14430         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
14431         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
14432
14433         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
14434
14435         # Flush negative dentry cache
14436         touch $DIR/$tdir/$tfile
14437
14438         # We are not checking for any leaked references here, they'll
14439         # become evident next time we do cleanup with module unload.
14440         rm -rf $DIR/$tdir
14441 }
14442 run_test 183 "No crash or request leak in case of strange dispositions ========"
14443
14444 # test suite 184 is for LU-2016, LU-2017
14445 test_184a() {
14446         check_swap_layouts_support
14447
14448         dir0=$DIR/$tdir/$testnum
14449         test_mkdir -p -c1 $dir0
14450         ref1=/etc/passwd
14451         ref2=/etc/group
14452         file1=$dir0/f1
14453         file2=$dir0/f2
14454         $LFS setstripe -c1 $file1
14455         cp $ref1 $file1
14456         $LFS setstripe -c2 $file2
14457         cp $ref2 $file2
14458         gen1=$($LFS getstripe -g $file1)
14459         gen2=$($LFS getstripe -g $file2)
14460
14461         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
14462         gen=$($LFS getstripe -g $file1)
14463         [[ $gen1 != $gen ]] ||
14464                 "Layout generation on $file1 does not change"
14465         gen=$($LFS getstripe -g $file2)
14466         [[ $gen2 != $gen ]] ||
14467                 "Layout generation on $file2 does not change"
14468
14469         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
14470         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
14471
14472         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
14473 }
14474 run_test 184a "Basic layout swap"
14475
14476 test_184b() {
14477         check_swap_layouts_support
14478
14479         dir0=$DIR/$tdir/$testnum
14480         mkdir -p $dir0 || error "creating dir $dir0"
14481         file1=$dir0/f1
14482         file2=$dir0/f2
14483         file3=$dir0/f3
14484         dir1=$dir0/d1
14485         dir2=$dir0/d2
14486         mkdir $dir1 $dir2
14487         $LFS setstripe -c1 $file1
14488         $LFS setstripe -c2 $file2
14489         $LFS setstripe -c1 $file3
14490         chown $RUNAS_ID $file3
14491         gen1=$($LFS getstripe -g $file1)
14492         gen2=$($LFS getstripe -g $file2)
14493
14494         $LFS swap_layouts $dir1 $dir2 &&
14495                 error "swap of directories layouts should fail"
14496         $LFS swap_layouts $dir1 $file1 &&
14497                 error "swap of directory and file layouts should fail"
14498         $RUNAS $LFS swap_layouts $file1 $file2 &&
14499                 error "swap of file we cannot write should fail"
14500         $LFS swap_layouts $file1 $file3 &&
14501                 error "swap of file with different owner should fail"
14502         /bin/true # to clear error code
14503 }
14504 run_test 184b "Forbidden layout swap (will generate errors)"
14505
14506 test_184c() {
14507         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
14508         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
14509         check_swap_layouts_support
14510
14511         local dir0=$DIR/$tdir/$testnum
14512         mkdir -p $dir0 || error "creating dir $dir0"
14513
14514         local ref1=$dir0/ref1
14515         local ref2=$dir0/ref2
14516         local file1=$dir0/file1
14517         local file2=$dir0/file2
14518         # create a file large enough for the concurrent test
14519         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
14520         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
14521         echo "ref file size: ref1($(stat -c %s $ref1))," \
14522              "ref2($(stat -c %s $ref2))"
14523
14524         cp $ref2 $file2
14525         dd if=$ref1 of=$file1 bs=16k &
14526         local DD_PID=$!
14527
14528         # Make sure dd starts to copy file
14529         while [ ! -f $file1 ]; do sleep 0.1; done
14530
14531         $LFS swap_layouts $file1 $file2
14532         local rc=$?
14533         wait $DD_PID
14534         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
14535         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
14536
14537         # how many bytes copied before swapping layout
14538         local copied=$(stat -c %s $file2)
14539         local remaining=$(stat -c %s $ref1)
14540         remaining=$((remaining - copied))
14541         echo "Copied $copied bytes before swapping layout..."
14542
14543         cmp -n $copied $file1 $ref2 | grep differ &&
14544                 error "Content mismatch [0, $copied) of ref2 and file1"
14545         cmp -n $copied $file2 $ref1 ||
14546                 error "Content mismatch [0, $copied) of ref1 and file2"
14547         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
14548                 error "Content mismatch [$copied, EOF) of ref1 and file1"
14549
14550         # clean up
14551         rm -f $ref1 $ref2 $file1 $file2
14552 }
14553 run_test 184c "Concurrent write and layout swap"
14554
14555 test_184d() {
14556         check_swap_layouts_support
14557         [ -z "$(which getfattr 2>/dev/null)" ] &&
14558                 skip_env "no getfattr command"
14559
14560         local file1=$DIR/$tdir/$tfile-1
14561         local file2=$DIR/$tdir/$tfile-2
14562         local file3=$DIR/$tdir/$tfile-3
14563         local lovea1
14564         local lovea2
14565
14566         mkdir -p $DIR/$tdir
14567         touch $file1 || error "create $file1 failed"
14568         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
14569                 error "create $file2 failed"
14570         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
14571                 error "create $file3 failed"
14572         lovea1=$(get_layout_param $file1)
14573
14574         $LFS swap_layouts $file2 $file3 ||
14575                 error "swap $file2 $file3 layouts failed"
14576         $LFS swap_layouts $file1 $file2 ||
14577                 error "swap $file1 $file2 layouts failed"
14578
14579         lovea2=$(get_layout_param $file2)
14580         echo "$lovea1"
14581         echo "$lovea2"
14582         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
14583
14584         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
14585         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
14586 }
14587 run_test 184d "allow stripeless layouts swap"
14588
14589 test_184e() {
14590         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
14591                 skip "Need MDS version at least 2.6.94"
14592         check_swap_layouts_support
14593         [ -z "$(which getfattr 2>/dev/null)" ] &&
14594                 skip_env "no getfattr command"
14595
14596         local file1=$DIR/$tdir/$tfile-1
14597         local file2=$DIR/$tdir/$tfile-2
14598         local file3=$DIR/$tdir/$tfile-3
14599         local lovea
14600
14601         mkdir -p $DIR/$tdir
14602         touch $file1 || error "create $file1 failed"
14603         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
14604                 error "create $file2 failed"
14605         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
14606                 error "create $file3 failed"
14607
14608         $LFS swap_layouts $file1 $file2 ||
14609                 error "swap $file1 $file2 layouts failed"
14610
14611         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
14612         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
14613
14614         echo 123 > $file1 || error "Should be able to write into $file1"
14615
14616         $LFS swap_layouts $file1 $file3 ||
14617                 error "swap $file1 $file3 layouts failed"
14618
14619         echo 123 > $file1 || error "Should be able to write into $file1"
14620
14621         rm -rf $file1 $file2 $file3
14622 }
14623 run_test 184e "Recreate layout after stripeless layout swaps"
14624
14625 test_184f() {
14626         # Create a file with name longer than sizeof(struct stat) ==
14627         # 144 to see if we can get chars from the file name to appear
14628         # in the returned striping. Note that 'f' == 0x66.
14629         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
14630
14631         mkdir -p $DIR/$tdir
14632         mcreate $DIR/$tdir/$file
14633         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
14634                 error "IOC_MDC_GETFILEINFO returned garbage striping"
14635         fi
14636 }
14637 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
14638
14639 test_185() { # LU-2441
14640         # LU-3553 - no volatile file support in old servers
14641         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
14642                 skip "Need MDS version at least 2.3.60"
14643
14644         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
14645         touch $DIR/$tdir/spoo
14646         local mtime1=$(stat -c "%Y" $DIR/$tdir)
14647         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
14648                 error "cannot create/write a volatile file"
14649         [ "$FILESET" == "" ] &&
14650         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
14651                 error "FID is still valid after close"
14652
14653         multiop_bg_pause $DIR/$tdir vVw4096_c
14654         local multi_pid=$!
14655
14656         local OLD_IFS=$IFS
14657         IFS=":"
14658         local fidv=($fid)
14659         IFS=$OLD_IFS
14660         # assume that the next FID for this client is sequential, since stdout
14661         # is unfortunately eaten by multiop_bg_pause
14662         local n=$((${fidv[1]} + 1))
14663         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
14664         if [ "$FILESET" == "" ]; then
14665                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
14666                         error "FID is missing before close"
14667         fi
14668         kill -USR1 $multi_pid
14669         # 1 second delay, so if mtime change we will see it
14670         sleep 1
14671         local mtime2=$(stat -c "%Y" $DIR/$tdir)
14672         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
14673 }
14674 run_test 185 "Volatile file support"
14675
14676 function create_check_volatile() {
14677         local idx=$1
14678         local tgt
14679
14680         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
14681         local PID=$!
14682         sleep 1
14683         local FID=$(cat /tmp/${tfile}.fid)
14684         [ "$FID" == "" ] && error "can't get FID for volatile"
14685         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
14686         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
14687         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
14688         kill -USR1 $PID
14689         wait
14690         sleep 1
14691         cancel_lru_locks mdc # flush opencache
14692         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
14693         return 0
14694 }
14695
14696 test_185a(){
14697         # LU-12516 - volatile creation via .lustre
14698         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
14699                 skip "Need MDS version at least 2.3.55"
14700
14701         create_check_volatile 0
14702         [ $MDSCOUNT -lt 2 ] && return 0
14703
14704         # DNE case
14705         create_check_volatile 1
14706
14707         return 0
14708 }
14709 run_test 185a "Volatile file creation in .lustre/fid/"
14710
14711 test_187a() {
14712         remote_mds_nodsh && skip "remote MDS with nodsh"
14713         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
14714                 skip "Need MDS version at least 2.3.0"
14715
14716         local dir0=$DIR/$tdir/$testnum
14717         mkdir -p $dir0 || error "creating dir $dir0"
14718
14719         local file=$dir0/file1
14720         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
14721         local dv1=$($LFS data_version $file)
14722         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
14723         local dv2=$($LFS data_version $file)
14724         [[ $dv1 != $dv2 ]] ||
14725                 error "data version did not change on write $dv1 == $dv2"
14726
14727         # clean up
14728         rm -f $file1
14729 }
14730 run_test 187a "Test data version change"
14731
14732 test_187b() {
14733         remote_mds_nodsh && skip "remote MDS with nodsh"
14734         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
14735                 skip "Need MDS version at least 2.3.0"
14736
14737         local dir0=$DIR/$tdir/$testnum
14738         mkdir -p $dir0 || error "creating dir $dir0"
14739
14740         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
14741         [[ ${DV[0]} != ${DV[1]} ]] ||
14742                 error "data version did not change on write"\
14743                       " ${DV[0]} == ${DV[1]}"
14744
14745         # clean up
14746         rm -f $file1
14747 }
14748 run_test 187b "Test data version change on volatile file"
14749
14750 test_200() {
14751         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14752         remote_mgs_nodsh && skip "remote MGS with nodsh"
14753         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14754
14755         local POOL=${POOL:-cea1}
14756         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
14757         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
14758         # Pool OST targets
14759         local first_ost=0
14760         local last_ost=$(($OSTCOUNT - 1))
14761         local ost_step=2
14762         local ost_list=$(seq $first_ost $ost_step $last_ost)
14763         local ost_range="$first_ost $last_ost $ost_step"
14764         local test_path=$POOL_ROOT/$POOL_DIR_NAME
14765         local file_dir=$POOL_ROOT/file_tst
14766         local subdir=$test_path/subdir
14767         local rc=0
14768
14769         if ! combined_mgs_mds ; then
14770                 mount_mgs_client
14771         fi
14772
14773         while : ; do
14774                 # former test_200a test_200b
14775                 pool_add $POOL                          || { rc=$? ; break; }
14776                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
14777                 # former test_200c test_200d
14778                 mkdir -p $test_path
14779                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
14780                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
14781                 mkdir -p $subdir
14782                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
14783                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
14784                                                         || { rc=$? ; break; }
14785                 # former test_200e test_200f
14786                 local files=$((OSTCOUNT*3))
14787                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
14788                                                         || { rc=$? ; break; }
14789                 pool_create_files $POOL $file_dir $files "$ost_list" \
14790                                                         || { rc=$? ; break; }
14791                 # former test_200g test_200h
14792                 pool_lfs_df $POOL                       || { rc=$? ; break; }
14793                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
14794
14795                 # former test_201a test_201b test_201c
14796                 pool_remove_first_target $POOL          || { rc=$? ; break; }
14797
14798                 local f=$test_path/$tfile
14799                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
14800                 pool_remove $POOL $f                    || { rc=$? ; break; }
14801                 break
14802         done
14803
14804         destroy_test_pools
14805
14806         if ! combined_mgs_mds ; then
14807                 umount_mgs_client
14808         fi
14809         return $rc
14810 }
14811 run_test 200 "OST pools"
14812
14813 # usage: default_attr <count | size | offset>
14814 default_attr() {
14815         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
14816 }
14817
14818 # usage: check_default_stripe_attr
14819 check_default_stripe_attr() {
14820         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
14821         case $1 in
14822         --stripe-count|-c)
14823                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
14824         --stripe-size|-S)
14825                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
14826         --stripe-index|-i)
14827                 EXPECTED=-1;;
14828         *)
14829                 error "unknown getstripe attr '$1'"
14830         esac
14831
14832         [ $ACTUAL == $EXPECTED ] ||
14833                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
14834 }
14835
14836 test_204a() {
14837         test_mkdir $DIR/$tdir
14838         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
14839
14840         check_default_stripe_attr --stripe-count
14841         check_default_stripe_attr --stripe-size
14842         check_default_stripe_attr --stripe-index
14843 }
14844 run_test 204a "Print default stripe attributes"
14845
14846 test_204b() {
14847         test_mkdir $DIR/$tdir
14848         $LFS setstripe --stripe-count 1 $DIR/$tdir
14849
14850         check_default_stripe_attr --stripe-size
14851         check_default_stripe_attr --stripe-index
14852 }
14853 run_test 204b "Print default stripe size and offset"
14854
14855 test_204c() {
14856         test_mkdir $DIR/$tdir
14857         $LFS setstripe --stripe-size 65536 $DIR/$tdir
14858
14859         check_default_stripe_attr --stripe-count
14860         check_default_stripe_attr --stripe-index
14861 }
14862 run_test 204c "Print default stripe count and offset"
14863
14864 test_204d() {
14865         test_mkdir $DIR/$tdir
14866         $LFS setstripe --stripe-index 0 $DIR/$tdir
14867
14868         check_default_stripe_attr --stripe-count
14869         check_default_stripe_attr --stripe-size
14870 }
14871 run_test 204d "Print default stripe count and size"
14872
14873 test_204e() {
14874         test_mkdir $DIR/$tdir
14875         $LFS setstripe -d $DIR/$tdir
14876
14877         check_default_stripe_attr --stripe-count --raw
14878         check_default_stripe_attr --stripe-size --raw
14879         check_default_stripe_attr --stripe-index --raw
14880 }
14881 run_test 204e "Print raw stripe attributes"
14882
14883 test_204f() {
14884         test_mkdir $DIR/$tdir
14885         $LFS setstripe --stripe-count 1 $DIR/$tdir
14886
14887         check_default_stripe_attr --stripe-size --raw
14888         check_default_stripe_attr --stripe-index --raw
14889 }
14890 run_test 204f "Print raw stripe size and offset"
14891
14892 test_204g() {
14893         test_mkdir $DIR/$tdir
14894         $LFS setstripe --stripe-size 65536 $DIR/$tdir
14895
14896         check_default_stripe_attr --stripe-count --raw
14897         check_default_stripe_attr --stripe-index --raw
14898 }
14899 run_test 204g "Print raw stripe count and offset"
14900
14901 test_204h() {
14902         test_mkdir $DIR/$tdir
14903         $LFS setstripe --stripe-index 0 $DIR/$tdir
14904
14905         check_default_stripe_attr --stripe-count --raw
14906         check_default_stripe_attr --stripe-size --raw
14907 }
14908 run_test 204h "Print raw stripe count and size"
14909
14910 # Figure out which job scheduler is being used, if any,
14911 # or use a fake one
14912 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
14913         JOBENV=SLURM_JOB_ID
14914 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
14915         JOBENV=LSB_JOBID
14916 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
14917         JOBENV=PBS_JOBID
14918 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
14919         JOBENV=LOADL_STEP_ID
14920 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
14921         JOBENV=JOB_ID
14922 else
14923         $LCTL list_param jobid_name > /dev/null 2>&1
14924         if [ $? -eq 0 ]; then
14925                 JOBENV=nodelocal
14926         else
14927                 JOBENV=FAKE_JOBID
14928         fi
14929 fi
14930 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
14931
14932 verify_jobstats() {
14933         local cmd=($1)
14934         shift
14935         local facets="$@"
14936
14937 # we don't really need to clear the stats for this test to work, since each
14938 # command has a unique jobid, but it makes debugging easier if needed.
14939 #       for facet in $facets; do
14940 #               local dev=$(convert_facet2label $facet)
14941 #               # clear old jobstats
14942 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
14943 #       done
14944
14945         # use a new JobID for each test, or we might see an old one
14946         [ "$JOBENV" = "FAKE_JOBID" ] &&
14947                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
14948
14949         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
14950
14951         [ "$JOBENV" = "nodelocal" ] && {
14952                 FAKE_JOBID=id.$testnum.%e.$RANDOM
14953                 $LCTL set_param jobid_name=$FAKE_JOBID
14954                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
14955         }
14956
14957         log "Test: ${cmd[*]}"
14958         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
14959
14960         if [ $JOBENV = "FAKE_JOBID" ]; then
14961                 FAKE_JOBID=$JOBVAL ${cmd[*]}
14962         else
14963                 ${cmd[*]}
14964         fi
14965
14966         # all files are created on OST0000
14967         for facet in $facets; do
14968                 local stats="*.$(convert_facet2label $facet).job_stats"
14969
14970                 # strip out libtool wrappers for in-tree executables
14971                 if [ $(do_facet $facet lctl get_param $stats |
14972                        sed -e 's/\.lt-/./' | grep -c $JOBVAL) -ne 1 ]; then
14973                         do_facet $facet lctl get_param $stats
14974                         error "No jobstats for $JOBVAL found on $facet::$stats"
14975                 fi
14976         done
14977 }
14978
14979 jobstats_set() {
14980         local new_jobenv=$1
14981
14982         set_persistent_param_and_check client "jobid_var" \
14983                 "$FSNAME.sys.jobid_var" $new_jobenv
14984 }
14985
14986 test_205() { # Job stats
14987         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14988         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
14989                 skip "Need MDS version with at least 2.7.1"
14990         remote_mgs_nodsh && skip "remote MGS with nodsh"
14991         remote_mds_nodsh && skip "remote MDS with nodsh"
14992         remote_ost_nodsh && skip "remote OST with nodsh"
14993         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
14994                 skip "Server doesn't support jobstats"
14995         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
14996
14997         local old_jobenv=$($LCTL get_param -n jobid_var)
14998         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
14999
15000         if [[ $PERM_CMD == *"set_param -P"* ]]; then
15001                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
15002         else
15003                 stack_trap "do_facet mgs $PERM_CMD \
15004                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
15005         fi
15006         changelog_register
15007
15008         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
15009                                 mdt.*.job_cleanup_interval | head -n 1)
15010         local new_interval=5
15011         do_facet $SINGLEMDS \
15012                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
15013         stack_trap "do_facet $SINGLEMDS \
15014                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
15015         local start=$SECONDS
15016
15017         local cmd
15018         # mkdir
15019         cmd="mkdir $DIR/$tdir"
15020         verify_jobstats "$cmd" "$SINGLEMDS"
15021         # rmdir
15022         cmd="rmdir $DIR/$tdir"
15023         verify_jobstats "$cmd" "$SINGLEMDS"
15024         # mkdir on secondary MDT
15025         if [ $MDSCOUNT -gt 1 ]; then
15026                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
15027                 verify_jobstats "$cmd" "mds2"
15028         fi
15029         # mknod
15030         cmd="mknod $DIR/$tfile c 1 3"
15031         verify_jobstats "$cmd" "$SINGLEMDS"
15032         # unlink
15033         cmd="rm -f $DIR/$tfile"
15034         verify_jobstats "$cmd" "$SINGLEMDS"
15035         # create all files on OST0000 so verify_jobstats can find OST stats
15036         # open & close
15037         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
15038         verify_jobstats "$cmd" "$SINGLEMDS"
15039         # setattr
15040         cmd="touch $DIR/$tfile"
15041         verify_jobstats "$cmd" "$SINGLEMDS ost1"
15042         # write
15043         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
15044         verify_jobstats "$cmd" "ost1"
15045         # read
15046         cancel_lru_locks osc
15047         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
15048         verify_jobstats "$cmd" "ost1"
15049         # truncate
15050         cmd="$TRUNCATE $DIR/$tfile 0"
15051         verify_jobstats "$cmd" "$SINGLEMDS ost1"
15052         # rename
15053         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
15054         verify_jobstats "$cmd" "$SINGLEMDS"
15055         # jobstats expiry - sleep until old stats should be expired
15056         local left=$((new_interval + 5 - (SECONDS - start)))
15057         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
15058                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
15059                         "0" $left
15060         cmd="mkdir $DIR/$tdir.expire"
15061         verify_jobstats "$cmd" "$SINGLEMDS"
15062         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
15063             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
15064
15065         # Ensure that jobid are present in changelog (if supported by MDS)
15066         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
15067                 changelog_dump | tail -10
15068                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
15069                 [ $jobids -eq 9 ] ||
15070                         error "Wrong changelog jobid count $jobids != 9"
15071
15072                 # LU-5862
15073                 JOBENV="disable"
15074                 jobstats_set $JOBENV
15075                 touch $DIR/$tfile
15076                 changelog_dump | grep $tfile
15077                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
15078                 [ $jobids -eq 0 ] ||
15079                         error "Unexpected jobids when jobid_var=$JOBENV"
15080         fi
15081
15082         lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"
15083         JOBENV="JOBCOMPLEX"
15084         JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
15085
15086         verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
15087 }
15088 run_test 205 "Verify job stats"
15089
15090 # LU-1480, LU-1773 and LU-1657
15091 test_206() {
15092         mkdir -p $DIR/$tdir
15093         $LFS setstripe -c -1 $DIR/$tdir
15094 #define OBD_FAIL_LOV_INIT 0x1403
15095         $LCTL set_param fail_loc=0xa0001403
15096         $LCTL set_param fail_val=1
15097         touch $DIR/$tdir/$tfile || true
15098 }
15099 run_test 206 "fail lov_init_raid0() doesn't lbug"
15100
15101 test_207a() {
15102         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
15103         local fsz=`stat -c %s $DIR/$tfile`
15104         cancel_lru_locks mdc
15105
15106         # do not return layout in getattr intent
15107 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
15108         $LCTL set_param fail_loc=0x170
15109         local sz=`stat -c %s $DIR/$tfile`
15110
15111         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
15112
15113         rm -rf $DIR/$tfile
15114 }
15115 run_test 207a "can refresh layout at glimpse"
15116
15117 test_207b() {
15118         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
15119         local cksum=`md5sum $DIR/$tfile`
15120         local fsz=`stat -c %s $DIR/$tfile`
15121         cancel_lru_locks mdc
15122         cancel_lru_locks osc
15123
15124         # do not return layout in getattr intent
15125 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
15126         $LCTL set_param fail_loc=0x171
15127
15128         # it will refresh layout after the file is opened but before read issues
15129         echo checksum is "$cksum"
15130         echo "$cksum" |md5sum -c --quiet || error "file differs"
15131
15132         rm -rf $DIR/$tfile
15133 }
15134 run_test 207b "can refresh layout at open"
15135
15136 test_208() {
15137         # FIXME: in this test suite, only RD lease is used. This is okay
15138         # for now as only exclusive open is supported. After generic lease
15139         # is done, this test suite should be revised. - Jinshan
15140
15141         remote_mds_nodsh && skip "remote MDS with nodsh"
15142         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
15143                 skip "Need MDS version at least 2.4.52"
15144
15145         echo "==== test 1: verify get lease work"
15146         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
15147
15148         echo "==== test 2: verify lease can be broken by upcoming open"
15149         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
15150         local PID=$!
15151         sleep 1
15152
15153         $MULTIOP $DIR/$tfile oO_RDONLY:c
15154         kill -USR1 $PID && wait $PID || error "break lease error"
15155
15156         echo "==== test 3: verify lease can't be granted if an open already exists"
15157         $MULTIOP $DIR/$tfile oO_RDONLY:_c &
15158         local PID=$!
15159         sleep 1
15160
15161         $MULTIOP $DIR/$tfile oO_RDONLY:eReUc && error "apply lease should fail"
15162         kill -USR1 $PID && wait $PID || error "open file error"
15163
15164         echo "==== test 4: lease can sustain over recovery"
15165         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
15166         PID=$!
15167         sleep 1
15168
15169         fail mds1
15170
15171         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
15172
15173         echo "==== test 5: lease broken can't be regained by replay"
15174         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
15175         PID=$!
15176         sleep 1
15177
15178         # open file to break lease and then recovery
15179         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
15180         fail mds1
15181
15182         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
15183
15184         rm -f $DIR/$tfile
15185 }
15186 run_test 208 "Exclusive open"
15187
15188 test_209() {
15189         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
15190                 skip_env "must have disp_stripe"
15191
15192         touch $DIR/$tfile
15193         sync; sleep 5; sync;
15194
15195         echo 3 > /proc/sys/vm/drop_caches
15196         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
15197
15198         # open/close 500 times
15199         for i in $(seq 500); do
15200                 cat $DIR/$tfile
15201         done
15202
15203         echo 3 > /proc/sys/vm/drop_caches
15204         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
15205
15206         echo "before: $req_before, after: $req_after"
15207         [ $((req_after - req_before)) -ge 300 ] &&
15208                 error "open/close requests are not freed"
15209         return 0
15210 }
15211 run_test 209 "read-only open/close requests should be freed promptly"
15212
15213 test_212() {
15214         size=`date +%s`
15215         size=$((size % 8192 + 1))
15216         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
15217         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
15218         rm -f $DIR/f212 $DIR/f212.xyz
15219 }
15220 run_test 212 "Sendfile test ============================================"
15221
15222 test_213() {
15223         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
15224         cancel_lru_locks osc
15225         lctl set_param fail_loc=0x8000040f
15226         # generate a read lock
15227         cat $DIR/$tfile > /dev/null
15228         # write to the file, it will try to cancel the above read lock.
15229         cat /etc/hosts >> $DIR/$tfile
15230 }
15231 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
15232
15233 test_214() { # for bug 20133
15234         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
15235         for (( i=0; i < 340; i++ )) ; do
15236                 touch $DIR/$tdir/d214c/a$i
15237         done
15238
15239         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
15240         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
15241         ls $DIR/d214c || error "ls $DIR/d214c failed"
15242         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
15243         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
15244 }
15245 run_test 214 "hash-indexed directory test - bug 20133"
15246
15247 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
15248 create_lnet_proc_files() {
15249         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
15250 }
15251
15252 # counterpart of create_lnet_proc_files
15253 remove_lnet_proc_files() {
15254         rm -f $TMP/lnet_$1.sys
15255 }
15256
15257 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
15258 # 3rd arg as regexp for body
15259 check_lnet_proc_stats() {
15260         local l=$(cat "$TMP/lnet_$1" |wc -l)
15261         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
15262
15263         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
15264 }
15265
15266 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
15267 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
15268 # optional and can be regexp for 2nd line (lnet.routes case)
15269 check_lnet_proc_entry() {
15270         local blp=2          # blp stands for 'position of 1st line of body'
15271         [ -z "$5" ] || blp=3 # lnet.routes case
15272
15273         local l=$(cat "$TMP/lnet_$1" |wc -l)
15274         # subtracting one from $blp because the body can be empty
15275         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
15276
15277         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
15278                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
15279
15280         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
15281                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
15282
15283         # bail out if any unexpected line happened
15284         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
15285         [ "$?" != 0 ] || error "$2 misformatted"
15286 }
15287
15288 test_215() { # for bugs 18102, 21079, 21517
15289         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15290
15291         local N='(0|[1-9][0-9]*)'       # non-negative numeric
15292         local P='[1-9][0-9]*'           # positive numeric
15293         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
15294         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
15295         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
15296         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
15297
15298         local L1 # regexp for 1st line
15299         local L2 # regexp for 2nd line (optional)
15300         local BR # regexp for the rest (body)
15301
15302         # lnet.stats should look as 11 space-separated non-negative numerics
15303         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
15304         create_lnet_proc_files "stats"
15305         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
15306         remove_lnet_proc_files "stats"
15307
15308         # lnet.routes should look like this:
15309         # Routing disabled/enabled
15310         # net hops priority state router
15311         # where net is a string like tcp0, hops > 0, priority >= 0,
15312         # state is up/down,
15313         # router is a string like 192.168.1.1@tcp2
15314         L1="^Routing (disabled|enabled)$"
15315         L2="^net +hops +priority +state +router$"
15316         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
15317         create_lnet_proc_files "routes"
15318         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
15319         remove_lnet_proc_files "routes"
15320
15321         # lnet.routers should look like this:
15322         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
15323         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
15324         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
15325         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
15326         L1="^ref +rtr_ref +alive +router$"
15327         BR="^$P +$P +(up|down) +$NID$"
15328         create_lnet_proc_files "routers"
15329         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
15330         remove_lnet_proc_files "routers"
15331
15332         # lnet.peers should look like this:
15333         # nid refs state last max rtr min tx min queue
15334         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
15335         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
15336         # numeric (0 or >0 or <0), queue >= 0.
15337         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
15338         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
15339         create_lnet_proc_files "peers"
15340         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
15341         remove_lnet_proc_files "peers"
15342
15343         # lnet.buffers  should look like this:
15344         # pages count credits min
15345         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
15346         L1="^pages +count +credits +min$"
15347         BR="^ +$N +$N +$I +$I$"
15348         create_lnet_proc_files "buffers"
15349         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
15350         remove_lnet_proc_files "buffers"
15351
15352         # lnet.nis should look like this:
15353         # nid status alive refs peer rtr max tx min
15354         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
15355         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
15356         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
15357         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
15358         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
15359         create_lnet_proc_files "nis"
15360         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
15361         remove_lnet_proc_files "nis"
15362
15363         # can we successfully write to lnet.stats?
15364         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
15365 }
15366 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
15367
15368 test_216() { # bug 20317
15369         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15370         remote_ost_nodsh && skip "remote OST with nodsh"
15371
15372         local node
15373         local facets=$(get_facets OST)
15374         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15375
15376         save_lustre_params client "osc.*.contention_seconds" > $p
15377         save_lustre_params $facets \
15378                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
15379         save_lustre_params $facets \
15380                 "ldlm.namespaces.filter-*.contended_locks" >> $p
15381         save_lustre_params $facets \
15382                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
15383         clear_stats osc.*.osc_stats
15384
15385         # agressive lockless i/o settings
15386         do_nodes $(comma_list $(osts_nodes)) \
15387                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
15388                         ldlm.namespaces.filter-*.contended_locks=0 \
15389                         ldlm.namespaces.filter-*.contention_seconds=60"
15390         lctl set_param -n osc.*.contention_seconds=60
15391
15392         $DIRECTIO write $DIR/$tfile 0 10 4096
15393         $CHECKSTAT -s 40960 $DIR/$tfile
15394
15395         # disable lockless i/o
15396         do_nodes $(comma_list $(osts_nodes)) \
15397                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
15398                         ldlm.namespaces.filter-*.contended_locks=32 \
15399                         ldlm.namespaces.filter-*.contention_seconds=0"
15400         lctl set_param -n osc.*.contention_seconds=0
15401         clear_stats osc.*.osc_stats
15402
15403         dd if=/dev/zero of=$DIR/$tfile count=0
15404         $CHECKSTAT -s 0 $DIR/$tfile
15405
15406         restore_lustre_params <$p
15407         rm -f $p
15408         rm $DIR/$tfile
15409 }
15410 run_test 216 "check lockless direct write updates file size and kms correctly"
15411
15412 test_217() { # bug 22430
15413         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15414
15415         local node
15416         local nid
15417
15418         for node in $(nodes_list); do
15419                 nid=$(host_nids_address $node $NETTYPE)
15420                 if [[ $nid = *-* ]] ; then
15421                         echo "lctl ping $(h2nettype $nid)"
15422                         lctl ping $(h2nettype $nid)
15423                 else
15424                         echo "skipping $node (no hyphen detected)"
15425                 fi
15426         done
15427 }
15428 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
15429
15430 test_218() {
15431        # do directio so as not to populate the page cache
15432        log "creating a 10 Mb file"
15433        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
15434        log "starting reads"
15435        dd if=$DIR/$tfile of=/dev/null bs=4096 &
15436        log "truncating the file"
15437        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
15438        log "killing dd"
15439        kill %+ || true # reads might have finished
15440        echo "wait until dd is finished"
15441        wait
15442        log "removing the temporary file"
15443        rm -rf $DIR/$tfile || error "tmp file removal failed"
15444 }
15445 run_test 218 "parallel read and truncate should not deadlock"
15446
15447 test_219() {
15448         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15449
15450         # write one partial page
15451         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
15452         # set no grant so vvp_io_commit_write will do sync write
15453         $LCTL set_param fail_loc=0x411
15454         # write a full page at the end of file
15455         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
15456
15457         $LCTL set_param fail_loc=0
15458         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
15459         $LCTL set_param fail_loc=0x411
15460         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
15461
15462         # LU-4201
15463         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
15464         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
15465 }
15466 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
15467
15468 test_220() { #LU-325
15469         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15470         remote_ost_nodsh && skip "remote OST with nodsh"
15471         remote_mds_nodsh && skip "remote MDS with nodsh"
15472         remote_mgs_nodsh && skip "remote MGS with nodsh"
15473
15474         local OSTIDX=0
15475
15476         # create on MDT0000 so the last_id and next_id are correct
15477         mkdir $DIR/$tdir
15478         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
15479         OST=${OST%_UUID}
15480
15481         # on the mdt's osc
15482         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
15483         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
15484                         osp.$mdtosc_proc1.prealloc_last_id)
15485         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
15486                         osp.$mdtosc_proc1.prealloc_next_id)
15487
15488         $LFS df -i
15489
15490         if ! combined_mgs_mds ; then
15491                 mount_mgs_client
15492         fi
15493
15494         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
15495         #define OBD_FAIL_OST_ENOINO              0x229
15496         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
15497         create_pool $FSNAME.$TESTNAME || return 1
15498         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
15499
15500         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
15501
15502         MDSOBJS=$((last_id - next_id))
15503         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
15504
15505         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
15506         echo "OST still has $count kbytes free"
15507
15508         echo "create $MDSOBJS files @next_id..."
15509         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
15510
15511         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
15512                         osp.$mdtosc_proc1.prealloc_last_id)
15513         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
15514                         osp.$mdtosc_proc1.prealloc_next_id)
15515
15516         echo "after creation, last_id=$last_id2, next_id=$next_id2"
15517         $LFS df -i
15518
15519         echo "cleanup..."
15520
15521         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
15522         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
15523
15524         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
15525                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
15526         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
15527                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
15528         echo "unlink $MDSOBJS files @$next_id..."
15529         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
15530
15531         if ! combined_mgs_mds ; then
15532                 umount_mgs_client
15533         fi
15534 }
15535 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
15536
15537 test_221() {
15538         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15539
15540         dd if=`which date` of=$MOUNT/date oflag=sync
15541         chmod +x $MOUNT/date
15542
15543         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
15544         $LCTL set_param fail_loc=0x80001401
15545
15546         $MOUNT/date > /dev/null
15547         rm -f $MOUNT/date
15548 }
15549 run_test 221 "make sure fault and truncate race to not cause OOM"
15550
15551 test_222a () {
15552         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15553
15554         rm -rf $DIR/$tdir
15555         test_mkdir $DIR/$tdir
15556         $LFS setstripe -c 1 -i 0 $DIR/$tdir
15557         createmany -o $DIR/$tdir/$tfile 10
15558         cancel_lru_locks mdc
15559         cancel_lru_locks osc
15560         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
15561         $LCTL set_param fail_loc=0x31a
15562         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
15563         $LCTL set_param fail_loc=0
15564         rm -r $DIR/$tdir
15565 }
15566 run_test 222a "AGL for ls should not trigger CLIO lock failure"
15567
15568 test_222b () {
15569         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15570
15571         rm -rf $DIR/$tdir
15572         test_mkdir $DIR/$tdir
15573         $LFS setstripe -c 1 -i 0 $DIR/$tdir
15574         createmany -o $DIR/$tdir/$tfile 10
15575         cancel_lru_locks mdc
15576         cancel_lru_locks osc
15577         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
15578         $LCTL set_param fail_loc=0x31a
15579         rm -r $DIR/$tdir || error "AGL for rmdir failed"
15580         $LCTL set_param fail_loc=0
15581 }
15582 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
15583
15584 test_223 () {
15585         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15586
15587         rm -rf $DIR/$tdir
15588         test_mkdir $DIR/$tdir
15589         $LFS setstripe -c 1 -i 0 $DIR/$tdir
15590         createmany -o $DIR/$tdir/$tfile 10
15591         cancel_lru_locks mdc
15592         cancel_lru_locks osc
15593         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
15594         $LCTL set_param fail_loc=0x31b
15595         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
15596         $LCTL set_param fail_loc=0
15597         rm -r $DIR/$tdir
15598 }
15599 run_test 223 "osc reenqueue if without AGL lock granted ======================="
15600
15601 test_224a() { # LU-1039, MRP-303
15602         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15603
15604         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
15605         $LCTL set_param fail_loc=0x508
15606         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 conv=fsync
15607         $LCTL set_param fail_loc=0
15608         df $DIR
15609 }
15610 run_test 224a "Don't panic on bulk IO failure"
15611
15612 test_224b() { # LU-1039, MRP-303
15613         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15614
15615         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
15616         cancel_lru_locks osc
15617         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
15618         $LCTL set_param fail_loc=0x515
15619         dd of=/dev/null if=$DIR/$tfile bs=4096 count=1
15620         $LCTL set_param fail_loc=0
15621         df $DIR
15622 }
15623 run_test 224b "Don't panic on bulk IO failure"
15624
15625 test_224c() { # LU-6441
15626         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15627         remote_mds_nodsh && skip "remote MDS with nodsh"
15628
15629         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15630         save_writethrough $p
15631         set_cache writethrough on
15632
15633         local pages_per_rpc=$($LCTL get_param \
15634                                 osc.*.max_pages_per_rpc)
15635         local at_max=$($LCTL get_param -n at_max)
15636         local timeout=$($LCTL get_param -n timeout)
15637         local test_at="at_max"
15638         local param_at="$FSNAME.sys.at_max"
15639         local test_timeout="timeout"
15640         local param_timeout="$FSNAME.sys.timeout"
15641
15642         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
15643
15644         set_persistent_param_and_check client "$test_at" "$param_at" 0
15645         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
15646
15647         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
15648         do_facet ost1 "$LCTL set_param fail_loc=0x520"
15649         $LFS setstripe -c 1 -i 0 $DIR/$tfile
15650         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
15651         sync
15652         do_facet ost1 "$LCTL set_param fail_loc=0"
15653
15654         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
15655         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
15656                 $timeout
15657
15658         $LCTL set_param -n $pages_per_rpc
15659         restore_lustre_params < $p
15660         rm -f $p
15661 }
15662 run_test 224c "Don't hang if one of md lost during large bulk RPC"
15663
15664 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
15665 test_225a () {
15666         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15667         if [ -z ${MDSSURVEY} ]; then
15668                 skip_env "mds-survey not found"
15669         fi
15670         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
15671                 skip "Need MDS version at least 2.2.51"
15672
15673         local mds=$(facet_host $SINGLEMDS)
15674         local target=$(do_nodes $mds 'lctl dl' |
15675                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
15676
15677         local cmd1="file_count=1000 thrhi=4"
15678         local cmd2="dir_count=2 layer=mdd stripe_count=0"
15679         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
15680         local cmd="$cmd1 $cmd2 $cmd3"
15681
15682         rm -f ${TMP}/mds_survey*
15683         echo + $cmd
15684         eval $cmd || error "mds-survey with zero-stripe failed"
15685         cat ${TMP}/mds_survey*
15686         rm -f ${TMP}/mds_survey*
15687 }
15688 run_test 225a "Metadata survey sanity with zero-stripe"
15689
15690 test_225b () {
15691         if [ -z ${MDSSURVEY} ]; then
15692                 skip_env "mds-survey not found"
15693         fi
15694         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
15695                 skip "Need MDS version at least 2.2.51"
15696         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15697         remote_mds_nodsh && skip "remote MDS with nodsh"
15698         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
15699                 skip_env "Need to mount OST to test"
15700         fi
15701
15702         local mds=$(facet_host $SINGLEMDS)
15703         local target=$(do_nodes $mds 'lctl dl' |
15704                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
15705
15706         local cmd1="file_count=1000 thrhi=4"
15707         local cmd2="dir_count=2 layer=mdd stripe_count=1"
15708         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
15709         local cmd="$cmd1 $cmd2 $cmd3"
15710
15711         rm -f ${TMP}/mds_survey*
15712         echo + $cmd
15713         eval $cmd || error "mds-survey with stripe_count failed"
15714         cat ${TMP}/mds_survey*
15715         rm -f ${TMP}/mds_survey*
15716 }
15717 run_test 225b "Metadata survey sanity with stripe_count = 1"
15718
15719 mcreate_path2fid () {
15720         local mode=$1
15721         local major=$2
15722         local minor=$3
15723         local name=$4
15724         local desc=$5
15725         local path=$DIR/$tdir/$name
15726         local fid
15727         local rc
15728         local fid_path
15729
15730         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
15731                 error "cannot create $desc"
15732
15733         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
15734         rc=$?
15735         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
15736
15737         fid_path=$($LFS fid2path $MOUNT $fid)
15738         rc=$?
15739         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
15740
15741         [ "$path" == "$fid_path" ] ||
15742                 error "fid2path returned $fid_path, expected $path"
15743
15744         echo "pass with $path and $fid"
15745 }
15746
15747 test_226a () {
15748         rm -rf $DIR/$tdir
15749         mkdir -p $DIR/$tdir
15750
15751         mcreate_path2fid 0010666 0 0 fifo "FIFO"
15752         mcreate_path2fid 0020666 1 3 null "character special file (null)"
15753         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
15754         mcreate_path2fid 0040666 0 0 dir "directory"
15755         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
15756         mcreate_path2fid 0100666 0 0 file "regular file"
15757         mcreate_path2fid 0120666 0 0 link "symbolic link"
15758         mcreate_path2fid 0140666 0 0 sock "socket"
15759 }
15760 run_test 226a "call path2fid and fid2path on files of all type"
15761
15762 test_226b () {
15763         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15764
15765         local MDTIDX=1
15766
15767         rm -rf $DIR/$tdir
15768         mkdir -p $DIR/$tdir
15769         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
15770                 error "create remote directory failed"
15771         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
15772         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
15773                                 "character special file (null)"
15774         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
15775                                 "character special file (no device)"
15776         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
15777         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
15778                                 "block special file (loop)"
15779         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
15780         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
15781         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
15782 }
15783 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
15784
15785 # LU-1299 Executing or running ldd on a truncated executable does not
15786 # cause an out-of-memory condition.
15787 test_227() {
15788         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15789         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
15790
15791         dd if=$(which date) of=$MOUNT/date bs=1k count=1
15792         chmod +x $MOUNT/date
15793
15794         $MOUNT/date > /dev/null
15795         ldd $MOUNT/date > /dev/null
15796         rm -f $MOUNT/date
15797 }
15798 run_test 227 "running truncated executable does not cause OOM"
15799
15800 # LU-1512 try to reuse idle OI blocks
15801 test_228a() {
15802         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15803         remote_mds_nodsh && skip "remote MDS with nodsh"
15804         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
15805
15806         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
15807         local myDIR=$DIR/$tdir
15808
15809         mkdir -p $myDIR
15810         #define OBD_FAIL_SEQ_EXHAUST             0x1002
15811         $LCTL set_param fail_loc=0x80001002
15812         createmany -o $myDIR/t- 10000
15813         $LCTL set_param fail_loc=0
15814         # The guard is current the largest FID holder
15815         touch $myDIR/guard
15816         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
15817                     tr -d '[')
15818         local IDX=$(($SEQ % 64))
15819
15820         do_facet $SINGLEMDS sync
15821         # Make sure journal flushed.
15822         sleep 6
15823         local blk1=$(do_facet $SINGLEMDS \
15824                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15825                      grep Blockcount | awk '{print $4}')
15826
15827         # Remove old files, some OI blocks will become idle.
15828         unlinkmany $myDIR/t- 10000
15829         # Create new files, idle OI blocks should be reused.
15830         createmany -o $myDIR/t- 2000
15831         do_facet $SINGLEMDS sync
15832         # Make sure journal flushed.
15833         sleep 6
15834         local blk2=$(do_facet $SINGLEMDS \
15835                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15836                      grep Blockcount | awk '{print $4}')
15837
15838         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
15839 }
15840 run_test 228a "try to reuse idle OI blocks"
15841
15842 test_228b() {
15843         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15844         remote_mds_nodsh && skip "remote MDS with nodsh"
15845         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
15846
15847         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
15848         local myDIR=$DIR/$tdir
15849
15850         mkdir -p $myDIR
15851         #define OBD_FAIL_SEQ_EXHAUST             0x1002
15852         $LCTL set_param fail_loc=0x80001002
15853         createmany -o $myDIR/t- 10000
15854         $LCTL set_param fail_loc=0
15855         # The guard is current the largest FID holder
15856         touch $myDIR/guard
15857         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
15858                     tr -d '[')
15859         local IDX=$(($SEQ % 64))
15860
15861         do_facet $SINGLEMDS sync
15862         # Make sure journal flushed.
15863         sleep 6
15864         local blk1=$(do_facet $SINGLEMDS \
15865                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15866                      grep Blockcount | awk '{print $4}')
15867
15868         # Remove old files, some OI blocks will become idle.
15869         unlinkmany $myDIR/t- 10000
15870
15871         # stop the MDT
15872         stop $SINGLEMDS || error "Fail to stop MDT."
15873         # remount the MDT
15874         start $SINGLEMDS $MDT_DEV $MDS_MOUNT_OPTS || error "Fail to start MDT."
15875
15876         df $MOUNT || error "Fail to df."
15877         # Create new files, idle OI blocks should be reused.
15878         createmany -o $myDIR/t- 2000
15879         do_facet $SINGLEMDS sync
15880         # Make sure journal flushed.
15881         sleep 6
15882         local blk2=$(do_facet $SINGLEMDS \
15883                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15884                      grep Blockcount | awk '{print $4}')
15885
15886         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
15887 }
15888 run_test 228b "idle OI blocks can be reused after MDT restart"
15889
15890 #LU-1881
15891 test_228c() {
15892         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15893         remote_mds_nodsh && skip "remote MDS with nodsh"
15894         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
15895
15896         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
15897         local myDIR=$DIR/$tdir
15898
15899         mkdir -p $myDIR
15900         #define OBD_FAIL_SEQ_EXHAUST             0x1002
15901         $LCTL set_param fail_loc=0x80001002
15902         # 20000 files can guarantee there are index nodes in the OI file
15903         createmany -o $myDIR/t- 20000
15904         $LCTL set_param fail_loc=0
15905         # The guard is current the largest FID holder
15906         touch $myDIR/guard
15907         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
15908                     tr -d '[')
15909         local IDX=$(($SEQ % 64))
15910
15911         do_facet $SINGLEMDS sync
15912         # Make sure journal flushed.
15913         sleep 6
15914         local blk1=$(do_facet $SINGLEMDS \
15915                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15916                      grep Blockcount | awk '{print $4}')
15917
15918         # Remove old files, some OI blocks will become idle.
15919         unlinkmany $myDIR/t- 20000
15920         rm -f $myDIR/guard
15921         # The OI file should become empty now
15922
15923         # Create new files, idle OI blocks should be reused.
15924         createmany -o $myDIR/t- 2000
15925         do_facet $SINGLEMDS sync
15926         # Make sure journal flushed.
15927         sleep 6
15928         local blk2=$(do_facet $SINGLEMDS \
15929                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15930                      grep Blockcount | awk '{print $4}')
15931
15932         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
15933 }
15934 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
15935
15936 test_229() { # LU-2482, LU-3448
15937         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15938         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
15939         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
15940                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
15941
15942         rm -f $DIR/$tfile
15943
15944         # Create a file with a released layout and stripe count 2.
15945         $MULTIOP $DIR/$tfile H2c ||
15946                 error "failed to create file with released layout"
15947
15948         $LFS getstripe -v $DIR/$tfile
15949
15950         local pattern=$($LFS getstripe -L $DIR/$tfile)
15951         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
15952
15953         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
15954                 error "getstripe"
15955         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
15956         stat $DIR/$tfile || error "failed to stat released file"
15957
15958         chown $RUNAS_ID $DIR/$tfile ||
15959                 error "chown $RUNAS_ID $DIR/$tfile failed"
15960
15961         chgrp $RUNAS_ID $DIR/$tfile ||
15962                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
15963
15964         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
15965         rm $DIR/$tfile || error "failed to remove released file"
15966 }
15967 run_test 229 "getstripe/stat/rm/attr changes work on released files"
15968
15969 test_230a() {
15970         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15971         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15972         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15973                 skip "Need MDS version at least 2.11.52"
15974
15975         local MDTIDX=1
15976
15977         test_mkdir $DIR/$tdir
15978         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
15979         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
15980         [ $mdt_idx -ne 0 ] &&
15981                 error "create local directory on wrong MDT $mdt_idx"
15982
15983         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
15984                         error "create remote directory failed"
15985         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
15986         [ $mdt_idx -ne $MDTIDX ] &&
15987                 error "create remote directory on wrong MDT $mdt_idx"
15988
15989         createmany -o $DIR/$tdir/test_230/t- 10 ||
15990                 error "create files on remote directory failed"
15991         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
15992         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
15993         rm -r $DIR/$tdir || error "unlink remote directory failed"
15994 }
15995 run_test 230a "Create remote directory and files under the remote directory"
15996
15997 test_230b() {
15998         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15999         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16000         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16001                 skip "Need MDS version at least 2.11.52"
16002
16003         local MDTIDX=1
16004         local mdt_index
16005         local i
16006         local file
16007         local pid
16008         local stripe_count
16009         local migrate_dir=$DIR/$tdir/migrate_dir
16010         local other_dir=$DIR/$tdir/other_dir
16011
16012         test_mkdir $DIR/$tdir
16013         test_mkdir -i0 -c1 $migrate_dir
16014         test_mkdir -i0 -c1 $other_dir
16015         for ((i=0; i<10; i++)); do
16016                 mkdir -p $migrate_dir/dir_${i}
16017                 createmany -o $migrate_dir/dir_${i}/f 10 ||
16018                         error "create files under remote dir failed $i"
16019         done
16020
16021         cp /etc/passwd $migrate_dir/$tfile
16022         cp /etc/passwd $other_dir/$tfile
16023         chattr +SAD $migrate_dir
16024         chattr +SAD $migrate_dir/$tfile
16025
16026         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
16027         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
16028         local old_dir_mode=$(stat -c%f $migrate_dir)
16029         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
16030
16031         mkdir -p $migrate_dir/dir_default_stripe2
16032         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
16033         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
16034
16035         mkdir -p $other_dir
16036         ln $migrate_dir/$tfile $other_dir/luna
16037         ln $migrate_dir/$tfile $migrate_dir/sofia
16038         ln $other_dir/$tfile $migrate_dir/david
16039         ln -s $migrate_dir/$tfile $other_dir/zachary
16040         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
16041         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
16042
16043         $LFS migrate -m $MDTIDX $migrate_dir ||
16044                 error "fails on migrating remote dir to MDT1"
16045
16046         echo "migratate to MDT1, then checking.."
16047         for ((i = 0; i < 10; i++)); do
16048                 for file in $(find $migrate_dir/dir_${i}); do
16049                         mdt_index=$($LFS getstripe -m $file)
16050                         [ $mdt_index == $MDTIDX ] ||
16051                                 error "$file is not on MDT${MDTIDX}"
16052                 done
16053         done
16054
16055         # the multiple link file should still in MDT0
16056         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
16057         [ $mdt_index == 0 ] ||
16058                 error "$file is not on MDT${MDTIDX}"
16059
16060         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
16061         [ "$old_dir_flag" = "$new_dir_flag" ] ||
16062                 error " expect $old_dir_flag get $new_dir_flag"
16063
16064         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
16065         [ "$old_file_flag" = "$new_file_flag" ] ||
16066                 error " expect $old_file_flag get $new_file_flag"
16067
16068         local new_dir_mode=$(stat -c%f $migrate_dir)
16069         [ "$old_dir_mode" = "$new_dir_mode" ] ||
16070                 error "expect mode $old_dir_mode get $new_dir_mode"
16071
16072         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
16073         [ "$old_file_mode" = "$new_file_mode" ] ||
16074                 error "expect mode $old_file_mode get $new_file_mode"
16075
16076         diff /etc/passwd $migrate_dir/$tfile ||
16077                 error "$tfile different after migration"
16078
16079         diff /etc/passwd $other_dir/luna ||
16080                 error "luna different after migration"
16081
16082         diff /etc/passwd $migrate_dir/sofia ||
16083                 error "sofia different after migration"
16084
16085         diff /etc/passwd $migrate_dir/david ||
16086                 error "david different after migration"
16087
16088         diff /etc/passwd $other_dir/zachary ||
16089                 error "zachary different after migration"
16090
16091         diff /etc/passwd $migrate_dir/${tfile}_ln ||
16092                 error "${tfile}_ln different after migration"
16093
16094         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
16095                 error "${tfile}_ln_other different after migration"
16096
16097         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
16098         [ $stripe_count = 2 ] ||
16099                 error "dir strpe_count $d != 2 after migration."
16100
16101         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
16102         [ $stripe_count = 2 ] ||
16103                 error "file strpe_count $d != 2 after migration."
16104
16105         #migrate back to MDT0
16106         MDTIDX=0
16107
16108         $LFS migrate -m $MDTIDX $migrate_dir ||
16109                 error "fails on migrating remote dir to MDT0"
16110
16111         echo "migrate back to MDT0, checking.."
16112         for file in $(find $migrate_dir); do
16113                 mdt_index=$($LFS getstripe -m $file)
16114                 [ $mdt_index == $MDTIDX ] ||
16115                         error "$file is not on MDT${MDTIDX}"
16116         done
16117
16118         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
16119         [ "$old_dir_flag" = "$new_dir_flag" ] ||
16120                 error " expect $old_dir_flag get $new_dir_flag"
16121
16122         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
16123         [ "$old_file_flag" = "$new_file_flag" ] ||
16124                 error " expect $old_file_flag get $new_file_flag"
16125
16126         local new_dir_mode=$(stat -c%f $migrate_dir)
16127         [ "$old_dir_mode" = "$new_dir_mode" ] ||
16128                 error "expect mode $old_dir_mode get $new_dir_mode"
16129
16130         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
16131         [ "$old_file_mode" = "$new_file_mode" ] ||
16132                 error "expect mode $old_file_mode get $new_file_mode"
16133
16134         diff /etc/passwd ${migrate_dir}/$tfile ||
16135                 error "$tfile different after migration"
16136
16137         diff /etc/passwd ${other_dir}/luna ||
16138                 error "luna different after migration"
16139
16140         diff /etc/passwd ${migrate_dir}/sofia ||
16141                 error "sofia different after migration"
16142
16143         diff /etc/passwd ${other_dir}/zachary ||
16144                 error "zachary different after migration"
16145
16146         diff /etc/passwd $migrate_dir/${tfile}_ln ||
16147                 error "${tfile}_ln different after migration"
16148
16149         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
16150                 error "${tfile}_ln_other different after migration"
16151
16152         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
16153         [ $stripe_count = 2 ] ||
16154                 error "dir strpe_count $d != 2 after migration."
16155
16156         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
16157         [ $stripe_count = 2 ] ||
16158                 error "file strpe_count $d != 2 after migration."
16159
16160         rm -rf $DIR/$tdir || error "rm dir failed after migration"
16161 }
16162 run_test 230b "migrate directory"
16163
16164 test_230c() {
16165         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16166         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16167         remote_mds_nodsh && skip "remote MDS with nodsh"
16168         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16169                 skip "Need MDS version at least 2.11.52"
16170
16171         local MDTIDX=1
16172         local total=3
16173         local mdt_index
16174         local file
16175         local migrate_dir=$DIR/$tdir/migrate_dir
16176
16177         #If migrating directory fails in the middle, all entries of
16178         #the directory is still accessiable.
16179         test_mkdir $DIR/$tdir
16180         test_mkdir -i0 -c1 $migrate_dir
16181         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
16182         stat $migrate_dir
16183         createmany -o $migrate_dir/f $total ||
16184                 error "create files under ${migrate_dir} failed"
16185
16186         # fail after migrating top dir, and this will fail only once, so the
16187         # first sub file migration will fail (currently f3), others succeed.
16188         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
16189         do_facet mds1 lctl set_param fail_loc=0x1801
16190         local t=$(ls $migrate_dir | wc -l)
16191         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
16192                 error "migrate should fail"
16193         local u=$(ls $migrate_dir | wc -l)
16194         [ "$u" == "$t" ] || error "$u != $t during migration"
16195
16196         # add new dir/file should succeed
16197         mkdir $migrate_dir/dir ||
16198                 error "mkdir failed under migrating directory"
16199         touch $migrate_dir/file ||
16200                 error "create file failed under migrating directory"
16201
16202         # add file with existing name should fail
16203         for file in $migrate_dir/f*; do
16204                 stat $file > /dev/null || error "stat $file failed"
16205                 $OPENFILE -f O_CREAT:O_EXCL $file &&
16206                         error "open(O_CREAT|O_EXCL) $file should fail"
16207                 $MULTIOP $file m && error "create $file should fail"
16208                 touch $DIR/$tdir/remote_dir/$tfile ||
16209                         error "touch $tfile failed"
16210                 ln $DIR/$tdir/remote_dir/$tfile $file &&
16211                         error "link $file should fail"
16212                 mdt_index=$($LFS getstripe -m $file)
16213                 if [ $mdt_index == 0 ]; then
16214                         # file failed to migrate is not allowed to rename to
16215                         mv $DIR/$tdir/remote_dir/$tfile $file &&
16216                                 error "rename to $file should fail"
16217                 else
16218                         mv $DIR/$tdir/remote_dir/$tfile $file ||
16219                                 error "rename to $file failed"
16220                 fi
16221                 echo hello >> $file || error "write $file failed"
16222         done
16223
16224         # resume migration with different options should fail
16225         $LFS migrate -m 0 $migrate_dir &&
16226                 error "migrate -m 0 $migrate_dir should fail"
16227
16228         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
16229                 error "migrate -c 2 $migrate_dir should fail"
16230
16231         # resume migration should succeed
16232         $LFS migrate -m $MDTIDX $migrate_dir ||
16233                 error "migrate $migrate_dir failed"
16234
16235         echo "Finish migration, then checking.."
16236         for file in $(find $migrate_dir); do
16237                 mdt_index=$($LFS getstripe -m $file)
16238                 [ $mdt_index == $MDTIDX ] ||
16239                         error "$file is not on MDT${MDTIDX}"
16240         done
16241
16242         rm -rf $DIR/$tdir || error "rm dir failed after migration"
16243 }
16244 run_test 230c "check directory accessiblity if migration failed"
16245
16246 test_230d() {
16247         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16248         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16249         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16250                 skip "Need MDS version at least 2.11.52"
16251         # LU-11235
16252         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
16253
16254         local migrate_dir=$DIR/$tdir/migrate_dir
16255         local old_index
16256         local new_index
16257         local old_count
16258         local new_count
16259         local new_hash
16260         local mdt_index
16261         local i
16262         local j
16263
16264         old_index=$((RANDOM % MDSCOUNT))
16265         old_count=$((MDSCOUNT - old_index))
16266         new_index=$((RANDOM % MDSCOUNT))
16267         new_count=$((MDSCOUNT - new_index))
16268         new_hash="all_char"
16269
16270         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
16271         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
16272
16273         test_mkdir $DIR/$tdir
16274         test_mkdir -i $old_index -c $old_count $migrate_dir
16275
16276         for ((i=0; i<100; i++)); do
16277                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
16278                 createmany -o $migrate_dir/dir_${i}/f 100 ||
16279                         error "create files under remote dir failed $i"
16280         done
16281
16282         echo -n "Migrate from MDT$old_index "
16283         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
16284         echo -n "to MDT$new_index"
16285         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
16286         echo
16287
16288         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
16289         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
16290                 error "migrate remote dir error"
16291
16292         echo "Finish migration, then checking.."
16293         for file in $(find $migrate_dir); do
16294                 mdt_index=$($LFS getstripe -m $file)
16295                 if [ $mdt_index -lt $new_index ] ||
16296                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
16297                         error "$file is on MDT$mdt_index"
16298                 fi
16299         done
16300
16301         rm -rf $DIR/$tdir || error "rm dir failed after migration"
16302 }
16303 run_test 230d "check migrate big directory"
16304
16305 test_230e() {
16306         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16307         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16308         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16309                 skip "Need MDS version at least 2.11.52"
16310
16311         local i
16312         local j
16313         local a_fid
16314         local b_fid
16315
16316         mkdir -p $DIR/$tdir
16317         mkdir $DIR/$tdir/migrate_dir
16318         mkdir $DIR/$tdir/other_dir
16319         touch $DIR/$tdir/migrate_dir/a
16320         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
16321         ls $DIR/$tdir/other_dir
16322
16323         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
16324                 error "migrate dir fails"
16325
16326         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
16327         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
16328
16329         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
16330         [ $mdt_index == 0 ] || error "a is not on MDT0"
16331
16332         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
16333                 error "migrate dir fails"
16334
16335         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
16336         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
16337
16338         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
16339         [ $mdt_index == 1 ] || error "a is not on MDT1"
16340
16341         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
16342         [ $mdt_index == 1 ] || error "b is not on MDT1"
16343
16344         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
16345         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
16346
16347         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
16348
16349         rm -rf $DIR/$tdir || error "rm dir failed after migration"
16350 }
16351 run_test 230e "migrate mulitple local link files"
16352
16353 test_230f() {
16354         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16355         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16356         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16357                 skip "Need MDS version at least 2.11.52"
16358
16359         local a_fid
16360         local ln_fid
16361
16362         mkdir -p $DIR/$tdir
16363         mkdir $DIR/$tdir/migrate_dir
16364         $LFS mkdir -i1 $DIR/$tdir/other_dir
16365         touch $DIR/$tdir/migrate_dir/a
16366         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
16367         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
16368         ls $DIR/$tdir/other_dir
16369
16370         # a should be migrated to MDT1, since no other links on MDT0
16371         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
16372                 error "#1 migrate dir fails"
16373         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
16374         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
16375         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
16376         [ $mdt_index == 1 ] || error "a is not on MDT1"
16377
16378         # a should stay on MDT1, because it is a mulitple link file
16379         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
16380                 error "#2 migrate dir fails"
16381         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
16382         [ $mdt_index == 1 ] || error "a is not on MDT1"
16383
16384         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
16385                 error "#3 migrate dir fails"
16386
16387         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
16388         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
16389         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
16390
16391         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
16392         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
16393
16394         # a should be migrated to MDT0, since no other links on MDT1
16395         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
16396                 error "#4 migrate dir fails"
16397         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
16398         [ $mdt_index == 0 ] || error "a is not on MDT0"
16399
16400         rm -rf $DIR/$tdir || error "rm dir failed after migration"
16401 }
16402 run_test 230f "migrate mulitple remote link files"
16403
16404 test_230g() {
16405         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16406         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16407         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16408                 skip "Need MDS version at least 2.11.52"
16409
16410         mkdir -p $DIR/$tdir/migrate_dir
16411
16412         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
16413                 error "migrating dir to non-exist MDT succeeds"
16414         true
16415 }
16416 run_test 230g "migrate dir to non-exist MDT"
16417
16418 test_230h() {
16419         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16420         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16421         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16422                 skip "Need MDS version at least 2.11.52"
16423
16424         local mdt_index
16425
16426         mkdir -p $DIR/$tdir/migrate_dir
16427
16428         $LFS migrate -m1 $DIR &&
16429                 error "migrating mountpoint1 should fail"
16430
16431         $LFS migrate -m1 $DIR/$tdir/.. &&
16432                 error "migrating mountpoint2 should fail"
16433
16434         # same as mv
16435         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
16436                 error "migrating $tdir/migrate_dir/.. should fail"
16437
16438         true
16439 }
16440 run_test 230h "migrate .. and root"
16441
16442 test_230i() {
16443         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16444         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16445         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16446                 skip "Need MDS version at least 2.11.52"
16447
16448         mkdir -p $DIR/$tdir/migrate_dir
16449
16450         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
16451                 error "migration fails with a tailing slash"
16452
16453         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
16454                 error "migration fails with two tailing slashes"
16455 }
16456 run_test 230i "lfs migrate -m tolerates trailing slashes"
16457
16458 test_230j() {
16459         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
16460         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16461                 skip "Need MDS version at least 2.11.52"
16462
16463         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
16464         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
16465                 error "create $tfile failed"
16466         cat /etc/passwd > $DIR/$tdir/$tfile
16467
16468         $LFS migrate -m 1 $DIR/$tdir
16469
16470         cmp /etc/passwd $DIR/$tdir/$tfile ||
16471                 error "DoM file mismatch after migration"
16472 }
16473 run_test 230j "DoM file data not changed after dir migration"
16474
16475 test_230k() {
16476         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
16477         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
16478                 skip "Need MDS version at least 2.11.56"
16479
16480         local total=20
16481         local files_on_starting_mdt=0
16482
16483         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
16484         $LFS getdirstripe $DIR/$tdir
16485         for i in $(seq $total); do
16486                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
16487                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
16488                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
16489         done
16490
16491         echo "$files_on_starting_mdt files on MDT0"
16492
16493         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
16494         $LFS getdirstripe $DIR/$tdir
16495
16496         files_on_starting_mdt=0
16497         for i in $(seq $total); do
16498                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
16499                         error "file $tfile.$i mismatch after migration"
16500                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
16501                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
16502         done
16503
16504         echo "$files_on_starting_mdt files on MDT1 after migration"
16505         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
16506
16507         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
16508         $LFS getdirstripe $DIR/$tdir
16509
16510         files_on_starting_mdt=0
16511         for i in $(seq $total); do
16512                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
16513                         error "file $tfile.$i mismatch after 2nd migration"
16514                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
16515                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
16516         done
16517
16518         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
16519         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
16520
16521         true
16522 }
16523 run_test 230k "file data not changed after dir migration"
16524
16525 test_230l() {
16526         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
16527         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
16528                 skip "Need MDS version at least 2.11.56"
16529
16530         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
16531         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
16532                 error "create files under remote dir failed $i"
16533         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
16534 }
16535 run_test 230l "readdir between MDTs won't crash"
16536
16537 test_231a()
16538 {
16539         # For simplicity this test assumes that max_pages_per_rpc
16540         # is the same across all OSCs
16541         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
16542         local bulk_size=$((max_pages * PAGE_SIZE))
16543         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
16544                                        head -n 1)
16545
16546         mkdir -p $DIR/$tdir
16547         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
16548                 error "failed to set stripe with -S ${brw_size}M option"
16549
16550         # clear the OSC stats
16551         $LCTL set_param osc.*.stats=0 &>/dev/null
16552         stop_writeback
16553
16554         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
16555         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
16556                 oflag=direct &>/dev/null || error "dd failed"
16557
16558         sync; sleep 1; sync # just to be safe
16559         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
16560         if [ x$nrpcs != "x1" ]; then
16561                 $LCTL get_param osc.*.stats
16562                 error "found $nrpcs ost_write RPCs, not 1 as expected"
16563         fi
16564
16565         start_writeback
16566         # Drop the OSC cache, otherwise we will read from it
16567         cancel_lru_locks osc
16568
16569         # clear the OSC stats
16570         $LCTL set_param osc.*.stats=0 &>/dev/null
16571
16572         # Client reads $bulk_size.
16573         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
16574                 iflag=direct &>/dev/null || error "dd failed"
16575
16576         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
16577         if [ x$nrpcs != "x1" ]; then
16578                 $LCTL get_param osc.*.stats
16579                 error "found $nrpcs ost_read RPCs, not 1 as expected"
16580         fi
16581 }
16582 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
16583
16584 test_231b() {
16585         mkdir -p $DIR/$tdir
16586         local i
16587         for i in {0..1023}; do
16588                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
16589                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
16590                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
16591         done
16592         sync
16593 }
16594 run_test 231b "must not assert on fully utilized OST request buffer"
16595
16596 test_232a() {
16597         mkdir -p $DIR/$tdir
16598         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
16599
16600         #define OBD_FAIL_LDLM_OST_LVB            0x31c
16601         do_facet ost1 $LCTL set_param fail_loc=0x31c
16602
16603         # ignore dd failure
16604         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
16605
16606         do_facet ost1 $LCTL set_param fail_loc=0
16607         umount_client $MOUNT || error "umount failed"
16608         mount_client $MOUNT || error "mount failed"
16609         stop ost1 || error "cannot stop ost1"
16610         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
16611 }
16612 run_test 232a "failed lock should not block umount"
16613
16614 test_232b() {
16615         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
16616                 skip "Need MDS version at least 2.10.58"
16617
16618         mkdir -p $DIR/$tdir
16619         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
16620         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
16621         sync
16622         cancel_lru_locks osc
16623
16624         #define OBD_FAIL_LDLM_OST_LVB            0x31c
16625         do_facet ost1 $LCTL set_param fail_loc=0x31c
16626
16627         # ignore failure
16628         $LFS data_version $DIR/$tdir/$tfile || true
16629
16630         do_facet ost1 $LCTL set_param fail_loc=0
16631         umount_client $MOUNT || error "umount failed"
16632         mount_client $MOUNT || error "mount failed"
16633         stop ost1 || error "cannot stop ost1"
16634         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
16635 }
16636 run_test 232b "failed data version lock should not block umount"
16637
16638 test_233a() {
16639         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
16640                 skip "Need MDS version at least 2.3.64"
16641         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
16642
16643         local fid=$($LFS path2fid $MOUNT)
16644
16645         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
16646                 error "cannot access $MOUNT using its FID '$fid'"
16647 }
16648 run_test 233a "checking that OBF of the FS root succeeds"
16649
16650 test_233b() {
16651         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
16652                 skip "Need MDS version at least 2.5.90"
16653         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
16654
16655         local fid=$($LFS path2fid $MOUNT/.lustre)
16656
16657         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
16658                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
16659
16660         fid=$($LFS path2fid $MOUNT/.lustre/fid)
16661         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
16662                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
16663 }
16664 run_test 233b "checking that OBF of the FS .lustre succeeds"
16665
16666 test_234() {
16667         local p="$TMP/sanityN-$TESTNAME.parameters"
16668         save_lustre_params client "llite.*.xattr_cache" > $p
16669         lctl set_param llite.*.xattr_cache 1 ||
16670                 skip_env "xattr cache is not supported"
16671
16672         mkdir -p $DIR/$tdir || error "mkdir failed"
16673         touch $DIR/$tdir/$tfile || error "touch failed"
16674         # OBD_FAIL_LLITE_XATTR_ENOMEM
16675         $LCTL set_param fail_loc=0x1405
16676         getfattr -n user.attr $DIR/$tdir/$tfile &&
16677                 error "getfattr should have failed with ENOMEM"
16678         $LCTL set_param fail_loc=0x0
16679         rm -rf $DIR/$tdir
16680
16681         restore_lustre_params < $p
16682         rm -f $p
16683 }
16684 run_test 234 "xattr cache should not crash on ENOMEM"
16685
16686 test_235() {
16687         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
16688                 skip "Need MDS version at least 2.4.52"
16689
16690         flock_deadlock $DIR/$tfile
16691         local RC=$?
16692         case $RC in
16693                 0)
16694                 ;;
16695                 124) error "process hangs on a deadlock"
16696                 ;;
16697                 *) error "error executing flock_deadlock $DIR/$tfile"
16698                 ;;
16699         esac
16700 }
16701 run_test 235 "LU-1715: flock deadlock detection does not work properly"
16702
16703 #LU-2935
16704 test_236() {
16705         check_swap_layouts_support
16706
16707         local ref1=/etc/passwd
16708         local ref2=/etc/group
16709         local file1=$DIR/$tdir/f1
16710         local file2=$DIR/$tdir/f2
16711
16712         test_mkdir -c1 $DIR/$tdir
16713         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
16714         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
16715         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
16716         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
16717         local fd=$(free_fd)
16718         local cmd="exec $fd<>$file2"
16719         eval $cmd
16720         rm $file2
16721         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
16722                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
16723         cmd="exec $fd>&-"
16724         eval $cmd
16725         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
16726
16727         #cleanup
16728         rm -rf $DIR/$tdir
16729 }
16730 run_test 236 "Layout swap on open unlinked file"
16731
16732 # LU-4659 linkea consistency
16733 test_238() {
16734         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
16735                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
16736                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
16737                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
16738
16739         touch $DIR/$tfile
16740         ln $DIR/$tfile $DIR/$tfile.lnk
16741         touch $DIR/$tfile.new
16742         mv $DIR/$tfile.new $DIR/$tfile
16743         local fid1=$($LFS path2fid $DIR/$tfile)
16744         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
16745         local path1=$($LFS fid2path $FSNAME "$fid1")
16746         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
16747         local path2=$($LFS fid2path $FSNAME "$fid2")
16748         [ $tfile.lnk == $path2 ] ||
16749                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
16750         rm -f $DIR/$tfile*
16751 }
16752 run_test 238 "Verify linkea consistency"
16753
16754 test_239A() { # was test_239
16755         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
16756                 skip "Need MDS version at least 2.5.60"
16757
16758         local list=$(comma_list $(mdts_nodes))
16759
16760         mkdir -p $DIR/$tdir
16761         createmany -o $DIR/$tdir/f- 5000
16762         unlinkmany $DIR/$tdir/f- 5000
16763         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
16764                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
16765         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
16766                         osp.*MDT*.sync_in_flight" | calc_sum)
16767         [ "$changes" -eq 0 ] || error "$changes not synced"
16768 }
16769 run_test 239A "osp_sync test"
16770
16771 test_239a() { #LU-5297
16772         remote_mds_nodsh && skip "remote MDS with nodsh"
16773
16774         touch $DIR/$tfile
16775         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
16776         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
16777         chgrp $RUNAS_GID $DIR/$tfile
16778         wait_delete_completed
16779 }
16780 run_test 239a "process invalid osp sync record correctly"
16781
16782 test_239b() { #LU-5297
16783         remote_mds_nodsh && skip "remote MDS with nodsh"
16784
16785         touch $DIR/$tfile1
16786         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
16787         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
16788         chgrp $RUNAS_GID $DIR/$tfile1
16789         wait_delete_completed
16790         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
16791         touch $DIR/$tfile2
16792         chgrp $RUNAS_GID $DIR/$tfile2
16793         wait_delete_completed
16794 }
16795 run_test 239b "process osp sync record with ENOMEM error correctly"
16796
16797 test_240() {
16798         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16799         remote_mds_nodsh && skip "remote MDS with nodsh"
16800
16801         mkdir -p $DIR/$tdir
16802
16803         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
16804                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
16805         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
16806                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
16807
16808         umount_client $MOUNT || error "umount failed"
16809         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
16810         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
16811         mount_client $MOUNT || error "failed to mount client"
16812
16813         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
16814         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
16815 }
16816 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
16817
16818 test_241_bio() {
16819         local count=$1
16820         local bsize=$2
16821
16822         for LOOP in $(seq $count); do
16823                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
16824                 cancel_lru_locks $OSC || true
16825         done
16826 }
16827
16828 test_241_dio() {
16829         local count=$1
16830         local bsize=$2
16831
16832         for LOOP in $(seq $1); do
16833                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
16834                         2>/dev/null
16835         done
16836 }
16837
16838 test_241a() { # was test_241
16839         local bsize=$PAGE_SIZE
16840
16841         (( bsize < 40960 )) && bsize=40960
16842         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
16843         ls -la $DIR/$tfile
16844         cancel_lru_locks $OSC
16845         test_241_bio 1000 $bsize &
16846         PID=$!
16847         test_241_dio 1000 $bsize
16848         wait $PID
16849 }
16850 run_test 241a "bio vs dio"
16851
16852 test_241b() {
16853         local bsize=$PAGE_SIZE
16854
16855         (( bsize < 40960 )) && bsize=40960
16856         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
16857         ls -la $DIR/$tfile
16858         test_241_dio 1000 $bsize &
16859         PID=$!
16860         test_241_dio 1000 $bsize
16861         wait $PID
16862 }
16863 run_test 241b "dio vs dio"
16864
16865 test_242() {
16866         remote_mds_nodsh && skip "remote MDS with nodsh"
16867
16868         mkdir -p $DIR/$tdir
16869         touch $DIR/$tdir/$tfile
16870
16871         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
16872         do_facet mds1 lctl set_param fail_loc=0x105
16873         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
16874
16875         do_facet mds1 lctl set_param fail_loc=0
16876         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
16877 }
16878 run_test 242 "mdt_readpage failure should not cause directory unreadable"
16879
16880 test_243()
16881 {
16882         test_mkdir $DIR/$tdir
16883         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
16884 }
16885 run_test 243 "various group lock tests"
16886
16887 test_244a()
16888 {
16889         test_mkdir $DIR/$tdir
16890         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
16891         sendfile_grouplock $DIR/$tdir/$tfile || \
16892                 error "sendfile+grouplock failed"
16893         rm -rf $DIR/$tdir
16894 }
16895 run_test 244a "sendfile with group lock tests"
16896
16897 test_244b()
16898 {
16899         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
16900
16901         local threads=50
16902         local size=$((1024*1024))
16903
16904         test_mkdir $DIR/$tdir
16905         for i in $(seq 1 $threads); do
16906                 local file=$DIR/$tdir/file_$((i / 10))
16907                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
16908                 local pids[$i]=$!
16909         done
16910         for i in $(seq 1 $threads); do
16911                 wait ${pids[$i]}
16912         done
16913 }
16914 run_test 244b "multi-threaded write with group lock"
16915
16916 test_245() {
16917         local flagname="multi_mod_rpcs"
16918         local connect_data_name="max_mod_rpcs"
16919         local out
16920
16921         # check if multiple modify RPCs flag is set
16922         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
16923                 grep "connect_flags:")
16924         echo "$out"
16925
16926         echo "$out" | grep -qw $flagname
16927         if [ $? -ne 0 ]; then
16928                 echo "connect flag $flagname is not set"
16929                 return
16930         fi
16931
16932         # check if multiple modify RPCs data is set
16933         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
16934         echo "$out"
16935
16936         echo "$out" | grep -qw $connect_data_name ||
16937                 error "import should have connect data $connect_data_name"
16938 }
16939 run_test 245 "check mdc connection flag/data: multiple modify RPCs"
16940
16941 test_246() { # LU-7371
16942         remote_ost_nodsh && skip "remote OST with nodsh"
16943         [ $OST1_VERSION -lt $(version_code 2.7.62) ] &&
16944                 skip "Need OST version >= 2.7.62"
16945
16946         do_facet ost1 $LCTL set_param fail_val=4095
16947 #define OBD_FAIL_OST_READ_SIZE          0x234
16948         do_facet ost1 $LCTL set_param fail_loc=0x234
16949         $LFS setstripe $DIR/$tfile -i 0 -c 1
16950         dd if=/dev/zero of=$DIR/$tfile bs=4095 count=1 > /dev/null 2>&1
16951         cancel_lru_locks $FSNAME-OST0000
16952         dd if=$DIR/$tfile of=/dev/null bs=1048576 || error "Read failed"
16953 }
16954 run_test 246 "Read file of size 4095 should return right length"
16955
16956 cleanup_247() {
16957         local submount=$1
16958
16959         trap 0
16960         umount_client $submount
16961         rmdir $submount
16962 }
16963
16964 test_247a() {
16965         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
16966                 grep -q subtree ||
16967                 skip_env "Fileset feature is not supported"
16968
16969         local submount=${MOUNT}_$tdir
16970
16971         mkdir $MOUNT/$tdir
16972         mkdir -p $submount || error "mkdir $submount failed"
16973         FILESET="$FILESET/$tdir" mount_client $submount ||
16974                 error "mount $submount failed"
16975         trap "cleanup_247 $submount" EXIT
16976         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
16977         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
16978                 error "read $MOUNT/$tdir/$tfile failed"
16979         cleanup_247 $submount
16980 }
16981 run_test 247a "mount subdir as fileset"
16982
16983 test_247b() {
16984         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
16985                 skip_env "Fileset feature is not supported"
16986
16987         local submount=${MOUNT}_$tdir
16988
16989         rm -rf $MOUNT/$tdir
16990         mkdir -p $submount || error "mkdir $submount failed"
16991         SKIP_FILESET=1
16992         FILESET="$FILESET/$tdir" mount_client $submount &&
16993                 error "mount $submount should fail"
16994         rmdir $submount
16995 }
16996 run_test 247b "mount subdir that dose not exist"
16997
16998 test_247c() {
16999         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
17000                 skip_env "Fileset feature is not supported"
17001
17002         local submount=${MOUNT}_$tdir
17003
17004         mkdir -p $MOUNT/$tdir/dir1
17005         mkdir -p $submount || error "mkdir $submount failed"
17006         trap "cleanup_247 $submount" EXIT
17007         FILESET="$FILESET/$tdir" mount_client $submount ||
17008                 error "mount $submount failed"
17009         local fid=$($LFS path2fid $MOUNT/)
17010         $LFS fid2path $submount $fid && error "fid2path should fail"
17011         cleanup_247 $submount
17012 }
17013 run_test 247c "running fid2path outside root"
17014
17015 test_247d() {
17016         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
17017                 skip "Fileset feature is not supported"
17018
17019         local submount=${MOUNT}_$tdir
17020
17021         mkdir -p $MOUNT/$tdir/dir1
17022         mkdir -p $submount || error "mkdir $submount failed"
17023         FILESET="$FILESET/$tdir" mount_client $submount ||
17024                 error "mount $submount failed"
17025         trap "cleanup_247 $submount" EXIT
17026         local fid=$($LFS path2fid $submount/dir1)
17027         $LFS fid2path $submount $fid || error "fid2path should succeed"
17028         cleanup_247 $submount
17029 }
17030 run_test 247d "running fid2path inside root"
17031
17032 # LU-8037
17033 test_247e() {
17034         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
17035                 grep -q subtree ||
17036                 skip "Fileset feature is not supported"
17037
17038         local submount=${MOUNT}_$tdir
17039
17040         mkdir $MOUNT/$tdir
17041         mkdir -p $submount || error "mkdir $submount failed"
17042         FILESET="$FILESET/.." mount_client $submount &&
17043                 error "mount $submount should fail"
17044         rmdir $submount
17045 }
17046 run_test 247e "mount .. as fileset"
17047
17048 test_248() {
17049         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
17050         [ -z "$fast_read_sav" ] && skip "no fast read support"
17051
17052         # create a large file for fast read verification
17053         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
17054
17055         # make sure the file is created correctly
17056         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
17057                 { rm -f $DIR/$tfile; skip "file creation error"; }
17058
17059         echo "Test 1: verify that fast read is 4 times faster on cache read"
17060
17061         # small read with fast read enabled
17062         $LCTL set_param -n llite.*.fast_read=1
17063         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
17064                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
17065                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
17066         # small read with fast read disabled
17067         $LCTL set_param -n llite.*.fast_read=0
17068         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
17069                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
17070                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
17071
17072         # verify that fast read is 4 times faster for cache read
17073         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
17074                 error_not_in_vm "fast read was not 4 times faster: " \
17075                            "$t_fast vs $t_slow"
17076
17077         echo "Test 2: verify the performance between big and small read"
17078         $LCTL set_param -n llite.*.fast_read=1
17079
17080         # 1k non-cache read
17081         cancel_lru_locks osc
17082         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
17083                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
17084                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
17085
17086         # 1M non-cache read
17087         cancel_lru_locks osc
17088         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
17089                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
17090                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
17091
17092         # verify that big IO is not 4 times faster than small IO
17093         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
17094                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
17095
17096         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
17097         rm -f $DIR/$tfile
17098 }
17099 run_test 248 "fast read verification"
17100
17101 test_249() { # LU-7890
17102         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
17103                 skip "Need at least version 2.8.54"
17104
17105         rm -f $DIR/$tfile
17106         $LFS setstripe -c 1 $DIR/$tfile
17107         # Offset 2T == 4k * 512M
17108         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
17109                 error "dd to 2T offset failed"
17110 }
17111 run_test 249 "Write above 2T file size"
17112
17113 test_250() {
17114         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
17115          && skip "no 16TB file size limit on ZFS"
17116
17117         $LFS setstripe -c 1 $DIR/$tfile
17118         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
17119         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
17120         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
17121         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
17122                 conv=notrunc,fsync && error "append succeeded"
17123         return 0
17124 }
17125 run_test 250 "Write above 16T limit"
17126
17127 test_251() {
17128         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
17129
17130         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
17131         #Skip once - writing the first stripe will succeed
17132         $LCTL set_param fail_loc=0xa0001407 fail_val=1
17133         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
17134                 error "short write happened"
17135
17136         $LCTL set_param fail_loc=0xa0001407 fail_val=1
17137         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
17138                 error "short read happened"
17139
17140         rm -f $DIR/$tfile
17141 }
17142 run_test 251 "Handling short read and write correctly"
17143
17144 test_252() {
17145         remote_mds_nodsh && skip "remote MDS with nodsh"
17146         remote_ost_nodsh && skip "remote OST with nodsh"
17147         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
17148                 skip_env "ldiskfs only test"
17149         fi
17150
17151         local tgt
17152         local dev
17153         local out
17154         local uuid
17155         local num
17156         local gen
17157
17158         # check lr_reader on OST0000
17159         tgt=ost1
17160         dev=$(facet_device $tgt)
17161         out=$(do_facet $tgt $LR_READER $dev)
17162         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
17163         echo "$out"
17164         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
17165         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
17166                 error "Invalid uuid returned by $LR_READER on target $tgt"
17167         echo -e "uuid returned by $LR_READER is '$uuid'\n"
17168
17169         # check lr_reader -c on MDT0000
17170         tgt=mds1
17171         dev=$(facet_device $tgt)
17172         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
17173                 skip "$LR_READER does not support additional options"
17174         fi
17175         out=$(do_facet $tgt $LR_READER -c $dev)
17176         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
17177         echo "$out"
17178         num=$(echo "$out" | grep -c "mdtlov")
17179         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
17180                 error "Invalid number of mdtlov clients returned by $LR_READER"
17181         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
17182
17183         # check lr_reader -cr on MDT0000
17184         out=$(do_facet $tgt $LR_READER -cr $dev)
17185         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
17186         echo "$out"
17187         echo "$out" | grep -q "^reply_data:$" ||
17188                 error "$LR_READER should have returned 'reply_data' section"
17189         num=$(echo "$out" | grep -c "client_generation")
17190         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
17191 }
17192 run_test 252 "check lr_reader tool"
17193
17194 test_253() {
17195         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17196         remote_mds_nodsh && skip "remote MDS with nodsh"
17197         remote_mgs_nodsh && skip "remote MGS with nodsh"
17198
17199         local ostidx=0
17200         local rc=0
17201         local ost_name=$(ostname_from_index $ostidx)
17202
17203         # on the mdt's osc
17204         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
17205         do_facet $SINGLEMDS $LCTL get_param -n \
17206                 osp.$mdtosc_proc1.reserved_mb_high ||
17207                 skip  "remote MDS does not support reserved_mb_high"
17208
17209         rm -rf $DIR/$tdir
17210         wait_mds_ost_sync
17211         wait_delete_completed
17212         mkdir $DIR/$tdir
17213
17214         if ! combined_mgs_mds ; then
17215                 mount_mgs_client
17216         fi
17217         pool_add $TESTNAME || error "Pool creation failed"
17218         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
17219
17220         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
17221                 error "Setstripe failed"
17222
17223         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
17224
17225         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
17226                     grep "watermarks")
17227         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
17228
17229         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
17230                         osp.$mdtosc_proc1.prealloc_status)
17231         echo "prealloc_status $oa_status"
17232
17233         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
17234                 error "File creation should fail"
17235
17236         #object allocation was stopped, but we still able to append files
17237         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
17238                 oflag=append || error "Append failed"
17239
17240         rm -f $DIR/$tdir/$tfile.0
17241
17242         # For this test, we want to delete the files we created to go out of
17243         # space but leave the watermark, so we remain nearly out of space
17244         ost_watermarks_enospc_delete_files $tfile $ostidx
17245
17246         wait_delete_completed
17247
17248         sleep_maxage
17249
17250         for i in $(seq 10 12); do
17251                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
17252                         2>/dev/null || error "File creation failed after rm"
17253         done
17254
17255         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
17256                         osp.$mdtosc_proc1.prealloc_status)
17257         echo "prealloc_status $oa_status"
17258
17259         if (( oa_status != 0 )); then
17260                 error "Object allocation still disable after rm"
17261         fi
17262
17263         if ! combined_mgs_mds ; then
17264                 umount_mgs_client
17265         fi
17266 }
17267 run_test 253 "Check object allocation limit"
17268
17269 test_254() {
17270         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17271         remote_mds_nodsh && skip "remote MDS with nodsh"
17272         do_facet $SINGLEMDS $LCTL get_param -n mdd.$MDT0.changelog_size ||
17273                 skip "MDS does not support changelog_size"
17274
17275         local cl_user
17276         local MDT0=$(facet_svc $SINGLEMDS)
17277
17278         changelog_register || error "changelog_register failed"
17279
17280         changelog_clear 0 || error "changelog_clear failed"
17281
17282         local size1=$(do_facet $SINGLEMDS \
17283                       $LCTL get_param -n mdd.$MDT0.changelog_size)
17284         echo "Changelog size $size1"
17285
17286         rm -rf $DIR/$tdir
17287         $LFS mkdir -i 0 $DIR/$tdir
17288         # change something
17289         mkdir -p $DIR/$tdir/pics/2008/zachy
17290         touch $DIR/$tdir/pics/2008/zachy/timestamp
17291         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
17292         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
17293         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
17294         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
17295         rm $DIR/$tdir/pics/desktop.jpg
17296
17297         local size2=$(do_facet $SINGLEMDS \
17298                       $LCTL get_param -n mdd.$MDT0.changelog_size)
17299         echo "Changelog size after work $size2"
17300
17301         (( $size2 > $size1 )) ||
17302                 error "new Changelog size=$size2 less than old size=$size1"
17303 }
17304 run_test 254 "Check changelog size"
17305
17306 ladvise_no_type()
17307 {
17308         local type=$1
17309         local file=$2
17310
17311         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
17312                 awk -F: '{print $2}' | grep $type > /dev/null
17313         if [ $? -ne 0 ]; then
17314                 return 0
17315         fi
17316         return 1
17317 }
17318
17319 ladvise_no_ioctl()
17320 {
17321         local file=$1
17322
17323         lfs ladvise -a willread $file > /dev/null 2>&1
17324         if [ $? -eq 0 ]; then
17325                 return 1
17326         fi
17327
17328         lfs ladvise -a willread $file 2>&1 |
17329                 grep "Inappropriate ioctl for device" > /dev/null
17330         if [ $? -eq 0 ]; then
17331                 return 0
17332         fi
17333         return 1
17334 }
17335
17336 percent() {
17337         bc <<<"scale=2; ($1 - $2) * 100 / $2"
17338 }
17339
17340 # run a random read IO workload
17341 # usage: random_read_iops <filename> <filesize> <iosize>
17342 random_read_iops() {
17343         local file=$1
17344         local fsize=$2
17345         local iosize=${3:-4096}
17346
17347         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
17348                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
17349 }
17350
17351 drop_file_oss_cache() {
17352         local file="$1"
17353         local nodes="$2"
17354
17355         $LFS ladvise -a dontneed $file 2>/dev/null ||
17356                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
17357 }
17358
17359 ladvise_willread_performance()
17360 {
17361         local repeat=10
17362         local average_origin=0
17363         local average_cache=0
17364         local average_ladvise=0
17365
17366         for ((i = 1; i <= $repeat; i++)); do
17367                 echo "Iter $i/$repeat: reading without willread hint"
17368                 cancel_lru_locks osc
17369                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
17370                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
17371                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
17372                 average_origin=$(bc <<<"$average_origin + $speed_origin")
17373
17374                 cancel_lru_locks osc
17375                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
17376                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
17377                 average_cache=$(bc <<<"$average_cache + $speed_cache")
17378
17379                 cancel_lru_locks osc
17380                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
17381                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
17382                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
17383                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
17384                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
17385         done
17386         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
17387         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
17388         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
17389
17390         speedup_cache=$(percent $average_cache $average_origin)
17391         speedup_ladvise=$(percent $average_ladvise $average_origin)
17392
17393         echo "Average uncached read: $average_origin"
17394         echo "Average speedup with OSS cached read: " \
17395                 "$average_cache = +$speedup_cache%"
17396         echo "Average speedup with ladvise willread: " \
17397                 "$average_ladvise = +$speedup_ladvise%"
17398
17399         local lowest_speedup=20
17400         if [ ${average_cache%.*} -lt $lowest_speedup ]; then
17401                 echo "Speedup with OSS cached read less than $lowest_speedup%," \
17402                         "got $average_cache%. Skipping ladvise willread check."
17403                 return 0
17404         fi
17405
17406         # the test won't work on ZFS until it supports 'ladvise dontneed', but
17407         # it is still good to run until then to exercise 'ladvise willread'
17408         ! $LFS ladvise -a dontneed $DIR/$tfile &&
17409                 [ "$ost1_FSTYPE" = "zfs" ] &&
17410                 echo "osd-zfs does not support dontneed or drop_caches" &&
17411                 return 0
17412
17413         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
17414         [ ${average_ladvise%.*} -gt $lowest_speedup ] ||
17415                 error_not_in_vm "Speedup with willread is less than " \
17416                         "$lowest_speedup%, got $average_ladvise%"
17417 }
17418
17419 test_255a() {
17420         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
17421                 skip "lustre < 2.8.54 does not support ladvise "
17422         remote_ost_nodsh && skip "remote OST with nodsh"
17423
17424         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
17425
17426         ladvise_no_type willread $DIR/$tfile &&
17427                 skip "willread ladvise is not supported"
17428
17429         ladvise_no_ioctl $DIR/$tfile &&
17430                 skip "ladvise ioctl is not supported"
17431
17432         local size_mb=100
17433         local size=$((size_mb * 1048576))
17434         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
17435                 error "dd to $DIR/$tfile failed"
17436
17437         lfs ladvise -a willread $DIR/$tfile ||
17438                 error "Ladvise failed with no range argument"
17439
17440         lfs ladvise -a willread -s 0 $DIR/$tfile ||
17441                 error "Ladvise failed with no -l or -e argument"
17442
17443         lfs ladvise -a willread -e 1 $DIR/$tfile ||
17444                 error "Ladvise failed with only -e argument"
17445
17446         lfs ladvise -a willread -l 1 $DIR/$tfile ||
17447                 error "Ladvise failed with only -l argument"
17448
17449         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
17450                 error "End offset should not be smaller than start offset"
17451
17452         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
17453                 error "End offset should not be equal to start offset"
17454
17455         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
17456                 error "Ladvise failed with overflowing -s argument"
17457
17458         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
17459                 error "Ladvise failed with overflowing -e argument"
17460
17461         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
17462                 error "Ladvise failed with overflowing -l argument"
17463
17464         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
17465                 error "Ladvise succeeded with conflicting -l and -e arguments"
17466
17467         echo "Synchronous ladvise should wait"
17468         local delay=4
17469 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
17470         do_nodes $(comma_list $(osts_nodes)) \
17471                 $LCTL set_param fail_val=$delay fail_loc=0x237
17472
17473         local start_ts=$SECONDS
17474         lfs ladvise -a willread $DIR/$tfile ||
17475                 error "Ladvise failed with no range argument"
17476         local end_ts=$SECONDS
17477         local inteval_ts=$((end_ts - start_ts))
17478
17479         if [ $inteval_ts -lt $(($delay - 1)) ]; then
17480                 error "Synchronous advice didn't wait reply"
17481         fi
17482
17483         echo "Asynchronous ladvise shouldn't wait"
17484         local start_ts=$SECONDS
17485         lfs ladvise -a willread -b $DIR/$tfile ||
17486                 error "Ladvise failed with no range argument"
17487         local end_ts=$SECONDS
17488         local inteval_ts=$((end_ts - start_ts))
17489
17490         if [ $inteval_ts -gt $(($delay / 2)) ]; then
17491                 error "Asynchronous advice blocked"
17492         fi
17493
17494         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
17495         ladvise_willread_performance
17496 }
17497 run_test 255a "check 'lfs ladvise -a willread'"
17498
17499 facet_meminfo() {
17500         local facet=$1
17501         local info=$2
17502
17503         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
17504 }
17505
17506 test_255b() {
17507         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
17508                 skip "lustre < 2.8.54 does not support ladvise "
17509         remote_ost_nodsh && skip "remote OST with nodsh"
17510
17511         lfs setstripe -c 1 -i 0 $DIR/$tfile
17512
17513         ladvise_no_type dontneed $DIR/$tfile &&
17514                 skip "dontneed ladvise is not supported"
17515
17516         ladvise_no_ioctl $DIR/$tfile &&
17517                 skip "ladvise ioctl is not supported"
17518
17519         ! $LFS ladvise -a dontneed $DIR/$tfile &&
17520                 [ "$ost1_FSTYPE" = "zfs" ] &&
17521                 skip "zfs-osd does not support 'ladvise dontneed'"
17522
17523         local size_mb=100
17524         local size=$((size_mb * 1048576))
17525         # In order to prevent disturbance of other processes, only check 3/4
17526         # of the memory usage
17527         local kibibytes=$((size_mb * 1024 * 3 / 4))
17528
17529         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
17530                 error "dd to $DIR/$tfile failed"
17531
17532         #force write to complete before dropping OST cache & checking memory
17533         sync
17534
17535         local total=$(facet_meminfo ost1 MemTotal)
17536         echo "Total memory: $total KiB"
17537
17538         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
17539         local before_read=$(facet_meminfo ost1 Cached)
17540         echo "Cache used before read: $before_read KiB"
17541
17542         lfs ladvise -a willread $DIR/$tfile ||
17543                 error "Ladvise willread failed"
17544         local after_read=$(facet_meminfo ost1 Cached)
17545         echo "Cache used after read: $after_read KiB"
17546
17547         lfs ladvise -a dontneed $DIR/$tfile ||
17548                 error "Ladvise dontneed again failed"
17549         local no_read=$(facet_meminfo ost1 Cached)
17550         echo "Cache used after dontneed ladvise: $no_read KiB"
17551
17552         if [ $total -lt $((before_read + kibibytes)) ]; then
17553                 echo "Memory is too small, abort checking"
17554                 return 0
17555         fi
17556
17557         if [ $((before_read + kibibytes)) -gt $after_read ]; then
17558                 error "Ladvise willread should use more memory" \
17559                         "than $kibibytes KiB"
17560         fi
17561
17562         if [ $((no_read + kibibytes)) -gt $after_read ]; then
17563                 error "Ladvise dontneed should release more memory" \
17564                         "than $kibibytes KiB"
17565         fi
17566 }
17567 run_test 255b "check 'lfs ladvise -a dontneed'"
17568
17569 test_255c() {
17570         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
17571                 skip "lustre < 2.10.53 does not support lockahead"
17572
17573         local count
17574         local new_count
17575         local difference
17576         local i
17577         local rc
17578
17579         test_mkdir -p $DIR/$tdir
17580         $LFS setstripe -i 0 -c 1 $DIR/$tdir
17581
17582         #test 10 returns only success/failure
17583         i=10
17584         lockahead_test -d $DIR/$tdir -t $i -f $tfile
17585         rc=$?
17586         if [ $rc -eq 255 ]; then
17587                 error "Ladvise test${i} failed, ${rc}"
17588         fi
17589
17590         #test 11 counts lock enqueue requests, all others count new locks
17591         i=11
17592         count=$(do_facet ost1 \
17593                 $LCTL get_param -n ost.OSS.ost.stats)
17594         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
17595
17596         lockahead_test -d $DIR/$tdir -t $i -f $tfile
17597         rc=$?
17598         if [ $rc -eq 255 ]; then
17599                 error "Ladvise test${i} failed, ${rc}"
17600         fi
17601
17602         new_count=$(do_facet ost1 \
17603                 $LCTL get_param -n ost.OSS.ost.stats)
17604         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
17605                    awk '{ print $2 }')
17606
17607         difference="$((new_count - count))"
17608         if [ $difference -ne $rc ]; then
17609                 error "Ladvise test${i}, bad enqueue count, returned " \
17610                       "${rc}, actual ${difference}"
17611         fi
17612
17613         for i in $(seq 12 21); do
17614                 # If we do not do this, we run the risk of having too many
17615                 # locks and starting lock cancellation while we are checking
17616                 # lock counts.
17617                 cancel_lru_locks osc
17618
17619                 count=$($LCTL get_param -n \
17620                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
17621
17622                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
17623                 rc=$?
17624                 if [ $rc -eq 255 ]; then
17625                         error "Ladvise test ${i} failed, ${rc}"
17626                 fi
17627
17628                 new_count=$($LCTL get_param -n \
17629                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
17630                 difference="$((new_count - count))"
17631
17632                 # Test 15 output is divided by 100 to map down to valid return
17633                 if [ $i -eq 15 ]; then
17634                         rc="$((rc * 100))"
17635                 fi
17636
17637                 if [ $difference -ne $rc ]; then
17638                         error "Ladvise test ${i}, bad lock count, returned " \
17639                               "${rc}, actual ${difference}"
17640                 fi
17641         done
17642
17643         #test 22 returns only success/failure
17644         i=22
17645         lockahead_test -d $DIR/$tdir -t $i -f $tfile
17646         rc=$?
17647         if [ $rc -eq 255 ]; then
17648                 error "Ladvise test${i} failed, ${rc}"
17649         fi
17650 }
17651 run_test 255c "suite of ladvise lockahead tests"
17652
17653 test_256() {
17654         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17655         remote_mds_nodsh && skip "remote MDS with nodsh"
17656         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
17657         changelog_users $SINGLEMDS | grep "^cl" &&
17658                 skip "active changelog user"
17659
17660         local cl_user
17661         local cat_sl
17662         local mdt_dev
17663
17664         mdt_dev=$(mdsdevname 1)
17665         echo $mdt_dev
17666
17667         changelog_register || error "changelog_register failed"
17668
17669         rm -rf $DIR/$tdir
17670         mkdir -p $DIR/$tdir
17671
17672         changelog_clear 0 || error "changelog_clear failed"
17673
17674         # change something
17675         touch $DIR/$tdir/{1..10}
17676
17677         # stop the MDT
17678         stop $SINGLEMDS || error "Fail to stop MDT"
17679
17680         # remount the MDT
17681
17682         start $SINGLEMDS $mdt_dev $MDS_MOUNT_OPTS || error "Fail to start MDT"
17683
17684         #after mount new plainllog is used
17685         touch $DIR/$tdir/{11..19}
17686         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
17687         stack_trap "rm -f $tmpfile"
17688         cat_sl=$(do_facet $SINGLEMDS "sync; \
17689                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
17690                  llog_reader $tmpfile | grep -c type=1064553b")
17691         do_facet $SINGLEMDS llog_reader $tmpfile
17692
17693         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
17694
17695         changelog_clear 0 || error "changelog_clear failed"
17696
17697         cat_sl=$(do_facet $SINGLEMDS "sync; \
17698                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
17699                  llog_reader $tmpfile | grep -c type=1064553b")
17700
17701         if (( cat_sl == 2 )); then
17702                 error "Empty plain llog was not deleted from changelog catalog"
17703         elif (( cat_sl != 1 )); then
17704                 error "Active plain llog shouldn't be deleted from catalog"
17705         fi
17706 }
17707 run_test 256 "Check llog delete for empty and not full state"
17708
17709 test_257() {
17710         remote_mds_nodsh && skip "remote MDS with nodsh"
17711         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
17712                 skip "Need MDS version at least 2.8.55"
17713
17714         test_mkdir $DIR/$tdir
17715
17716         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
17717                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
17718         stat $DIR/$tdir
17719
17720 #define OBD_FAIL_MDS_XATTR_REP                  0x161
17721         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
17722         local facet=mds$((mdtidx + 1))
17723         set_nodes_failloc $(facet_active_host $facet) 0x80000161
17724         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
17725
17726         stop $facet || error "stop MDS failed"
17727         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
17728                 error "start MDS fail"
17729         wait_recovery_complete $facet
17730 }
17731 run_test 257 "xattr locks are not lost"
17732
17733 # Verify we take the i_mutex when security requires it
17734 test_258a() {
17735 #define OBD_FAIL_IMUTEX_SEC 0x141c
17736         $LCTL set_param fail_loc=0x141c
17737         touch $DIR/$tfile
17738         chmod u+s $DIR/$tfile
17739         chmod a+rwx $DIR/$tfile
17740         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
17741         RC=$?
17742         if [ $RC -ne 0 ]; then
17743                 error "error, failed to take i_mutex, rc=$?"
17744         fi
17745         rm -f $DIR/$tfile
17746 }
17747 run_test 258a "verify i_mutex security behavior when suid attributes is set"
17748
17749 # Verify we do NOT take the i_mutex in the normal case
17750 test_258b() {
17751 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
17752         $LCTL set_param fail_loc=0x141d
17753         touch $DIR/$tfile
17754         chmod a+rwx $DIR
17755         chmod a+rw $DIR/$tfile
17756         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
17757         RC=$?
17758         if [ $RC -ne 0 ]; then
17759                 error "error, took i_mutex unnecessarily, rc=$?"
17760         fi
17761         rm -f $DIR/$tfile
17762
17763 }
17764 run_test 258b "verify i_mutex security behavior"
17765
17766 test_259() {
17767         local file=$DIR/$tfile
17768         local before
17769         local after
17770
17771         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
17772
17773         stack_trap "rm -f $file" EXIT
17774
17775         wait_delete_completed
17776         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
17777         echo "before: $before"
17778
17779         $LFS setstripe -i 0 -c 1 $file
17780         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
17781         sync_all_data
17782         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
17783         echo "after write: $after"
17784
17785 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
17786         do_facet ost1 $LCTL set_param fail_loc=0x2301
17787         $TRUNCATE $file 0
17788         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
17789         echo "after truncate: $after"
17790
17791         stop ost1
17792         do_facet ost1 $LCTL set_param fail_loc=0
17793         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
17794         sleep 2
17795         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
17796         echo "after restart: $after"
17797         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
17798                 error "missing truncate?"
17799
17800         return 0
17801 }
17802 run_test 259 "crash at delayed truncate"
17803
17804 test_260() {
17805 #define OBD_FAIL_MDC_CLOSE               0x806
17806         $LCTL set_param fail_loc=0x80000806
17807         touch $DIR/$tfile
17808
17809 }
17810 run_test 260 "Check mdc_close fail"
17811
17812 ### Data-on-MDT sanity tests ###
17813 test_270a() {
17814         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17815                 skip "Need MDS version at least 2.10.55 for DoM"
17816
17817         # create DoM file
17818         local dom=$DIR/$tdir/dom_file
17819         local tmp=$DIR/$tdir/tmp_file
17820
17821         mkdir -p $DIR/$tdir
17822
17823         # basic checks for DoM component creation
17824         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
17825                 error "Can set MDT layout to non-first entry"
17826
17827         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
17828                 error "Can define multiple entries as MDT layout"
17829
17830         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
17831
17832         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
17833         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
17834         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
17835
17836         local mdtidx=$($LFS getstripe -m $dom)
17837         local mdtname=MDT$(printf %04x $mdtidx)
17838         local facet=mds$((mdtidx + 1))
17839         local space_check=1
17840
17841         # Skip free space checks with ZFS
17842         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
17843
17844         # write
17845         sync
17846         local size_tmp=$((65536 * 3))
17847         local mdtfree1=$(do_facet $facet \
17848                          lctl get_param -n osd*.*$mdtname.kbytesfree)
17849
17850         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
17851         # check also direct IO along write
17852         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
17853         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
17854         sync
17855         cmp $tmp $dom || error "file data is different"
17856         [ $(stat -c%s $dom) == $size_tmp ] ||
17857                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
17858         if [ $space_check == 1 ]; then
17859                 local mdtfree2=$(do_facet $facet \
17860                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
17861
17862                 # increase in usage from by $size_tmp
17863                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
17864                         error "MDT free space wrong after write: " \
17865                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
17866         fi
17867
17868         # truncate
17869         local size_dom=10000
17870
17871         $TRUNCATE $dom $size_dom
17872         [ $(stat -c%s $dom) == $size_dom ] ||
17873                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
17874         if [ $space_check == 1 ]; then
17875                 mdtfree1=$(do_facet $facet \
17876                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17877                 # decrease in usage from $size_tmp to new $size_dom
17878                 [ $(($mdtfree1 - $mdtfree2)) -ge \
17879                   $(((size_tmp - size_dom) / 1024)) ] ||
17880                         error "MDT free space is wrong after truncate: " \
17881                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
17882         fi
17883
17884         # append
17885         cat $tmp >> $dom
17886         sync
17887         size_dom=$((size_dom + size_tmp))
17888         [ $(stat -c%s $dom) == $size_dom ] ||
17889                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
17890         if [ $space_check == 1 ]; then
17891                 mdtfree2=$(do_facet $facet \
17892                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17893                 # increase in usage by $size_tmp from previous
17894                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
17895                         error "MDT free space is wrong after append: " \
17896                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
17897         fi
17898
17899         # delete
17900         rm $dom
17901         if [ $space_check == 1 ]; then
17902                 mdtfree1=$(do_facet $facet \
17903                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17904                 # decrease in usage by $size_dom from previous
17905                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
17906                         error "MDT free space is wrong after removal: " \
17907                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
17908         fi
17909
17910         # combined striping
17911         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
17912                 error "Can't create DoM + OST striping"
17913
17914         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
17915         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
17916         # check also direct IO along write
17917         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
17918         sync
17919         cmp $tmp $dom || error "file data is different"
17920         [ $(stat -c%s $dom) == $size_tmp ] ||
17921                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
17922         rm $dom $tmp
17923
17924         return 0
17925 }
17926 run_test 270a "DoM: basic functionality tests"
17927
17928 test_270b() {
17929         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17930                 skip "Need MDS version at least 2.10.55"
17931
17932         local dom=$DIR/$tdir/dom_file
17933         local max_size=1048576
17934
17935         mkdir -p $DIR/$tdir
17936         $LFS setstripe -E $max_size -L mdt $dom
17937
17938         # truncate over the limit
17939         $TRUNCATE $dom $(($max_size + 1)) &&
17940                 error "successful truncate over the maximum size"
17941         # write over the limit
17942         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
17943                 error "successful write over the maximum size"
17944         # append over the limit
17945         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
17946         echo "12345" >> $dom && error "successful append over the maximum size"
17947         rm $dom
17948
17949         return 0
17950 }
17951 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
17952
17953 test_270c() {
17954         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17955                 skip "Need MDS version at least 2.10.55"
17956
17957         mkdir -p $DIR/$tdir
17958         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
17959
17960         # check files inherit DoM EA
17961         touch $DIR/$tdir/first
17962         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
17963                 error "bad pattern"
17964         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
17965                 error "bad stripe count"
17966         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
17967                 error "bad stripe size"
17968
17969         # check directory inherits DoM EA and uses it as default
17970         mkdir $DIR/$tdir/subdir
17971         touch $DIR/$tdir/subdir/second
17972         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
17973                 error "bad pattern in sub-directory"
17974         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
17975                 error "bad stripe count in sub-directory"
17976         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
17977                 error "bad stripe size in sub-directory"
17978         return 0
17979 }
17980 run_test 270c "DoM: DoM EA inheritance tests"
17981
17982 test_270d() {
17983         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17984                 skip "Need MDS version at least 2.10.55"
17985
17986         mkdir -p $DIR/$tdir
17987         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
17988
17989         # inherit default DoM striping
17990         mkdir $DIR/$tdir/subdir
17991         touch $DIR/$tdir/subdir/f1
17992
17993         # change default directory striping
17994         $LFS setstripe -c 1 $DIR/$tdir/subdir
17995         touch $DIR/$tdir/subdir/f2
17996         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
17997                 error "wrong default striping in file 2"
17998         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
17999                 error "bad pattern in file 2"
18000         return 0
18001 }
18002 run_test 270d "DoM: change striping from DoM to RAID0"
18003
18004 test_270e() {
18005         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18006                 skip "Need MDS version at least 2.10.55"
18007
18008         mkdir -p $DIR/$tdir/dom
18009         mkdir -p $DIR/$tdir/norm
18010         DOMFILES=20
18011         NORMFILES=10
18012         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
18013         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
18014
18015         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
18016         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
18017
18018         # find DoM files by layout
18019         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
18020         [ $NUM -eq  $DOMFILES ] ||
18021                 error "lfs find -L: found $NUM, expected $DOMFILES"
18022         echo "Test 1: lfs find 20 DOM files by layout: OK"
18023
18024         # there should be 1 dir with default DOM striping
18025         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
18026         [ $NUM -eq  1 ] ||
18027                 error "lfs find -L: found $NUM, expected 1 dir"
18028         echo "Test 2: lfs find 1 DOM dir by layout: OK"
18029
18030         # find DoM files by stripe size
18031         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
18032         [ $NUM -eq  $DOMFILES ] ||
18033                 error "lfs find -S: found $NUM, expected $DOMFILES"
18034         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
18035
18036         # find files by stripe offset except DoM files
18037         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
18038         [ $NUM -eq  $NORMFILES ] ||
18039                 error "lfs find -i: found $NUM, expected $NORMFILES"
18040         echo "Test 5: lfs find no DOM files by stripe index: OK"
18041         return 0
18042 }
18043 run_test 270e "DoM: lfs find with DoM files test"
18044
18045 test_270f() {
18046         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18047                 skip "Need MDS version at least 2.10.55"
18048
18049         local mdtname=${FSNAME}-MDT0000-mdtlov
18050         local dom=$DIR/$tdir/dom_file
18051         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
18052                                                 lod.$mdtname.dom_stripesize)
18053         local dom_limit=131072
18054
18055         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
18056         local dom_current=$(do_facet mds1 $LCTL get_param -n \
18057                                                 lod.$mdtname.dom_stripesize)
18058         [ ${dom_limit} -eq ${dom_current} ] ||
18059                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
18060
18061         $LFS mkdir -i 0 -c 1 $DIR/$tdir
18062         $LFS setstripe -d $DIR/$tdir
18063         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
18064                 error "Can't set directory default striping"
18065
18066         # exceed maximum stripe size
18067         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
18068                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
18069         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
18070                 error "Able to create DoM component size more than LOD limit"
18071
18072         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
18073         dom_current=$(do_facet mds1 $LCTL get_param -n \
18074                                                 lod.$mdtname.dom_stripesize)
18075         [ 0 -eq ${dom_current} ] ||
18076                 error "Can't set zero DoM stripe limit"
18077         rm $dom
18078
18079         # attempt to create DoM file on server with disabled DoM should
18080         # remove DoM entry from layout and be succeed
18081         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
18082                 error "Can't create DoM file (DoM is disabled)"
18083         [ $($LFS getstripe -L $dom) == "mdt" ] &&
18084                 error "File has DoM component while DoM is disabled"
18085         rm $dom
18086
18087         # attempt to create DoM file with only DoM stripe should return error
18088         $LFS setstripe -E $dom_limit -L mdt $dom &&
18089                 error "Able to create DoM-only file while DoM is disabled"
18090
18091         # too low values to be aligned with smallest stripe size 64K
18092         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
18093         dom_current=$(do_facet mds1 $LCTL get_param -n \
18094                                                 lod.$mdtname.dom_stripesize)
18095         [ 30000 -eq ${dom_current} ] &&
18096                 error "Can set too small DoM stripe limit"
18097
18098         # 64K is a minimal stripe size in Lustre, expect limit of that size
18099         [ 65536 -eq ${dom_current} ] ||
18100                 error "Limit is not set to 64K but ${dom_current}"
18101
18102         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
18103         dom_current=$(do_facet mds1 $LCTL get_param -n \
18104                                                 lod.$mdtname.dom_stripesize)
18105         echo $dom_current
18106         [ 2147483648 -eq ${dom_current} ] &&
18107                 error "Can set too large DoM stripe limit"
18108
18109         do_facet mds1 $LCTL set_param -n \
18110                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
18111         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
18112                 error "Can't create DoM component size after limit change"
18113         do_facet mds1 $LCTL set_param -n \
18114                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
18115         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
18116                 error "Can't create DoM file after limit decrease"
18117         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
18118                 error "Can create big DoM component after limit decrease"
18119         touch ${dom}_def ||
18120                 error "Can't create file with old default layout"
18121
18122         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
18123         return 0
18124 }
18125 run_test 270f "DoM: maximum DoM stripe size checks"
18126
18127 test_271a() {
18128         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18129                 skip "Need MDS version at least 2.10.55"
18130
18131         local dom=$DIR/$tdir/dom
18132
18133         mkdir -p $DIR/$tdir
18134
18135         $LFS setstripe -E 1024K -L mdt $dom
18136
18137         lctl set_param -n mdc.*.stats=clear
18138         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
18139         cat $dom > /dev/null
18140         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
18141         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
18142         ls $dom
18143         rm -f $dom
18144 }
18145 run_test 271a "DoM: data is cached for read after write"
18146
18147 test_271b() {
18148         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18149                 skip "Need MDS version at least 2.10.55"
18150
18151         local dom=$DIR/$tdir/dom
18152
18153         mkdir -p $DIR/$tdir
18154
18155         $LFS setstripe -E 1024K -L mdt -E EOF $dom
18156
18157         lctl set_param -n mdc.*.stats=clear
18158         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
18159         cancel_lru_locks mdc
18160         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
18161         # second stat to check size is cached on client
18162         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
18163         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
18164         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
18165         rm -f $dom
18166 }
18167 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
18168
18169 test_271ba() {
18170         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18171                 skip "Need MDS version at least 2.10.55"
18172
18173         local dom=$DIR/$tdir/dom
18174
18175         mkdir -p $DIR/$tdir
18176
18177         $LFS setstripe -E 1024K -L mdt -E EOF $dom
18178
18179         lctl set_param -n mdc.*.stats=clear
18180         lctl set_param -n osc.*.stats=clear
18181         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
18182         cancel_lru_locks mdc
18183         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
18184         # second stat to check size is cached on client
18185         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
18186         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
18187         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
18188         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
18189         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
18190         rm -f $dom
18191 }
18192 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
18193
18194
18195 get_mdc_stats() {
18196         local mdtidx=$1
18197         local param=$2
18198         local mdt=MDT$(printf %04x $mdtidx)
18199
18200         if [ -z $param ]; then
18201                 lctl get_param -n mdc.*$mdt*.stats
18202         else
18203                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
18204         fi
18205 }
18206
18207 test_271c() {
18208         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18209                 skip "Need MDS version at least 2.10.55"
18210
18211         local dom=$DIR/$tdir/dom
18212
18213         mkdir -p $DIR/$tdir
18214
18215         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
18216
18217         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
18218         local facet=mds$((mdtidx + 1))
18219
18220         cancel_lru_locks mdc
18221         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
18222         createmany -o $dom 1000
18223         lctl set_param -n mdc.*.stats=clear
18224         smalliomany -w $dom 1000 200
18225         get_mdc_stats $mdtidx
18226         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
18227         # Each file has 1 open, 1 IO enqueues, total 2000
18228         # but now we have also +1 getxattr for security.capability, total 3000
18229         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
18230         unlinkmany $dom 1000
18231
18232         cancel_lru_locks mdc
18233         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
18234         createmany -o $dom 1000
18235         lctl set_param -n mdc.*.stats=clear
18236         smalliomany -w $dom 1000 200
18237         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
18238         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
18239         # for OPEN and IO lock.
18240         [ $((enq - enq_2)) -ge 1000 ] ||
18241                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
18242         unlinkmany $dom 1000
18243         return 0
18244 }
18245 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
18246
18247 cleanup_271def_tests() {
18248         trap 0
18249         rm -f $1
18250 }
18251
18252 test_271d() {
18253         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
18254                 skip "Need MDS version at least 2.10.57"
18255
18256         local dom=$DIR/$tdir/dom
18257         local tmp=$TMP/$tfile
18258         trap "cleanup_271def_tests $tmp" EXIT
18259
18260         mkdir -p $DIR/$tdir
18261
18262         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
18263
18264         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
18265
18266         cancel_lru_locks mdc
18267         dd if=/dev/urandom of=$tmp bs=1000 count=1
18268         dd if=$tmp of=$dom bs=1000 count=1
18269         cancel_lru_locks mdc
18270
18271         cat /etc/hosts >> $tmp
18272         lctl set_param -n mdc.*.stats=clear
18273
18274         # append data to the same file it should update local page
18275         echo "Append to the same page"
18276         cat /etc/hosts >> $dom
18277         local num=$(get_mdc_stats $mdtidx ost_read)
18278         local ra=$(get_mdc_stats $mdtidx req_active)
18279         local rw=$(get_mdc_stats $mdtidx req_waittime)
18280
18281         [ -z $num ] || error "$num READ RPC occured"
18282         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
18283         echo "... DONE"
18284
18285         # compare content
18286         cmp $tmp $dom || error "file miscompare"
18287
18288         cancel_lru_locks mdc
18289         lctl set_param -n mdc.*.stats=clear
18290
18291         echo "Open and read file"
18292         cat $dom > /dev/null
18293         local num=$(get_mdc_stats $mdtidx ost_read)
18294         local ra=$(get_mdc_stats $mdtidx req_active)
18295         local rw=$(get_mdc_stats $mdtidx req_waittime)
18296
18297         [ -z $num ] || error "$num READ RPC occured"
18298         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
18299         echo "... DONE"
18300
18301         # compare content
18302         cmp $tmp $dom || error "file miscompare"
18303
18304         return 0
18305 }
18306 run_test 271d "DoM: read on open (1K file in reply buffer)"
18307
18308 test_271f() {
18309         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
18310                 skip "Need MDS version at least 2.10.57"
18311
18312         local dom=$DIR/$tdir/dom
18313         local tmp=$TMP/$tfile
18314         trap "cleanup_271def_tests $tmp" EXIT
18315
18316         mkdir -p $DIR/$tdir
18317
18318         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
18319
18320         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
18321
18322         cancel_lru_locks mdc
18323         dd if=/dev/urandom of=$tmp bs=265000 count=1
18324         dd if=$tmp of=$dom bs=265000 count=1
18325         cancel_lru_locks mdc
18326         cat /etc/hosts >> $tmp
18327         lctl set_param -n mdc.*.stats=clear
18328
18329         echo "Append to the same page"
18330         cat /etc/hosts >> $dom
18331         local num=$(get_mdc_stats $mdtidx ost_read)
18332         local ra=$(get_mdc_stats $mdtidx req_active)
18333         local rw=$(get_mdc_stats $mdtidx req_waittime)
18334
18335         [ -z $num ] || error "$num READ RPC occured"
18336         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
18337         echo "... DONE"
18338
18339         # compare content
18340         cmp $tmp $dom || error "file miscompare"
18341
18342         cancel_lru_locks mdc
18343         lctl set_param -n mdc.*.stats=clear
18344
18345         echo "Open and read file"
18346         cat $dom > /dev/null
18347         local num=$(get_mdc_stats $mdtidx ost_read)
18348         local ra=$(get_mdc_stats $mdtidx req_active)
18349         local rw=$(get_mdc_stats $mdtidx req_waittime)
18350
18351         [ -z $num ] && num=0
18352         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
18353         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
18354         echo "... DONE"
18355
18356         # compare content
18357         cmp $tmp $dom || error "file miscompare"
18358
18359         return 0
18360 }
18361 run_test 271f "DoM: read on open (200K file and read tail)"
18362
18363 test_271g() {
18364         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
18365                 skip "Skipping due to old client or server version"
18366
18367         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
18368         # to get layout
18369         $CHECKSTAT -t file $DIR1/$tfile
18370
18371         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
18372         MULTIOP_PID=$!
18373         sleep 1
18374         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
18375         $LCTL set_param fail_loc=0x80000314
18376         rm $DIR1/$tfile || error "Unlink fails"
18377         RC=$?
18378         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
18379         [ $RC -eq 0 ] || error "Failed write to stale object"
18380 }
18381 run_test 271g "Discard DoM data vs client flush race"
18382
18383 test_272a() {
18384         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
18385                 skip "Need MDS version at least 2.11.50"
18386
18387         local dom=$DIR/$tdir/dom
18388         mkdir -p $DIR/$tdir
18389
18390         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
18391         dd if=/dev/urandom of=$dom bs=512K count=1 ||
18392                 error "failed to write data into $dom"
18393         local old_md5=$(md5sum $dom)
18394
18395         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
18396                 error "failed to migrate to the same DoM component"
18397
18398         local new_md5=$(md5sum $dom)
18399
18400         [ "$old_md5" == "$new_md5" ] ||
18401                 error "md5sum differ: $old_md5, $new_md5"
18402
18403         [ $($LFS getstripe -c $dom) -eq 2 ] ||
18404                 error "migrate stripe count bad: $(LFS getstripe -c $dom) != 2"
18405 }
18406 run_test 272a "DoM migration: new layout with the same DOM component"
18407
18408 test_272b() {
18409         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
18410                 skip "Need MDS version at least 2.11.50"
18411
18412         local dom=$DIR/$tdir/dom
18413         mkdir -p $DIR/$tdir
18414         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
18415
18416         local mdtidx=$($LFS getstripe -m $dom)
18417         local mdtname=MDT$(printf %04x $mdtidx)
18418         local facet=mds$((mdtidx + 1))
18419
18420         local mdtfree1=$(do_facet $facet \
18421                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18422         dd if=/dev/urandom of=$dom bs=2M count=1 ||
18423                 error "failed to write data into $dom"
18424         local old_md5=$(md5sum $dom)
18425         cancel_lru_locks mdc
18426         local mdtfree1=$(do_facet $facet \
18427                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18428
18429         $LFS migrate -c2 $dom ||
18430                 error "failed to migrate to the new composite layout"
18431         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
18432                 error "MDT stripe was not removed"
18433
18434         cancel_lru_locks mdc
18435         local new_md5=$(md5sum $dom)
18436         [ "$old_md5" == "$new_md5" ] ||
18437                 error "$old_md5 != $new_md5"
18438
18439         # Skip free space checks with ZFS
18440         if [ "$(facet_fstype $facet)" != "zfs" ]; then
18441                 local mdtfree2=$(do_facet $facet \
18442                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18443                 [ $mdtfree2 -gt $mdtfree1 ] ||
18444                         error "MDT space is not freed after migration"
18445         fi
18446         return 0
18447 }
18448 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
18449
18450 test_272c() {
18451         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
18452                 skip "Need MDS version at least 2.11.50"
18453
18454         local dom=$DIR/$tdir/$tfile
18455         mkdir -p $DIR/$tdir
18456         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
18457
18458         local mdtidx=$($LFS getstripe -m $dom)
18459         local mdtname=MDT$(printf %04x $mdtidx)
18460         local facet=mds$((mdtidx + 1))
18461
18462         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
18463                 error "failed to write data into $dom"
18464         local old_md5=$(md5sum $dom)
18465         cancel_lru_locks mdc
18466         local mdtfree1=$(do_facet $facet \
18467                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18468
18469         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
18470                 error "failed to migrate to the new composite layout"
18471         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
18472                 error "MDT stripe was not removed"
18473
18474         cancel_lru_locks mdc
18475         local new_md5=$(md5sum $dom)
18476         [ "$old_md5" == "$new_md5" ] ||
18477                 error "$old_md5 != $new_md5"
18478
18479         # Skip free space checks with ZFS
18480         if [ "$(facet_fstype $facet)" != "zfs" ]; then
18481                 local mdtfree2=$(do_facet $facet \
18482                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18483                 [ $mdtfree2 -gt $mdtfree1 ] ||
18484                         error "MDS space is not freed after migration"
18485         fi
18486         return 0
18487 }
18488 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
18489
18490 test_272d() {
18491         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
18492                 skip "Need MDS version at least 2.12.55"
18493
18494         local dom=$DIR/$tdir/$tfile
18495         mkdir -p $DIR/$tdir
18496         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
18497
18498         local mdtidx=$($LFS getstripe -m $dom)
18499         local mdtname=MDT$(printf %04x $mdtidx)
18500         local facet=mds$((mdtidx + 1))
18501
18502         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
18503                 error "failed to write data into $dom"
18504         local old_md5=$(md5sum $dom)
18505         cancel_lru_locks mdc
18506         local mdtfree1=$(do_facet $facet \
18507                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18508
18509         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
18510                 error "failed mirroring to the new composite layout"
18511         $LFS mirror resync $dom ||
18512                 error "failed mirror resync"
18513         $LFS mirror split --mirror-id 1 -d $dom ||
18514                 error "failed mirror split"
18515
18516         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
18517                 error "MDT stripe was not removed"
18518
18519         cancel_lru_locks mdc
18520         local new_md5=$(md5sum $dom)
18521         [ "$old_md5" == "$new_md5" ] ||
18522                 error "$old_md5 != $new_md5"
18523
18524         # Skip free space checks with ZFS
18525         if [ "$(facet_fstype $facet)" != "zfs" ]; then
18526                 local mdtfree2=$(do_facet $facet \
18527                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18528                 [ $mdtfree2 -gt $mdtfree1 ] ||
18529                         error "MDS space is not freed after DOM mirror deletion"
18530         fi
18531         return 0
18532 }
18533 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
18534
18535 test_272e() {
18536         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
18537                 skip "Need MDS version at least 2.12.55"
18538
18539         local dom=$DIR/$tdir/$tfile
18540         mkdir -p $DIR/$tdir
18541         $LFS setstripe -c 2 $dom
18542
18543         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
18544                 error "failed to write data into $dom"
18545         local old_md5=$(md5sum $dom)
18546         cancel_lru_locks mdc
18547
18548         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
18549                 error "failed mirroring to the DOM layout"
18550         $LFS mirror resync $dom ||
18551                 error "failed mirror resync"
18552         $LFS mirror split --mirror-id 1 -d $dom ||
18553                 error "failed mirror split"
18554
18555         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
18556                 error "MDT stripe was not removed"
18557
18558         cancel_lru_locks mdc
18559         local new_md5=$(md5sum $dom)
18560         [ "$old_md5" == "$new_md5" ] ||
18561                 error "$old_md5 != $new_md5"
18562
18563         return 0
18564 }
18565 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
18566
18567 test_272f() {
18568         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
18569                 skip "Need MDS version at least 2.12.55"
18570
18571         local dom=$DIR/$tdir/$tfile
18572         mkdir -p $DIR/$tdir
18573         $LFS setstripe -c 2 $dom
18574
18575         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
18576                 error "failed to write data into $dom"
18577         local old_md5=$(md5sum $dom)
18578         cancel_lru_locks mdc
18579
18580         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
18581                 error "failed migrating to the DOM file"
18582
18583         cancel_lru_locks mdc
18584         local new_md5=$(md5sum $dom)
18585         [ "$old_md5" != "$new_md5" ] &&
18586                 error "$old_md5 != $new_md5"
18587
18588         return 0
18589 }
18590 run_test 272f "DoM migration: OST-striped file to DOM file"
18591
18592 test_273a() {
18593         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
18594                 skip "Need MDS version at least 2.11.50"
18595
18596         # Layout swap cannot be done if either file has DOM component,
18597         # this will never be supported, migration should be used instead
18598
18599         local dom=$DIR/$tdir/$tfile
18600         mkdir -p $DIR/$tdir
18601
18602         $LFS setstripe -c2 ${dom}_plain
18603         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
18604         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
18605                 error "can swap layout with DoM component"
18606         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
18607                 error "can swap layout with DoM component"
18608
18609         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
18610         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
18611                 error "can swap layout with DoM component"
18612         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
18613                 error "can swap layout with DoM component"
18614         return 0
18615 }
18616 run_test 273a "DoM: layout swapping should fail with DOM"
18617
18618 test_275() {
18619         remote_ost_nodsh && skip "remote OST with nodsh"
18620         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
18621                 skip "Need OST version >= 2.10.57"
18622
18623         local file=$DIR/$tfile
18624         local oss
18625
18626         oss=$(comma_list $(osts_nodes))
18627
18628         dd if=/dev/urandom of=$file bs=1M count=2 ||
18629                 error "failed to create a file"
18630         cancel_lru_locks osc
18631
18632         #lock 1
18633         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
18634                 error "failed to read a file"
18635
18636 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
18637         $LCTL set_param fail_loc=0x8000031f
18638
18639         cancel_lru_locks osc &
18640         sleep 1
18641
18642 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
18643         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
18644         #IO takes another lock, but matches the PENDING one
18645         #and places it to the IO RPC
18646         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
18647                 error "failed to read a file with PENDING lock"
18648 }
18649 run_test 275 "Read on a canceled duplicate lock"
18650
18651 test_276() {
18652         remote_ost_nodsh && skip "remote OST with nodsh"
18653         local pid
18654
18655         do_facet ost1 "(while true; do \
18656                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
18657                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
18658         pid=$!
18659
18660         for LOOP in $(seq 20); do
18661                 stop ost1
18662                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
18663         done
18664         kill -9 $pid
18665         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
18666                 rm $TMP/sanity_276_pid"
18667 }
18668 run_test 276 "Race between mount and obd_statfs"
18669
18670 test_277() {
18671         $LCTL set_param ldlm.namespaces.*.lru_size=0
18672         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
18673         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
18674                         grep ^used_mb | awk '{print $2}')
18675         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
18676         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
18677                 oflag=direct conv=notrunc
18678         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
18679                         grep ^used_mb | awk '{print $2}')
18680         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
18681 }
18682 run_test 277 "Direct IO shall drop page cache"
18683
18684 test_278() {
18685         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
18686         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
18687         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
18688                 skip "needs the same host for mdt1 mdt2" && return
18689
18690         local pid1
18691         local pid2
18692
18693 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
18694         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
18695         stop mds2 &
18696         pid2=$!
18697
18698         stop mds1
18699
18700         echo "Starting MDTs"
18701         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
18702         wait $pid2
18703 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
18704 #will return NULL
18705         do_facet mds2 $LCTL set_param fail_loc=0
18706
18707         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
18708 }
18709 run_test 278 "Race starting MDS between MDTs stop/start"
18710
18711 cleanup_test_300() {
18712         trap 0
18713         umask $SAVE_UMASK
18714 }
18715 test_striped_dir() {
18716         local mdt_index=$1
18717         local stripe_count
18718         local stripe_index
18719
18720         mkdir -p $DIR/$tdir
18721
18722         SAVE_UMASK=$(umask)
18723         trap cleanup_test_300 RETURN EXIT
18724
18725         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
18726                                                 $DIR/$tdir/striped_dir ||
18727                 error "set striped dir error"
18728
18729         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
18730         [ "$mode" = "755" ] || error "expect 755 got $mode"
18731
18732         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
18733                 error "getdirstripe failed"
18734         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
18735         if [ "$stripe_count" != "2" ]; then
18736                 error "1:stripe_count is $stripe_count, expect 2"
18737         fi
18738         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
18739         if [ "$stripe_count" != "2" ]; then
18740                 error "2:stripe_count is $stripe_count, expect 2"
18741         fi
18742
18743         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
18744         if [ "$stripe_index" != "$mdt_index" ]; then
18745                 error "stripe_index is $stripe_index, expect $mdt_index"
18746         fi
18747
18748         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
18749                 error "nlink error after create striped dir"
18750
18751         mkdir $DIR/$tdir/striped_dir/a
18752         mkdir $DIR/$tdir/striped_dir/b
18753
18754         stat $DIR/$tdir/striped_dir/a ||
18755                 error "create dir under striped dir failed"
18756         stat $DIR/$tdir/striped_dir/b ||
18757                 error "create dir under striped dir failed"
18758
18759         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
18760                 error "nlink error after mkdir"
18761
18762         rmdir $DIR/$tdir/striped_dir/a
18763         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
18764                 error "nlink error after rmdir"
18765
18766         rmdir $DIR/$tdir/striped_dir/b
18767         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
18768                 error "nlink error after rmdir"
18769
18770         chattr +i $DIR/$tdir/striped_dir
18771         createmany -o $DIR/$tdir/striped_dir/f 10 &&
18772                 error "immutable flags not working under striped dir!"
18773         chattr -i $DIR/$tdir/striped_dir
18774
18775         rmdir $DIR/$tdir/striped_dir ||
18776                 error "rmdir striped dir error"
18777
18778         cleanup_test_300
18779
18780         true
18781 }
18782
18783 test_300a() {
18784         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
18785                 skip "skipped for lustre < 2.7.0"
18786         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18787         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18788
18789         test_striped_dir 0 || error "failed on striped dir on MDT0"
18790         test_striped_dir 1 || error "failed on striped dir on MDT0"
18791 }
18792 run_test 300a "basic striped dir sanity test"
18793
18794 test_300b() {
18795         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
18796                 skip "skipped for lustre < 2.7.0"
18797         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18798         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18799
18800         local i
18801         local mtime1
18802         local mtime2
18803         local mtime3
18804
18805         test_mkdir $DIR/$tdir || error "mkdir fail"
18806         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
18807                 error "set striped dir error"
18808         for i in {0..9}; do
18809                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
18810                 sleep 1
18811                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
18812                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
18813                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
18814                 sleep 1
18815                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
18816                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
18817                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
18818         done
18819         true
18820 }
18821 run_test 300b "check ctime/mtime for striped dir"
18822
18823 test_300c() {
18824         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
18825                 skip "skipped for lustre < 2.7.0"
18826         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18827         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18828
18829         local file_count
18830
18831         mkdir -p $DIR/$tdir
18832         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
18833                 error "set striped dir error"
18834
18835         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
18836                 error "chown striped dir failed"
18837
18838         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
18839                 error "create 5k files failed"
18840
18841         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
18842
18843         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
18844
18845         rm -rf $DIR/$tdir
18846 }
18847 run_test 300c "chown && check ls under striped directory"
18848
18849 test_300d() {
18850         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
18851                 skip "skipped for lustre < 2.7.0"
18852         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18853         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18854
18855         local stripe_count
18856         local file
18857
18858         mkdir -p $DIR/$tdir
18859         $LFS setstripe -c 2 $DIR/$tdir
18860
18861         #local striped directory
18862         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
18863                 error "set striped dir error"
18864         createmany -o $DIR/$tdir/striped_dir/f 10 ||
18865                 error "create 10 files failed"
18866
18867         #remote striped directory
18868         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
18869                 error "set striped dir error"
18870         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
18871                 error "create 10 files failed"
18872
18873         for file in $(find $DIR/$tdir); do
18874                 stripe_count=$($LFS getstripe -c $file)
18875                 [ $stripe_count -eq 2 ] ||
18876                         error "wrong stripe $stripe_count for $file"
18877         done
18878
18879         rm -rf $DIR/$tdir
18880 }
18881 run_test 300d "check default stripe under striped directory"
18882
18883 test_300e() {
18884         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18885                 skip "Need MDS version at least 2.7.55"
18886         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18887         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18888
18889         local stripe_count
18890         local file
18891
18892         mkdir -p $DIR/$tdir
18893
18894         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
18895                 error "set striped dir error"
18896
18897         touch $DIR/$tdir/striped_dir/a
18898         touch $DIR/$tdir/striped_dir/b
18899         touch $DIR/$tdir/striped_dir/c
18900
18901         mkdir $DIR/$tdir/striped_dir/dir_a
18902         mkdir $DIR/$tdir/striped_dir/dir_b
18903         mkdir $DIR/$tdir/striped_dir/dir_c
18904
18905         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
18906                 error "set striped adir under striped dir error"
18907
18908         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
18909                 error "set striped bdir under striped dir error"
18910
18911         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
18912                 error "set striped cdir under striped dir error"
18913
18914         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
18915                 error "rename dir under striped dir fails"
18916
18917         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
18918                 error "rename dir under different stripes fails"
18919
18920         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
18921                 error "rename file under striped dir should succeed"
18922
18923         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
18924                 error "rename dir under striped dir should succeed"
18925
18926         rm -rf $DIR/$tdir
18927 }
18928 run_test 300e "check rename under striped directory"
18929
18930 test_300f() {
18931         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18932         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18933         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18934                 skip "Need MDS version at least 2.7.55"
18935
18936         local stripe_count
18937         local file
18938
18939         rm -rf $DIR/$tdir
18940         mkdir -p $DIR/$tdir
18941
18942         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
18943                 error "set striped dir error"
18944
18945         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
18946                 error "set striped dir error"
18947
18948         touch $DIR/$tdir/striped_dir/a
18949         mkdir $DIR/$tdir/striped_dir/dir_a
18950         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
18951                 error "create striped dir under striped dir fails"
18952
18953         touch $DIR/$tdir/striped_dir1/b
18954         mkdir $DIR/$tdir/striped_dir1/dir_b
18955         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
18956                 error "create striped dir under striped dir fails"
18957
18958         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
18959                 error "rename dir under different striped dir should fail"
18960
18961         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
18962                 error "rename striped dir under diff striped dir should fail"
18963
18964         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
18965                 error "rename file under diff striped dirs fails"
18966
18967         rm -rf $DIR/$tdir
18968 }
18969 run_test 300f "check rename cross striped directory"
18970
18971 test_300_check_default_striped_dir()
18972 {
18973         local dirname=$1
18974         local default_count=$2
18975         local default_index=$3
18976         local stripe_count
18977         local stripe_index
18978         local dir_stripe_index
18979         local dir
18980
18981         echo "checking $dirname $default_count $default_index"
18982         $LFS setdirstripe -D -c $default_count -i $default_index \
18983                                 -t all_char $DIR/$tdir/$dirname ||
18984                 error "set default stripe on striped dir error"
18985         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
18986         [ $stripe_count -eq $default_count ] ||
18987                 error "expect $default_count get $stripe_count for $dirname"
18988
18989         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
18990         [ $stripe_index -eq $default_index ] ||
18991                 error "expect $default_index get $stripe_index for $dirname"
18992
18993         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
18994                                                 error "create dirs failed"
18995
18996         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
18997         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
18998         for dir in $(find $DIR/$tdir/$dirname/*); do
18999                 stripe_count=$($LFS getdirstripe -c $dir)
19000                 [ $stripe_count -eq $default_count ] ||
19001                 [ $stripe_count -eq 0 ] || [ $default_count -eq 1 ] ||
19002                 error "stripe count $default_count != $stripe_count for $dir"
19003
19004                 stripe_index=$($LFS getdirstripe -i $dir)
19005                 [ $default_index -eq -1 ] ||
19006                         [ $stripe_index -eq $default_index ] ||
19007                         error "$stripe_index != $default_index for $dir"
19008
19009                 #check default stripe
19010                 stripe_count=$($LFS getdirstripe -D -c $dir)
19011                 [ $stripe_count -eq $default_count ] ||
19012                 error "default count $default_count != $stripe_count for $dir"
19013
19014                 stripe_index=$($LFS getdirstripe -D -i $dir)
19015                 [ $stripe_index -eq $default_index ] ||
19016                 error "default index $default_index != $stripe_index for $dir"
19017         done
19018         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
19019 }
19020
19021 test_300g() {
19022         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19023         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19024                 skip "Need MDS version at least 2.7.55"
19025
19026         local dir
19027         local stripe_count
19028         local stripe_index
19029
19030         mkdir $DIR/$tdir
19031         mkdir $DIR/$tdir/normal_dir
19032
19033         #Checking when client cache stripe index
19034         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
19035         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
19036                 error "create striped_dir failed"
19037
19038         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
19039                 error "create dir0 fails"
19040         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
19041         [ $stripe_index -eq 0 ] ||
19042                 error "dir0 expect index 0 got $stripe_index"
19043
19044         mkdir $DIR/$tdir/striped_dir/dir1 ||
19045                 error "create dir1 fails"
19046         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
19047         [ $stripe_index -eq 1 ] ||
19048                 error "dir1 expect index 1 got $stripe_index"
19049
19050         #check default stripe count/stripe index
19051         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
19052         test_300_check_default_striped_dir normal_dir 1 0
19053         test_300_check_default_striped_dir normal_dir 2 1
19054         test_300_check_default_striped_dir normal_dir 2 -1
19055
19056         #delete default stripe information
19057         echo "delete default stripeEA"
19058         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
19059                 error "set default stripe on striped dir error"
19060
19061         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
19062         for dir in $(find $DIR/$tdir/normal_dir/*); do
19063                 stripe_count=$($LFS getdirstripe -c $dir)
19064                 [ $stripe_count -eq 0 ] ||
19065                         error "expect 1 get $stripe_count for $dir"
19066                 stripe_index=$($LFS getdirstripe -i $dir)
19067                 [ $stripe_index -eq 0 ] ||
19068                         error "expect 0 get $stripe_index for $dir"
19069         done
19070 }
19071 run_test 300g "check default striped directory for normal directory"
19072
19073 test_300h() {
19074         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19075         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19076                 skip "Need MDS version at least 2.7.55"
19077
19078         local dir
19079         local stripe_count
19080
19081         mkdir $DIR/$tdir
19082         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
19083                 error "set striped dir error"
19084
19085         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
19086         test_300_check_default_striped_dir striped_dir 1 0
19087         test_300_check_default_striped_dir striped_dir 2 1
19088         test_300_check_default_striped_dir striped_dir 2 -1
19089
19090         #delete default stripe information
19091         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
19092                 error "set default stripe on striped dir error"
19093
19094         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
19095         for dir in $(find $DIR/$tdir/striped_dir/*); do
19096                 stripe_count=$($LFS getdirstripe -c $dir)
19097                 [ $stripe_count -eq 0 ] ||
19098                         error "expect 1 get $stripe_count for $dir"
19099         done
19100 }
19101 run_test 300h "check default striped directory for striped directory"
19102
19103 test_300i() {
19104         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19105         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19106         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19107                 skip "Need MDS version at least 2.7.55"
19108
19109         local stripe_count
19110         local file
19111
19112         mkdir $DIR/$tdir
19113
19114         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
19115                 error "set striped dir error"
19116
19117         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
19118                 error "create files under striped dir failed"
19119
19120         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
19121                 error "set striped hashdir error"
19122
19123         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
19124                 error "create dir0 under hash dir failed"
19125         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
19126                 error "create dir1 under hash dir failed"
19127
19128         # unfortunately, we need to umount to clear dir layout cache for now
19129         # once we fully implement dir layout, we can drop this
19130         umount_client $MOUNT || error "umount failed"
19131         mount_client $MOUNT || error "mount failed"
19132
19133         $LFS find -H fnv_1a_64 $DIR/$tdir/hashdir
19134         local dircnt=$($LFS find -H fnv_1a_64 $DIR/$tdir/hashdir | wc -l)
19135         [ $dircnt -eq 1 ] || error "lfs find striped dir got:$dircnt,except:1"
19136
19137         #set the stripe to be unknown hash type
19138         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
19139         $LCTL set_param fail_loc=0x1901
19140         for ((i = 0; i < 10; i++)); do
19141                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
19142                         error "stat f-$i failed"
19143                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
19144         done
19145
19146         touch $DIR/$tdir/striped_dir/f0 &&
19147                 error "create under striped dir with unknown hash should fail"
19148
19149         $LCTL set_param fail_loc=0
19150
19151         umount_client $MOUNT || error "umount failed"
19152         mount_client $MOUNT || error "mount failed"
19153
19154         return 0
19155 }
19156 run_test 300i "client handle unknown hash type striped directory"
19157
19158 test_300j() {
19159         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19160         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19161         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19162                 skip "Need MDS version at least 2.7.55"
19163
19164         local stripe_count
19165         local file
19166
19167         mkdir $DIR/$tdir
19168
19169         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
19170         $LCTL set_param fail_loc=0x1702
19171         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
19172                 error "set striped dir error"
19173
19174         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
19175                 error "create files under striped dir failed"
19176
19177         $LCTL set_param fail_loc=0
19178
19179         rm -rf $DIR/$tdir || error "unlink striped dir fails"
19180
19181         return 0
19182 }
19183 run_test 300j "test large update record"
19184
19185 test_300k() {
19186         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19187         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19188         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19189                 skip "Need MDS version at least 2.7.55"
19190
19191         # this test needs a huge transaction
19192         local kb
19193         kb=$(do_facet $SINGLEMDS lctl get_param -n osd*.lustre-MDT0000.kbytestotal)
19194         [ $kb -lt $((1024*1024)) ] && skip "too small mds: $kb"
19195
19196         local stripe_count
19197         local file
19198
19199         mkdir $DIR/$tdir
19200
19201         #define OBD_FAIL_LARGE_STRIPE   0x1703
19202         $LCTL set_param fail_loc=0x1703
19203         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
19204                 error "set striped dir error"
19205         $LCTL set_param fail_loc=0
19206
19207         $LFS getdirstripe $DIR/$tdir/striped_dir ||
19208                 error "getstripeddir fails"
19209         rm -rf $DIR/$tdir/striped_dir ||
19210                 error "unlink striped dir fails"
19211
19212         return 0
19213 }
19214 run_test 300k "test large striped directory"
19215
19216 test_300l() {
19217         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19218         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19219         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19220                 skip "Need MDS version at least 2.7.55"
19221
19222         local stripe_index
19223
19224         test_mkdir -p $DIR/$tdir/striped_dir
19225         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
19226                         error "chown $RUNAS_ID failed"
19227         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
19228                 error "set default striped dir failed"
19229
19230         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
19231         $LCTL set_param fail_loc=0x80000158
19232         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
19233
19234         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
19235         [ $stripe_index -eq 1 ] ||
19236                 error "expect 1 get $stripe_index for $dir"
19237 }
19238 run_test 300l "non-root user to create dir under striped dir with stale layout"
19239
19240 test_300m() {
19241         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19242         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
19243         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19244                 skip "Need MDS version at least 2.7.55"
19245
19246         mkdir -p $DIR/$tdir/striped_dir
19247         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
19248                 error "set default stripes dir error"
19249
19250         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
19251
19252         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
19253         [ $stripe_count -eq 0 ] ||
19254                         error "expect 0 get $stripe_count for a"
19255
19256         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
19257                 error "set default stripes dir error"
19258
19259         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
19260
19261         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
19262         [ $stripe_count -eq 0 ] ||
19263                         error "expect 0 get $stripe_count for b"
19264
19265         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
19266                 error "set default stripes dir error"
19267
19268         mkdir $DIR/$tdir/striped_dir/c &&
19269                 error "default stripe_index is invalid, mkdir c should fails"
19270
19271         rm -rf $DIR/$tdir || error "rmdir fails"
19272 }
19273 run_test 300m "setstriped directory on single MDT FS"
19274
19275 cleanup_300n() {
19276         local list=$(comma_list $(mdts_nodes))
19277
19278         trap 0
19279         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
19280 }
19281
19282 test_300n() {
19283         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19284         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19285         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19286                 skip "Need MDS version at least 2.7.55"
19287         remote_mds_nodsh && skip "remote MDS with nodsh"
19288
19289         local stripe_index
19290         local list=$(comma_list $(mdts_nodes))
19291
19292         trap cleanup_300n RETURN EXIT
19293         mkdir -p $DIR/$tdir
19294         chmod 777 $DIR/$tdir
19295         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
19296                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
19297                 error "create striped dir succeeds with gid=0"
19298
19299         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
19300         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
19301                 error "create striped dir fails with gid=-1"
19302
19303         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
19304         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
19305                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
19306                 error "set default striped dir succeeds with gid=0"
19307
19308
19309         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
19310         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
19311                 error "set default striped dir fails with gid=-1"
19312
19313
19314         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
19315         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
19316                                         error "create test_dir fails"
19317         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
19318                                         error "create test_dir1 fails"
19319         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
19320                                         error "create test_dir2 fails"
19321         cleanup_300n
19322 }
19323 run_test 300n "non-root user to create dir under striped dir with default EA"
19324
19325 test_300o() {
19326         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19327         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19328         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19329                 skip "Need MDS version at least 2.7.55"
19330
19331         local numfree1
19332         local numfree2
19333
19334         mkdir -p $DIR/$tdir
19335
19336         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
19337         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
19338         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
19339                 skip "not enough free inodes $numfree1 $numfree2"
19340         fi
19341
19342         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
19343         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
19344         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
19345                 skip "not enough free space $numfree1 $numfree2"
19346         fi
19347
19348         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
19349                 error "setdirstripe fails"
19350
19351         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
19352                 error "create dirs fails"
19353
19354         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
19355         ls $DIR/$tdir/striped_dir > /dev/null ||
19356                 error "ls striped dir fails"
19357         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
19358                 error "unlink big striped dir fails"
19359 }
19360 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
19361
19362 test_300p() {
19363         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19364         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19365         remote_mds_nodsh && skip "remote MDS with nodsh"
19366
19367         mkdir -p $DIR/$tdir
19368
19369         #define OBD_FAIL_OUT_ENOSPC     0x1704
19370         do_facet mds2 lctl set_param fail_loc=0x80001704
19371         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
19372                  && error "create striped directory should fail"
19373
19374         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
19375
19376         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
19377         true
19378 }
19379 run_test 300p "create striped directory without space"
19380
19381 test_300q() {
19382         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19383         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19384
19385         local fd=$(free_fd)
19386         local cmd="exec $fd<$tdir"
19387         cd $DIR
19388         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
19389         eval $cmd
19390         cmd="exec $fd<&-"
19391         trap "eval $cmd" EXIT
19392         cd $tdir || error "cd $tdir fails"
19393         rmdir  ../$tdir || error "rmdir $tdir fails"
19394         mkdir local_dir && error "create dir succeeds"
19395         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
19396         eval $cmd
19397         return 0
19398 }
19399 run_test 300q "create remote directory under orphan directory"
19400
19401 test_300r() {
19402         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.7.55) ] &&
19403                 skip "Need MDS version at least 2.7.55" && return
19404         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
19405
19406         mkdir $DIR/$tdir
19407
19408         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
19409                 error "set striped dir error"
19410
19411         $LFS getdirstripe $DIR/$tdir/striped_dir ||
19412                 error "getstripeddir fails"
19413
19414         local stripe_count
19415         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
19416                       awk '/lmv_stripe_count:/ { print $2 }')
19417
19418         [ $MDSCOUNT -ne $stripe_count ] &&
19419                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
19420
19421         rm -rf $DIR/$tdir/striped_dir ||
19422                 error "unlink striped dir fails"
19423 }
19424 run_test 300r "test -1 striped directory"
19425
19426 prepare_remote_file() {
19427         mkdir $DIR/$tdir/src_dir ||
19428                 error "create remote source failed"
19429
19430         cp /etc/hosts $DIR/$tdir/src_dir/a ||
19431                  error "cp to remote source failed"
19432         touch $DIR/$tdir/src_dir/a
19433
19434         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
19435                 error "create remote target dir failed"
19436
19437         touch $DIR/$tdir/tgt_dir/b
19438
19439         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
19440                 error "rename dir cross MDT failed!"
19441
19442         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
19443                 error "src_child still exists after rename"
19444
19445         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
19446                 error "missing file(a) after rename"
19447
19448         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
19449                 error "diff after rename"
19450 }
19451
19452 test_310a() {
19453         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
19454         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19455
19456         local remote_file=$DIR/$tdir/tgt_dir/b
19457
19458         mkdir -p $DIR/$tdir
19459
19460         prepare_remote_file || error "prepare remote file failed"
19461
19462         #open-unlink file
19463         $OPENUNLINK $remote_file $remote_file ||
19464                 error "openunlink $remote_file failed"
19465         $CHECKSTAT -a $remote_file || error "$remote_file exists"
19466 }
19467 run_test 310a "open unlink remote file"
19468
19469 test_310b() {
19470         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
19471         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19472
19473         local remote_file=$DIR/$tdir/tgt_dir/b
19474
19475         mkdir -p $DIR/$tdir
19476
19477         prepare_remote_file || error "prepare remote file failed"
19478
19479         ln $remote_file $DIR/$tfile || error "link failed for remote file"
19480         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
19481         $CHECKSTAT -t file $remote_file || error "check file failed"
19482 }
19483 run_test 310b "unlink remote file with multiple links while open"
19484
19485 test_310c() {
19486         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19487         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
19488
19489         local remote_file=$DIR/$tdir/tgt_dir/b
19490
19491         mkdir -p $DIR/$tdir
19492
19493         prepare_remote_file || error "prepare remote file failed"
19494
19495         ln $remote_file $DIR/$tfile || error "link failed for remote file"
19496         multiop_bg_pause $remote_file O_uc ||
19497                         error "mulitop failed for remote file"
19498         MULTIPID=$!
19499         $MULTIOP $DIR/$tfile Ouc
19500         kill -USR1 $MULTIPID
19501         wait $MULTIPID
19502 }
19503 run_test 310c "open-unlink remote file with multiple links"
19504
19505 #LU-4825
19506 test_311() {
19507         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19508         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
19509         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
19510                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
19511         remote_mds_nodsh && skip "remote MDS with nodsh"
19512
19513         local old_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
19514         local mdts=$(comma_list $(mdts_nodes))
19515
19516         mkdir -p $DIR/$tdir
19517         $LFS setstripe -i 0 -c 1 $DIR/$tdir
19518         createmany -o $DIR/$tdir/$tfile. 1000
19519
19520         # statfs data is not real time, let's just calculate it
19521         old_iused=$((old_iused + 1000))
19522
19523         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
19524                         osp.*OST0000*MDT0000.create_count")
19525         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
19526                                 osp.*OST0000*MDT0000.max_create_count")
19527         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
19528
19529         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
19530         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
19531         [ $index -ne 0 ] || error "$tfile stripe index is 0"
19532
19533         unlinkmany $DIR/$tdir/$tfile. 1000
19534
19535         do_nodes $mdts "$LCTL set_param -n \
19536                         osp.*OST0000*.max_create_count=$max_count"
19537         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
19538                 do_nodes $mdts "$LCTL set_param -n \
19539                                 osp.*OST0000*.create_count=$count"
19540         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
19541                         grep "=0" && error "create_count is zero"
19542
19543         local new_iused
19544         for i in $(seq 120); do
19545                 new_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
19546                 # system may be too busy to destroy all objs in time, use
19547                 # a somewhat small value to not fail autotest
19548                 [ $((old_iused - new_iused)) -gt 400 ] && break
19549                 sleep 1
19550         done
19551
19552         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
19553         [ $((old_iused - new_iused)) -gt 400 ] ||
19554                 error "objs not destroyed after unlink"
19555 }
19556 run_test 311 "disable OSP precreate, and unlink should destroy objs"
19557
19558 zfs_oid_to_objid()
19559 {
19560         local ost=$1
19561         local objid=$2
19562
19563         local vdevdir=$(dirname $(facet_vdevice $ost))
19564         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
19565         local zfs_zapid=$(do_facet $ost $cmd |
19566                           grep -w "/O/0/d$((objid%32))" -C 5 |
19567                           awk '/Object/{getline; print $1}')
19568         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
19569                           awk "/$objid = /"'{printf $3}')
19570
19571         echo $zfs_objid
19572 }
19573
19574 zfs_object_blksz() {
19575         local ost=$1
19576         local objid=$2
19577
19578         local vdevdir=$(dirname $(facet_vdevice $ost))
19579         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
19580         local blksz=$(do_facet $ost $cmd $objid |
19581                       awk '/dblk/{getline; printf $4}')
19582
19583         case "${blksz: -1}" in
19584                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
19585                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
19586                 *) ;;
19587         esac
19588
19589         echo $blksz
19590 }
19591
19592 test_312() { # LU-4856
19593         remote_ost_nodsh && skip "remote OST with nodsh"
19594         [ "$ost1_FSTYPE" = "zfs" ] ||
19595                 skip_env "the test only applies to zfs"
19596
19597         local max_blksz=$(do_facet ost1 \
19598                           $ZFS get -p recordsize $(facet_device ost1) |
19599                           awk '!/VALUE/{print $3}')
19600
19601         # to make life a little bit easier
19602         $LFS mkdir -c 1 -i 0 $DIR/$tdir
19603         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19604
19605         local tf=$DIR/$tdir/$tfile
19606         touch $tf
19607         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
19608
19609         # Get ZFS object id
19610         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
19611         # block size change by sequential overwrite
19612         local bs
19613
19614         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
19615                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
19616
19617                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
19618                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
19619         done
19620         rm -f $tf
19621
19622         # block size change by sequential append write
19623         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
19624         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
19625         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
19626         local count
19627
19628         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
19629                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
19630                         oflag=sync conv=notrunc
19631
19632                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
19633                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
19634                         error "blksz error, actual $blksz, " \
19635                                 "expected: 2 * $count * $PAGE_SIZE"
19636         done
19637         rm -f $tf
19638
19639         # random write
19640         touch $tf
19641         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
19642         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
19643
19644         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
19645         blksz=$(zfs_object_blksz ost1 $zfs_objid)
19646         [ $blksz -eq $PAGE_SIZE ] ||
19647                 error "blksz error: $blksz, expected: $PAGE_SIZE"
19648
19649         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
19650         blksz=$(zfs_object_blksz ost1 $zfs_objid)
19651         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
19652
19653         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
19654         blksz=$(zfs_object_blksz ost1 $zfs_objid)
19655         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
19656 }
19657 run_test 312 "make sure ZFS adjusts its block size by write pattern"
19658
19659 test_313() {
19660         remote_ost_nodsh && skip "remote OST with nodsh"
19661
19662         local file=$DIR/$tfile
19663
19664         rm -f $file
19665         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
19666
19667         # define OBD_FAIL_TGT_RCVD_EIO           0x720
19668         do_facet ost1 "$LCTL set_param fail_loc=0x720"
19669         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
19670                 error "write should failed"
19671         do_facet ost1 "$LCTL set_param fail_loc=0"
19672         rm -f $file
19673 }
19674 run_test 313 "io should fail after last_rcvd update fail"
19675
19676 test_314() {
19677         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
19678
19679         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
19680         do_facet ost1 "$LCTL set_param fail_loc=0x720"
19681         rm -f $DIR/$tfile
19682         wait_delete_completed
19683         do_facet ost1 "$LCTL set_param fail_loc=0"
19684 }
19685 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
19686
19687 test_315() { # LU-618
19688         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
19689
19690         local file=$DIR/$tfile
19691         rm -f $file
19692
19693         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
19694                 error "multiop file write failed"
19695         $MULTIOP $file oO_RDONLY:r4063232_c &
19696         PID=$!
19697
19698         sleep 2
19699
19700         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
19701         kill -USR1 $PID
19702
19703         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
19704         rm -f $file
19705 }
19706 run_test 315 "read should be accounted"
19707
19708 test_316() {
19709         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19710         large_xattr_enabled || skip_env "ea_inode feature disabled"
19711
19712         rm -rf $DIR/$tdir/d
19713         mkdir -p $DIR/$tdir/d
19714         chown nobody $DIR/$tdir/d
19715         touch $DIR/$tdir/d/file
19716
19717         $LFS mv -M1 $DIR/$tdir/d || error "lfs mv failed"
19718 }
19719 run_test 316 "lfs mv"
19720
19721 test_317() {
19722         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
19723                 skip "Need MDS version at least 2.11.53"
19724         if [ "$ost1_FSTYPE" == "zfs" ]; then
19725                 skip "LU-10370: no implementation for ZFS"
19726         fi
19727
19728         local trunc_sz
19729         local grant_blk_size
19730
19731         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
19732                         awk '/grant_block_size:/ { print $2; exit; }')
19733         #
19734         # Create File of size 5M. Truncate it to below size's and verify
19735         # blocks count.
19736         #
19737         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
19738                 error "Create file $DIR/$tfile failed"
19739         stack_trap "rm -f $DIR/$tfile" EXIT
19740
19741         for trunc_sz in 2097152 4097 4000 509 0; do
19742                 $TRUNCATE $DIR/$tfile $trunc_sz ||
19743                         error "truncate $tfile to $trunc_sz failed"
19744                 local sz=$(stat --format=%s $DIR/$tfile)
19745                 local blk=$(stat --format=%b $DIR/$tfile)
19746                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
19747                                      grant_blk_size) * 8))
19748
19749                 if [[ $blk -ne $trunc_blk ]]; then
19750                         $(which stat) $DIR/$tfile
19751                         error "Expected Block $trunc_blk got $blk for $tfile"
19752                 fi
19753
19754                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
19755                         error "Expected Size $trunc_sz got $sz for $tfile"
19756         done
19757
19758         #
19759         # sparse file test
19760         # Create file with a hole and write actual two blocks. Block count
19761         # must be 16.
19762         #
19763         dd if=/dev/zero of=$DIR/$tfile bs=$grant_blk_size count=2 seek=5 \
19764                 conv=fsync || error "Create file : $DIR/$tfile"
19765
19766         # Calculate the final truncate size.
19767         trunc_sz=$(($(stat --format=%s $DIR/$tfile) - (grant_blk_size + 1)))
19768
19769         #
19770         # truncate to size $trunc_sz bytes. Strip the last block
19771         # The block count must drop to 8
19772         #
19773         $TRUNCATE $DIR/$tfile $trunc_sz ||
19774                 error "truncate $tfile to $trunc_sz failed"
19775
19776         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
19777         sz=$(stat --format=%s $DIR/$tfile)
19778         blk=$(stat --format=%b $DIR/$tfile)
19779
19780         if [[ $blk -ne $trunc_bsz ]]; then
19781                 $(which stat) $DIR/$tfile
19782                 error "Expected Block $trunc_bsz got $blk for $tfile"
19783         fi
19784
19785         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
19786                 error "Expected Size $trunc_sz got $sz for $tfile"
19787 }
19788 run_test 317 "Verify blocks get correctly update after truncate"
19789
19790 test_318() {
19791         local old_max_active=$($LCTL get_param -n \
19792                             llite.*.max_read_ahead_async_active 2>/dev/null)
19793
19794         $LCTL set_param llite.*.max_read_ahead_async_active=256
19795         local max_active=$($LCTL get_param -n \
19796                            llite.*.max_read_ahead_async_active 2>/dev/null)
19797         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
19798
19799         # currently reset to 0 is unsupported, leave it 512 for now.
19800         $LCTL set_param llite.*.max_read_ahead_async_active=0 &&
19801                 error "set max_read_ahead_async_active should fail"
19802
19803         $LCTL set_param llite.*.max_read_ahead_async_active=512
19804         max_active=$($LCTL get_param -n \
19805                      llite.*.max_read_ahead_async_active 2>/dev/null)
19806         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
19807
19808         # restore @max_active
19809         [ $old_max_active -ne 0 ] && $LCTL set_param \
19810                 llite.*.max_read_ahead_async_active=$old_max_active
19811
19812         local old_threshold=$($LCTL get_param -n \
19813                 llite.*.read_ahead_async_file_threshold_mb 2>/dev/null)
19814         local max_per_file_mb=$($LCTL get_param -n \
19815                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
19816
19817         local invalid=$(($max_per_file_mb + 1))
19818         $LCTL set_param \
19819                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
19820                         && error "set $invalid should fail"
19821
19822         local valid=$(($invalid - 1))
19823         $LCTL set_param \
19824                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
19825                         error "set $valid should succeed"
19826         local threshold=$($LCTL get_param -n \
19827                 llite.*.read_ahead_async_file_threshold_mb 2>/dev/null)
19828         [ $threshold -eq $valid ] || error \
19829                 "expect threshold $valid got $threshold"
19830         $LCTL set_param \
19831                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
19832 }
19833 run_test 318 "Verify async readahead tunables"
19834
19835 test_319() {
19836         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
19837
19838         local before=$(date +%s)
19839         local evict
19840         local mdir=$DIR/$tdir
19841         local file=$mdir/xxx
19842
19843         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
19844         touch $file
19845
19846 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
19847         $LCTL set_param fail_val=5 fail_loc=0x8000032c
19848         $LFS mv -m1 $file &
19849
19850         sleep 1
19851         dd if=$file of=/dev/null
19852         wait
19853         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
19854           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
19855
19856         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
19857 }
19858 run_test 319 "lost lease lock on migrate error"
19859
19860 test_fake_rw() {
19861         local read_write=$1
19862         if [ "$read_write" = "write" ]; then
19863                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
19864         elif [ "$read_write" = "read" ]; then
19865                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
19866         else
19867                 error "argument error"
19868         fi
19869
19870         # turn off debug for performance testing
19871         local saved_debug=$($LCTL get_param -n debug)
19872         $LCTL set_param debug=0
19873
19874         $LFS setstripe -c 1 -i 0 $DIR/$tfile
19875
19876         # get ost1 size - lustre-OST0000
19877         local ost1_avail_size=$($LFS df | awk /${ost1_svc}/'{ print $4 }')
19878         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
19879         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
19880
19881         if [ "$read_write" = "read" ]; then
19882                 truncate -s $(expr 1048576 \* $blocks) $DIR/$tfile
19883         fi
19884
19885         local start_time=$(date +%s.%N)
19886         $dd_cmd bs=1M count=$blocks oflag=sync ||
19887                 error "real dd $read_write error"
19888         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
19889
19890         if [ "$read_write" = "write" ]; then
19891                 rm -f $DIR/$tfile
19892         fi
19893
19894         # define OBD_FAIL_OST_FAKE_RW           0x238
19895         do_facet ost1 $LCTL set_param fail_loc=0x238
19896
19897         local start_time=$(date +%s.%N)
19898         $dd_cmd bs=1M count=$blocks oflag=sync ||
19899                 error "fake dd $read_write error"
19900         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
19901
19902         if [ "$read_write" = "write" ]; then
19903                 # verify file size
19904                 cancel_lru_locks osc
19905                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
19906                         error "$tfile size not $blocks MB"
19907         fi
19908         do_facet ost1 $LCTL set_param fail_loc=0
19909
19910         echo "fake $read_write $duration_fake vs. normal $read_write" \
19911                 "$duration in seconds"
19912         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
19913                 error_not_in_vm "fake write is slower"
19914
19915         $LCTL set_param -n debug="$saved_debug"
19916         rm -f $DIR/$tfile
19917 }
19918 test_399a() { # LU-7655 for OST fake write
19919         remote_ost_nodsh && skip "remote OST with nodsh"
19920
19921         test_fake_rw write
19922 }
19923 run_test 399a "fake write should not be slower than normal write"
19924
19925 test_399b() { # LU-8726 for OST fake read
19926         remote_ost_nodsh && skip "remote OST with nodsh"
19927         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
19928                 skip_env "ldiskfs only test"
19929         fi
19930
19931         test_fake_rw read
19932 }
19933 run_test 399b "fake read should not be slower than normal read"
19934
19935 test_400a() { # LU-1606, was conf-sanity test_74
19936         if ! which $CC > /dev/null 2>&1; then
19937                 skip_env "$CC is not installed"
19938         fi
19939
19940         local extra_flags=''
19941         local out=$TMP/$tfile
19942         local prefix=/usr/include/lustre
19943         local prog
19944
19945         if ! [[ -d $prefix ]]; then
19946                 # Assume we're running in tree and fixup the include path.
19947                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
19948                 extra_flags+=" -L$LUSTRE/utils/.lib"
19949         fi
19950
19951         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
19952                 $CC -Wall -Werror $extra_flags -o $out $prog -llustreapi ||
19953                         error "client api broken"
19954         done
19955         rm -f $out
19956 }
19957 run_test 400a "Lustre client api program can compile and link"
19958
19959 test_400b() { # LU-1606, LU-5011
19960         local header
19961         local out=$TMP/$tfile
19962         local prefix=/usr/include/linux/lustre
19963
19964         # We use a hard coded prefix so that this test will not fail
19965         # when run in tree. There are headers in lustre/include/lustre/
19966         # that are not packaged (like lustre_idl.h) and have more
19967         # complicated include dependencies (like config.h and lnet/types.h).
19968         # Since this test about correct packaging we just skip them when
19969         # they don't exist (see below) rather than try to fixup cppflags.
19970
19971         if ! which $CC > /dev/null 2>&1; then
19972                 skip_env "$CC is not installed"
19973         fi
19974
19975         for header in $prefix/*.h; do
19976                 if ! [[ -f "$header" ]]; then
19977                         continue
19978                 fi
19979
19980                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
19981                         continue # lustre_ioctl.h is internal header
19982                 fi
19983
19984                 $CC -Wall -Werror -include $header -c -x c /dev/null -o $out ||
19985                         error "cannot compile '$header'"
19986         done
19987         rm -f $out
19988 }
19989 run_test 400b "packaged headers can be compiled"
19990
19991 test_401a() { #LU-7437
19992         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
19993         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
19994
19995         #count the number of parameters by "list_param -R"
19996         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
19997         #count the number of parameters by listing proc files
19998         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
19999         echo "proc_dirs='$proc_dirs'"
20000         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
20001         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
20002                       sort -u | wc -l)
20003
20004         [ $params -eq $procs ] ||
20005                 error "found $params parameters vs. $procs proc files"
20006
20007         # test the list_param -D option only returns directories
20008         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
20009         #count the number of parameters by listing proc directories
20010         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
20011                 sort -u | wc -l)
20012
20013         [ $params -eq $procs ] ||
20014                 error "found $params parameters vs. $procs proc files"
20015 }
20016 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
20017
20018 test_401b() {
20019         local save=$($LCTL get_param -n jobid_var)
20020         local tmp=testing
20021
20022         $LCTL set_param foo=bar jobid_var=$tmp bar=baz &&
20023                 error "no error returned when setting bad parameters"
20024
20025         local jobid_new=$($LCTL get_param -n foe jobid_var baz)
20026         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
20027
20028         $LCTL set_param -n fog=bam jobid_var=$save bat=fog
20029         local jobid_old=$($LCTL get_param -n foe jobid_var bag)
20030         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
20031 }
20032 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
20033
20034 test_401c() {
20035         local jobid_var_old=$($LCTL get_param -n jobid_var)
20036         local jobid_var_new
20037
20038         $LCTL set_param jobid_var= &&
20039                 error "no error returned for 'set_param a='"
20040
20041         jobid_var_new=$($LCTL get_param -n jobid_var)
20042         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
20043                 error "jobid_var was changed by setting without value"
20044
20045         $LCTL set_param jobid_var &&
20046                 error "no error returned for 'set_param a'"
20047
20048         jobid_var_new=$($LCTL get_param -n jobid_var)
20049         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
20050                 error "jobid_var was changed by setting without value"
20051 }
20052 run_test 401c "Verify 'lctl set_param' without value fails in either format."
20053
20054 test_401d() {
20055         local jobid_var_old=$($LCTL get_param -n jobid_var)
20056         local jobid_var_new
20057         local new_value="foo=bar"
20058
20059         $LCTL set_param jobid_var=$new_value ||
20060                 error "'set_param a=b' did not accept a value containing '='"
20061
20062         jobid_var_new=$($LCTL get_param -n jobid_var)
20063         [[ "$jobid_var_new" == "$new_value" ]] ||
20064                 error "'set_param a=b' failed on a value containing '='"
20065
20066         # Reset the jobid_var to test the other format
20067         $LCTL set_param jobid_var=$jobid_var_old
20068         jobid_var_new=$($LCTL get_param -n jobid_var)
20069         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
20070                 error "failed to reset jobid_var"
20071
20072         $LCTL set_param jobid_var $new_value ||
20073                 error "'set_param a b' did not accept a value containing '='"
20074
20075         jobid_var_new=$($LCTL get_param -n jobid_var)
20076         [[ "$jobid_var_new" == "$new_value" ]] ||
20077                 error "'set_param a b' failed on a value containing '='"
20078
20079         $LCTL set_param jobid_var $jobid_var_old
20080         jobid_var_new=$($LCTL get_param -n jobid_var)
20081         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
20082                 error "failed to reset jobid_var"
20083 }
20084 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
20085
20086 test_402() {
20087         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
20088         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
20089                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
20090         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
20091                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
20092                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
20093         remote_mds_nodsh && skip "remote MDS with nodsh"
20094
20095         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
20096 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
20097         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
20098         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
20099                 echo "Touch failed - OK"
20100 }
20101 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
20102
20103 test_403() {
20104         local file1=$DIR/$tfile.1
20105         local file2=$DIR/$tfile.2
20106         local tfile=$TMP/$tfile
20107
20108         rm -f $file1 $file2 $tfile
20109
20110         touch $file1
20111         ln $file1 $file2
20112
20113         # 30 sec OBD_TIMEOUT in ll_getattr()
20114         # right before populating st_nlink
20115         $LCTL set_param fail_loc=0x80001409
20116         stat -c %h $file1 > $tfile &
20117
20118         # create an alias, drop all locks and reclaim the dentry
20119         < $file2
20120         cancel_lru_locks mdc
20121         cancel_lru_locks osc
20122         sysctl -w vm.drop_caches=2
20123
20124         wait
20125
20126         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
20127
20128         rm -f $tfile $file1 $file2
20129 }
20130 run_test 403 "i_nlink should not drop to zero due to aliasing"
20131
20132 test_404() { # LU-6601
20133         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
20134                 skip "Need server version newer than 2.8.52"
20135         remote_mds_nodsh && skip "remote MDS with nodsh"
20136
20137         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
20138                 awk '/osp .*-osc-MDT/ { print $4}')
20139
20140         local osp
20141         for osp in $mosps; do
20142                 echo "Deactivate: " $osp
20143                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
20144                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
20145                         awk -vp=$osp '$4 == p { print $2 }')
20146                 [ $stat = IN ] || {
20147                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
20148                         error "deactivate error"
20149                 }
20150                 echo "Activate: " $osp
20151                 do_facet $SINGLEMDS $LCTL --device %$osp activate
20152                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
20153                         awk -vp=$osp '$4 == p { print $2 }')
20154                 [ $stat = UP ] || {
20155                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
20156                         error "activate error"
20157                 }
20158         done
20159 }
20160 run_test 404 "validate manual {de}activated works properly for OSPs"
20161
20162 test_405() {
20163         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
20164         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
20165                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
20166                         skip "Layout swap lock is not supported"
20167
20168         check_swap_layouts_support
20169
20170         test_mkdir $DIR/$tdir
20171         swap_lock_test -d $DIR/$tdir ||
20172                 error "One layout swap locked test failed"
20173 }
20174 run_test 405 "Various layout swap lock tests"
20175
20176 test_406() {
20177         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20178         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
20179         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
20180         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20181         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
20182                 skip "Need MDS version at least 2.8.50"
20183
20184         local def_stripe_size=$($LFS getstripe -S $MOUNT)
20185         local test_pool=$TESTNAME
20186
20187         if ! combined_mgs_mds ; then
20188                 mount_mgs_client
20189         fi
20190         pool_add $test_pool || error "pool_add failed"
20191         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
20192                 error "pool_add_targets failed"
20193
20194         save_layout_restore_at_exit $MOUNT
20195
20196         # parent set default stripe count only, child will stripe from both
20197         # parent and fs default
20198         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
20199                 error "setstripe $MOUNT failed"
20200         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
20201         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
20202         for i in $(seq 10); do
20203                 local f=$DIR/$tdir/$tfile.$i
20204                 touch $f || error "touch failed"
20205                 local count=$($LFS getstripe -c $f)
20206                 [ $count -eq $OSTCOUNT ] ||
20207                         error "$f stripe count $count != $OSTCOUNT"
20208                 local offset=$($LFS getstripe -i $f)
20209                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
20210                 local size=$($LFS getstripe -S $f)
20211                 [ $size -eq $((def_stripe_size * 2)) ] ||
20212                         error "$f stripe size $size != $((def_stripe_size * 2))"
20213                 local pool=$($LFS getstripe -p $f)
20214                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
20215         done
20216
20217         # change fs default striping, delete parent default striping, now child
20218         # will stripe from new fs default striping only
20219         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
20220                 error "change $MOUNT default stripe failed"
20221         $LFS setstripe -c 0 $DIR/$tdir ||
20222                 error "delete $tdir default stripe failed"
20223         for i in $(seq 11 20); do
20224                 local f=$DIR/$tdir/$tfile.$i
20225                 touch $f || error "touch $f failed"
20226                 local count=$($LFS getstripe -c $f)
20227                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
20228                 local offset=$($LFS getstripe -i $f)
20229                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
20230                 local size=$($LFS getstripe -S $f)
20231                 [ $size -eq $def_stripe_size ] ||
20232                         error "$f stripe size $size != $def_stripe_size"
20233                 local pool=$($LFS getstripe -p $f)
20234                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
20235         done
20236
20237         unlinkmany $DIR/$tdir/$tfile. 1 20
20238
20239         local f=$DIR/$tdir/$tfile
20240         pool_remove_all_targets $test_pool $f
20241         pool_remove $test_pool $f
20242
20243         if ! combined_mgs_mds ; then
20244                 umount_mgs_client
20245         fi
20246 }
20247 run_test 406 "DNE support fs default striping"
20248
20249 test_407() {
20250         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20251         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
20252                 skip "Need MDS version at least 2.8.55"
20253         remote_mds_nodsh && skip "remote MDS with nodsh"
20254
20255         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
20256                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
20257         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
20258                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
20259         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
20260
20261         #define OBD_FAIL_DT_TXN_STOP    0x2019
20262         for idx in $(seq $MDSCOUNT); do
20263                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
20264         done
20265         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
20266         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
20267                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
20268         true
20269 }
20270 run_test 407 "transaction fail should cause operation fail"
20271
20272 test_408() {
20273         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
20274
20275         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
20276         lctl set_param fail_loc=0x8000040a
20277         # let ll_prepare_partial_page() fail
20278         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
20279
20280         rm -f $DIR/$tfile
20281
20282         # create at least 100 unused inodes so that
20283         # shrink_icache_memory(0) should not return 0
20284         touch $DIR/$tfile-{0..100}
20285         rm -f $DIR/$tfile-{0..100}
20286         sync
20287
20288         echo 2 > /proc/sys/vm/drop_caches
20289 }
20290 run_test 408 "drop_caches should not hang due to page leaks"
20291
20292 test_409()
20293 {
20294         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20295
20296         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
20297         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
20298         touch $DIR/$tdir/guard || error "(2) Fail to create"
20299
20300         local PREFIX=$(str_repeat 'A' 128)
20301         echo "Create 1K hard links start at $(date)"
20302         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
20303                 error "(3) Fail to hard link"
20304
20305         echo "Links count should be right although linkEA overflow"
20306         stat $DIR/$tdir/guard || error "(4) Fail to stat"
20307         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
20308         [ $linkcount -eq 1001 ] ||
20309                 error "(5) Unexpected hard links count: $linkcount"
20310
20311         echo "List all links start at $(date)"
20312         ls -l $DIR/$tdir/foo > /dev/null ||
20313                 error "(6) Fail to list $DIR/$tdir/foo"
20314
20315         echo "Unlink hard links start at $(date)"
20316         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
20317                 error "(7) Fail to unlink"
20318         echo "Unlink hard links finished at $(date)"
20319 }
20320 run_test 409 "Large amount of cross-MDTs hard links on the same file"
20321
20322 test_410()
20323 {
20324         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
20325                 skip "Need client version at least 2.9.59"
20326
20327         # Create a file, and stat it from the kernel
20328         local testfile=$DIR/$tfile
20329         touch $testfile
20330
20331         local run_id=$RANDOM
20332         local my_ino=$(stat --format "%i" $testfile)
20333
20334         # Try to insert the module. This will always fail as the
20335         # module is designed to not be inserted.
20336         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
20337             &> /dev/null
20338
20339         # Anything but success is a test failure
20340         dmesg | grep -q \
20341             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
20342             error "no inode match"
20343 }
20344 run_test 410 "Test inode number returned from kernel thread"
20345
20346 cleanup_test411_cgroup() {
20347         trap 0
20348         rmdir "$1"
20349 }
20350
20351 test_411() {
20352         local cg_basedir=/sys/fs/cgroup/memory
20353         # LU-9966
20354         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
20355                 skip "no setup for cgroup"
20356
20357         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
20358                 error "test file creation failed"
20359         cancel_lru_locks osc
20360
20361         # Create a very small memory cgroup to force a slab allocation error
20362         local cgdir=$cg_basedir/osc_slab_alloc
20363         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
20364         trap "cleanup_test411_cgroup $cgdir" EXIT
20365         echo 2M > $cgdir/memory.kmem.limit_in_bytes
20366         echo 1M > $cgdir/memory.limit_in_bytes
20367
20368         # Should not LBUG, just be killed by oom-killer
20369         # dd will return 0 even allocation failure in some environment.
20370         # So don't check return value
20371         sh -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
20372         cleanup_test411_cgroup $cgdir
20373
20374         return 0
20375 }
20376 run_test 411 "Slab allocation error with cgroup does not LBUG"
20377
20378 test_412() {
20379         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20380         if [ $(lustre_version_code mds1) -lt $(version_code 2.10.55) ]; then
20381                 skip "Need server version at least 2.10.55"
20382         fi
20383
20384         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
20385                 error "mkdir failed"
20386         $LFS getdirstripe $DIR/$tdir
20387         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
20388         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
20389                 error "expect $((MDSCOUT - 1)) get $stripe_index"
20390         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
20391         [ $stripe_count -eq 2 ] ||
20392                 error "expect 2 get $stripe_count"
20393 }
20394 run_test 412 "mkdir on specific MDTs"
20395
20396 test_413a() {
20397         [ $MDSCOUNT -lt 2 ] &&
20398                 skip "We need at least 2 MDTs for this test"
20399
20400         if [ $(lustre_version_code mds1) -lt $(version_code 2.10.55) ]; then
20401                 skip "Need server version at least 2.10.55"
20402         fi
20403
20404         mkdir $DIR/$tdir || error "mkdir failed"
20405
20406         # find MDT that is the most full
20407         local max=$($LFS df | grep MDT |
20408                 awk 'BEGIN { a=0 }
20409                         { sub("%", "", $5)
20410                           if (0+$5 >= a)
20411                           {
20412                                 a = $5
20413                                 b = $6
20414                           }
20415                         }
20416                      END { split(b, c, ":")
20417                            sub("]", "", c[2])
20418                            print c[2]
20419                          }')
20420
20421         for i in $(seq $((MDSCOUNT - 1))); do
20422                 $LFS mkdir -c $i $DIR/$tdir/d$i ||
20423                         error "mkdir d$i failed"
20424                 $LFS getdirstripe $DIR/$tdir/d$i
20425                 local stripe_index=$($LFS getdirstripe -i $DIR/$tdir/d$i)
20426                 [ $stripe_index -ne $max ] ||
20427                         error "don't expect $max"
20428         done
20429 }
20430 run_test 413a "mkdir on less full MDTs"
20431
20432 test_413b() {
20433         [ $MDSCOUNT -lt 2 ] &&
20434                 skip "We need at least 2 MDTs for this test"
20435
20436         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
20437                 skip "Need server version at least 2.12.52"
20438
20439         mkdir $DIR/$tdir || error "mkdir failed"
20440         $LFS setdirstripe -D -i -1 -H space $DIR/$tdir ||
20441                 error "setdirstripe failed"
20442
20443         local qos_prio_free
20444         local qos_threshold_rr
20445         local count
20446
20447         qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
20448         qos_prio_free=${qos_prio_free%%%}
20449         qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr | head -n1)
20450         qos_threshold_rr=${qos_threshold_rr%%%}
20451         qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
20452
20453         stack_trap "$LCTL set_param lmv.*.qos_prio_free=$qos_prio_free" EXIT
20454         stack_trap "$LCTL set_param lmv.*.qos_threshold_rr=$qos_threshold_rr" \
20455                 EXIT
20456         stack_trap "$LCTL set_param lmv.*.qos_maxage=$qos_maxage" EXIT
20457
20458         echo "mkdir with roundrobin"
20459
20460         $LCTL set_param lmv.*.qos_threshold_rr=100
20461         for i in $(seq $((100 * MDSCOUNT))); do
20462                 mkdir $DIR/$tdir/subdir$i || error "mkdir subdir$i failed"
20463         done
20464         for i in $(seq $MDSCOUNT); do
20465                 count=$($LFS getdirstripe -i $DIR/$tdir/* | grep ^$((i - 1))$ |
20466                         wc -w)
20467                 echo "$count directories created on MDT$((i - 1))"
20468                 [ $count -eq 100 ] || error "subdirs are not evenly distributed"
20469         done
20470
20471         rm -rf $DIR/$tdir/*
20472
20473         $LCTL set_param lmv.*.qos_threshold_rr=$qos_threshold_rr
20474         # Shorten statfs result age, so that it can be updated in time
20475         $LCTL set_param lmv.*.qos_maxage=1
20476         sleep_maxage
20477
20478         local ffree
20479         local max
20480         local min
20481         local max_index
20482         local min_index
20483
20484         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree | uniq))
20485         echo "MDT filesfree available: ${ffree[@]}"
20486         max=${ffree[0]}
20487         min=${ffree[0]}
20488         max_index=0
20489         min_index=0
20490         for ((i = 0; i < ${#ffree[@]}; i++)); do
20491                 if [[ ${ffree[i]} -gt $max ]]; then
20492                         max=${ffree[i]}
20493                         max_index=$i
20494                 fi
20495                 if [[ ${ffree[i]} -lt $min ]]; then
20496                         min=${ffree[i]}
20497                         min_index=$i
20498                 fi
20499         done
20500         echo "Min free files: MDT$min_index: $min"
20501         echo "Max free files: MDT$max_index: $max"
20502
20503         [ $min -eq 0 ] && skip "no free files in MDT$min_index"
20504         [ $min -gt 10000000 ] && skip "too much free files in MDT$min_index"
20505
20506         # Check if we need to generate uneven MDTs
20507         test_mkdir -i $min_index -c 1 -p $DIR/$tdir-MDT$min_index
20508         local threshold=10
20509         local diff=$((max - min))
20510         local diff2=$((diff * 100 / min))
20511
20512         echo -n "Check for uneven MDTs: "
20513         echo -n "diff=$diff files ($diff2%) must be > $threshold% ..."
20514
20515         if [ $diff2 -gt $threshold ]; then
20516                 echo "ok"
20517                 echo "Don't need to fill MDT$min_index"
20518         else
20519                 # generate uneven MDTs, create till 25% diff
20520                 echo "no"
20521                 diff2=$((threshold - diff2))
20522                 diff=$((min * diff2 / 100))
20523                 # 50 sec per 10000 files in vm
20524                 [ $diff -gt 40000 ] && [ "$SLOW" = "no" ] &&
20525                         skip "$diff files to create"
20526                 echo "Fill $diff2% diff in MDT$min_index with $diff files"
20527                 local i
20528                 local value="$(generate_string 1024)"
20529                 for i in $(seq $diff); do
20530                         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE \
20531                                 $DIR/$tdir-MDT$min_index/f$i > /dev/null ||
20532                                 error "create f$i failed"
20533                         setfattr -n user.413b -v $value \
20534                                 $DIR/$tdir-MDT$min_index/f$i ||
20535                                 error "setfattr f$i failed"
20536                 done
20537         fi
20538
20539         min=$((100 *MDSCOUNT))
20540         max=0
20541
20542         echo "mkdir with balanced space usage"
20543         $LCTL set_param lmv.*.qos_prio_free=100
20544         for i in $(seq $((100 * MDSCOUNT))); do
20545                 mkdir $DIR/$tdir/subdir$i || error "mkdir subdir$i failed"
20546         done
20547         for i in $(seq $MDSCOUNT); do
20548                 count=$($LFS getdirstripe -i $DIR/$tdir/* | grep ^$((i - 1))$ |
20549                         wc -w)
20550                 echo "$count directories created on MDT$((i - 1))"
20551                 [ $min -gt $count ] && min=$count
20552                 [ $max -lt $count ] && max=$count
20553         done
20554         [ $((max - min)) -gt $MDSCOUNT ] ||
20555                 error "subdirs shouldn't be evenly distributed"
20556
20557         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
20558
20559         $LFS setdirstripe -D -d $DIR/$tdir || error "setdirstripe -d failed"
20560         getfattr -n trusted.dmv $DIR/$tdir && error "default dir layout exists"
20561         true
20562 }
20563 run_test 413b "mkdir with balanced space usage"
20564
20565 test_414() {
20566 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
20567         $LCTL set_param fail_loc=0x80000521
20568         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
20569         rm -f $DIR/$tfile
20570 }
20571 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
20572
20573 test_415() {
20574         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20575         [ $(lustre_version_code mds1) -lt $(version_code 2.11.52) ] &&
20576                 skip "Need server version at least 2.11.52"
20577
20578         # LU-11102
20579         local total
20580         local setattr_pid
20581         local start_time
20582         local end_time
20583         local duration
20584
20585         total=500
20586         # this test may be slow on ZFS
20587         [ "$mds1_FSTYPE" == "zfs" ] && total=100
20588
20589         # though this test is designed for striped directory, let's test normal
20590         # directory too since lock is always saved as CoS lock.
20591         test_mkdir $DIR/$tdir || error "mkdir $tdir"
20592         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
20593
20594         (
20595                 while true; do
20596                         touch $DIR/$tdir
20597                 done
20598         ) &
20599         setattr_pid=$!
20600
20601         start_time=$(date +%s)
20602         for i in $(seq $total); do
20603                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
20604                         > /dev/null
20605         done
20606         end_time=$(date +%s)
20607         duration=$((end_time - start_time))
20608
20609         kill -9 $setattr_pid
20610
20611         echo "rename $total files took $duration sec"
20612         [ $duration -lt 100 ] || error "rename took $duration sec"
20613 }
20614 run_test 415 "lock revoke is not missing"
20615
20616 test_416() {
20617         [ $(lustre_version_code mds1) -lt $(version_code 2.11.55) ] &&
20618                 skip "Need server version at least 2.11.55"
20619
20620         # define OBD_FAIL_OSD_TXN_START    0x19a
20621         do_facet mds1 lctl set_param fail_loc=0x19a
20622
20623         lfs mkdir -c $MDSCOUNT $DIR/$tdir
20624
20625         true
20626 }
20627 run_test 416 "transaction start failure won't cause system hung"
20628
20629 cleanup_417() {
20630         trap 0
20631         do_nodes $(comma_list $(mdts_nodes)) \
20632                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
20633         do_nodes $(comma_list $(mdts_nodes)) \
20634                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
20635         do_nodes $(comma_list $(mdts_nodes)) \
20636                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
20637 }
20638
20639 test_417() {
20640         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20641         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
20642                 skip "Need MDS version at least 2.11.56"
20643
20644         trap cleanup_417 RETURN EXIT
20645
20646         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
20647         do_nodes $(comma_list $(mdts_nodes)) \
20648                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
20649         $LFS migrate -m 0 $DIR/$tdir.1 &&
20650                 error "migrate dir $tdir.1 should fail"
20651
20652         do_nodes $(comma_list $(mdts_nodes)) \
20653                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
20654         $LFS mkdir -i 1 $DIR/$tdir.2 &&
20655                 error "create remote dir $tdir.2 should fail"
20656
20657         do_nodes $(comma_list $(mdts_nodes)) \
20658                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
20659         $LFS mkdir -c 2 $DIR/$tdir.3 &&
20660                 error "create striped dir $tdir.3 should fail"
20661         true
20662 }
20663 run_test 417 "disable remote dir, striped dir and dir migration"
20664
20665 # Checks that the outputs of df [-i] and lfs df [-i] match
20666 #
20667 # usage: check_lfs_df <blocks | inodes> <mountpoint>
20668 check_lfs_df() {
20669         local dir=$2
20670         local inodes
20671         local df_out
20672         local lfs_df_out
20673         local count
20674         local passed=false
20675
20676         # blocks or inodes
20677         [ "$1" == "blocks" ] && inodes= || inodes="-i"
20678
20679         for count in {1..100}; do
20680                 cancel_lru_locks
20681                 sync; sleep 0.2
20682
20683                 # read the lines of interest
20684                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
20685                         error "df $inodes $dir | tail -n +2 failed"
20686                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
20687                         error "lfs df $inodes $dir | grep summary: failed"
20688
20689                 # skip first substrings of each output as they are different
20690                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
20691                 # compare the two outputs
20692                 passed=true
20693                 for i in {1..5}; do
20694                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
20695                 done
20696                 $passed && break
20697         done
20698
20699         if ! $passed; then
20700                 df -P $inodes $dir
20701                 echo
20702                 lfs df $inodes $dir
20703                 error "df and lfs df $1 output mismatch: "      \
20704                       "df ${inodes}: ${df_out[*]}, "            \
20705                       "lfs df ${inodes}: ${lfs_df_out[*]}"
20706         fi
20707 }
20708
20709 test_418() {
20710         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20711
20712         local dir=$DIR/$tdir
20713         local numfiles=$((RANDOM % 4096 + 2))
20714         local numblocks=$((RANDOM % 256 + 1))
20715
20716         wait_delete_completed
20717         test_mkdir $dir
20718
20719         # check block output
20720         check_lfs_df blocks $dir
20721         # check inode output
20722         check_lfs_df inodes $dir
20723
20724         # create a single file and retest
20725         echo "Creating a single file and testing"
20726         createmany -o $dir/$tfile- 1 &>/dev/null ||
20727                 error "creating 1 file in $dir failed"
20728         check_lfs_df blocks $dir
20729         check_lfs_df inodes $dir
20730
20731         # create a random number of files
20732         echo "Creating $((numfiles - 1)) files and testing"
20733         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
20734                 error "creating $((numfiles - 1)) files in $dir failed"
20735
20736         # write a random number of blocks to the first test file
20737         echo "Writing $numblocks 4K blocks and testing"
20738         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
20739                 count=$numblocks &>/dev/null ||
20740                 error "dd to $dir/${tfile}-0 failed"
20741
20742         # retest
20743         check_lfs_df blocks $dir
20744         check_lfs_df inodes $dir
20745
20746         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
20747                 error "unlinking $numfiles files in $dir failed"
20748 }
20749 run_test 418 "df and lfs df outputs match"
20750
20751 test_419()
20752 {
20753         local dir=$DIR/$tdir
20754
20755         mkdir -p $dir
20756         touch $dir/file
20757
20758         cancel_lru_locks mdc
20759
20760         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
20761         $LCTL set_param fail_loc=0x1410
20762         cat $dir/file
20763         $LCTL set_param fail_loc=0
20764         rm -rf $dir
20765 }
20766 run_test 419 "Verify open file by name doesn't crash kernel"
20767
20768 test_420()
20769 {
20770         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
20771                 skip "Need MDS version at least 2.12.53"
20772
20773         local SAVE_UMASK=$(umask)
20774         local dir=$DIR/$tdir
20775         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
20776
20777         mkdir -p $dir
20778         umask 0000
20779         mkdir -m03777 $dir/testdir
20780         ls -dn $dir/testdir
20781         # Need to remove trailing '.' when SELinux is enabled
20782         local dirperms=$(ls -dn $dir/testdir |
20783                          awk '{ sub(/\.$/, "", $1); print $1}')
20784         [ $dirperms == "drwxrwsrwt" ] ||
20785                 error "incorrect perms on $dir/testdir"
20786
20787         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
20788                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
20789         ls -n $dir/testdir/testfile
20790         local fileperms=$(ls -n $dir/testdir/testfile |
20791                           awk '{ sub(/\.$/, "", $1); print $1}')
20792         [ $fileperms == "-rwxr-xr-x" ] ||
20793                 error "incorrect perms on $dir/testdir/testfile"
20794
20795         umask $SAVE_UMASK
20796 }
20797 run_test 420 "clear SGID bit on non-directories for non-members"
20798
20799 test_421a() {
20800         local cnt
20801         local fid1
20802         local fid2
20803
20804         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
20805                 skip "Need MDS version at least 2.12.54"
20806
20807         test_mkdir $DIR/$tdir
20808         createmany -o $DIR/$tdir/f 3
20809         cnt=$(ls -1 $DIR/$tdir | wc -l)
20810         [ $cnt != 3 ] && error "unexpected #files: $cnt"
20811
20812         fid1=$(lfs path2fid $DIR/$tdir/f1)
20813         fid2=$(lfs path2fid $DIR/$tdir/f2)
20814         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
20815
20816         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
20817         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
20818
20819         cnt=$(ls -1 $DIR/$tdir | wc -l)
20820         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
20821
20822         rm -f $DIR/$tdir/f3 || error "can't remove f3"
20823         createmany -o $DIR/$tdir/f 3
20824         cnt=$(ls -1 $DIR/$tdir | wc -l)
20825         [ $cnt != 3 ] && error "unexpected #files: $cnt"
20826
20827         fid1=$(lfs path2fid $DIR/$tdir/f1)
20828         fid2=$(lfs path2fid $DIR/$tdir/f2)
20829         echo "remove using fsname $FSNAME"
20830         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
20831
20832         cnt=$(ls -1 $DIR/$tdir | wc -l)
20833         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
20834 }
20835 run_test 421a "simple rm by fid"
20836
20837 test_421b() {
20838         local cnt
20839         local FID1
20840         local FID2
20841
20842         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
20843                 skip "Need MDS version at least 2.12.54"
20844
20845         test_mkdir $DIR/$tdir
20846         createmany -o $DIR/$tdir/f 3
20847         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
20848         MULTIPID=$!
20849
20850         FID1=$(lfs path2fid $DIR/$tdir/f1)
20851         FID2=$(lfs path2fid $DIR/$tdir/f2)
20852         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
20853
20854         kill -USR1 $MULTIPID
20855         wait
20856
20857         cnt=$(ls $DIR/$tdir | wc -l)
20858         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
20859 }
20860 run_test 421b "rm by fid on open file"
20861
20862 test_421c() {
20863         local cnt
20864         local FIDS
20865
20866         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
20867                 skip "Need MDS version at least 2.12.54"
20868
20869         test_mkdir $DIR/$tdir
20870         createmany -o $DIR/$tdir/f 3
20871         touch $DIR/$tdir/$tfile
20872         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
20873         cnt=$(ls -1 $DIR/$tdir | wc -l)
20874         [ $cnt != 184 ] && error "unexpected #files: $cnt"
20875
20876         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
20877         $LFS rmfid $DIR $FID1 || error "rmfid failed"
20878
20879         cnt=$(ls $DIR/$tdir | wc -l)
20880         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
20881 }
20882 run_test 421c "rm by fid against hardlinked files"
20883
20884 test_421d() {
20885         local cnt
20886         local FIDS
20887
20888         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
20889                 skip "Need MDS version at least 2.12.54"
20890
20891         test_mkdir $DIR/$tdir
20892         createmany -o $DIR/$tdir/f 4097
20893         cnt=$(ls -1 $DIR/$tdir | wc -l)
20894         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
20895
20896         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
20897         $LFS rmfid $DIR $FIDS || error "rmfid failed"
20898
20899         cnt=$(ls $DIR/$tdir | wc -l)
20900         rm -rf $DIR/$tdir
20901         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
20902 }
20903 run_test 421d "rmfid en masse"
20904
20905 test_421e() {
20906         local cnt
20907         local FID
20908
20909         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20910         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
20911                 skip "Need MDS version at least 2.12.54"
20912
20913         mkdir -p $DIR/$tdir
20914         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
20915         createmany -o $DIR/$tdir/striped_dir/f 512
20916         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
20917         [ $cnt != 512 ] && error "unexpected #files: $cnt"
20918
20919         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
20920                 sed "s/[/][^:]*://g")
20921         $LFS rmfid $DIR $FIDS || error "rmfid failed"
20922
20923         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
20924         rm -rf $DIR/$tdir
20925         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
20926 }
20927 run_test 421e "rmfid in DNE"
20928
20929 test_421f() {
20930         local cnt
20931         local FID
20932
20933         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
20934                 skip "Need MDS version at least 2.12.54"
20935
20936         test_mkdir $DIR/$tdir
20937         touch $DIR/$tdir/f
20938         cnt=$(ls -1 $DIR/$tdir | wc -l)
20939         [ $cnt != 1 ] && error "unexpected #files: $cnt"
20940
20941         FID=$(lfs path2fid $DIR/$tdir/f)
20942         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
20943         # rmfid should fail
20944         cnt=$(ls -1 $DIR/$tdir | wc -l)
20945         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
20946
20947         chmod a+rw $DIR/$tdir
20948         ls -la $DIR/$tdir
20949         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
20950         # rmfid should fail
20951         cnt=$(ls -1 $DIR/$tdir | wc -l)
20952         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
20953
20954         rm -f $DIR/$tdir/f
20955         $RUNAS touch $DIR/$tdir/f
20956         FID=$(lfs path2fid $DIR/$tdir/f)
20957         echo "rmfid as root"
20958         $LFS rmfid $DIR $FID || error "rmfid as root failed"
20959         cnt=$(ls -1 $DIR/$tdir | wc -l)
20960         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
20961
20962         rm -f $DIR/$tdir/f
20963         $RUNAS touch $DIR/$tdir/f
20964         cnt=$(ls -1 $DIR/$tdir | wc -l)
20965         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
20966         FID=$(lfs path2fid $DIR/$tdir/f)
20967         # rmfid w/o user_fid2path mount option should fail
20968         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
20969         cnt=$(ls -1 $DIR/$tdir | wc -l)
20970         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
20971
20972         umount_client $MOUNT || "failed to umount client"
20973         mount_client $MOUNT "$MOUNT_OPTS,user_fid2path" ||
20974                 "failed to mount client'"
20975
20976         $RUNAS $LFS rmfid $DIR $FID || error "rmfid failed"
20977         # rmfid should succeed
20978         cnt=$(ls -1 $DIR/$tdir | wc -l)
20979         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
20980
20981         # rmfid shouldn't allow to remove files due to dir's permission
20982         chmod a+rwx $DIR/$tdir
20983         touch $DIR/$tdir/f
20984         ls -la $DIR/$tdir
20985         FID=$(lfs path2fid $DIR/$tdir/f)
20986         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail"
20987
20988         umount_client $MOUNT || "failed to umount client"
20989         mount_client $MOUNT "$MOUNT_OPTS" ||
20990                 "failed to mount client'"
20991
20992 }
20993 run_test 421f "rmfid checks permissions"
20994
20995 test_421g() {
20996         local cnt
20997         local FIDS
20998
20999         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21000         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
21001                 skip "Need MDS version at least 2.12.54"
21002
21003         mkdir -p $DIR/$tdir
21004         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
21005         createmany -o $DIR/$tdir/striped_dir/f 512
21006         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
21007         [ $cnt != 512 ] && error "unexpected #files: $cnt"
21008
21009         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
21010                 sed "s/[/][^:]*://g")
21011
21012         rm -f $DIR/$tdir/striped_dir/f1*
21013         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
21014         removed=$((512 - cnt))
21015
21016         # few files have been just removed, so we expect
21017         # rmfid to fail on their fids
21018         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
21019         [ $removed != $errors ] && error "$errors != $removed"
21020
21021         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
21022         rm -rf $DIR/$tdir
21023         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
21024 }
21025 run_test 421g "rmfid to return errors properly"
21026
21027 prep_801() {
21028         [[ $(lustre_version_code mds1) -lt $(version_code 2.9.55) ]] ||
21029         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
21030                 skip "Need server version at least 2.9.55"
21031
21032         start_full_debug_logging
21033 }
21034
21035 post_801() {
21036         stop_full_debug_logging
21037 }
21038
21039 barrier_stat() {
21040         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
21041                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
21042                            awk '/The barrier for/ { print $7 }')
21043                 echo $st
21044         else
21045                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
21046                 echo \'$st\'
21047         fi
21048 }
21049
21050 barrier_expired() {
21051         local expired
21052
21053         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
21054                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
21055                           awk '/will be expired/ { print $7 }')
21056         else
21057                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
21058         fi
21059
21060         echo $expired
21061 }
21062
21063 test_801a() {
21064         prep_801
21065
21066         echo "Start barrier_freeze at: $(date)"
21067         #define OBD_FAIL_BARRIER_DELAY          0x2202
21068         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
21069         # Do not reduce barrier time - See LU-11873
21070         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
21071
21072         sleep 2
21073         local b_status=$(barrier_stat)
21074         echo "Got barrier status at: $(date)"
21075         [ "$b_status" = "'freezing_p1'" ] ||
21076                 error "(1) unexpected barrier status $b_status"
21077
21078         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
21079         wait
21080         b_status=$(barrier_stat)
21081         [ "$b_status" = "'frozen'" ] ||
21082                 error "(2) unexpected barrier status $b_status"
21083
21084         local expired=$(barrier_expired)
21085         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
21086         sleep $((expired + 3))
21087
21088         b_status=$(barrier_stat)
21089         [ "$b_status" = "'expired'" ] ||
21090                 error "(3) unexpected barrier status $b_status"
21091
21092         # Do not reduce barrier time - See LU-11873
21093         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
21094                 error "(4) fail to freeze barrier"
21095
21096         b_status=$(barrier_stat)
21097         [ "$b_status" = "'frozen'" ] ||
21098                 error "(5) unexpected barrier status $b_status"
21099
21100         echo "Start barrier_thaw at: $(date)"
21101         #define OBD_FAIL_BARRIER_DELAY          0x2202
21102         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
21103         do_facet mgs $LCTL barrier_thaw $FSNAME &
21104
21105         sleep 2
21106         b_status=$(barrier_stat)
21107         echo "Got barrier status at: $(date)"
21108         [ "$b_status" = "'thawing'" ] ||
21109                 error "(6) unexpected barrier status $b_status"
21110
21111         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
21112         wait
21113         b_status=$(barrier_stat)
21114         [ "$b_status" = "'thawed'" ] ||
21115                 error "(7) unexpected barrier status $b_status"
21116
21117         #define OBD_FAIL_BARRIER_FAILURE        0x2203
21118         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
21119         do_facet mgs $LCTL barrier_freeze $FSNAME
21120
21121         b_status=$(barrier_stat)
21122         [ "$b_status" = "'failed'" ] ||
21123                 error "(8) unexpected barrier status $b_status"
21124
21125         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
21126         do_facet mgs $LCTL barrier_thaw $FSNAME
21127
21128         post_801
21129 }
21130 run_test 801a "write barrier user interfaces and stat machine"
21131
21132 test_801b() {
21133         prep_801
21134
21135         mkdir $DIR/$tdir || error "(1) fail to mkdir"
21136         createmany -d $DIR/$tdir/d 6 || "(2) fail to mkdir"
21137         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
21138         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
21139         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
21140
21141         cancel_lru_locks mdc
21142
21143         # 180 seconds should be long enough
21144         do_facet mgs $LCTL barrier_freeze $FSNAME 180
21145
21146         local b_status=$(barrier_stat)
21147         [ "$b_status" = "'frozen'" ] ||
21148                 error "(6) unexpected barrier status $b_status"
21149
21150         mkdir $DIR/$tdir/d0/d10 &
21151         mkdir_pid=$!
21152
21153         touch $DIR/$tdir/d1/f13 &
21154         touch_pid=$!
21155
21156         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
21157         ln_pid=$!
21158
21159         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
21160         mv_pid=$!
21161
21162         rm -f $DIR/$tdir/d4/f12 &
21163         rm_pid=$!
21164
21165         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
21166
21167         # To guarantee taht the 'stat' is not blocked
21168         b_status=$(barrier_stat)
21169         [ "$b_status" = "'frozen'" ] ||
21170                 error "(8) unexpected barrier status $b_status"
21171
21172         # let above commands to run at background
21173         sleep 5
21174
21175         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
21176         ps -p $touch_pid || error "(10) touch should be blocked"
21177         ps -p $ln_pid || error "(11) link should be blocked"
21178         ps -p $mv_pid || error "(12) rename should be blocked"
21179         ps -p $rm_pid || error "(13) unlink should be blocked"
21180
21181         b_status=$(barrier_stat)
21182         [ "$b_status" = "'frozen'" ] ||
21183                 error "(14) unexpected barrier status $b_status"
21184
21185         do_facet mgs $LCTL barrier_thaw $FSNAME
21186         b_status=$(barrier_stat)
21187         [ "$b_status" = "'thawed'" ] ||
21188                 error "(15) unexpected barrier status $b_status"
21189
21190         wait $mkdir_pid || error "(16) mkdir should succeed"
21191         wait $touch_pid || error "(17) touch should succeed"
21192         wait $ln_pid || error "(18) link should succeed"
21193         wait $mv_pid || error "(19) rename should succeed"
21194         wait $rm_pid || error "(20) unlink should succeed"
21195
21196         post_801
21197 }
21198 run_test 801b "modification will be blocked by write barrier"
21199
21200 test_801c() {
21201         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
21202
21203         prep_801
21204
21205         stop mds2 || error "(1) Fail to stop mds2"
21206
21207         do_facet mgs $LCTL barrier_freeze $FSNAME 30
21208
21209         local b_status=$(barrier_stat)
21210         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
21211                 do_facet mgs $LCTL barrier_thaw $FSNAME
21212                 error "(2) unexpected barrier status $b_status"
21213         }
21214
21215         do_facet mgs $LCTL barrier_rescan $FSNAME ||
21216                 error "(3) Fail to rescan barrier bitmap"
21217
21218         # Do not reduce barrier time - See LU-11873
21219         do_facet mgs $LCTL barrier_freeze $FSNAME 20
21220
21221         b_status=$(barrier_stat)
21222         [ "$b_status" = "'frozen'" ] ||
21223                 error "(4) unexpected barrier status $b_status"
21224
21225         do_facet mgs $LCTL barrier_thaw $FSNAME
21226         b_status=$(barrier_stat)
21227         [ "$b_status" = "'thawed'" ] ||
21228                 error "(5) unexpected barrier status $b_status"
21229
21230         local devname=$(mdsdevname 2)
21231
21232         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
21233
21234         do_facet mgs $LCTL barrier_rescan $FSNAME ||
21235                 error "(7) Fail to rescan barrier bitmap"
21236
21237         post_801
21238 }
21239 run_test 801c "rescan barrier bitmap"
21240
21241 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
21242 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
21243 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
21244 saved_MOUNT_OPTS=$MOUNT_OPTS
21245
21246 cleanup_802a() {
21247         trap 0
21248
21249         stopall
21250         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
21251         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
21252         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
21253         MOUNT_OPTS=$saved_MOUNT_OPTS
21254         setupall
21255 }
21256
21257 test_802a() {
21258
21259         [[ $(lustre_version_code mds1) -lt $(version_code 2.9.55) ]] ||
21260         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
21261                 skip "Need server version at least 2.9.55"
21262
21263         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
21264
21265         mkdir $DIR/$tdir || error "(1) fail to mkdir"
21266
21267         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
21268                 error "(2) Fail to copy"
21269
21270         trap cleanup_802a EXIT
21271
21272         # sync by force before remount as readonly
21273         sync; sync_all_data; sleep 3; sync_all_data
21274
21275         stopall
21276
21277         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
21278         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
21279         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
21280
21281         echo "Mount the server as read only"
21282         setupall server_only || error "(3) Fail to start servers"
21283
21284         echo "Mount client without ro should fail"
21285         mount_client $MOUNT &&
21286                 error "(4) Mount client without 'ro' should fail"
21287
21288         echo "Mount client with ro should succeed"
21289         MOUNT_OPTS=$(csa_add "$MOUNT_OPTS" -o ro)
21290         mount_client $MOUNT ||
21291                 error "(5) Mount client with 'ro' should succeed"
21292
21293         echo "Modify should be refused"
21294         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
21295
21296         echo "Read should be allowed"
21297         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
21298                 error "(7) Read should succeed under ro mode"
21299
21300         cleanup_802a
21301 }
21302 run_test 802a "simulate readonly device"
21303
21304 test_802b() {
21305         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21306         remote_mds_nodsh && skip "remote MDS with nodsh"
21307
21308         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
21309                 skip "readonly option not available"
21310
21311         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
21312
21313         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
21314                 error "(2) Fail to copy"
21315
21316         # write back all cached data before setting MDT to readonly
21317         cancel_lru_locks
21318         sync_all_data
21319
21320         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
21321         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
21322
21323         echo "Modify should be refused"
21324         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
21325
21326         echo "Read should be allowed"
21327         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
21328                 error "(7) Read should succeed under ro mode"
21329
21330         # disable readonly
21331         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
21332 }
21333 run_test 802b "be able to set MDTs to readonly"
21334
21335 test_803() {
21336         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
21337         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
21338                 skip "MDS needs to be newer than 2.10.54"
21339
21340         mkdir -p $DIR/$tdir
21341         # Create some objects on all MDTs to trigger related logs objects
21342         for idx in $(seq $MDSCOUNT); do
21343                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
21344                         $DIR/$tdir/dir${idx} ||
21345                         error "Fail to create $DIR/$tdir/dir${idx}"
21346         done
21347
21348         sync; sleep 3
21349         wait_delete_completed # ensure old test cleanups are finished
21350         echo "before create:"
21351         $LFS df -i $MOUNT
21352         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
21353
21354         for i in {1..10}; do
21355                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
21356                         error "Fail to create $DIR/$tdir/foo$i"
21357         done
21358
21359         sync; sleep 3
21360         echo "after create:"
21361         $LFS df -i $MOUNT
21362         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
21363
21364         # allow for an llog to be cleaned up during the test
21365         [ $after_used -ge $((before_used + 10 - 1)) ] ||
21366                 error "before ($before_used) + 10 > after ($after_used)"
21367
21368         for i in {1..10}; do
21369                 rm -rf $DIR/$tdir/foo$i ||
21370                         error "Fail to remove $DIR/$tdir/foo$i"
21371         done
21372
21373         sleep 3 # avoid MDT return cached statfs
21374         wait_delete_completed
21375         echo "after unlink:"
21376         $LFS df -i $MOUNT
21377         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
21378
21379         # allow for an llog to be created during the test
21380         [ $after_used -le $((before_used + 1)) ] ||
21381                 error "after ($after_used) > before ($before_used) + 1"
21382 }
21383 run_test 803 "verify agent object for remote object"
21384
21385 test_804() {
21386         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
21387         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
21388                 skip "MDS needs to be newer than 2.10.54"
21389         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
21390
21391         mkdir -p $DIR/$tdir
21392         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
21393                 error "Fail to create $DIR/$tdir/dir0"
21394
21395         local fid=$($LFS path2fid $DIR/$tdir/dir0)
21396         local dev=$(mdsdevname 2)
21397
21398         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
21399                 grep ${fid} || error "NOT found agent entry for dir0"
21400
21401         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
21402                 error "Fail to create $DIR/$tdir/dir1"
21403
21404         touch $DIR/$tdir/dir1/foo0 ||
21405                 error "Fail to create $DIR/$tdir/dir1/foo0"
21406         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
21407         local rc=0
21408
21409         for idx in $(seq $MDSCOUNT); do
21410                 dev=$(mdsdevname $idx)
21411                 do_facet mds${idx} \
21412                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
21413                         grep ${fid} && rc=$idx
21414         done
21415
21416         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
21417                 error "Fail to rename foo0 to foo1"
21418         if [ $rc -eq 0 ]; then
21419                 for idx in $(seq $MDSCOUNT); do
21420                         dev=$(mdsdevname $idx)
21421                         do_facet mds${idx} \
21422                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
21423                         grep ${fid} && rc=$idx
21424                 done
21425         fi
21426
21427         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
21428                 error "Fail to rename foo1 to foo2"
21429         if [ $rc -eq 0 ]; then
21430                 for idx in $(seq $MDSCOUNT); do
21431                         dev=$(mdsdevname $idx)
21432                         do_facet mds${idx} \
21433                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
21434                         grep ${fid} && rc=$idx
21435                 done
21436         fi
21437
21438         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
21439
21440         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
21441                 error "Fail to link to $DIR/$tdir/dir1/foo2"
21442         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
21443                 error "Fail to rename foo2 to foo0"
21444         unlink $DIR/$tdir/dir1/foo0 ||
21445                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
21446         rm -rf $DIR/$tdir/dir0 ||
21447                 error "Fail to rm $DIR/$tdir/dir0"
21448
21449         for idx in $(seq $MDSCOUNT); do
21450                 dev=$(mdsdevname $idx)
21451                 rc=0
21452
21453                 stop mds${idx}
21454                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
21455                         rc=$?
21456                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
21457                         error "mount mds$idx failed"
21458                 df $MOUNT > /dev/null 2>&1
21459
21460                 # e2fsck should not return error
21461                 [ $rc -eq 0 ] ||
21462                         error "e2fsck detected error on MDT${idx}: rc=$rc"
21463         done
21464 }
21465 run_test 804 "verify agent entry for remote entry"
21466
21467 cleanup_805() {
21468         do_facet $SINGLEMDS zfs set quota=$old $fsset
21469         unlinkmany $DIR/$tdir/f- 1000000
21470         trap 0
21471 }
21472
21473 test_805() {
21474         local zfs_version=$(do_node $SINGLEMDS cat /sys/module/zfs/version)
21475         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
21476         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
21477                 skip "netfree not implemented before 0.7"
21478         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
21479                 skip "Need MDS version at least 2.10.57"
21480
21481         local fsset
21482         local freekb
21483         local usedkb
21484         local old
21485         local quota
21486         local pref="osd-zfs.lustre-MDT0000."
21487
21488         # limit available space on MDS dataset to meet nospace issue
21489         # quickly. then ZFS 0.7.2 can use reserved space if asked
21490         # properly (using netfree flag in osd_declare_destroy()
21491         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
21492         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
21493                 gawk '{print $3}')
21494         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
21495         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
21496         let "usedkb=usedkb-freekb"
21497         let "freekb=freekb/2"
21498         if let "freekb > 5000"; then
21499                 let "freekb=5000"
21500         fi
21501         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
21502         trap cleanup_805 EXIT
21503         mkdir $DIR/$tdir
21504         $LFS setstripe -E 1M -L mdt $DIR/$tdir || error "DoM not working"
21505         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
21506         rm -rf $DIR/$tdir || error "not able to remove"
21507         do_facet $SINGLEMDS zfs set quota=$old $fsset
21508         trap 0
21509 }
21510 run_test 805 "ZFS can remove from full fs"
21511
21512 # Size-on-MDS test
21513 check_lsom_data()
21514 {
21515         local file=$1
21516         local size=$($LFS getsom -s $file)
21517         local expect=$(stat -c %s $file)
21518
21519         [[ $size == $expect ]] ||
21520                 error "$file expected size: $expect, got: $size"
21521
21522         local blocks=$($LFS getsom -b $file)
21523         expect=$(stat -c %b $file)
21524         [[ $blocks == $expect ]] ||
21525                 error "$file expected blocks: $expect, got: $blocks"
21526 }
21527
21528 check_lsom_size()
21529 {
21530         local size=$($LFS getsom -s $1)
21531         local expect=$2
21532
21533         [[ $size == $expect ]] ||
21534                 error "$file expected size: $expect, got: $size"
21535 }
21536
21537 test_806() {
21538         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21539                 skip "Need MDS version at least 2.11.52"
21540
21541         local bs=1048576
21542
21543         touch $DIR/$tfile || error "touch $tfile failed"
21544
21545         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
21546         save_lustre_params client "llite.*.xattr_cache" > $save
21547         lctl set_param llite.*.xattr_cache=0
21548         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
21549
21550         # single-threaded write
21551         echo "Test SOM for single-threaded write"
21552         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
21553                 error "write $tfile failed"
21554         check_lsom_size $DIR/$tfile $bs
21555
21556         local num=32
21557         local size=$(($num * $bs))
21558         local offset=0
21559         local i
21560
21561         echo "Test SOM for single client multi-threaded($num) write"
21562         $TRUNCATE $DIR/$tfile 0
21563         for ((i = 0; i < $num; i++)); do
21564                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
21565                 local pids[$i]=$!
21566                 offset=$((offset + $bs))
21567         done
21568         for (( i=0; i < $num; i++ )); do
21569                 wait ${pids[$i]}
21570         done
21571         check_lsom_size $DIR/$tfile $size
21572
21573         $TRUNCATE $DIR/$tfile 0
21574         for ((i = 0; i < $num; i++)); do
21575                 offset=$((offset - $bs))
21576                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
21577                 local pids[$i]=$!
21578         done
21579         for (( i=0; i < $num; i++ )); do
21580                 wait ${pids[$i]}
21581         done
21582         check_lsom_size $DIR/$tfile $size
21583
21584         # multi-client wirtes
21585         num=$(get_node_count ${CLIENTS//,/ })
21586         size=$(($num * $bs))
21587         offset=0
21588         i=0
21589
21590         echo "Test SOM for multi-client ($num) writes"
21591         $TRUNCATE $DIR/$tfile 0
21592         for client in ${CLIENTS//,/ }; do
21593                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
21594                 local pids[$i]=$!
21595                 i=$((i + 1))
21596                 offset=$((offset + $bs))
21597         done
21598         for (( i=0; i < $num; i++ )); do
21599                 wait ${pids[$i]}
21600         done
21601         check_lsom_size $DIR/$tfile $offset
21602
21603         i=0
21604         $TRUNCATE $DIR/$tfile 0
21605         for client in ${CLIENTS//,/ }; do
21606                 offset=$((offset - $bs))
21607                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
21608                 local pids[$i]=$!
21609                 i=$((i + 1))
21610         done
21611         for (( i=0; i < $num; i++ )); do
21612                 wait ${pids[$i]}
21613         done
21614         check_lsom_size $DIR/$tfile $size
21615
21616         # verify truncate
21617         echo "Test SOM for truncate"
21618         $TRUNCATE $DIR/$tfile 1048576
21619         check_lsom_size $DIR/$tfile 1048576
21620         $TRUNCATE $DIR/$tfile 1234
21621         check_lsom_size $DIR/$tfile 1234
21622
21623         # verify SOM blocks count
21624         echo "Verify SOM block count"
21625         $TRUNCATE $DIR/$tfile 0
21626         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
21627                 error "failed to write file $tfile"
21628         check_lsom_data $DIR/$tfile
21629 }
21630 run_test 806 "Verify Lazy Size on MDS"
21631
21632 test_807() {
21633         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
21634         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21635                 skip "Need MDS version at least 2.11.52"
21636
21637         # Registration step
21638         changelog_register || error "changelog_register failed"
21639         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
21640         changelog_users $SINGLEMDS | grep -q $cl_user ||
21641                 error "User $cl_user not found in changelog_users"
21642
21643         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
21644         save_lustre_params client "llite.*.xattr_cache" > $save
21645         lctl set_param llite.*.xattr_cache=0
21646         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
21647
21648         rm -rf $DIR/$tdir || error "rm $tdir failed"
21649         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
21650         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
21651         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
21652         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
21653                 error "truncate $tdir/trunc failed"
21654
21655         local bs=1048576
21656         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 ||
21657                 error "write $tfile failed"
21658
21659         # multi-client wirtes
21660         local num=$(get_node_count ${CLIENTS//,/ })
21661         local offset=0
21662         local i=0
21663
21664         echo "Test SOM for multi-client ($num) writes"
21665         touch $DIR/$tfile || error "touch $tfile failed"
21666         $TRUNCATE $DIR/$tfile 0
21667         for client in ${CLIENTS//,/ }; do
21668                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
21669                 local pids[$i]=$!
21670                 i=$((i + 1))
21671                 offset=$((offset + $bs))
21672         done
21673         for (( i=0; i < $num; i++ )); do
21674                 wait ${pids[$i]}
21675         done
21676
21677         sleep 5
21678         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
21679         check_lsom_data $DIR/$tdir/trunc
21680         check_lsom_data $DIR/$tdir/single_dd
21681         check_lsom_data $DIR/$tfile
21682
21683         rm -rf $DIR/$tdir
21684         # Deregistration step
21685         changelog_deregister || error "changelog_deregister failed"
21686 }
21687 run_test 807 "verify LSOM syncing tool"
21688
21689 check_som_nologged()
21690 {
21691         local lines=$($LFS changelog $FSNAME-MDT0000 |
21692                 grep 'x=trusted.som' | wc -l)
21693         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
21694 }
21695
21696 test_808() {
21697         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
21698                 skip "Need MDS version at least 2.11.55"
21699
21700         # Registration step
21701         changelog_register || error "changelog_register failed"
21702
21703         touch $DIR/$tfile || error "touch $tfile failed"
21704         check_som_nologged
21705
21706         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
21707                 error "write $tfile failed"
21708         check_som_nologged
21709
21710         $TRUNCATE $DIR/$tfile 1234
21711         check_som_nologged
21712
21713         $TRUNCATE $DIR/$tfile 1048576
21714         check_som_nologged
21715
21716         # Deregistration step
21717         changelog_deregister || error "changelog_deregister failed"
21718 }
21719 run_test 808 "Check trusted.som xattr not logged in Changelogs"
21720
21721 check_som_nodata()
21722 {
21723         $LFS getsom $1
21724         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
21725 }
21726
21727 test_809() {
21728         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
21729                 skip "Need MDS version at least 2.11.56"
21730
21731         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
21732                 error "failed to create DoM-only file $DIR/$tfile"
21733         touch $DIR/$tfile || error "touch $tfile failed"
21734         check_som_nodata $DIR/$tfile
21735
21736         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
21737                 error "write $tfile failed"
21738         check_som_nodata $DIR/$tfile
21739
21740         $TRUNCATE $DIR/$tfile 1234
21741         check_som_nodata $DIR/$tfile
21742
21743         $TRUNCATE $DIR/$tfile 4097
21744         check_som_nodata $DIR/$file
21745 }
21746 run_test 809 "Verify no SOM xattr store for DoM-only files"
21747
21748 test_810() {
21749         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21750         $GSS && skip_env "could not run with gss"
21751
21752         set_checksums 1
21753         stack_trap "set_checksums $ORIG_CSUM" EXIT
21754         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
21755
21756         local csum
21757         local before
21758         local after
21759         for csum in $CKSUM_TYPES; do
21760                 #define OBD_FAIL_OSC_NO_GRANT   0x411
21761                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
21762                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
21763                         eval set -- $i
21764                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
21765                         before=$(md5sum $DIR/$tfile)
21766                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
21767                         after=$(md5sum $DIR/$tfile)
21768                         [ "$before" == "$after" ] ||
21769                                 error "$csum: $before != $after bs=$1 seek=$2"
21770                 done
21771         done
21772 }
21773 run_test 810 "partial page writes on ZFS (LU-11663)"
21774
21775 test_811() {
21776         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.11.56) ] &&
21777                 skip "Need MDS version at least 2.11.56"
21778
21779         #define OBD_FAIL_MDS_ORPHAN_DELETE      0x165
21780         do_facet mds1 $LCTL set_param fail_loc=0x165
21781         $MULTIOP $DIR/$tfile Ouc || error "multiop failed"
21782
21783         stop mds1
21784         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
21785
21786         sleep 5
21787         [[ $(do_facet mds1 pgrep orph_.*-MDD | wc -l) -eq 0 ]] ||
21788                 error "MDD orphan cleanup thread not quit"
21789 }
21790 run_test 811 "orphan name stub can be cleaned up in startup"
21791
21792 test_812() {
21793         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
21794                 skip "OST < 2.12.51 doesn't support this fail_loc"
21795         [ "$SHARED_KEY" = true ] &&
21796                 skip "OSC connections never go IDLE with Shared-Keys enabled"
21797
21798         $LFS setstripe -c 1 -i 0 $DIR/$tfile
21799         # ensure ost1 is connected
21800         stat $DIR/$tfile >/dev/null || error "can't stat"
21801         wait_osc_import_state client ost1 FULL
21802         # no locks, no reqs to let the connection idle
21803         cancel_lru_locks osc
21804
21805         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
21806 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
21807         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
21808         wait_osc_import_state client ost1 CONNECTING
21809         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
21810
21811         stat $DIR/$tfile >/dev/null || error "can't stat file"
21812 }
21813 run_test 812 "do not drop reqs generated when imp is going to idle (LU-11951)"
21814
21815 test_813() {
21816         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
21817         [ -z "$file_heat_sav" ] && skip "no file heat support"
21818
21819         local readsample
21820         local writesample
21821         local readbyte
21822         local writebyte
21823         local readsample1
21824         local writesample1
21825         local readbyte1
21826         local writebyte1
21827
21828         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
21829         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
21830
21831         $LCTL set_param -n llite.*.file_heat=1
21832         echo "Turn on file heat"
21833         echo "Period second: $period_second, Decay percentage: $decay_pct"
21834
21835         echo "QQQQ" > $DIR/$tfile
21836         echo "QQQQ" > $DIR/$tfile
21837         echo "QQQQ" > $DIR/$tfile
21838         cat $DIR/$tfile > /dev/null
21839         cat $DIR/$tfile > /dev/null
21840         cat $DIR/$tfile > /dev/null
21841         cat $DIR/$tfile > /dev/null
21842
21843         local out=$($LFS heat_get $DIR/$tfile)
21844
21845         $LFS heat_get $DIR/$tfile
21846         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
21847         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
21848         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
21849         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
21850
21851         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
21852         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
21853         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
21854         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
21855
21856         sleep $((period_second + 3))
21857         echo "Sleep $((period_second + 3)) seconds..."
21858         # The recursion formula to calculate the heat of the file f is as
21859         # follow:
21860         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
21861         # Where Hi is the heat value in the period between time points i*I and
21862         # (i+1)*I; Ci is the access count in the period; the symbol P refers
21863         # to the weight of Ci.
21864         out=$($LFS heat_get $DIR/$tfile)
21865         $LFS heat_get $DIR/$tfile
21866         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
21867         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
21868         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
21869         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
21870
21871         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
21872                 error "read sample ($readsample) is wrong"
21873         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
21874                 error "write sample ($writesample) is wrong"
21875         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
21876                 error "read bytes ($readbyte) is wrong"
21877         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
21878                 error "write bytes ($writebyte) is wrong"
21879
21880         echo "QQQQ" > $DIR/$tfile
21881         echo "QQQQ" > $DIR/$tfile
21882         echo "QQQQ" > $DIR/$tfile
21883         cat $DIR/$tfile > /dev/null
21884         cat $DIR/$tfile > /dev/null
21885         cat $DIR/$tfile > /dev/null
21886         cat $DIR/$tfile > /dev/null
21887
21888         sleep $((period_second + 3))
21889         echo "Sleep $((period_second + 3)) seconds..."
21890
21891         out=$($LFS heat_get $DIR/$tfile)
21892         $LFS heat_get $DIR/$tfile
21893         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
21894         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
21895         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
21896         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
21897
21898         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
21899                 4 * $decay_pct) / 100") -eq 1 ] ||
21900                 error "read sample ($readsample1) is wrong"
21901         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
21902                 3 * $decay_pct) / 100") -eq 1 ] ||
21903                 error "write sample ($writesample1) is wrong"
21904         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
21905                 20 * $decay_pct) / 100") -eq 1 ] ||
21906                 error "read bytes ($readbyte1) is wrong"
21907         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
21908                 15 * $decay_pct) / 100") -eq 1 ] ||
21909                 error "write bytes ($writebyte1) is wrong"
21910
21911         echo "Turn off file heat for the file $DIR/$tfile"
21912         $LFS heat_set -o $DIR/$tfile
21913
21914         echo "QQQQ" > $DIR/$tfile
21915         echo "QQQQ" > $DIR/$tfile
21916         echo "QQQQ" > $DIR/$tfile
21917         cat $DIR/$tfile > /dev/null
21918         cat $DIR/$tfile > /dev/null
21919         cat $DIR/$tfile > /dev/null
21920         cat $DIR/$tfile > /dev/null
21921
21922         out=$($LFS heat_get $DIR/$tfile)
21923         $LFS heat_get $DIR/$tfile
21924         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
21925         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
21926         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
21927         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
21928
21929         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
21930         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
21931         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
21932         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
21933
21934         echo "Trun on file heat for the file $DIR/$tfile"
21935         $LFS heat_set -O $DIR/$tfile
21936
21937         echo "QQQQ" > $DIR/$tfile
21938         echo "QQQQ" > $DIR/$tfile
21939         echo "QQQQ" > $DIR/$tfile
21940         cat $DIR/$tfile > /dev/null
21941         cat $DIR/$tfile > /dev/null
21942         cat $DIR/$tfile > /dev/null
21943         cat $DIR/$tfile > /dev/null
21944
21945         out=$($LFS heat_get $DIR/$tfile)
21946         $LFS heat_get $DIR/$tfile
21947         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
21948         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
21949         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
21950         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
21951
21952         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
21953         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
21954         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
21955         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
21956
21957         $LFS heat_set -c $DIR/$tfile
21958         $LCTL set_param -n llite.*.file_heat=0
21959         echo "Turn off file heat support for the Lustre filesystem"
21960
21961         echo "QQQQ" > $DIR/$tfile
21962         echo "QQQQ" > $DIR/$tfile
21963         echo "QQQQ" > $DIR/$tfile
21964         cat $DIR/$tfile > /dev/null
21965         cat $DIR/$tfile > /dev/null
21966         cat $DIR/$tfile > /dev/null
21967         cat $DIR/$tfile > /dev/null
21968
21969         out=$($LFS heat_get $DIR/$tfile)
21970         $LFS heat_get $DIR/$tfile
21971         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
21972         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
21973         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
21974         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
21975
21976         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
21977         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
21978         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
21979         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
21980
21981         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
21982         rm -f $DIR/$tfile
21983 }
21984 run_test 813 "File heat verfication"
21985
21986 test_814()
21987 {
21988         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
21989         echo -n y >> $DIR/$tfile
21990         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
21991         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
21992 }
21993 run_test 814 "sparse cp works as expected (LU-12361)"
21994
21995 test_815()
21996 {
21997         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
21998         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
21999 }
22000 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
22001
22002 test_816() {
22003         [ "$SHARED_KEY" = true ] &&
22004                 skip "OSC connections never go IDLE with Shared-Keys enabled"
22005
22006         $LFS setstripe -c 1 -i 0 $DIR/$tfile
22007         # ensure ost1 is connected
22008         stat $DIR/$tfile >/dev/null || error "can't stat"
22009         wait_osc_import_state client ost1 FULL
22010         # no locks, no reqs to let the connection idle
22011         cancel_lru_locks osc
22012         lru_resize_disable osc
22013         local before
22014         local now
22015         before=$($LCTL get_param -n \
22016                  ldlm.namespaces.$FSNAME-OST0000-osc-[^M]*.lru_size)
22017
22018         wait_osc_import_state client ost1 IDLE
22019         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
22020         now=$($LCTL get_param -n \
22021               ldlm.namespaces.$FSNAME-OST0000-osc-[^M]*.lru_size)
22022         [ $before == $now ] || error "lru_size changed $before != $now"
22023 }
22024 run_test 816 "do not reset lru_resize on idle reconnect"
22025
22026 cleanup_817() {
22027         umount $tmpdir
22028         exportfs -u localhost:$DIR/nfsexp
22029         rm -rf $DIR/nfsexp
22030 }
22031
22032 test_817() {
22033         systemctl restart nfs-server.service || skip "failed to restart nfsd"
22034
22035         mkdir -p $DIR/nfsexp
22036         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
22037                 error "failed to export nfs"
22038
22039         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
22040         stack_trap cleanup_817 EXIT
22041
22042         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
22043                 error "failed to mount nfs to $tmpdir"
22044
22045         cp /bin/true $tmpdir
22046         $DIR/nfsexp/true || error "failed to execute 'true' command"
22047 }
22048 run_test 817 "nfsd won't cache write lock for exec file"
22049
22050 test_818() {
22051         mkdir $DIR/$tdir
22052         $LFS setstripe -c1 -i0 $DIR/$tfile
22053         $LFS setstripe -c1 -i1 $DIR/$tfile
22054         stop $SINGLEMDS
22055         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
22056         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
22057         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
22058                 error "start $SINGLEMDS failed"
22059         rm -rf $DIR/$tdir
22060 }
22061 run_test 818 "unlink with failed llog"
22062
22063 #
22064 # tests that do cleanup/setup should be run at the end
22065 #
22066
22067 test_900() {
22068         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22069         local ls
22070
22071         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
22072         $LCTL set_param fail_loc=0x903
22073
22074         cancel_lru_locks MGC
22075
22076         FAIL_ON_ERROR=true cleanup
22077         FAIL_ON_ERROR=true setup
22078 }
22079 run_test 900 "umount should not race with any mgc requeue thread"
22080
22081 complete $SECONDS
22082 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
22083 check_and_cleanup_lustre
22084 if [ "$I_MOUNTED" != "yes" ]; then
22085         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
22086 fi
22087 exit_status