Whamcloud - gitweb
LU-8264 lod: lfs setstripe fix for pool.
[fs/lustre-release.git] / lustre / tests / sanity.sh
1 #!/bin/bash
2 # -*- tab-width: 8; indent-tabs-mode: t; -*-
3 #
4 # Run select tests by setting ONLY, or as arguments to the script.
5 # Skip specific tests by setting EXCEPT.
6 #
7 # e.g. ONLY="22 23" or ONLY="`seq 32 39`" or EXCEPT="31"
8 set -e
9
10 ONLY=${ONLY:-"$*"}
11 # bug number for skipped test: LU-9693 LU-6493 LU-9693
12 ALWAYS_EXCEPT="$SANITY_EXCEPT  42a     42b     42c"
13 # UPDATE THE COMMENT ABOVE WITH BUG NUMBERS WHEN CHANGING ALWAYS_EXCEPT!
14
15 # skipped tests: LU-8411 LU-9096 LU-9054
16 ALWAYS_EXCEPT="  407     253     312     $ALWAYS_EXCEPT"
17
18 # Check Grants after these tests
19 GRANT_CHECK_LIST="$GRANT_CHECK_LIST 42a 42b 42c 42d 42e 63a 63b 64a 64b 64c"
20
21 is_sles11()                                             # LU-4341
22 {
23         if [ -r /etc/SuSE-release ]
24         then
25                 local vers=$(grep VERSION /etc/SuSE-release | awk '{print $3}')
26                 local patchlev=$(grep PATCHLEVEL /etc/SuSE-release |
27                         awk '{ print $3 }')
28                 if [ $vers -eq 11 ] && [ $patchlev -ge 3 ]; then
29                         return 0
30                 fi
31         fi
32         return 1
33 }
34
35 if is_sles11; then                                      # LU-4341
36         ALWAYS_EXCEPT="$ALWAYS_EXCEPT 170"
37 fi
38
39 SRCDIR=$(cd $(dirname $0); echo $PWD)
40 export PATH=$PATH:/sbin
41
42 TMP=${TMP:-/tmp}
43 OSC=${OSC:-"osc"}
44
45 CC=${CC:-cc}
46 CHECKSTAT=${CHECKSTAT:-"checkstat -v"}
47 CREATETEST=${CREATETEST:-createtest}
48 LFS=${LFS:-lfs}
49 LVERIFY=${LVERIFY:-ll_dirstripe_verify}
50 LCTL=${LCTL:-lctl}
51 OPENFILE=${OPENFILE:-openfile}
52 OPENUNLINK=${OPENUNLINK:-openunlink}
53 export MULTIOP=${MULTIOP:-multiop}
54 READS=${READS:-"reads"}
55 MUNLINK=${MUNLINK:-munlink}
56 SOCKETSERVER=${SOCKETSERVER:-socketserver}
57 SOCKETCLIENT=${SOCKETCLIENT:-socketclient}
58 MEMHOG=${MEMHOG:-memhog}
59 DIRECTIO=${DIRECTIO:-directio}
60 ACCEPTOR_PORT=${ACCEPTOR_PORT:-988}
61 STRIPES_PER_OBJ=-1
62 CHECK_GRANT=${CHECK_GRANT:-"yes"}
63 GRANT_CHECK_LIST=${GRANT_CHECK_LIST:-""}
64 export PARALLEL=${PARALLEL:-"no"}
65
66 export NAME=${NAME:-local}
67
68 SAVE_PWD=$PWD
69
70 CLEANUP=${CLEANUP:-:}
71 SETUP=${SETUP:-:}
72 TRACE=${TRACE:-""}
73 LUSTRE=${LUSTRE:-$(cd $(dirname $0)/..; echo $PWD)}
74 LUSTRE_TESTS_API_DIR=${LUSTRE_TESTS_API_DIR:-${LUSTRE}/tests/clientapi}
75 . $LUSTRE/tests/test-framework.sh
76 init_test_env $@
77 . ${CONFIG:=$LUSTRE/tests/cfg/${NAME}.sh}
78 init_logging
79
80 #                                  5          12          (min)"
81 [ "$SLOW" = "no" ] && EXCEPT_SLOW="27m 64b 68 71 115 300o"
82
83 if [ $(facet_fstype $SINGLEMDS) = "zfs" ]; then
84         # bug number for skipped test: LU-1957
85         ALWAYS_EXCEPT="$ALWAYS_EXCEPT  180"
86         #                                               13    (min)"
87         [ "$SLOW" = "no" ] && EXCEPT_SLOW="$EXCEPT_SLOW 51b"
88 fi
89
90 FAIL_ON_ERROR=false
91
92 cleanup() {
93         echo -n "cln.."
94         pgrep ll_sa > /dev/null && { echo "There are ll_sa thread not exit!"; exit 20; }
95         cleanupall ${FORCE} $* || { echo "FAILed to clean up"; exit 20; }
96 }
97 setup() {
98         echo -n "mnt.."
99         load_modules
100         setupall || exit 10
101         echo "done"
102 }
103
104 check_swap_layouts_support()
105 {
106         $LCTL get_param -n llite.*.sbi_flags | grep -q layout ||
107                 { skip "Does not support layout lock."; return 0; }
108         return 1
109 }
110
111 check_and_setup_lustre
112 DIR=${DIR:-$MOUNT}
113 assert_DIR
114
115 MDT0=$($LCTL get_param -n mdc.*.mds_server_uuid |
116         awk '{ gsub(/_UUID/,""); print $1 }' | head -n1)
117 MAXFREE=${MAXFREE:-$((200000 * $OSTCOUNT))}
118
119 [ -f $DIR/d52a/foo ] && chattr -a $DIR/d52a/foo
120 [ -f $DIR/d52b/foo ] && chattr -i $DIR/d52b/foo
121 rm -rf $DIR/[Rdfs][0-9]*
122
123 # $RUNAS_ID may get set incorrectly somewhere else
124 [ $UID -eq 0 -a $RUNAS_ID -eq 0 ] && error "\$RUNAS_ID set to 0, but \$UID is also 0!"
125
126 check_runas_id $RUNAS_ID $RUNAS_GID $RUNAS
127
128 build_test_filter
129
130 if [ "${ONLY}" = "MOUNT" ] ; then
131         echo "Lustre is up, please go on"
132         exit
133 fi
134
135 echo "preparing for tests involving mounts"
136 EXT2_DEV=${EXT2_DEV:-$TMP/SANITY.LOOP}
137 touch $EXT2_DEV
138 mke2fs -j -F $EXT2_DEV 8000 > /dev/null
139 echo # add a newline after mke2fs.
140
141 umask 077
142
143 OLDDEBUG=$(lctl get_param -n debug 2> /dev/null)
144 lctl set_param debug=-1 2> /dev/null || true
145 test_0a() {
146         touch $DIR/$tfile
147         $CHECKSTAT -t file $DIR/$tfile || error "$tfile is not a file"
148         rm $DIR/$tfile
149         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
150 }
151 run_test 0a "touch; rm ====================="
152
153 test_0b() {
154         chmod 0755 $DIR || error "chmod 0755 $DIR failed"
155         $CHECKSTAT -p 0755 $DIR || error "$DIR permission is not 0755"
156 }
157 run_test 0b "chmod 0755 $DIR ============================="
158
159 test_0c() {
160         $LCTL get_param mdc.*.import | grep "state: FULL" ||
161                 error "import not FULL"
162         $LCTL get_param mdc.*.import | grep "target: $FSNAME-MDT" ||
163                 error "bad target"
164 }
165 run_test 0c "check import proc"
166
167 test_1() {
168         test_mkdir $DIR/$tdir
169         test_mkdir $DIR/$tdir/d2
170         mkdir $DIR/$tdir/d2 && error "we expect EEXIST, but not returned"
171         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a dir"
172         rmdir $DIR/$tdir/d2
173         rmdir $DIR/$tdir
174         $CHECKSTAT -a $DIR/$tdir || error "$tdir was not removed"
175 }
176 run_test 1 "mkdir; remkdir; rmdir"
177
178 test_2() {
179         test_mkdir $DIR/$tdir
180         touch $DIR/$tdir/$tfile || error "touch $tdir/$tfile failed"
181         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
182         rm -r $DIR/$tdir
183         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$file is not removed"
184 }
185 run_test 2 "mkdir; touch; rmdir; check file"
186
187 test_3() {
188         test_mkdir $DIR/$tdir
189         $CHECKSTAT -t dir $DIR/$tdir || error "$tdir is not a directory"
190         touch $DIR/$tdir/$tfile
191         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
192         rm -r $DIR/$tdir
193         $CHECKSTAT -a $DIR/$tdir || error "$tdir is not removed"
194 }
195 run_test 3 "mkdir; touch; rmdir; check dir"
196
197 # LU-4471 - failed rmdir on remote directories still removes directory on MDT0
198 test_4() {
199         test_mkdir -i 1 $DIR/$tdir
200
201         touch $DIR/$tdir/$tfile ||
202                 error "Create file under remote directory failed"
203
204         rmdir $DIR/$tdir &&
205                 error "Expect error removing in-use dir $DIR/$tdir"
206
207         test -d $DIR/$tdir || error "Remote directory disappeared"
208
209         rm -rf $DIR/$tdir || error "remove remote dir error"
210 }
211 run_test 4 "mkdir; touch dir/file; rmdir; checkdir (expect error)"
212
213 test_5() {
214         test_mkdir $DIR/$tdir
215         test_mkdir $DIR/$tdir/d2
216         chmod 0707 $DIR/$tdir/d2 || error "chmod 0707 $tdir/d2 failed"
217         $CHECKSTAT -t dir -p 0707 $DIR/$tdir/d2 || error "$tdir/d2 not mode 707"
218         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a directory"
219 }
220 run_test 5 "mkdir .../d5 .../d5/d2; chmod .../d5/d2"
221
222 test_6a() {
223         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
224         chmod 0666 $DIR/$tfile || error "chmod 0666 $tfile failed"
225         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
226                 error "$tfile does not have perm 0666 or UID $UID"
227         $RUNAS chmod 0444 $DIR/$tfile && error "chmod $tfile worked on UID $UID"
228         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
229                 error "$tfile should be 0666 and owned by UID $UID"
230 }
231 run_test 6a "touch f6a; chmod f6a; $RUNAS chmod f6a (should return error) =="
232
233 test_6c() {
234         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID" && return
235         touch $DIR/$tfile
236         chown $RUNAS_ID $DIR/$tfile || error "chown $RUNAS_ID $file failed"
237         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
238                 error "$tfile should be owned by UID $RUNAS_ID"
239         $RUNAS chown $UID $DIR/$tfile && error "chown $UID $file succeeded"
240         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
241                 error "$tfile should be owned by UID $RUNAS_ID"
242 }
243 run_test 6c "touch f6c; chown f6c; $RUNAS chown f6c (should return error) =="
244
245 test_6e() {
246         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID" && return
247         touch $DIR/$tfile
248         chgrp $RUNAS_ID $DIR/$tfile || error "chgrp $RUNAS_ID $file failed"
249         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
250                 error "$tfile should be owned by GID $UID"
251         $RUNAS chgrp $UID $DIR/$tfile && error "chgrp $UID $file succeeded"
252         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
253                 error "$tfile should be owned by UID $UID and GID $RUNAS_ID"
254 }
255 run_test 6e "touch+chgrp $tfile; $RUNAS chgrp $tfile (should return error)"
256
257 test_6g() {
258         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID" && return
259         test_mkdir $DIR/$tdir
260         chmod 777 $DIR/$tdir || error "chmod 0777 $tdir failed"
261         $RUNAS mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
262         chmod g+s $DIR/$tdir/d || error "chmod g+s $tdir/d failed"
263         test_mkdir $DIR/$tdir/d/subdir
264         $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir/d/subdir ||
265                 error "$tdir/d/subdir should be GID $RUNAS_GID"
266         if [[ $MDSCOUNT -gt 1 ]]; then
267                 # check remote dir sgid inherite
268                 $LFS mkdir -i 0 $DIR/$tdir.local ||
269                         error "mkdir $tdir.local failed"
270                 chmod g+s $DIR/$tdir.local ||
271                         error "chmod $tdir.local failed"
272                 chgrp $RUNAS_GID $DIR/$tdir.local ||
273                         error "chgrp $tdir.local failed"
274                 $LFS mkdir -i 1 $DIR/$tdir.local/$tdir.remote ||
275                         error "mkdir $tdir.remote failed"
276                 $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir.local/$tdir.remote ||
277                         error "$tdir.remote should be owned by $UID.$RUNAS_ID"
278                 $CHECKSTAT -p 02755 $DIR/$tdir.local/$tdir.remote ||
279                         error "$tdir.remote should be mode 02755"
280         fi
281 }
282 run_test 6g "verify new dir in sgid dir inherits group"
283
284 test_6h() { # bug 7331
285         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID" && return
286         touch $DIR/$tfile || error "touch failed"
287         chown $RUNAS_ID:$RUNAS_GID $DIR/$tfile || error "initial chown failed"
288         $RUNAS -G$RUNAS_GID chown $RUNAS_ID:0 $DIR/$tfile &&
289                 error "chown $RUNAS_ID:0 $tfile worked as GID $RUNAS_GID"
290         $CHECKSTAT -t file -u \#$RUNAS_ID -g \#$RUNAS_GID $DIR/$tfile ||
291                 error "$tdir/$tfile should be UID $RUNAS_UID GID $RUNAS_GID"
292 }
293 run_test 6h "$RUNAS chown RUNAS_ID.0 .../$tfile (should return error)"
294
295 test_7a() {
296         test_mkdir $DIR/$tdir
297         $MCREATE $DIR/$tdir/$tfile
298         chmod 0666 $DIR/$tdir/$tfile
299         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
300                 error "$tdir/$tfile should be mode 0666"
301 }
302 run_test 7a "mkdir .../d7; mcreate .../d7/f; chmod .../d7/f ===="
303
304 test_7b() {
305         if [ ! -d $DIR/$tdir ]; then
306                 test_mkdir $DIR/$tdir
307         fi
308         $MCREATE $DIR/$tdir/$tfile
309         echo -n foo > $DIR/$tdir/$tfile
310         [ "$(cat $DIR/$tdir/$tfile)" = "foo" ] || error "$tdir/$tfile not 'foo'"
311         $CHECKSTAT -t file -s 3 $DIR/$tdir/$tfile || error "$tfile size not 3"
312 }
313 run_test 7b "mkdir .../d7; mcreate d7/f2; echo foo > d7/f2 ====="
314
315 test_8() {
316         test_mkdir $DIR/$tdir
317         touch $DIR/$tdir/$tfile
318         chmod 0666 $DIR/$tdir/$tfile
319         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
320                 error "$tfile mode not 0666"
321 }
322 run_test 8 "mkdir .../d8; touch .../d8/f; chmod .../d8/f ======="
323
324 test_9() {
325         test_mkdir $DIR/$tdir
326         test_mkdir $DIR/$tdir/d2
327         test_mkdir $DIR/$tdir/d2/d3
328         $CHECKSTAT -t dir $DIR/$tdir/d2/d3 || error "$tdir/d2/d3 not a dir"
329 }
330 run_test 9 "mkdir .../d9 .../d9/d2 .../d9/d2/d3 ================"
331
332 test_10() {
333         test_mkdir $DIR/$tdir
334         test_mkdir $DIR/$tdir/d2
335         touch $DIR/$tdir/d2/$tfile
336         $CHECKSTAT -t file $DIR/$tdir/d2/$tfile ||
337                 error "$tdir/d2/$tfile not a file"
338 }
339 run_test 10 "mkdir .../d10 .../d10/d2; touch .../d10/d2/f ======"
340
341 test_11() {
342         test_mkdir $DIR/$tdir
343         test_mkdir $DIR/$tdir/d2
344         chmod 0666 $DIR/$tdir/d2
345         chmod 0705 $DIR/$tdir/d2
346         $CHECKSTAT -t dir -p 0705 $DIR/$tdir/d2 ||
347                 error "$tdir/d2 mode not 0705"
348 }
349 run_test 11 "mkdir .../d11 d11/d2; chmod .../d11/d2 ============"
350
351 test_12() {
352         test_mkdir $DIR/$tdir
353         touch $DIR/$tdir/$tfile
354         chmod 0666 $DIR/$tdir/$tfile
355         chmod 0654 $DIR/$tdir/$tfile
356         $CHECKSTAT -t file -p 0654 $DIR/$tdir/$tfile ||
357                 error "$tdir/d2 mode not 0654"
358 }
359 run_test 12 "touch .../d12/f; chmod .../d12/f .../d12/f ========"
360
361 test_13() {
362         test_mkdir $DIR/$tdir
363         dd if=/dev/zero of=$DIR/$tdir/$tfile count=10
364         >  $DIR/$tdir/$tfile
365         $CHECKSTAT -t file -s 0 $DIR/$tdir/$tfile ||
366                 error "$tdir/$tfile size not 0 after truncate"
367 }
368 run_test 13 "creat .../d13/f; dd .../d13/f; > .../d13/f ========"
369
370 test_14() {
371         test_mkdir $DIR/$tdir
372         touch $DIR/$tdir/$tfile
373         rm $DIR/$tdir/$tfile
374         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
375 }
376 run_test 14 "touch .../d14/f; rm .../d14/f; rm .../d14/f ======="
377
378 test_15() {
379         test_mkdir $DIR/$tdir
380         touch $DIR/$tdir/$tfile
381         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}_2
382         $CHECKSTAT -t file $DIR/$tdir/${tfile}_2 ||
383                 error "$tdir/${tfile_2} not a file after rename"
384         rm $DIR/$tdir/${tfile}_2 || error "unlink failed after rename"
385 }
386 run_test 15 "touch .../d15/f; mv .../d15/f .../d15/f2 =========="
387
388 test_16() {
389         test_mkdir $DIR/$tdir
390         touch $DIR/$tdir/$tfile
391         rm -rf $DIR/$tdir/$tfile
392         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
393 }
394 run_test 16 "touch .../d16/f; rm -rf .../d16/f"
395
396 test_17a() {
397         test_mkdir $DIR/$tdir
398         touch $DIR/$tdir/$tfile
399         ln -s $DIR/$tdir/$tfile $DIR/$tdir/l-exist
400         ls -l $DIR/$tdir
401         $CHECKSTAT -l $DIR/$tdir/$tfile $DIR/$tdir/l-exist ||
402                 error "$tdir/l-exist not a symlink"
403         $CHECKSTAT -f -t f $DIR/$tdir/l-exist ||
404                 error "$tdir/l-exist not referencing a file"
405         rm -f $DIR/$tdir/l-exist
406         $CHECKSTAT -a $DIR/$tdir/l-exist || error "$tdir/l-exist not removed"
407 }
408 run_test 17a "symlinks: create, remove (real)"
409
410 test_17b() {
411         test_mkdir $DIR/$tdir
412         ln -s no-such-file $DIR/$tdir/l-dangle
413         ls -l $DIR/$tdir
414         $CHECKSTAT -l no-such-file $DIR/$tdir/l-dangle ||
415                 error "$tdir/l-dangle not referencing no-such-file"
416         $CHECKSTAT -fa $DIR/$tdir/l-dangle ||
417                 error "$tdir/l-dangle not referencing non-existent file"
418         rm -f $DIR/$tdir/l-dangle
419         $CHECKSTAT -a $DIR/$tdir/l-dangle || error "$tdir/l-dangle not removed"
420 }
421 run_test 17b "symlinks: create, remove (dangling)"
422
423 test_17c() { # bug 3440 - don't save failed open RPC for replay
424         test_mkdir $DIR/$tdir
425         ln -s foo $DIR/$tdir/$tfile
426         cat $DIR/$tdir/$tfile && error "opened non-existent symlink" || true
427 }
428 run_test 17c "symlinks: open dangling (should return error)"
429
430 test_17d() {
431         test_mkdir $DIR/$tdir
432         ln -s foo $DIR/$tdir/$tfile
433         touch $DIR/$tdir/$tfile || error "creating to new symlink"
434 }
435 run_test 17d "symlinks: create dangling"
436
437 test_17e() {
438         test_mkdir $DIR/$tdir
439         local foo=$DIR/$tdir/$tfile
440         ln -s $foo $foo || error "create symlink failed"
441         ls -l $foo || error "ls -l failed"
442         ls $foo && error "ls not failed" || true
443 }
444 run_test 17e "symlinks: create recursive symlink (should return error)"
445
446 test_17f() {
447         test_mkdir $DIR/$tdir
448         ln -s 1234567890/2234567890/3234567890/4234567890 $DIR/$tdir/111
449         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890 $DIR/$tdir/222
450         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890 $DIR/$tdir/333
451         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890 $DIR/$tdir/444
452         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890 $DIR/$tdir/555
453         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
454         ls -l  $DIR/$tdir
455 }
456 run_test 17f "symlinks: long and very long symlink name"
457
458 # str_repeat(S, N) generate a string that is string S repeated N times
459 str_repeat() {
460         local s=$1
461         local n=$2
462         local ret=''
463         while [ $((n -= 1)) -ge 0 ]; do
464                 ret=$ret$s
465         done
466         echo $ret
467 }
468
469 # Long symlinks and LU-2241
470 test_17g() {
471         test_mkdir $DIR/$tdir
472         local TESTS="59 60 61 4094 4095"
473
474         # Fix for inode size boundary in 2.1.4
475         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.1.4) ] &&
476                 TESTS="4094 4095"
477
478         # Patch not applied to 2.2 or 2.3 branches
479         [ $(lustre_version_code $SINGLEMDS) -ge $(version_code 2.2.0) ] &&
480         [ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.3.55) ] &&
481                 TESTS="4094 4095"
482
483         # skip long symlink name for rhel6.5.
484         # rhel6.5 has a limit (PATH_MAX - sizeof(struct filename))
485         grep -q '6.5' /etc/redhat-release &>/dev/null &&
486                 TESTS="59 60 61 4062 4063"
487
488         for i in $TESTS; do
489                 local SYMNAME=$(str_repeat 'x' $i)
490                 ln -s $SYMNAME $DIR/$tdir/f$i || error "failed $i-char symlink"
491                 readlink $DIR/$tdir/f$i || error "failed $i-char readlink"
492         done
493 }
494 run_test 17g "symlinks: really long symlink name and inode boundaries"
495
496 test_17h() { #bug 17378
497         remote_mds_nodsh && skip "remote MDS with nodsh" && return
498         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
499         local mdt_idx
500         test_mkdir $DIR/$tdir
501         if [[ $MDSCOUNT -gt 1 ]]; then
502                 mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
503         else
504                 mdt_idx=0
505         fi
506         $LFS setstripe -c -1 $DIR/$tdir
507         #define OBD_FAIL_MDS_LOV_PREP_CREATE 0x141
508         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000141
509         touch $DIR/$tdir/$tfile || true
510 }
511 run_test 17h "create objects: lov_free_memmd() doesn't lbug"
512
513 test_17i() { #bug 20018
514         remote_mds_nodsh && skip "remote MDS with nodsh" && return
515         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
516         test_mkdir -c1 $DIR/$tdir
517         local foo=$DIR/$tdir/$tfile
518         local mdt_idx
519         if [[ $MDSCOUNT -gt 1 ]]; then
520                 mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
521         else
522                 mdt_idx=0
523         fi
524         ln -s $foo $foo || error "create symlink failed"
525 #define OBD_FAIL_MDS_READLINK_EPROTO     0x143
526         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000143
527         ls -l $foo && error "error not detected"
528         return 0
529 }
530 run_test 17i "don't panic on short symlink"
531
532 test_17k() { #bug 22301
533         [[ -z "$(which rsync 2>/dev/null)" ]] &&
534                 skip "no rsync command" && return 0
535         rsync --help | grep -q xattr ||
536                 skip_env "$(rsync --version | head -n1) does not support xattrs"
537         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return 0
538         test_mkdir $DIR/$tdir
539         test_mkdir $DIR/$tdir.new
540         touch $DIR/$tdir/$tfile
541         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
542         rsync -av -X $DIR/$tdir/ $DIR/$tdir.new ||
543                 error "rsync failed with xattrs enabled"
544 }
545 run_test 17k "symlinks: rsync with xattrs enabled"
546
547 test_17l() { # LU-279
548         [[ -z "$(which getfattr 2>/dev/null)" ]] &&
549                 skip "no getfattr command" && return 0
550         test_mkdir $DIR/$tdir
551         touch $DIR/$tdir/$tfile
552         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
553         for path in "$DIR/$tdir" "$DIR/$tdir/$tfile" "$DIR/$tdir/$tfile.lnk"; do
554                 # -h to not follow symlinks. -m '' to list all the xattrs.
555                 # grep to remove first line: '# file: $path'.
556                 for xattr in `getfattr -hm '' $path 2>/dev/null | grep -v '^#'`;
557                 do
558                         lgetxattr_size_check $path $xattr ||
559                                 error "lgetxattr_size_check $path $xattr failed"
560                 done
561         done
562 }
563 run_test 17l "Ensure lgetxattr's returned xattr size is consistent"
564
565 # LU-1540
566 test_17m() {
567         local short_sym="0123456789"
568         local wdir=$DIR/$tdir
569         local i
570
571         remote_mds_nodsh && skip "remote MDS with nodsh" && return
572         [ $(lustre_version_code $SINGLEMDS) -ge $(version_code 2.2.0) ] &&
573         [ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.2.93) ] &&
574                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks" && return
575
576         [ "$(facet_fstype $SINGLEMDS)" != "ldiskfs" ] &&
577                 skip "ldiskfs only test" && return 0
578
579         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
580
581         test_mkdir $wdir
582         long_sym=$short_sym
583         # create a long symlink file
584         for ((i = 0; i < 4; ++i)); do
585                 long_sym=${long_sym}${long_sym}
586         done
587
588         echo "create 512 short and long symlink files under $wdir"
589         for ((i = 0; i < 256; ++i)); do
590                 ln -sf ${long_sym}"a5a5" $wdir/long-$i
591                 ln -sf ${short_sym}"a5a5" $wdir/short-$i
592         done
593
594         echo "erase them"
595         rm -f $wdir/*
596         sync
597         wait_delete_completed
598
599         echo "recreate the 512 symlink files with a shorter string"
600         for ((i = 0; i < 512; ++i)); do
601                 # rewrite the symlink file with a shorter string
602                 ln -sf ${long_sym} $wdir/long-$i || error "long_sym failed"
603                 ln -sf ${short_sym} $wdir/short-$i || error "short_sym failed"
604         done
605
606         local mds_index=$(($($LFS getstripe -M $wdir) + 1))
607         local devname=$(mdsdevname $mds_index)
608
609         echo "stop and checking mds${mds_index}:"
610         # e2fsck should not return error
611         stop mds${mds_index}
612         run_e2fsck $(facet_active_host mds${mds_index}) $devname -n
613         rc=$?
614
615         start mds${mds_index} $devname $MDS_MOUNT_OPTS ||
616                 error "start mds${mds_index} failed"
617         df $MOUNT > /dev/null 2>&1
618         [ $rc -eq 0 ] ||
619                 error "e2fsck detected error for short/long symlink: rc=$rc"
620 }
621 run_test 17m "run e2fsck against MDT which contains short/long symlink"
622
623 check_fs_consistency_17n() {
624         local mdt_index
625         local rc=0
626
627         # create/unlink in 17n only change 2 MDTs(MDT1/MDT2),
628         # so it only check MDT1/MDT2 instead of all of MDTs.
629         for mdt_index in 1 2; do
630                 local devname=$(mdsdevname $mdt_index)
631                 # e2fsck should not return error
632                 stop mds${mdt_index}
633                 run_e2fsck $(facet_active_host mds$mdt_index) $devname -n ||
634                         rc=$((rc + $?))
635
636                 start mds${mdt_index} $devname $MDS_MOUNT_OPTS ||
637                         error "mount mds$mdt_index failed"
638                 df $MOUNT > /dev/null 2>&1
639         done
640         return $rc
641 }
642
643 test_17n() {
644         local i
645
646         remote_mds_nodsh && skip "remote MDS with nodsh" && return
647         [ $(lustre_version_code $SINGLEMDS) -ge $(version_code 2.2.0) ] &&
648         [ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.2.93) ] &&
649                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks" && return
650
651         [ "$(facet_fstype $SINGLEMDS)" != "ldiskfs" ] &&
652                 skip "ldiskfs only test" && return 0
653
654         [[ $MDSCOUNT -lt 2 ]] && skip "needs >= 2 MDTs" && return
655
656         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
657
658         test_mkdir $DIR/$tdir
659         for ((i=0; i<10; i++)); do
660                 $LFS mkdir -i1 -c2 $DIR/$tdir/remote_dir_${i} ||
661                         error "create remote dir error $i"
662                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
663                         error "create files under remote dir failed $i"
664         done
665
666         check_fs_consistency_17n ||
667                 error "e2fsck report error after create files under remote dir"
668
669         for ((i = 0; i < 10; i++)); do
670                 rm -rf $DIR/$tdir/remote_dir_${i} ||
671                         error "destroy remote dir error $i"
672         done
673
674         check_fs_consistency_17n ||
675                 error "e2fsck report error after unlink files under remote dir"
676
677         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.4.50) ] &&
678                 skip "lustre < 2.4.50 does not support migrate mv " && return
679
680         for ((i = 0; i < 10; i++)); do
681                 mkdir -p $DIR/$tdir/remote_dir_${i}
682                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
683                         error "create files under remote dir failed $i"
684                 $LFS migrate --mdt-index 1 $DIR/$tdir/remote_dir_${i} ||
685                         error "migrate remote dir error $i"
686         done
687         check_fs_consistency_17n || error "e2fsck report error after migration"
688
689         for ((i = 0; i < 10; i++)); do
690                 rm -rf $DIR/$tdir/remote_dir_${i} ||
691                         error "destroy remote dir error $i"
692         done
693
694         check_fs_consistency_17n || error "e2fsck report error after unlink"
695 }
696 run_test 17n "run e2fsck against master/slave MDT which contains remote dir"
697
698 test_17o() {
699         remote_mds_nodsh && skip "remote MDS with nodsh" && return
700         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.3.64) ] &&
701                 skip "Need MDS version at least 2.3.64" && return
702
703         local wdir=$DIR/${tdir}o
704         local mdt_index
705         local rc=0
706
707         test_mkdir $wdir
708         touch $wdir/$tfile
709         mdt_index=$($LFS getstripe -M $wdir/$tfile)
710         mdt_index=$((mdt_index + 1))
711
712         cancel_lru_locks mdc
713         #fail mds will wait the failover finish then set
714         #following fail_loc to avoid interfer the recovery process.
715         fail mds${mdt_index}
716
717         #define OBD_FAIL_OSD_LMA_INCOMPAT 0x194
718         do_facet mds${mdt_index} lctl set_param fail_loc=0x194
719         ls -l $wdir/$tfile && rc=1
720         do_facet mds${mdt_index} lctl set_param fail_loc=0
721         [[ $rc -eq 0 ]] || error "stat file should fail"
722 }
723 run_test 17o "stat file with incompat LMA feature"
724
725 test_18() {
726         touch $DIR/$tfile || error "Failed to touch $DIR/$tfile: $?"
727         ls $DIR || error "Failed to ls $DIR: $?"
728 }
729 run_test 18 "touch .../f ; ls ... =============================="
730
731 test_19a() {
732         touch $DIR/$tfile
733         ls -l $DIR
734         rm $DIR/$tfile
735         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
736 }
737 run_test 19a "touch .../f19 ; ls -l ... ; rm .../f19 ==========="
738
739 test_19b() {
740         ls -l $DIR/$tfile && error "ls -l $tfile failed"|| true
741 }
742 run_test 19b "ls -l .../f19 (should return error) =============="
743
744 test_19c() {
745         [ $RUNAS_ID -eq $UID ] &&
746                 skip_env "RUNAS_ID = UID = $UID -- skipping" && return
747         $RUNAS touch $DIR/$tfile && error "create non-root file failed" || true
748 }
749 run_test 19c "$RUNAS touch .../f19 (should return error) =="
750
751 test_19d() {
752         cat $DIR/f19 && error || true
753 }
754 run_test 19d "cat .../f19 (should return error) =============="
755
756 test_20() {
757         touch $DIR/$tfile
758         rm $DIR/$tfile
759         touch $DIR/$tfile
760         rm $DIR/$tfile
761         touch $DIR/$tfile
762         rm $DIR/$tfile
763         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
764 }
765 run_test 20 "touch .../f ; ls -l ..."
766
767 test_21() {
768         test_mkdir $DIR/$tdir
769         [ -f $DIR/$tdir/dangle ] && rm -f $DIR/$tdir/dangle
770         ln -s dangle $DIR/$tdir/link
771         echo foo >> $DIR/$tdir/link
772         cat $DIR/$tdir/dangle
773         $CHECKSTAT -t link $DIR/$tdir/link || error "$tdir/link not a link"
774         $CHECKSTAT -f -t file $DIR/$tdir/link ||
775                 error "$tdir/link not linked to a file"
776 }
777 run_test 21 "write to dangling link"
778
779 test_22() {
780         local wdir=$DIR/$tdir
781         test_mkdir $wdir
782         chown $RUNAS_ID:$RUNAS_GID $wdir
783         (cd $wdir || error "cd $wdir failed";
784                 $RUNAS tar cf - /etc/hosts /etc/sysconfig/network |
785                 $RUNAS tar xf -)
786         ls -lR $wdir/etc || error "ls -lR $wdir/etc failed"
787         $CHECKSTAT -t dir $wdir/etc || error "checkstat -t dir failed"
788         $CHECKSTAT -u \#$RUNAS_ID -g \#$RUNAS_GID $wdir/etc ||
789                 error "checkstat -u failed"
790 }
791 run_test 22 "unpack tar archive as non-root user"
792
793 # was test_23
794 test_23a() {
795         test_mkdir $DIR/$tdir
796         local file=$DIR/$tdir/$tfile
797
798         openfile -f O_CREAT:O_EXCL $file || error "$file create failed"
799         openfile -f O_CREAT:O_EXCL $file &&
800                 error "$file recreate succeeded" || true
801 }
802 run_test 23a "O_CREAT|O_EXCL in subdir"
803
804 test_23b() { # bug 18988
805         test_mkdir $DIR/$tdir
806         local file=$DIR/$tdir/$tfile
807
808         rm -f $file
809         echo foo > $file || error "write filed"
810         echo bar >> $file || error "append filed"
811         $CHECKSTAT -s 8 $file || error "wrong size"
812         rm $file
813 }
814 run_test 23b "O_APPEND check"
815
816 # rename sanity
817 test_24a() {
818         echo '-- same directory rename'
819         test_mkdir $DIR/$tdir
820         touch $DIR/$tdir/$tfile.1
821         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
822         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
823 }
824 run_test 24a "rename file to non-existent target"
825
826 test_24b() {
827         test_mkdir $DIR/$tdir
828         touch $DIR/$tdir/$tfile.{1,2}
829         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
830         $CHECKSTAT -a $DIR/$tdir/$tfile.1 || error "$tfile.1 exists"
831         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
832 }
833 run_test 24b "rename file to existing target"
834
835 test_24c() {
836         test_mkdir $DIR/$tdir
837         test_mkdir $DIR/$tdir/d$testnum.1
838         mv $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
839         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
840         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
841 }
842 run_test 24c "rename directory to non-existent target"
843
844 test_24d() {
845         test_mkdir -c1 $DIR/$tdir
846         test_mkdir -c1 $DIR/$tdir/d$testnum.1
847         test_mkdir -c1 $DIR/$tdir/d$testnum.2
848         mrename $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
849         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
850         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
851 }
852 run_test 24d "rename directory to existing target"
853
854 test_24e() {
855         echo '-- cross directory renames --'
856         test_mkdir $DIR/R5a
857         test_mkdir $DIR/R5b
858         touch $DIR/R5a/f
859         mv $DIR/R5a/f $DIR/R5b/g
860         $CHECKSTAT -a $DIR/R5a/f || error
861         $CHECKSTAT -t file $DIR/R5b/g || error
862 }
863 run_test 24e "touch .../R5a/f; rename .../R5a/f .../R5b/g ======"
864
865 test_24f() {
866         test_mkdir $DIR/R6a
867         test_mkdir $DIR/R6b
868         touch $DIR/R6a/f $DIR/R6b/g
869         mv $DIR/R6a/f $DIR/R6b/g
870         $CHECKSTAT -a $DIR/R6a/f || error
871         $CHECKSTAT -t file $DIR/R6b/g || error
872 }
873 run_test 24f "touch .../R6a/f R6b/g; mv .../R6a/f .../R6b/g ===="
874
875 test_24g() {
876         test_mkdir $DIR/R7a
877         test_mkdir $DIR/R7b
878         test_mkdir $DIR/R7a/d
879         mv $DIR/R7a/d $DIR/R7b/e
880         $CHECKSTAT -a $DIR/R7a/d || error
881         $CHECKSTAT -t dir $DIR/R7b/e || error
882 }
883 run_test 24g "mkdir .../R7{a,b}/d; mv .../R7a/d .../R7b/e ======"
884
885 test_24h() {
886         test_mkdir -c1 $DIR/R8a
887         test_mkdir -c1 $DIR/R8b
888         test_mkdir -c1 $DIR/R8a/d
889         test_mkdir -c1 $DIR/R8b/e
890         mrename $DIR/R8a/d $DIR/R8b/e
891         $CHECKSTAT -a $DIR/R8a/d || error
892         $CHECKSTAT -t dir $DIR/R8b/e || error
893 }
894 run_test 24h "mkdir .../R8{a,b}/{d,e}; rename .../R8a/d .../R8b/e"
895
896 test_24i() {
897         echo "-- rename error cases"
898         test_mkdir $DIR/R9
899         test_mkdir $DIR/R9/a
900         touch $DIR/R9/f
901         mrename $DIR/R9/f $DIR/R9/a
902         $CHECKSTAT -t file $DIR/R9/f || error
903         $CHECKSTAT -t dir  $DIR/R9/a || error
904         $CHECKSTAT -a $DIR/R9/a/f || error
905 }
906 run_test 24i "rename file to dir error: touch f ; mkdir a ; rename f a"
907
908 test_24j() {
909         test_mkdir $DIR/R10
910         mrename $DIR/R10/f $DIR/R10/g
911         $CHECKSTAT -t dir $DIR/R10 || error
912         $CHECKSTAT -a $DIR/R10/f || error
913         $CHECKSTAT -a $DIR/R10/g || error
914 }
915 run_test 24j "source does not exist ============================"
916
917 test_24k() {
918         test_mkdir $DIR/R11a
919         test_mkdir $DIR/R11a/d
920         touch $DIR/R11a/f
921         mv $DIR/R11a/f $DIR/R11a/d
922         $CHECKSTAT -a $DIR/R11a/f || error
923         $CHECKSTAT -t file $DIR/R11a/d/f || error
924 }
925 run_test 24k "touch .../R11a/f; mv .../R11a/f .../R11a/d ======="
926
927 # bug 2429 - rename foo foo foo creates invalid file
928 test_24l() {
929         f="$DIR/f24l"
930         $MULTIOP $f OcNs || error
931 }
932 run_test 24l "Renaming a file to itself ========================"
933
934 test_24m() {
935         f="$DIR/f24m"
936         $MULTIOP $f OcLN ${f}2 ${f}2 || error "link ${f}2 ${f}2 failed"
937         # on ext3 this does not remove either the source or target files
938         # though the "expected" operation would be to remove the source
939         $CHECKSTAT -t file ${f} || error "${f} missing"
940         $CHECKSTAT -t file ${f}2 || error "${f}2 missing"
941 }
942 run_test 24m "Renaming a file to a hard link to itself ========="
943
944 test_24n() {
945     f="$DIR/f24n"
946     # this stats the old file after it was renamed, so it should fail
947     touch ${f}
948     $CHECKSTAT ${f}
949     mv ${f} ${f}.rename
950     $CHECKSTAT ${f}.rename
951     $CHECKSTAT -a ${f}
952 }
953 run_test 24n "Statting the old file after renaming (Posix rename 2)"
954
955 test_24o() {
956         test_mkdir $DIR/$tdir
957         rename_many -s random -v -n 10 $DIR/$tdir
958 }
959 run_test 24o "rename of files during htree split"
960
961 test_24p() {
962         test_mkdir $DIR/R12a
963         test_mkdir $DIR/R12b
964         DIRINO=`ls -lid $DIR/R12a | awk '{ print $1 }'`
965         mrename $DIR/R12a $DIR/R12b
966         $CHECKSTAT -a $DIR/R12a || error
967         $CHECKSTAT -t dir $DIR/R12b || error
968         DIRINO2=`ls -lid $DIR/R12b | awk '{ print $1 }'`
969         [ "$DIRINO" = "$DIRINO2" ] || error "R12a $DIRINO != R12b $DIRINO2"
970 }
971 run_test 24p "mkdir .../R12{a,b}; rename .../R12a .../R12b"
972
973 cleanup_multiop_pause() {
974         trap 0
975         kill -USR1 $MULTIPID
976 }
977
978 test_24q() {
979         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
980         test_mkdir $DIR/R13a
981         test_mkdir $DIR/R13b
982         local DIRINO=$(ls -lid $DIR/R13a | awk '{ print $1 }')
983         multiop_bg_pause $DIR/R13b D_c || error "multiop failed to start"
984         MULTIPID=$!
985
986         trap cleanup_multiop_pause EXIT
987         mrename $DIR/R13a $DIR/R13b
988         $CHECKSTAT -a $DIR/R13a || error "R13a still exists"
989         $CHECKSTAT -t dir $DIR/R13b || error "R13b does not exist"
990         local DIRINO2=$(ls -lid $DIR/R13b | awk '{ print $1 }')
991         [ "$DIRINO" = "$DIRINO2" ] || error "R13a $DIRINO != R13b $DIRINO2"
992         cleanup_multiop_pause
993         wait $MULTIPID || error "multiop close failed"
994 }
995 run_test 24q "mkdir .../R13{a,b}; open R13b rename R13a R13b ==="
996
997 test_24r() { #bug 3789
998         test_mkdir $DIR/R14a
999         test_mkdir $DIR/R14a/b
1000         mrename $DIR/R14a $DIR/R14a/b && error "rename to subdir worked!"
1001         $CHECKSTAT -t dir $DIR/R14a || error "$DIR/R14a missing"
1002         $CHECKSTAT -t dir $DIR/R14a/b || error "$DIR/R14a/b missing"
1003 }
1004 run_test 24r "mkdir .../R14a/b; rename .../R14a .../R14a/b ====="
1005
1006 test_24s() {
1007         test_mkdir $DIR/R15a
1008         test_mkdir $DIR/R15a/b
1009         test_mkdir $DIR/R15a/b/c
1010         mrename $DIR/R15a $DIR/R15a/b/c && error "rename to sub-subdir worked!"
1011         $CHECKSTAT -t dir $DIR/R15a || error "$DIR/R15a missing"
1012         $CHECKSTAT -t dir $DIR/R15a/b/c || error "$DIR/R15a/b/c missing"
1013 }
1014 run_test 24s "mkdir .../R15a/b/c; rename .../R15a .../R15a/b/c ="
1015 test_24t() {
1016         test_mkdir $DIR/R16a
1017         test_mkdir $DIR/R16a/b
1018         test_mkdir $DIR/R16a/b/c
1019         mrename $DIR/R16a/b/c $DIR/R16a && error "rename to sub-subdir worked!"
1020         $CHECKSTAT -t dir $DIR/R16a || error "$DIR/R16a missing"
1021         $CHECKSTAT -t dir $DIR/R16a/b/c || error "$DIR/R16a/b/c missing"
1022 }
1023 run_test 24t "mkdir .../R16a/b/c; rename .../R16a/b/c .../R16a ="
1024
1025 test_24u() { # bug12192
1026         $MULTIOP $DIR/$tfile C2w$((2048 * 1024))c || error
1027         $CHECKSTAT -s $((2048 * 1024)) $DIR/$tfile || error "wrong file size"
1028 }
1029 run_test 24u "create stripe file"
1030
1031 page_size() {
1032         local size
1033         size=$(getconf PAGE_SIZE 2>/dev/null)
1034         echo -n ${size:-4096}
1035 }
1036
1037 simple_cleanup_common() {
1038         local rc=0
1039         trap 0
1040         [ -z "$DIR" -o -z "$tdir" ] && return 0
1041
1042         local start=$SECONDS
1043         rm -rf $DIR/$tdir
1044         rc=$?
1045         wait_delete_completed
1046         echo "cleanup time $((SECONDS - start))"
1047         return $rc
1048 }
1049
1050 max_pages_per_rpc() {
1051         local mdtname="$(printf "MDT%04x" ${1:-0})"
1052         $LCTL get_param -n mdc.*$mdtname*.max_pages_per_rpc
1053 }
1054
1055 test_24v() {
1056         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
1057         local nrfiles=${COUNT:-100000}
1058         # Performance issue on ZFS see LU-4072 (c.f. LU-2887)
1059         [ $(facet_fstype $SINGLEMDS) = "zfs" ] && nrfiles=${COUNT:-10000}
1060
1061         local fname="$DIR/$tdir/$tfile"
1062         test_mkdir "$(dirname $fname)"
1063         # assume MDT0000 has the fewest inodes
1064         local stripes=$($LFS getdirstripe -c $(dirname $fname))
1065         local free_inodes=$(($(mdt_free_inodes 0) * stripes))
1066         [[ $free_inodes -lt $nrfiles ]] && nrfiles=$free_inodes
1067
1068         trap simple_cleanup_common EXIT
1069
1070         createmany -m "$fname" $nrfiles
1071
1072         cancel_lru_locks mdc
1073         lctl set_param mdc.*.stats clear
1074
1075         # was previously test_24D: LU-6101
1076         # readdir() returns correct number of entries after cursor reload
1077         local num_ls=$(ls $DIR/$tdir | wc -l)
1078         local num_uniq=$(ls $DIR/$tdir | sort -u | wc -l)
1079         local num_all=$(ls -a $DIR/$tdir | wc -l)
1080         if [ $num_ls -ne $nrfiles -o $num_uniq -ne $nrfiles -o \
1081              $num_all -ne $((nrfiles + 2)) ]; then
1082                 error "Expected $nrfiles files, got $num_ls " \
1083                         "($num_uniq unique $num_all .&..)"
1084         fi
1085         # LU-5 large readdir
1086         # dirent_size = 32 bytes for sizeof(struct lu_dirent) +
1087         #               N bytes for name (len($nrfiles) rounded to 8 bytes) +
1088         #               8 bytes for luda_type (4 bytes rounded to 8 bytes)
1089         # take into account of overhead in lu_dirpage header and end mark in
1090         # each page, plus one in rpc_num calculation.
1091         local dirent_size=$((32 + (${#tfile} | 7) + 1 + 8))
1092         local page_entries=$((($(page_size) - 24) / dirent_size))
1093         local mdt_idx=$($LFS getdirstripe -i $(dirname $fname))
1094         local rpc_pages=$(max_pages_per_rpc $mdt_idx)
1095         local rpc_max=$((nrfiles / (page_entries * rpc_pages) + stripes))
1096         local mds_readpage=$(calc_stats mdc.*.stats mds_readpage)
1097         echo "readpages: $mds_readpage rpc_max: $rpc_max"
1098         (( $mds_readpage < $rpc_max - 2 || $mds_readpage > $rpc_max + 1)) &&
1099                 error "large readdir doesn't take effect: " \
1100                       "$mds_readpage should be about $rpc_max"
1101
1102         simple_cleanup_common
1103 }
1104 run_test 24v "list large directory (test hash collision, b=17560)"
1105
1106 test_24w() { # bug21506
1107         SZ1=234852
1108         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=4096 || return 1
1109         dd if=/dev/zero bs=$SZ1 count=1 >> $DIR/$tfile || return 2
1110         dd if=$DIR/$tfile of=$DIR/${tfile}_left bs=1M skip=4097 || return 3
1111         SZ2=`ls -l $DIR/${tfile}_left | awk '{print $5}'`
1112         [[ "$SZ1" -eq "$SZ2" ]] ||
1113                 error "Error reading at the end of the file $tfile"
1114 }
1115 run_test 24w "Reading a file larger than 4Gb"
1116
1117 test_24x() {
1118         [[ $MDSCOUNT -lt 2 ]] && skip "needs >= 2 MDTs" && return
1119
1120         [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.7.56) ]] &&
1121                 skip "Need MDS version at least 2.7.56" && return
1122
1123         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
1124         local MDTIDX=1
1125         local remote_dir=$DIR/$tdir/remote_dir
1126
1127         test_mkdir $DIR/$tdir
1128         $LFS mkdir -i $MDTIDX $remote_dir ||
1129                 error "create remote directory failed"
1130
1131         test_mkdir $DIR/$tdir/src_dir
1132         touch $DIR/$tdir/src_file
1133         test_mkdir $remote_dir/tgt_dir
1134         touch $remote_dir/tgt_file
1135
1136         mrename $DIR/$tdir/src_dir $remote_dir/tgt_dir ||
1137                 error "rename dir cross MDT failed!"
1138
1139         mrename $DIR/$tdir/src_file $remote_dir/tgt_file ||
1140                 error "rename file cross MDT failed!"
1141
1142         touch $DIR/$tdir/ln_file
1143         ln $DIR/$tdir/ln_file $remote_dir/ln_name ||
1144                 error "ln file cross MDT failed"
1145
1146         rm -rf $DIR/$tdir || error "Can not delete directories"
1147 }
1148 run_test 24x "cross MDT rename/link"
1149
1150 test_24y() {
1151         [[ $MDSCOUNT -lt 2 ]] && skip "needs >= 2 MDTs" && return
1152         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
1153         local remote_dir=$DIR/$tdir/remote_dir
1154         local mdtidx=1
1155
1156         test_mkdir $DIR/$tdir
1157         $LFS mkdir -i $mdtidx $remote_dir ||
1158                    error "create remote directory failed"
1159
1160         test_mkdir $remote_dir/src_dir
1161         touch $remote_dir/src_file
1162         test_mkdir $remote_dir/tgt_dir
1163         touch $remote_dir/tgt_file
1164
1165         mrename $remote_dir/src_dir $remote_dir/tgt_dir ||
1166                 error "rename subdir in the same remote dir failed!"
1167
1168         mrename $remote_dir/src_file $remote_dir/tgt_file ||
1169                 error "rename files in the same remote dir failed!"
1170
1171         ln $remote_dir/tgt_file $remote_dir/tgt_file1 ||
1172                 error "link files in the same remote dir failed!"
1173
1174         rm -rf $DIR/$tdir || error "Can not delete directories"
1175 }
1176 run_test 24y "rename/link on the same dir should succeed"
1177
1178 test_24A() { # LU-3182
1179         local NFILES=5000
1180
1181         rm -rf $DIR/$tdir
1182         test_mkdir $DIR/$tdir
1183         trap simple_cleanup_common EXIT
1184         createmany -m $DIR/$tdir/$tfile $NFILES
1185         local t=$(ls $DIR/$tdir | wc -l)
1186         local u=$(ls $DIR/$tdir | sort -u | wc -l)
1187         local v=$(ls -ai $DIR/$tdir | sort -u | wc -l)
1188         if [ $t -ne $NFILES -o $u -ne $NFILES -o $v -ne $((NFILES + 2)) ] ; then
1189                 error "Expected $NFILES files, got $t ($u unique $v .&..)"
1190         fi
1191
1192         simple_cleanup_common || error "Can not delete directories"
1193 }
1194 run_test 24A "readdir() returns correct number of entries."
1195
1196 test_24B() { # LU-4805
1197         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
1198         local count
1199
1200         test_mkdir $DIR/$tdir
1201         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
1202                 error "create striped dir failed"
1203
1204         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1205         [ $count -eq 2 ] || error "Expected 2, got $count"
1206
1207         touch $DIR/$tdir/striped_dir/a
1208
1209         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1210         [ $count -eq 3 ] || error "Expected 3, got $count"
1211
1212         touch $DIR/$tdir/striped_dir/.f
1213
1214         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1215         [ $count -eq 4 ] || error "Expected 4, got $count"
1216
1217         rm -rf $DIR/$tdir || error "Can not delete directories"
1218 }
1219 run_test 24B "readdir for striped dir return correct number of entries"
1220
1221 test_24C() {
1222         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
1223
1224         mkdir $DIR/$tdir
1225         mkdir $DIR/$tdir/d0
1226         mkdir $DIR/$tdir/d1
1227
1228         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/d0/striped_dir ||
1229                 error "create striped dir failed"
1230
1231         cd $DIR/$tdir/d0/striped_dir
1232
1233         local d0_ino=$(ls -i -l -a $DIR/$tdir | grep "d0" | awk '{print $1}')
1234         local d1_ino=$(ls -i -l -a $DIR/$tdir | grep "d1" | awk '{print $1}')
1235         local parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1236
1237         [ "$d0_ino" = "$parent_ino" ] ||
1238                 error ".. wrong, expect $d0_ino, get $parent_ino"
1239
1240         mv $DIR/$tdir/d0/striped_dir $DIR/$tdir/d1/ ||
1241                 error "mv striped dir failed"
1242
1243         parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1244
1245         [ "$d1_ino" = "$parent_ino" ] ||
1246                 error ".. wrong after mv, expect $d1_ino, get $parent_ino"
1247 }
1248 run_test 24C "check .. in striped dir"
1249
1250 test_24E() {
1251         [[ $MDSCOUNT -lt 4 ]] && skip "needs >= 4 MDTs" && return
1252         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
1253
1254         mkdir -p $DIR/$tdir
1255         mkdir $DIR/$tdir/src_dir
1256         $LFS mkdir -i 1 $DIR/$tdir/src_dir/src_child ||
1257                 error "create remote source failed"
1258
1259         touch $DIR/$tdir/src_dir/src_child/a
1260
1261         $LFS mkdir -i 2 $DIR/$tdir/tgt_dir ||
1262                 error "create remote target dir failed"
1263
1264         $LFS mkdir -i 3 $DIR/$tdir/tgt_dir/tgt_child ||
1265                 error "create remote target child failed"
1266
1267         mrename $DIR/$tdir/src_dir/src_child $DIR/$tdir/tgt_dir/tgt_child ||
1268                 error "rename dir cross MDT failed!"
1269
1270         find $DIR/$tdir
1271
1272         $CHECKSTAT -t dir $DIR/$tdir/src_dir/src_child &&
1273                 error "src_child still exists after rename"
1274
1275         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/tgt_child/a ||
1276                 error "missing file(a) after rename"
1277
1278         rm -rf $DIR/$tdir || error "Can not delete directories"
1279 }
1280 run_test 24E "cross MDT rename/link"
1281
1282 test_25a() {
1283         echo '== symlink sanity ============================================='
1284
1285         test_mkdir $DIR/d25
1286         ln -s d25 $DIR/s25
1287         touch $DIR/s25/foo || error
1288 }
1289 run_test 25a "create file in symlinked directory ==============="
1290
1291 test_25b() {
1292         [ ! -d $DIR/d25 ] && test_25a
1293         $CHECKSTAT -t file $DIR/s25/foo || error
1294 }
1295 run_test 25b "lookup file in symlinked directory ==============="
1296
1297 test_26a() {
1298         test_mkdir $DIR/d26
1299         test_mkdir $DIR/d26/d26-2
1300         ln -s d26/d26-2 $DIR/s26
1301         touch $DIR/s26/foo || error
1302 }
1303 run_test 26a "multiple component symlink ======================="
1304
1305 test_26b() {
1306         test_mkdir -p $DIR/$tdir/d26-2
1307         ln -s $tdir/d26-2/foo $DIR/s26-2
1308         touch $DIR/s26-2 || error
1309 }
1310 run_test 26b "multiple component symlink at end of lookup ======"
1311
1312 test_26c() {
1313         test_mkdir $DIR/d26.2
1314         touch $DIR/d26.2/foo
1315         ln -s d26.2 $DIR/s26.2-1
1316         ln -s s26.2-1 $DIR/s26.2-2
1317         ln -s s26.2-2 $DIR/s26.2-3
1318         chmod 0666 $DIR/s26.2-3/foo
1319 }
1320 run_test 26c "chain of symlinks"
1321
1322 # recursive symlinks (bug 439)
1323 test_26d() {
1324         ln -s d26-3/foo $DIR/d26-3
1325 }
1326 run_test 26d "create multiple component recursive symlink"
1327
1328 test_26e() {
1329         [ ! -h $DIR/d26-3 ] && test_26d
1330         rm $DIR/d26-3
1331 }
1332 run_test 26e "unlink multiple component recursive symlink"
1333
1334 # recursive symlinks (bug 7022)
1335 test_26f() {
1336         test_mkdir $DIR/$tdir
1337         test_mkdir $DIR/$tdir/$tfile
1338         cd $DIR/$tdir/$tfile           || error "cd $DIR/$tdir/$tfile failed"
1339         test_mkdir -p lndir/bar1
1340         test_mkdir $DIR/$tdir/$tfile/$tfile
1341         cd $tfile                || error "cd $tfile failed"
1342         ln -s .. dotdot          || error "ln dotdot failed"
1343         ln -s dotdot/lndir lndir || error "ln lndir failed"
1344         cd $DIR/$tdir                 || error "cd $DIR/$tdir failed"
1345         output=`ls $tfile/$tfile/lndir/bar1`
1346         [ "$output" = bar1 ] && error "unexpected output"
1347         rm -r $tfile             || error "rm $tfile failed"
1348         $CHECKSTAT -a $DIR/$tfile || error "$tfile not gone"
1349 }
1350 run_test 26f "rm -r of a directory which has recursive symlink"
1351
1352 test_27a() {
1353         test_mkdir $DIR/$tdir
1354         $LFS getstripe $DIR/$tdir
1355         $LFS setstripe -c 1 $DIR/$tdir/$tfile || error "setstripe failed"
1356         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1357         cp /etc/hosts $DIR/$tdir/$tfile || error
1358 }
1359 run_test 27a "one stripe file"
1360
1361 test_27b() {
1362         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs" && return
1363         test_mkdir $DIR/$tdir
1364         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1365         $LFS getstripe -c $DIR/$tdir/$tfile
1366         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
1367                 error "two-stripe file doesn't have two stripes"
1368
1369         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1370 }
1371 run_test 27b "create and write to two stripe file"
1372
1373 test_27d() {
1374         test_mkdir $DIR/$tdir
1375         $LFS setstripe -c 0 -i -1 -S 0 $DIR/$tdir/$tfile ||
1376                 error "setstripe failed"
1377         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1378         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1379 }
1380 run_test 27d "create file with default settings"
1381
1382 test_27e() {
1383         # LU-5839 adds check for existed layout before setting it
1384         [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.7.56) ]] &&
1385                 skip "Need MDS version at least 2.7.56" && return
1386         test_mkdir $DIR/$tdir
1387         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1388         $LFS setstripe -c 2 $DIR/$tdir/$tfile && error "setstripe worked twice"
1389         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1390 }
1391 run_test 27e "setstripe existing file (should return error)"
1392
1393 test_27f() {
1394         test_mkdir $DIR/$tdir
1395         $LFS setstripe -S 100 -i 0 -c 1 $DIR/$tdir/$tfile &&
1396                 error "$SETSTRIPE $DIR/$tdir/$tfile failed"
1397         $CHECKSTAT -t file $DIR/$tdir/$tfile &&
1398                 error "$CHECKSTAT -t file $DIR/$tdir/$tfile should fail"
1399         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1400         $LFS getstripe $DIR/$tdir/$tfile || error "$LFS getstripe failed"
1401 }
1402 run_test 27f "setstripe with bad stripe size (should return error)"
1403
1404 test_27g() {
1405         test_mkdir $DIR/$tdir
1406         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1407         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "no stripe info" ||
1408                 error "$DIR/$tdir/$tfile has object"
1409 }
1410 run_test 27g "$LFS getstripe with no objects"
1411
1412 test_27i() {
1413         test_mkdir $DIR/$tdir
1414         touch $DIR/$tdir/$tfile || error "touch failed"
1415         [[ $($LFS getstripe -c $DIR/$tdir/$tfile) -gt 0 ]] ||
1416                 error "missing objects"
1417 }
1418 run_test 27i "$LFS getstripe with some objects"
1419
1420 test_27j() {
1421         test_mkdir $DIR/$tdir
1422         $LFS setstripe -i $OSTCOUNT $DIR/$tdir/$tfile &&
1423                 error "setstripe failed" || true
1424 }
1425 run_test 27j "setstripe with bad stripe offset (should return error)"
1426
1427 test_27k() { # bug 2844
1428         test_mkdir $DIR/$tdir
1429         local file=$DIR/$tdir/$tfile
1430         local ll_max_blksize=$((4 * 1024 * 1024))
1431         $LFS setstripe -S 67108864 $file || error "setstripe failed"
1432         local blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1433         [ $blksize -le $ll_max_blksize ] || error "1:$blksize > $ll_max_blksize"
1434         dd if=/dev/zero of=$file bs=4k count=1
1435         blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1436         [ $blksize -le $ll_max_blksize ] || error "2:$blksize > $ll_max_blksize"
1437 }
1438 run_test 27k "limit i_blksize for broken user apps"
1439
1440 test_27l() {
1441         mcreate $DIR/$tfile || error "creating file"
1442         $RUNAS $LFS setstripe -c 1 $DIR/$tfile &&
1443                 error "setstripe should have failed" || true
1444 }
1445 run_test 27l "check setstripe permissions (should return error)"
1446
1447 test_27m() {
1448         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs" && return
1449
1450         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
1451                    head -n1)
1452         if [[ $ORIGFREE -gt $MAXFREE ]]; then
1453                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
1454                 return
1455         fi
1456         trap simple_cleanup_common EXIT
1457         test_mkdir $DIR/$tdir
1458         $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.1
1459         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1024 count=$MAXFREE &&
1460                 error "dd should fill OST0"
1461         i=2
1462         while $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.$i; do
1463                 i=$((i + 1))
1464                 [ $i -gt 256 ] && break
1465         done
1466         i=$((i + 1))
1467         touch $DIR/$tdir/$tfile.$i
1468         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1469             awk '{print $1}'| grep -w "0") ] &&
1470                 error "OST0 was full but new created file still use it"
1471         i=$((i + 1))
1472         touch $DIR/$tdir/$tfile.$i
1473         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1474             awk '{print $1}'| grep -w "0") ] &&
1475                 error "OST0 was full but new created file still use it"
1476         simple_cleanup_common
1477 }
1478 run_test 27m "create file while OST0 was full"
1479
1480 sleep_maxage() {
1481         local delay=$(do_facet $SINGLEMDS lctl get_param -n lov.*.qos_maxage |
1482                       head -n 1 | awk '{ print $1 * 2 }')
1483         sleep $delay
1484 }
1485
1486 # OSCs keep a NOSPC flag that will be reset after ~5s (qos_maxage)
1487 # if the OST isn't full anymore.
1488 reset_enospc() {
1489         local OSTIDX=${1:-""}
1490
1491         local list=$(comma_list $(osts_nodes))
1492         [ "$OSTIDX" ] && list=$(facet_host ost$((OSTIDX + 1)))
1493
1494         do_nodes $list lctl set_param fail_loc=0
1495         sync    # initiate all OST_DESTROYs from MDS to OST
1496         sleep_maxage
1497 }
1498
1499 exhaust_precreations() {
1500         local OSTIDX=$1
1501         local FAILLOC=$2
1502         local FAILIDX=${3:-$OSTIDX}
1503         local ofacet=ost$((OSTIDX + 1))
1504
1505         test_mkdir -p -c1 $DIR/$tdir
1506         local mdtidx=$($LFS getstripe -M $DIR/$tdir)
1507         local mfacet=mds$((mdtidx + 1))
1508         echo OSTIDX=$OSTIDX MDTIDX=$mdtidx
1509
1510         local OST=$(ostname_from_index $OSTIDX)
1511
1512         # on the mdt's osc
1513         local mdtosc_proc1=$(get_mdtosc_proc_path $mfacet $OST)
1514         local last_id=$(do_facet $mfacet lctl get_param -n \
1515                         osc.$mdtosc_proc1.prealloc_last_id)
1516         local next_id=$(do_facet $mfacet lctl get_param -n \
1517                         osc.$mdtosc_proc1.prealloc_next_id)
1518
1519         local mdtosc_proc2=$(get_mdtosc_proc_path $mfacet)
1520         do_facet $mfacet lctl get_param osc.$mdtosc_proc2.prealloc*
1521
1522         test_mkdir -p $DIR/$tdir/${OST}
1523         $SETSTRIPE -i $OSTIDX -c 1 $DIR/$tdir/${OST}
1524 #define OBD_FAIL_OST_ENOSPC              0x215
1525         do_facet $ofacet lctl set_param fail_val=$FAILIDX fail_loc=0x215
1526         echo "Creating to objid $last_id on ost $OST..."
1527         createmany -o $DIR/$tdir/${OST}/f $next_id $((last_id - next_id + 2))
1528         do_facet $mfacet lctl get_param osc.$mdtosc_proc2.prealloc*
1529         do_facet $ofacet lctl set_param fail_loc=$FAILLOC
1530         sleep_maxage
1531 }
1532
1533 exhaust_all_precreations() {
1534         local i
1535         for (( i=0; i < OSTCOUNT; i++ )) ; do
1536                 exhaust_precreations $i $1 -1
1537         done
1538 }
1539
1540 test_27n() {
1541         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs" && return
1542         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
1543         remote_mds_nodsh && skip "remote MDS with nodsh" && return
1544         remote_ost_nodsh && skip "remote OST with nodsh" && return
1545
1546         reset_enospc
1547         rm -f $DIR/$tdir/$tfile
1548         exhaust_precreations 0 0x80000215
1549         $LFS setstripe -c -1 $DIR/$tdir
1550         touch $DIR/$tdir/$tfile || error
1551         $LFS getstripe $DIR/$tdir/$tfile
1552         reset_enospc
1553 }
1554 run_test 27n "create file with some full OSTs"
1555
1556 test_27o() {
1557         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs" && return
1558         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
1559         remote_mds_nodsh && skip "remote MDS with nodsh" && return
1560         remote_ost_nodsh && skip "remote OST with nodsh" && return
1561
1562         reset_enospc
1563         rm -f $DIR/$tdir/$tfile
1564         exhaust_all_precreations 0x215
1565
1566         touch $DIR/$tdir/$tfile && error "able to create $DIR/$tdir/$tfile"
1567
1568         reset_enospc
1569         rm -rf $DIR/$tdir/*
1570 }
1571 run_test 27o "create file with all full OSTs (should error)"
1572
1573 test_27p() {
1574         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs" && return
1575         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
1576         remote_mds_nodsh && skip "remote MDS with nodsh" && return
1577         remote_ost_nodsh && skip "remote OST with nodsh" && return
1578
1579         reset_enospc
1580         rm -f $DIR/$tdir/$tfile
1581         test_mkdir $DIR/$tdir
1582
1583         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1584         $TRUNCATE $DIR/$tdir/$tfile 80000000 || error "truncate failed"
1585         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1586
1587         exhaust_precreations 0 0x80000215
1588         echo foo >> $DIR/$tdir/$tfile || error "append failed"
1589         $CHECKSTAT -s 80000004 $DIR/$tdir/$tfile || error "checkstat failed"
1590         $LFS getstripe $DIR/$tdir/$tfile
1591
1592         reset_enospc
1593 }
1594 run_test 27p "append to a truncated file with some full OSTs"
1595
1596 test_27q() {
1597         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs" && return
1598         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
1599         remote_mds_nodsh && skip "remote MDS with nodsh" && return
1600         remote_ost_nodsh && skip "remote OST with nodsh" && return
1601
1602         reset_enospc
1603         rm -f $DIR/$tdir/$tfile
1604
1605         test_mkdir $DIR/$tdir
1606         $MCREATE $DIR/$tdir/$tfile || error "mcreate $DIR/$tdir/$tfile failed"
1607         $TRUNCATE $DIR/$tdir/$tfile 80000000 ||
1608                 error "truncate $DIR/$tdir/$tfile failed"
1609         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1610
1611         exhaust_all_precreations 0x215
1612
1613         echo foo >> $DIR/$tdir/$tfile && error "append succeeded"
1614         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat 2 failed"
1615
1616         reset_enospc
1617 }
1618 run_test 27q "append to truncated file with all OSTs full (should error)"
1619
1620 test_27r() {
1621         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs" && return
1622         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
1623         remote_mds_nodsh && skip "remote MDS with nodsh" && return
1624         remote_ost_nodsh && skip "remote OST with nodsh" && return
1625
1626         reset_enospc
1627         rm -f $DIR/$tdir/$tfile
1628         exhaust_precreations 0 0x80000215
1629
1630         $LFS setstripe -i 0 -c 2 $DIR/$tdir/$tfile # && error
1631
1632         reset_enospc
1633 }
1634 run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
1635
1636 test_27s() { # bug 10725
1637         test_mkdir $DIR/$tdir
1638         local stripe_size=$((4096 * 1024 * 1024))       # 2^32
1639         local stripe_count=0
1640         [ $OSTCOUNT -eq 1 ] || stripe_count=2
1641         $LFS setstripe -S $stripe_size -c $stripe_count $DIR/$tdir &&
1642                 error "stripe width >= 2^32 succeeded" || true
1643
1644 }
1645 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
1646
1647 test_27t() { # bug 10864
1648         WDIR=$(pwd)
1649         WLFS=$(which lfs)
1650         cd $DIR
1651         touch $tfile
1652         $WLFS getstripe $tfile
1653         cd $WDIR
1654 }
1655 run_test 27t "check that utils parse path correctly"
1656
1657 test_27u() { # bug 4900
1658         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs" && return
1659         remote_mds_nodsh && skip "remote MDS with nodsh" && return
1660         local index
1661         local list=$(comma_list $(mdts_nodes))
1662
1663 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
1664         do_nodes $list $LCTL set_param fail_loc=0x139
1665         test_mkdir -p $DIR/$tdir
1666         trap simple_cleanup_common EXIT
1667         createmany -o $DIR/$tdir/t- 1000
1668         do_nodes $list $LCTL set_param fail_loc=0
1669
1670         TLOG=$TMP/$tfile.getstripe
1671         $LFS getstripe $DIR/$tdir > $TLOG
1672         OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
1673         unlinkmany $DIR/$tdir/t- 1000
1674         trap 0
1675         [[ $OBJS -gt 0 ]] &&
1676                 error "$OBJS objects created on OST-0. See $TLOG" ||
1677                 rm -f $TLOG
1678 }
1679 run_test 27u "skip object creation on OSC w/o objects"
1680
1681 test_27v() { # bug 4900
1682         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs" && return
1683         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
1684         remote_mds_nodsh && skip "remote MDS with nodsh" && return
1685         remote_ost_nodsh && skip "remote OST with nodsh" && return
1686
1687         exhaust_all_precreations 0x215
1688         reset_enospc
1689
1690         $LFS setstripe -c 1 $DIR/$tdir         # 1 stripe / file
1691
1692         touch $DIR/$tdir/$tfile
1693         #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
1694         # all except ost1
1695         for (( i=1; i < OSTCOUNT; i++ )); do
1696                 do_facet ost$i lctl set_param fail_loc=0x705
1697         done
1698         local START=`date +%s`
1699         createmany -o $DIR/$tdir/$tfile 32
1700
1701         local FINISH=`date +%s`
1702         local TIMEOUT=`lctl get_param -n timeout`
1703         local PROCESS=$((FINISH - START))
1704         [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
1705                error "$FINISH - $START >= $TIMEOUT / 2"
1706         sleep $((TIMEOUT / 2 - PROCESS))
1707         reset_enospc
1708 }
1709 run_test 27v "skip object creation on slow OST"
1710
1711 test_27w() { # bug 10997
1712         test_mkdir $DIR/$tdir
1713         $LFS setstripe -S 65536 $DIR/$tdir/f0 || error "setstripe failed"
1714         [ $($LFS getstripe -S $DIR/$tdir/f0) -ne 65536 ] &&
1715                 error "stripe size $size != 65536" || true
1716         [ $($LFS getstripe -d $DIR/$tdir | grep -c "stripe_count") -eq 0 ] &&
1717                 error "$LFS getstripe -d $DIR/$tdir no 'stripe_count'" || true
1718 }
1719 run_test 27w "check $LFS setstripe -S and getstrip -d options"
1720
1721 test_27wa() {
1722         [[ $OSTCOUNT -lt 2 ]] &&
1723                 skip_env "skipping multiple stripe count/offset test" && return
1724
1725         test_mkdir $DIR/$tdir
1726         for i in $(seq 1 $OSTCOUNT); do
1727                 offset=$((i - 1))
1728                 $LFS setstripe -c $i -i $offset $DIR/$tdir/f$i ||
1729                         error "setstripe -c $i -i $offset failed"
1730                 count=$($LFS getstripe -c $DIR/$tdir/f$i)
1731                 index=$($LFS getstripe -i $DIR/$tdir/f$i)
1732                 [ $count -ne $i ] && error "stripe count $count != $i" || true
1733                 [ $index -ne $offset ] &&
1734                         error "stripe offset $index != $offset" || true
1735         done
1736 }
1737 run_test 27wa "check $LFS setstripe -c -i options"
1738
1739 test_27x() {
1740         remote_ost_nodsh && skip "remote OST with nodsh" && return
1741         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs" && return
1742         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
1743         OFFSET=$(($OSTCOUNT - 1))
1744         OSTIDX=0
1745         local OST=$(ostname_from_index $OSTIDX)
1746
1747         test_mkdir $DIR/$tdir
1748         $LFS setstripe -c 1 $DIR/$tdir  # 1 stripe per file
1749         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 1
1750         sleep_maxage
1751         createmany -o $DIR/$tdir/$tfile $OSTCOUNT
1752         for i in $(seq 0 $OFFSET); do
1753                 [ $($LFS getstripe $DIR/$tdir/$tfile$i | grep -A 10 obdidx |
1754                         awk '{print $1}' | grep -w "$OSTIDX") ] &&
1755                 error "OST0 was degraded but new created file still use it"
1756         done
1757         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 0
1758 }
1759 run_test 27x "create files while OST0 is degraded"
1760
1761 test_27y() {
1762         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs" && return
1763         remote_mds_nodsh && skip "remote MDS with nodsh" && return
1764         remote_ost_nodsh && skip "remote OST with nodsh" && return
1765         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
1766
1767         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
1768         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
1769                 osc.$mdtosc.prealloc_last_id)
1770         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
1771                 osc.$mdtosc.prealloc_next_id)
1772         local fcount=$((last_id - next_id))
1773         [[ $fcount -eq 0 ]] && skip "not enough space on OST0" && return
1774         [[ $fcount -gt $OSTCOUNT ]] && fcount=$OSTCOUNT
1775
1776         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
1777                          awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
1778         local OST_DEACTIVE_IDX=-1
1779         local OSC
1780         local OSTIDX
1781         local OST
1782
1783         for OSC in $MDS_OSCS; do
1784                 OST=$(osc_to_ost $OSC)
1785                 OSTIDX=$(index_from_ostuuid $OST)
1786                 if [ $OST_DEACTIVE_IDX == -1 ]; then
1787                         OST_DEACTIVE_IDX=$OSTIDX
1788                 fi
1789                 if [ $OSTIDX != $OST_DEACTIVE_IDX ]; then
1790                         echo $OSC "is Deactivated:"
1791                         do_facet $SINGLEMDS lctl --device  %$OSC deactivate
1792                 fi
1793         done
1794
1795         OSTIDX=$(index_from_ostuuid $OST)
1796         test_mkdir $DIR/$tdir
1797         $LFS setstripe -c 1 $DIR/$tdir      # 1 stripe / file
1798
1799         for OSC in $MDS_OSCS; do
1800                 OST=$(osc_to_ost $OSC)
1801                 OSTIDX=$(index_from_ostuuid $OST)
1802                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
1803                         echo $OST "is degraded:"
1804                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
1805                                                 obdfilter.$OST.degraded=1
1806                 fi
1807         done
1808
1809         sleep_maxage
1810         createmany -o $DIR/$tdir/$tfile $fcount
1811
1812         for OSC in $MDS_OSCS; do
1813                 OST=$(osc_to_ost $OSC)
1814                 OSTIDX=$(index_from_ostuuid $OST)
1815                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
1816                         echo $OST "is recovered from degraded:"
1817                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
1818                                                 obdfilter.$OST.degraded=0
1819                 else
1820                         do_facet $SINGLEMDS lctl --device %$OSC activate
1821                 fi
1822         done
1823
1824         # all osp devices get activated, hence -1 stripe count restored
1825         local stripe_count=0
1826
1827         # sleep 2*lod_qos_maxage seconds waiting for lod qos to notice osp
1828         # devices get activated.
1829         sleep_maxage
1830         $LFS setstripe -c -1 $DIR/$tfile
1831         stripe_count=$($LFS getstripe -c $DIR/$tfile)
1832         rm -f $DIR/$tfile
1833         [ $stripe_count -ne $OSTCOUNT ] &&
1834                 error "Of $OSTCOUNT OSTs, only $stripe_count is available"
1835         return 0
1836 }
1837 run_test 27y "create files while OST0 is degraded and the rest inactive"
1838
1839 check_seq_oid()
1840 {
1841         log "check file $1"
1842
1843         lmm_count=$($GETSTRIPE -c $1)
1844         lmm_seq=$($GETSTRIPE -v $1 | awk '/lmm_seq/ { print $2 }')
1845         lmm_oid=$($GETSTRIPE -v $1 | awk '/lmm_object_id/ { print $2 }')
1846
1847         local old_ifs="$IFS"
1848         IFS=$'[:]'
1849         fid=($($LFS path2fid $1))
1850         IFS="$old_ifs"
1851
1852         log "FID seq ${fid[1]}, oid ${fid[2]} ver ${fid[3]}"
1853         log "LOV seq $lmm_seq, oid $lmm_oid, count: $lmm_count"
1854
1855         # compare lmm_seq and lu_fid->f_seq
1856         [ $lmm_seq = ${fid[1]} ] || { error "SEQ mismatch"; return 1; }
1857         # compare lmm_object_id and lu_fid->oid
1858         [ $lmm_oid = ${fid[2]} ] || { error "OID mismatch"; return 2; }
1859
1860         # check the trusted.fid attribute of the OST objects of the file
1861         local have_obdidx=false
1862         local stripe_nr=0
1863         $GETSTRIPE $1 | while read obdidx oid hex seq; do
1864                 # skip lines up to and including "obdidx"
1865                 [ -z "$obdidx" ] && break
1866                 [ "$obdidx" = "obdidx" ] && have_obdidx=true && continue
1867                 $have_obdidx || continue
1868
1869                 local ost=$((obdidx + 1))
1870                 local dev=$(ostdevname $ost)
1871                 local oid_hex
1872
1873                 log "want: stripe:$stripe_nr ost:$obdidx oid:$oid/$hex seq:$seq"
1874
1875                 seq=$(echo $seq | sed -e "s/^0x//g")
1876                 if [ $seq == 0 ] || [ $(facet_fstype ost$ost) == zfs ]; then
1877                         oid_hex=$(echo $oid)
1878                 else
1879                         oid_hex=$(echo $hex | sed -e "s/^0x//g")
1880                 fi
1881                 local obj_file="O/$seq/d$((oid %32))/$oid_hex"
1882
1883                 local ff=""
1884                 #
1885                 # Don't unmount/remount the OSTs if we don't need to do that.
1886                 # LU-2577 changes filter_fid to be smaller, so debugfs needs
1887                 # update too, until that use mount/ll_decode_filter_fid/mount.
1888                 # Re-enable when debugfs will understand new filter_fid.
1889                 #
1890                 if [ $(facet_fstype ost$ost) == ldiskfs ]; then
1891                         ff=$(do_facet ost$ost "$DEBUGFS -c -R 'stat $obj_file' \
1892                                 $dev 2>/dev/null" | grep "parent=")
1893                 fi
1894                 if [ -z "$ff" ]; then
1895                         stop ost$ost
1896                         mount_fstype ost$ost
1897                         ff=$(do_facet ost$ost $LL_DECODE_FILTER_FID \
1898                                 $(facet_mntpt ost$ost)/$obj_file)
1899                         unmount_fstype ost$ost
1900                         start ost$ost $dev $OST_MOUNT_OPTS
1901                         clients_up
1902                 fi
1903
1904                 [ -z "$ff" ] && error "$obj_file: no filter_fid info"
1905
1906                 echo "$ff" | sed -e 's#.*objid=#got: objid=#'
1907
1908                 # /mnt/O/0/d23/23: objid=23 seq=0 parent=[0x200000400:0x1e:0x1]
1909                 # fid: objid=23 seq=0 parent=[0x200000400:0x1e:0x0] stripe=1
1910                 #
1911                 # fid: parent=[0x200000400:0x1e:0x0] stripe=1 stripe_count=2 \
1912                 #       stripe_size=1048576 component_id=1 component_start=0 \
1913                 #       component_end=33554432
1914                 local ff_parent=$(sed -e 's/.*parent=.//' <<<$ff)
1915                 local ff_pseq=$(cut -d: -f1 <<<$ff_parent)
1916                 local ff_poid=$(cut -d: -f2 <<<$ff_parent)
1917                 local ff_pstripe
1918                 if grep -q 'stripe=' <<<$ff; then
1919                         ff_pstripe=$(sed -e 's/.*stripe=//' -e 's/ .*//' <<<$ff)
1920                 else
1921                         # $LL_DECODE_FILTER_FID does not print "stripe="; look
1922                         # into f_ver in this case.  See comment on ff_parent.
1923                         ff_pstripe=$(cut -d: -f3 <<<$ff_parent | sed -e 's/]//')
1924                 fi
1925
1926                 # compare lmm_seq and filter_fid->ff_parent.f_seq
1927                 [ $ff_pseq = $lmm_seq ] ||
1928                         error "FF parent SEQ $ff_pseq != $lmm_seq"
1929                 # compare lmm_object_id and filter_fid->ff_parent.f_oid
1930                 [ $ff_poid = $lmm_oid ] ||
1931                         error "FF parent OID $ff_poid != $lmm_oid"
1932                 (($ff_pstripe == $stripe_nr)) ||
1933                         error "FF stripe $ff_pstripe != $stripe_nr"
1934
1935                 stripe_nr=$((stripe_nr + 1))
1936                 [ $(lustre_version_code client) -lt $(version_code 2.9.55) ] &&
1937                         continue
1938                 if grep -q 'stripe_count=' <<<$ff; then
1939                         local ff_scnt=$(sed -e 's/.*stripe_count=//' \
1940                                             -e 's/ .*//' <<<$ff)
1941                         [ $lmm_count = $ff_scnt ] ||
1942                                 error "FF stripe count $lmm_count != $ff_scnt"
1943                 fi
1944         done
1945 }
1946
1947 test_27z() {
1948         remote_ost_nodsh && skip "remote OST with nodsh" && return
1949         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
1950         test_mkdir $DIR/$tdir
1951
1952         $LFS setstripe -c 1 -i 0 -S 64k $DIR/$tdir/$tfile-1 ||
1953                 { error "setstripe -c -1 failed"; return 1; }
1954         # We need to send a write to every object to get parent FID info set.
1955         # This _should_ also work for setattr, but does not currently.
1956         # touch $DIR/$tdir/$tfile-1 ||
1957         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
1958                 { error "dd $tfile-1 failed"; return 2; }
1959         $LFS setstripe -c -1 -i $((OSTCOUNT - 1)) -S 1M $DIR/$tdir/$tfile-2 ||
1960                 { error "setstripe -c -1 failed"; return 3; }
1961         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
1962                 { error "dd $tfile-2 failed"; return 4; }
1963
1964         # make sure write RPCs have been sent to OSTs
1965         sync; sleep 5; sync
1966
1967         check_seq_oid $DIR/$tdir/$tfile-1 || return 5
1968         check_seq_oid $DIR/$tdir/$tfile-2 || return 6
1969 }
1970 run_test 27z "check SEQ/OID on the MDT and OST filesystems"
1971
1972 test_27A() { # b=19102
1973         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
1974         local restore_size=$($GETSTRIPE -S $MOUNT)
1975         local restore_count=$($GETSTRIPE -c $MOUNT)
1976         local restore_offset=$($GETSTRIPE -i $MOUNT)
1977         $SETSTRIPE -c 0 -i -1 -S 0 $MOUNT
1978         wait_update $HOSTNAME "$GETSTRIPE -c $MOUNT | sed 's/  *//g'" "1" 20 ||
1979                 error "stripe count $($GETSTRIPE -c $MOUNT) != 1"
1980         local default_size=$($GETSTRIPE -S $MOUNT)
1981         local default_offset=$($GETSTRIPE -i $MOUNT)
1982         local dsize=$((1024 * 1024))
1983         [ $default_size -eq $dsize ] ||
1984                 error "stripe size $default_size != $dsize"
1985         [ $default_offset -eq -1 ] ||error "stripe offset $default_offset != -1"
1986         $SETSTRIPE -c $restore_count -i $restore_offset -S $restore_size $MOUNT
1987 }
1988 run_test 27A "check filesystem-wide default LOV EA values"
1989
1990 test_27B() { # LU-2523
1991         test_mkdir $DIR/$tdir
1992         rm -f $DIR/$tdir/f0 $DIR/$tdir/f1
1993         touch $DIR/$tdir/f0
1994         # open f1 with O_LOV_DELAY_CREATE
1995         # rename f0 onto f1
1996         # call setstripe ioctl on open file descriptor for f1
1997         # close
1998         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \
1999                 $DIR/$tdir/f0
2000
2001         rm -f $DIR/$tdir/f1
2002         # open f1 with O_LOV_DELAY_CREATE
2003         # unlink f1
2004         # call setstripe ioctl on open file descriptor for f1
2005         # close
2006         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c
2007
2008         # Allow multiop to fail in imitation of NFS's busted semantics.
2009         true
2010 }
2011 run_test 27B "call setstripe on open unlinked file/rename victim"
2012
2013 test_27C() { #LU-2871
2014         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs" && return
2015
2016         declare -a ost_idx
2017         local index
2018         local found
2019         local i
2020         local j
2021
2022         test_mkdir $DIR/$tdir
2023         cd $DIR/$tdir
2024         for i in $(seq 0 $((OSTCOUNT - 1))); do
2025                 # set stripe across all OSTs starting from OST$i
2026                 $SETSTRIPE -i $i -c -1 $tfile$i
2027                 # get striping information
2028                 ost_idx=($($GETSTRIPE $tfile$i |
2029                          tail -n $((OSTCOUNT + 1)) | awk '{print $1}'))
2030                 echo ${ost_idx[@]}
2031
2032                 # check the layout
2033                 [ ${#ost_idx[@]} -eq $OSTCOUNT ] ||
2034                         error "${#ost_idx[@]} != $OSTCOUNT"
2035
2036                 for index in $(seq 0 $((OSTCOUNT - 1))); do
2037                         found=0
2038                         for j in $(echo ${ost_idx[@]}); do
2039                                 if [ $index -eq $j ]; then
2040                                         found=1
2041                                         break
2042                                 fi
2043                         done
2044                         [ $found = 1 ] ||
2045                                 error "Can not find $index in ${ost_idx[@]}"
2046                 done
2047         done
2048 }
2049 run_test 27C "check full striping across all OSTs"
2050
2051 test_27D() {
2052         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs" && return
2053         [ -n "$FILESET" ] && skip "SKIP due to FILESET set" && return
2054         remote_mds_nodsh && skip "remote MDS with nodsh" && return
2055         local POOL=${POOL:-testpool}
2056         local first_ost=0
2057         local last_ost=$(($OSTCOUNT - 1))
2058         local ost_step=1
2059         local ost_list=$(seq $first_ost $ost_step $last_ost)
2060         local ost_range="$first_ost $last_ost $ost_step"
2061
2062         if ! combined_mgs_mds ; then
2063                 mount_mgs_client
2064         fi
2065
2066         test_mkdir $DIR/$tdir
2067         pool_add $POOL || error "pool_add failed"
2068         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2069
2070         local skip27D
2071         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.8.55) ] &&
2072                 skip27D += "-s 29"
2073         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.9.55) -o \
2074           $(lustre_version_code client) -lt $(version_code 2.9.55) ] &&
2075                 skip27D += "-s 30,31"
2076         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2077                 error "llapi_layout_test failed"
2078
2079         destroy_test_pools || error "destroy test pools failed"
2080
2081         if ! combined_mgs_mds ; then
2082                 umount_mgs_client
2083         fi
2084 }
2085 run_test 27D "validate llapi_layout API"
2086
2087 # Verify that default_easize is increased from its initial value after
2088 # accessing a widely striped file.
2089 test_27E() {
2090         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs" && return
2091         [ $(lustre_version_code client) -lt $(version_code 2.5.57) ] &&
2092                 skip "client does not have LU-3338 fix" && return
2093
2094         # 72 bytes is the minimum space required to store striping
2095         # information for a file striped across one OST:
2096         # (sizeof(struct lov_user_md_v3) +
2097         #  sizeof(struct lov_user_ost_data_v1))
2098         local min_easize=72
2099         $LCTL set_param -n llite.*.default_easize $min_easize ||
2100                 error "lctl set_param failed"
2101         local easize=$($LCTL get_param -n llite.*.default_easize)
2102
2103         [ $easize -eq $min_easize ] ||
2104                 error "failed to set default_easize"
2105
2106         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2107                 error "setstripe failed"
2108         cat $DIR/$tfile
2109         rm $DIR/$tfile
2110
2111         easize=$($LCTL get_param -n llite.*.default_easize)
2112
2113         [ $easize -gt $min_easize ] ||
2114                 error "default_easize not updated"
2115 }
2116 run_test 27E "check that default extended attribute size properly increases"
2117
2118 test_27F() { # LU-5346/LU-7975
2119         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
2120         [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.8.51) ]] &&
2121                 skip "Need MDS version at least 2.8.51" && return
2122         remote_ost_nodsh && skip "remote OST with nodsh" && return
2123
2124         test_mkdir $DIR/$tdir
2125         rm -f $DIR/$tdir/f0
2126         $SETSTRIPE -c 2 $DIR/$tdir
2127
2128         # stop all OSTs to reproduce situation for LU-7975 ticket
2129         for num in $(seq $OSTCOUNT); do
2130                 stop ost$num
2131         done
2132
2133         # open/create f0 with O_LOV_DELAY_CREATE
2134         # truncate f0 to a non-0 size
2135         # close
2136         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2137
2138         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2139         # open/write it again to force delayed layout creation
2140         cat /etc/hosts > $DIR/$tdir/f0 &
2141         catpid=$!
2142
2143         # restart OSTs
2144         for num in $(seq $OSTCOUNT); do
2145                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2146                         error "ost$num failed to start"
2147         done
2148
2149         wait $catpid || error "cat failed"
2150
2151         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2152         [[ $($GETSTRIPE -c $DIR/$tdir/f0) == 2 ]] || error "wrong stripecount"
2153
2154 }
2155 run_test 27F "Client resend delayed layout creation with non-zero size"
2156
2157 # createtest also checks that device nodes are created and
2158 # then visible correctly (#2091)
2159 test_28() { # bug 2091
2160         test_mkdir $DIR/d28
2161         $CREATETEST $DIR/d28/ct || error
2162 }
2163 run_test 28 "create/mknod/mkdir with bad file types ============"
2164
2165 test_29() {
2166         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return 0
2167         sync; sleep 1; sync # flush out any dirty pages from previous tests
2168         cancel_lru_locks
2169         test_mkdir $DIR/d29
2170         touch $DIR/d29/foo
2171         log 'first d29'
2172         ls -l $DIR/d29
2173
2174         declare -i LOCKCOUNTORIG=0
2175         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
2176                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
2177         done
2178         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
2179
2180         declare -i LOCKUNUSEDCOUNTORIG=0
2181         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
2182                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
2183         done
2184
2185         log 'second d29'
2186         ls -l $DIR/d29
2187         log 'done'
2188
2189         declare -i LOCKCOUNTCURRENT=0
2190         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
2191                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
2192         done
2193
2194         declare -i LOCKUNUSEDCOUNTCURRENT=0
2195         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
2196                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
2197         done
2198
2199         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
2200                 $LCTL set_param -n ldlm.dump_namespaces ""
2201                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
2202                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
2203                 log "dumped log to $TMP/test_29.dk (bug 5793)"
2204                 return 2
2205         fi
2206         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
2207                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
2208                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
2209                 log "dumped log to $TMP/test_29.dk (bug 5793)"
2210                 return 3
2211         fi
2212 }
2213 run_test 29 "IT_GETATTR regression  ============================"
2214
2215 test_30a() { # was test_30
2216         cp $(which ls) $DIR || cp /bin/ls $DIR
2217         $DIR/ls / || error
2218         rm $DIR/ls
2219 }
2220 run_test 30a "execute binary from Lustre (execve) =============="
2221
2222 test_30b() {
2223         cp `which ls` $DIR || cp /bin/ls $DIR
2224         chmod go+rx $DIR/ls
2225         $RUNAS $DIR/ls / || error
2226         rm $DIR/ls
2227 }
2228 run_test 30b "execute binary from Lustre as non-root ==========="
2229
2230 test_30c() { # b=22376
2231         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
2232         cp `which ls` $DIR || cp /bin/ls $DIR
2233         chmod a-rw $DIR/ls
2234         cancel_lru_locks mdc
2235         cancel_lru_locks osc
2236         $RUNAS $DIR/ls / || error
2237         rm -f $DIR/ls
2238 }
2239 run_test 30c "execute binary from Lustre without read perms ===="
2240
2241 test_31a() {
2242         $OPENUNLINK $DIR/f31 $DIR/f31 || error
2243         $CHECKSTAT -a $DIR/f31 || error
2244 }
2245 run_test 31a "open-unlink file =================================="
2246
2247 test_31b() {
2248         touch $DIR/f31 || error
2249         ln $DIR/f31 $DIR/f31b || error
2250         $MULTIOP $DIR/f31b Ouc || error
2251         $CHECKSTAT -t file $DIR/f31 || error
2252 }
2253 run_test 31b "unlink file with multiple links while open ======="
2254
2255 test_31c() {
2256         touch $DIR/f31 || error
2257         ln $DIR/f31 $DIR/f31c || error
2258         multiop_bg_pause $DIR/f31 O_uc || return 1
2259         MULTIPID=$!
2260         $MULTIOP $DIR/f31c Ouc
2261         kill -USR1 $MULTIPID
2262         wait $MULTIPID
2263 }
2264 run_test 31c "open-unlink file with multiple links ============="
2265
2266 test_31d() {
2267         opendirunlink $DIR/d31d $DIR/d31d || error
2268         $CHECKSTAT -a $DIR/d31d || error
2269 }
2270 run_test 31d "remove of open directory ========================="
2271
2272 test_31e() { # bug 2904
2273         openfilleddirunlink $DIR/d31e || error
2274 }
2275 run_test 31e "remove of open non-empty directory ==============="
2276
2277 test_31f() { # bug 4554
2278         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
2279         set -vx
2280         test_mkdir $DIR/d31f
2281         $SETSTRIPE -S 1048576 -c 1 $DIR/d31f
2282         cp /etc/hosts $DIR/d31f
2283         ls -l $DIR/d31f
2284         $GETSTRIPE $DIR/d31f/hosts
2285         multiop_bg_pause $DIR/d31f D_c || return 1
2286         MULTIPID=$!
2287
2288         rm -rv $DIR/d31f || error "first of $DIR/d31f"
2289         test_mkdir $DIR/d31f
2290         $SETSTRIPE -S 1048576 -c 1 $DIR/d31f
2291         cp /etc/hosts $DIR/d31f
2292         ls -l $DIR/d31f
2293         $GETSTRIPE $DIR/d31f/hosts
2294         multiop_bg_pause $DIR/d31f D_c || return 1
2295         MULTIPID2=$!
2296
2297         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
2298         wait $MULTIPID || error "first opendir $MULTIPID failed"
2299
2300         sleep 6
2301
2302         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
2303         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
2304         set +vx
2305 }
2306 run_test 31f "remove of open directory with open-unlink file ==="
2307
2308 test_31g() {
2309         echo "-- cross directory link --"
2310         test_mkdir -c1 $DIR/${tdir}ga
2311         test_mkdir -c1 $DIR/${tdir}gb
2312         touch $DIR/${tdir}ga/f
2313         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
2314         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
2315         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
2316         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
2317         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
2318 }
2319 run_test 31g "cross directory link==============="
2320
2321 test_31h() {
2322         echo "-- cross directory link --"
2323         test_mkdir -c1 $DIR/${tdir}
2324         test_mkdir -c1 $DIR/${tdir}/dir
2325         touch $DIR/${tdir}/f
2326         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
2327         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
2328         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
2329         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
2330         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
2331 }
2332 run_test 31h "cross directory link under child==============="
2333
2334 test_31i() {
2335         echo "-- cross directory link --"
2336         test_mkdir -c1 $DIR/$tdir
2337         test_mkdir -c1 $DIR/$tdir/dir
2338         touch $DIR/$tdir/dir/f
2339         ln $DIR/$tdir/dir/f $DIR/$tdir/g
2340         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
2341         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
2342         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
2343         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
2344 }
2345 run_test 31i "cross directory link under parent==============="
2346
2347 test_31j() {
2348         test_mkdir -c1 -p $DIR/$tdir
2349         test_mkdir -c1 -p $DIR/$tdir/dir1
2350         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
2351         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
2352         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
2353         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
2354         return 0
2355 }
2356 run_test 31j "link for directory==============="
2357
2358 test_31k() {
2359         test_mkdir -c1 -p $DIR/$tdir
2360         touch $DIR/$tdir/s
2361         touch $DIR/$tdir/exist
2362         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
2363         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
2364         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
2365         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
2366         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
2367         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
2368         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
2369         return 0
2370 }
2371 run_test 31k "link to file: the same, non-existing, dir==============="
2372
2373 test_31m() {
2374         mkdir $DIR/d31m
2375         touch $DIR/d31m/s
2376         mkdir $DIR/d31m2
2377         touch $DIR/d31m2/exist
2378         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
2379         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
2380         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
2381         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
2382         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
2383         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
2384         return 0
2385 }
2386 run_test 31m "link to file: the same, non-existing, dir==============="
2387
2388 test_31n() {
2389         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
2390         nlink=$(stat --format=%h $DIR/$tfile)
2391         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
2392         local fd=$(free_fd)
2393         local cmd="exec $fd<$DIR/$tfile"
2394         eval $cmd
2395         cmd="exec $fd<&-"
2396         trap "eval $cmd" EXIT
2397         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
2398         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
2399         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
2400         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
2401         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
2402         eval $cmd
2403 }
2404 run_test 31n "check link count of unlinked file"
2405
2406 link_one() {
2407         local TEMPNAME=$(mktemp $1_XXXXXX)
2408         mlink $TEMPNAME $1 2> /dev/null &&
2409                 echo "$BASHPID: link $TEMPNAME to $1 succeeded"
2410         munlink $TEMPNAME
2411 }
2412
2413 test_31o() { # LU-2901
2414         test_mkdir $DIR/$tdir
2415         for LOOP in $(seq 100); do
2416                 rm -f $DIR/$tdir/$tfile*
2417                 for THREAD in $(seq 8); do
2418                         link_one $DIR/$tdir/$tfile.$LOOP &
2419                 done
2420                 wait
2421                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
2422                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
2423                         error "$LINKS duplicate links to $tfile.$LOOP" &&
2424                         break || true
2425         done
2426 }
2427 run_test 31o "duplicate hard links with same filename"
2428
2429 test_31p() {
2430         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
2431
2432         test_mkdir $DIR/$tdir
2433         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
2434         $LFS setdirstripe -D -c2 -t all_char $DIR/$tdir/striped_dir
2435
2436         opendirunlink $DIR/$tdir/striped_dir/test1 ||
2437                 error "open unlink test1 failed"
2438         opendirunlink $DIR/$tdir/striped_dir/test2 ||
2439                 error "open unlink test2 failed"
2440
2441         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
2442                 error "test1 still exists"
2443         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
2444                 error "test2 still exists"
2445 }
2446 run_test 31p "remove of open striped directory"
2447
2448 cleanup_test32_mount() {
2449         local rc=0
2450         trap 0
2451         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
2452         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
2453         losetup -d $loopdev || true
2454         rm -rf $DIR/$tdir
2455         return $rc
2456 }
2457
2458 test_32a() {
2459         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
2460         echo "== more mountpoints and symlinks ================="
2461         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
2462         trap cleanup_test32_mount EXIT
2463         test_mkdir -p $DIR/$tdir/ext2-mountpoint
2464         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint || error
2465         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. || error
2466         cleanup_test32_mount
2467 }
2468 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
2469
2470 test_32b() {
2471         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
2472         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
2473         trap cleanup_test32_mount EXIT
2474         test_mkdir -p $DIR/$tdir/ext2-mountpoint
2475         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint || error
2476         ls -al $DIR/$tdir/ext2-mountpoint/.. || error
2477         cleanup_test32_mount
2478 }
2479 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
2480
2481 test_32c() {
2482         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
2483         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
2484         trap cleanup_test32_mount EXIT
2485         test_mkdir -p $DIR/$tdir/ext2-mountpoint
2486         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint || error
2487         test_mkdir -p $DIR/$tdir/d2/test_dir
2488         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir || error
2489         cleanup_test32_mount
2490 }
2491 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
2492
2493 test_32d() {
2494         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
2495         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
2496         trap cleanup_test32_mount EXIT
2497         test_mkdir -p $DIR/$tdir/ext2-mountpoint
2498         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint || error
2499         test_mkdir -p $DIR/$tdir/d2/test_dir
2500         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir || error
2501         cleanup_test32_mount
2502 }
2503 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
2504
2505 test_32e() {
2506         rm -fr $DIR/$tdir
2507         test_mkdir -p $DIR/$tdir/tmp
2508         local tmp_dir=$DIR/$tdir/tmp
2509         ln -s $DIR/$tdir $tmp_dir/symlink11
2510         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
2511         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
2512         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
2513 }
2514 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
2515
2516 test_32f() {
2517         rm -fr $DIR/$tdir
2518         test_mkdir -p $DIR/$tdir/tmp
2519         local tmp_dir=$DIR/$tdir/tmp
2520         ln -s $DIR/$tdir $tmp_dir/symlink11
2521         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
2522         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
2523         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
2524 }
2525 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
2526
2527 test_32g() {
2528         local tmp_dir=$DIR/$tdir/tmp
2529         test_mkdir -p $tmp_dir
2530         test_mkdir $DIR/${tdir}2
2531         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
2532         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
2533         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
2534         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
2535         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
2536         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
2537 }
2538 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
2539
2540 test_32h() {
2541         rm -fr $DIR/$tdir $DIR/${tdir}2
2542         tmp_dir=$DIR/$tdir/tmp
2543         test_mkdir -p $tmp_dir
2544         test_mkdir $DIR/${tdir}2
2545         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
2546         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
2547         ls $tmp_dir/symlink12 || error "listing symlink12"
2548         ls $DIR/$tdir/symlink02  || error "listing symlink02"
2549 }
2550 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
2551
2552 test_32i() {
2553         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
2554         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
2555         trap cleanup_test32_mount EXIT
2556         test_mkdir -p $DIR/$tdir/ext2-mountpoint
2557         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint || error
2558         touch $DIR/$tdir/test_file
2559         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file || error
2560         cleanup_test32_mount
2561 }
2562 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
2563
2564 test_32j() {
2565         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
2566         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
2567         trap cleanup_test32_mount EXIT
2568         test_mkdir -p $DIR/$tdir/ext2-mountpoint
2569         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint || error
2570         touch $DIR/$tdir/test_file
2571         cat $DIR/$tdir/ext2-mountpoint/../test_file || error
2572         cleanup_test32_mount
2573 }
2574 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
2575
2576 test_32k() {
2577         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
2578         rm -fr $DIR/$tdir
2579         trap cleanup_test32_mount EXIT
2580         test_mkdir -p $DIR/$tdir/ext2-mountpoint
2581         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint
2582         test_mkdir -p $DIR/$tdir/d2
2583         touch $DIR/$tdir/d2/test_file || error
2584         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file || error
2585         cleanup_test32_mount
2586 }
2587 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
2588
2589 test_32l() {
2590         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
2591         rm -fr $DIR/$tdir
2592         trap cleanup_test32_mount EXIT
2593         test_mkdir -p $DIR/$tdir/ext2-mountpoint
2594         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint || error
2595         test_mkdir -p $DIR/$tdir/d2
2596         touch $DIR/$tdir/d2/test_file
2597         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file || error
2598         cleanup_test32_mount
2599 }
2600 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
2601
2602 test_32m() {
2603         rm -fr $DIR/d32m
2604         test_mkdir -p $DIR/d32m/tmp
2605         TMP_DIR=$DIR/d32m/tmp
2606         ln -s $DIR $TMP_DIR/symlink11
2607         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
2608         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 || error
2609         $CHECKSTAT -t link $DIR/d32m/symlink01 || error
2610 }
2611 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
2612
2613 test_32n() {
2614         rm -fr $DIR/d32n
2615         test_mkdir -p $DIR/d32n/tmp
2616         TMP_DIR=$DIR/d32n/tmp
2617         ln -s $DIR $TMP_DIR/symlink11
2618         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
2619         ls -l $DIR/d32n/tmp/symlink11  || error
2620         ls -l $DIR/d32n/symlink01 || error
2621 }
2622 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
2623
2624 test_32o() {
2625         touch $DIR/$tfile
2626         test_mkdir -p $DIR/d32o/tmp
2627         TMP_DIR=$DIR/d32o/tmp
2628         ln -s $DIR/$tfile $TMP_DIR/symlink12
2629         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
2630         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 || error
2631         $CHECKSTAT -t link $DIR/d32o/symlink02 || error
2632         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 || error
2633         $CHECKSTAT -t file -f $DIR/d32o/symlink02 || error
2634 }
2635 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
2636
2637 test_32p() {
2638         log 32p_1
2639         rm -fr $DIR/d32p
2640         log 32p_2
2641         rm -f $DIR/$tfile
2642         log 32p_3
2643         touch $DIR/$tfile
2644         log 32p_4
2645         test_mkdir -p $DIR/d32p/tmp
2646         log 32p_5
2647         TMP_DIR=$DIR/d32p/tmp
2648         log 32p_6
2649         ln -s $DIR/$tfile $TMP_DIR/symlink12
2650         log 32p_7
2651         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
2652         log 32p_8
2653         cat $DIR/d32p/tmp/symlink12 || error
2654         log 32p_9
2655         cat $DIR/d32p/symlink02 || error
2656         log 32p_10
2657 }
2658 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
2659
2660 test_32q() {
2661         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
2662         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
2663         trap cleanup_test32_mount EXIT
2664         test_mkdir -p $DIR/$tdir/ext2-mountpoint
2665         touch $DIR/$tdir/ext2-mountpoint/under_the_mount
2666         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint
2667         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
2668         cleanup_test32_mount
2669 }
2670 run_test 32q "stat follows mountpoints in Lustre (should return error)"
2671
2672 test_32r() {
2673         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
2674         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
2675         trap cleanup_test32_mount EXIT
2676         test_mkdir -p $DIR/$tdir/ext2-mountpoint
2677         touch $DIR/$tdir/ext2-mountpoint/under_the_mount
2678         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint
2679         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
2680         cleanup_test32_mount
2681 }
2682 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
2683
2684 test_33aa() {
2685         rm -f $DIR/$tfile
2686         touch $DIR/$tfile
2687         chmod 444 $DIR/$tfile
2688         chown $RUNAS_ID $DIR/$tfile
2689         log 33_1
2690         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
2691         log 33_2
2692 }
2693 run_test 33aa "write file with mode 444 (should return error)"
2694
2695 test_33a() {
2696         rm -fr $DIR/$tdir
2697         test_mkdir $DIR/$tdir
2698         chown $RUNAS_ID $DIR/$tdir
2699         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
2700                 error "$RUNAS create $tdir/$tfile failed"
2701         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
2702                 error "open RDWR" || true
2703 }
2704 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
2705
2706 test_33b() {
2707         rm -fr $DIR/$tdir
2708         test_mkdir $DIR/$tdir
2709         chown $RUNAS_ID $DIR/$tdir
2710         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
2711 }
2712 run_test 33b "test open file with malformed flags (No panic)"
2713
2714 test_33c() {
2715         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
2716         local ostnum
2717         local ostname
2718         local write_bytes
2719         local all_zeros
2720
2721         remote_ost_nodsh && skip "remote OST with nodsh" && return
2722         all_zeros=:
2723         rm -fr $DIR/$tdir
2724         test_mkdir $DIR/$tdir
2725         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
2726
2727         sync
2728         for ostnum in $(seq $OSTCOUNT); do
2729                 # test-framework's OST numbering is one-based, while Lustre's
2730                 # is zero-based
2731                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
2732                 # Parsing llobdstat's output sucks; we could grep the /proc
2733                 # path, but that's likely to not be as portable as using the
2734                 # llobdstat utility.  So we parse lctl output instead.
2735                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
2736                         obdfilter/$ostname/stats |
2737                         awk '/^write_bytes/ {print $7}' )
2738                 echo "baseline_write_bytes@$OSTnum/$ostname=$write_bytes"
2739                 if (( ${write_bytes:-0} > 0 ))
2740                 then
2741                         all_zeros=false
2742                         break;
2743                 fi
2744         done
2745
2746         $all_zeros || return 0
2747
2748         # Write four bytes
2749         echo foo > $DIR/$tdir/bar
2750         # Really write them
2751         sync
2752
2753         # Total up write_bytes after writing.  We'd better find non-zeros.
2754         for ostnum in $(seq $OSTCOUNT); do
2755                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
2756                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
2757                         obdfilter/$ostname/stats |
2758                         awk '/^write_bytes/ {print $7}' )
2759                 echo "write_bytes@$OSTnum/$ostname=$write_bytes"
2760                 if (( ${write_bytes:-0} > 0 ))
2761                 then
2762                         all_zeros=false
2763                         break;
2764                 fi
2765         done
2766
2767         if $all_zeros
2768         then
2769                 for ostnum in $(seq $OSTCOUNT); do
2770                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
2771                         echo "Check that write_bytes is present in obdfilter/*/stats:"
2772                         do_facet ost$ostnum lctl get_param -n \
2773                                 obdfilter/$ostname/stats
2774                 done
2775                 error "OST not keeping write_bytes stats (b22312)"
2776         fi
2777 }
2778 run_test 33c "test llobdstat and write_bytes"
2779
2780 test_33d() {
2781         [[ $MDSCOUNT -lt 2 ]] && skip "needs >= 2 MDTs" && return
2782         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
2783         local MDTIDX=1
2784         local remote_dir=$DIR/$tdir/remote_dir
2785
2786         test_mkdir $DIR/$tdir
2787         $LFS mkdir -i $MDTIDX $remote_dir ||
2788                 error "create remote directory failed"
2789
2790         touch $remote_dir/$tfile
2791         chmod 444 $remote_dir/$tfile
2792         chown $RUNAS_ID $remote_dir/$tfile
2793
2794         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
2795
2796         chown $RUNAS_ID $remote_dir
2797         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
2798                                         error "create" || true
2799         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
2800                                     error "open RDWR" || true
2801         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
2802 }
2803 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
2804
2805 test_33e() {
2806         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
2807
2808         mkdir $DIR/$tdir
2809
2810         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
2811         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
2812         mkdir $DIR/$tdir/local_dir
2813
2814         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
2815         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
2816         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
2817
2818         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
2819                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
2820
2821         rmdir $DIR/$tdir/* || error "rmdir failed"
2822
2823         umask 777
2824         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
2825         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
2826         mkdir $DIR/$tdir/local_dir
2827
2828         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
2829         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
2830         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
2831
2832         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
2833                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
2834
2835         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
2836
2837         umask 000
2838         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
2839         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
2840         mkdir $DIR/$tdir/local_dir
2841
2842         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
2843         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
2844         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
2845
2846         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
2847                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
2848 }
2849 run_test 33e "mkdir and striped directory should have same mode"
2850
2851 cleanup_33f() {
2852         trap 0
2853         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
2854 }
2855
2856 test_33f() {
2857         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
2858         remote_mds_nodsh && skip "remote MDS with nodsh" && return
2859
2860         mkdir $DIR/$tdir
2861         chmod go+rwx $DIR/$tdir
2862         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
2863         trap cleanup_33f EXIT
2864
2865         $RUNAS lfs mkdir -c$MDSCOUNT $DIR/$tdir/striped_dir ||
2866                 error "cannot create striped directory"
2867
2868         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
2869                 error "cannot create files in striped directory"
2870
2871         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
2872                 error "cannot remove files in striped directory"
2873
2874         $RUNAS rmdir $DIR/$tdir/striped_dir ||
2875                 error "cannot remove striped directory"
2876
2877         cleanup_33f
2878 }
2879 run_test 33f "nonroot user can create, access, and remove a striped directory"
2880
2881 test_33g() {
2882         mkdir -p $DIR/$tdir/dir2
2883
2884         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
2885         echo $err
2886         [[ $err =~ "exists" ]] || error "Not exists error"
2887 }
2888 run_test 33g "nonroot user create already existing root created file"
2889
2890 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
2891 test_34a() {
2892         rm -f $DIR/f34
2893         $MCREATE $DIR/f34 || error
2894         $GETSTRIPE $DIR/f34 2>&1 | grep -q "no stripe info" || error
2895         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error
2896         $GETSTRIPE $DIR/f34 2>&1 | grep -q "no stripe info" || error
2897         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 || error
2898 }
2899 run_test 34a "truncate file that has not been opened ==========="
2900
2901 test_34b() {
2902         [ ! -f $DIR/f34 ] && test_34a
2903         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 || error
2904         $OPENFILE -f O_RDONLY $DIR/f34
2905         $GETSTRIPE $DIR/f34 2>&1 | grep -q "no stripe info" || error
2906         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 || error
2907 }
2908 run_test 34b "O_RDONLY opening file doesn't create objects ====="
2909
2910 test_34c() {
2911         [ ! -f $DIR/f34 ] && test_34a
2912         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 || error
2913         $OPENFILE -f O_RDWR $DIR/f34
2914         $GETSTRIPE $DIR/f34 2>&1 | grep -q "no stripe info" && error
2915         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 || error
2916 }
2917 run_test 34c "O_RDWR opening file-with-size works =============="
2918
2919 test_34d() {
2920         [ ! -f $DIR/f34 ] && test_34a
2921         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 || error
2922         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 || error
2923         rm $DIR/f34
2924 }
2925 run_test 34d "write to sparse file ============================="
2926
2927 test_34e() {
2928         rm -f $DIR/f34e
2929         $MCREATE $DIR/f34e || error
2930         $TRUNCATE $DIR/f34e 1000 || error
2931         $CHECKSTAT -s 1000 $DIR/f34e || error
2932         $OPENFILE -f O_RDWR $DIR/f34e
2933         $CHECKSTAT -s 1000 $DIR/f34e || error
2934 }
2935 run_test 34e "create objects, some with size and some without =="
2936
2937 test_34f() { # bug 6242, 6243
2938         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
2939         SIZE34F=48000
2940         rm -f $DIR/f34f
2941         $MCREATE $DIR/f34f || error
2942         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
2943         dd if=$DIR/f34f of=$TMP/f34f
2944         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
2945         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
2946         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
2947         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
2948         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
2949 }
2950 run_test 34f "read from a file with no objects until EOF ======="
2951
2952 test_34g() {
2953         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
2954         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE || error
2955         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error
2956         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile || error "truncate failed"
2957         cancel_lru_locks osc
2958         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile || \
2959                 error "wrong size after lock cancel"
2960
2961         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error
2962         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile || \
2963                 error "expanding truncate failed"
2964         cancel_lru_locks osc
2965         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile || \
2966                 error "wrong expanded size after lock cancel"
2967 }
2968 run_test 34g "truncate long file ==============================="
2969
2970 test_34h() {
2971         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
2972         local gid=10
2973         local sz=1000
2974
2975         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error
2976         sync # Flush the cache so that multiop below does not block on cache
2977              # flush when getting the group lock
2978         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
2979         MULTIPID=$!
2980
2981         # Since just timed wait is not good enough, let's do a sync write
2982         # that way we are sure enough time for a roundtrip + processing
2983         # passed + 2 seconds of extra margin.
2984         dd if=/dev/zero of=$DIR/${tfile}-1 bs=4096 oflag=direct count=1
2985         rm $DIR/${tfile}-1
2986         sleep 2
2987
2988         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
2989                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
2990                 kill -9 $MULTIPID
2991         fi
2992         wait $MULTIPID
2993         local nsz=`stat -c %s $DIR/$tfile`
2994         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
2995 }
2996 run_test 34h "ftruncate file under grouplock should not block"
2997
2998 test_35a() {
2999         cp /bin/sh $DIR/f35a
3000         chmod 444 $DIR/f35a
3001         chown $RUNAS_ID $DIR/f35a
3002         $RUNAS $DIR/f35a && error || true
3003         rm $DIR/f35a
3004 }
3005 run_test 35a "exec file with mode 444 (should return and not leak)"
3006
3007 test_36a() {
3008         rm -f $DIR/f36
3009         utime $DIR/f36 || error
3010 }
3011 run_test 36a "MDS utime check (mknod, utime)"
3012
3013 test_36b() {
3014         echo "" > $DIR/f36
3015         utime $DIR/f36 || error
3016 }
3017 run_test 36b "OST utime check (open, utime)"
3018
3019 test_36c() {
3020         rm -f $DIR/d36/f36
3021         test_mkdir $DIR/d36
3022         chown $RUNAS_ID $DIR/d36
3023         $RUNAS utime $DIR/d36/f36 || error
3024 }
3025 run_test 36c "non-root MDS utime check (mknod, utime)"
3026
3027 test_36d() {
3028         [ ! -d $DIR/d36 ] && test_36c
3029         echo "" > $DIR/d36/f36
3030         $RUNAS utime $DIR/d36/f36 || error
3031 }
3032 run_test 36d "non-root OST utime check (open, utime)"
3033
3034 test_36e() {
3035         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping" && return
3036         test_mkdir $DIR/$tdir
3037         touch $DIR/$tdir/$tfile
3038         $RUNAS utime $DIR/$tdir/$tfile &&
3039                 error "utime worked, expected failure" || true
3040 }
3041 run_test 36e "utime on non-owned file (should return error)"
3042
3043 subr_36fh() {
3044         local fl="$1"
3045         local LANG_SAVE=$LANG
3046         local LC_LANG_SAVE=$LC_LANG
3047         export LANG=C LC_LANG=C # for date language
3048
3049         DATESTR="Dec 20  2000"
3050         test_mkdir $DIR/$tdir
3051         lctl set_param fail_loc=$fl
3052         date; date +%s
3053         cp /etc/hosts $DIR/$tdir/$tfile
3054         sync & # write RPC generated with "current" inode timestamp, but delayed
3055         sleep 1
3056         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
3057         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
3058         cancel_lru_locks osc
3059         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
3060         date; date +%s
3061         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
3062                 echo "BEFORE: $LS_BEFORE" && \
3063                 echo "AFTER : $LS_AFTER" && \
3064                 echo "WANT  : $DATESTR" && \
3065                 error "$DIR/$tdir/$tfile timestamps changed" || true
3066
3067         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
3068 }
3069
3070 test_36f() {
3071         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
3072         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
3073         subr_36fh "0x80000214"
3074 }
3075 run_test 36f "utime on file racing with OST BRW write =========="
3076
3077 test_36g() {
3078         remote_ost_nodsh && skip "remote OST with nodsh" && return
3079         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
3080         local fmd_max_age
3081         local fmd_before
3082         local fmd_after
3083
3084         test_mkdir $DIR/$tdir
3085         fmd_max_age=$(do_facet ost1 \
3086                 "lctl get_param -n obdfilter.*.client_cache_seconds 2> /dev/null | \
3087                 head -n 1")
3088
3089         fmd_before=$(do_facet ost1 \
3090                 "awk '/ll_fmd_cache/ {print \\\$2}' /proc/slabinfo")
3091         touch $DIR/$tdir/$tfile
3092         sleep $((fmd_max_age + 12))
3093         fmd_after=$(do_facet ost1 \
3094                 "awk '/ll_fmd_cache/ {print \\\$2}' /proc/slabinfo")
3095
3096         echo "fmd_before: $fmd_before"
3097         echo "fmd_after: $fmd_after"
3098         [[ $fmd_after -gt $fmd_before ]] &&
3099                 echo "AFTER: $fmd_after > BEFORE: $fmd_before" &&
3100                 error "fmd didn't expire after ping" || true
3101 }
3102 run_test 36g "filter mod data cache expiry ====================="
3103
3104 test_36h() {
3105         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
3106         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
3107         subr_36fh "0x80000227"
3108 }
3109 run_test 36h "utime on file racing with OST BRW write =========="
3110
3111 test_36i() {
3112         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
3113
3114         test_mkdir $DIR/$tdir
3115         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
3116
3117         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
3118         local new_mtime=$((mtime + 200))
3119
3120         #change Modify time of striped dir
3121         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
3122                         error "change mtime failed"
3123
3124         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
3125
3126         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
3127 }
3128 run_test 36i "change mtime on striped directory"
3129
3130 # test_37 - duplicate with tests 32q 32r
3131
3132 test_38() {
3133         local file=$DIR/$tfile
3134         touch $file
3135         openfile -f O_DIRECTORY $file
3136         local RC=$?
3137         local ENOTDIR=20
3138         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
3139         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
3140 }
3141 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
3142
3143 test_39a() { # was test_39
3144         touch $DIR/$tfile
3145         touch $DIR/${tfile}2
3146 #       ls -l  $DIR/$tfile $DIR/${tfile}2
3147 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
3148 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
3149         sleep 2
3150         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
3151         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
3152                 echo "mtime"
3153                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
3154                 echo "atime"
3155                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
3156                 echo "ctime"
3157                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
3158                 error "O_TRUNC didn't change timestamps"
3159         fi
3160 }
3161 run_test 39a "mtime changed on create"
3162
3163 test_39b() {
3164         test_mkdir -c1 $DIR/$tdir
3165         cp -p /etc/passwd $DIR/$tdir/fopen
3166         cp -p /etc/passwd $DIR/$tdir/flink
3167         cp -p /etc/passwd $DIR/$tdir/funlink
3168         cp -p /etc/passwd $DIR/$tdir/frename
3169         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
3170
3171         sleep 1
3172         echo "aaaaaa" >> $DIR/$tdir/fopen
3173         echo "aaaaaa" >> $DIR/$tdir/flink
3174         echo "aaaaaa" >> $DIR/$tdir/funlink
3175         echo "aaaaaa" >> $DIR/$tdir/frename
3176
3177         local open_new=`stat -c %Y $DIR/$tdir/fopen`
3178         local link_new=`stat -c %Y $DIR/$tdir/flink`
3179         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
3180         local rename_new=`stat -c %Y $DIR/$tdir/frename`
3181
3182         cat $DIR/$tdir/fopen > /dev/null
3183         ln $DIR/$tdir/flink $DIR/$tdir/flink2
3184         rm -f $DIR/$tdir/funlink2
3185         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
3186
3187         for (( i=0; i < 2; i++ )) ; do
3188                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
3189                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
3190                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
3191                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
3192
3193                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
3194                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
3195                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
3196                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
3197
3198                 cancel_lru_locks osc
3199                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3200         done
3201 }
3202 run_test 39b "mtime change on open, link, unlink, rename  ======"
3203
3204 # this should be set to past
3205 TEST_39_MTIME=`date -d "1 year ago" +%s`
3206
3207 # bug 11063
3208 test_39c() {
3209         touch $DIR1/$tfile
3210         sleep 2
3211         local mtime0=`stat -c %Y $DIR1/$tfile`
3212
3213         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
3214         local mtime1=`stat -c %Y $DIR1/$tfile`
3215         [ "$mtime1" = $TEST_39_MTIME ] || \
3216                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
3217
3218         local d1=`date +%s`
3219         echo hello >> $DIR1/$tfile
3220         local d2=`date +%s`
3221         local mtime2=`stat -c %Y $DIR1/$tfile`
3222         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
3223                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
3224
3225         mv $DIR1/$tfile $DIR1/$tfile-1
3226
3227         for (( i=0; i < 2; i++ )) ; do
3228                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
3229                 [ "$mtime2" = "$mtime3" ] || \
3230                         error "mtime ($mtime2) changed (to $mtime3) on rename"
3231
3232                 cancel_lru_locks osc
3233                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3234         done
3235 }
3236 run_test 39c "mtime change on rename ==========================="
3237
3238 # bug 21114
3239 test_39d() {
3240         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
3241         touch $DIR1/$tfile
3242
3243         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
3244
3245         for (( i=0; i < 2; i++ )) ; do
3246                 local mtime=`stat -c %Y $DIR1/$tfile`
3247                 [ $mtime = $TEST_39_MTIME ] || \
3248                         error "mtime($mtime) is not set to $TEST_39_MTIME"
3249
3250                 cancel_lru_locks osc
3251                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3252         done
3253 }
3254 run_test 39d "create, utime, stat =============================="
3255
3256 # bug 21114
3257 test_39e() {
3258         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
3259         touch $DIR1/$tfile
3260         local mtime1=`stat -c %Y $DIR1/$tfile`
3261
3262         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
3263
3264         for (( i=0; i < 2; i++ )) ; do
3265                 local mtime2=`stat -c %Y $DIR1/$tfile`
3266                 [ $mtime2 = $TEST_39_MTIME ] || \
3267                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
3268
3269                 cancel_lru_locks osc
3270                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3271         done
3272 }
3273 run_test 39e "create, stat, utime, stat ========================"
3274
3275 # bug 21114
3276 test_39f() {
3277         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
3278         touch $DIR1/$tfile
3279         mtime1=`stat -c %Y $DIR1/$tfile`
3280
3281         sleep 2
3282         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
3283
3284         for (( i=0; i < 2; i++ )) ; do
3285                 local mtime2=`stat -c %Y $DIR1/$tfile`
3286                 [ $mtime2 = $TEST_39_MTIME ] || \
3287                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
3288
3289                 cancel_lru_locks osc
3290                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3291         done
3292 }
3293 run_test 39f "create, stat, sleep, utime, stat ================="
3294
3295 # bug 11063
3296 test_39g() {
3297         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
3298         echo hello >> $DIR1/$tfile
3299         local mtime1=`stat -c %Y $DIR1/$tfile`
3300
3301         sleep 2
3302         chmod o+r $DIR1/$tfile
3303
3304         for (( i=0; i < 2; i++ )) ; do
3305                 local mtime2=`stat -c %Y $DIR1/$tfile`
3306                 [ "$mtime1" = "$mtime2" ] || \
3307                         error "lost mtime: $mtime2, should be $mtime1"
3308
3309                 cancel_lru_locks osc
3310                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3311         done
3312 }
3313 run_test 39g "write, chmod, stat ==============================="
3314
3315 # bug 11063
3316 test_39h() {
3317         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
3318         touch $DIR1/$tfile
3319         sleep 1
3320
3321         local d1=`date`
3322         echo hello >> $DIR1/$tfile
3323         local mtime1=`stat -c %Y $DIR1/$tfile`
3324
3325         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
3326         local d2=`date`
3327         if [ "$d1" != "$d2" ]; then
3328                 echo "write and touch not within one second"
3329         else
3330                 for (( i=0; i < 2; i++ )) ; do
3331                         local mtime2=`stat -c %Y $DIR1/$tfile`
3332                         [ "$mtime2" = $TEST_39_MTIME ] || \
3333                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
3334
3335                         cancel_lru_locks osc
3336                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3337                 done
3338         fi
3339 }
3340 run_test 39h "write, utime within one second, stat ============="
3341
3342 test_39i() {
3343         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
3344         touch $DIR1/$tfile
3345         sleep 1
3346
3347         echo hello >> $DIR1/$tfile
3348         local mtime1=`stat -c %Y $DIR1/$tfile`
3349
3350         mv $DIR1/$tfile $DIR1/$tfile-1
3351
3352         for (( i=0; i < 2; i++ )) ; do
3353                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
3354
3355                 [ "$mtime1" = "$mtime2" ] || \
3356                         error "lost mtime: $mtime2, should be $mtime1"
3357
3358                 cancel_lru_locks osc
3359                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3360         done
3361 }
3362 run_test 39i "write, rename, stat =============================="
3363
3364 test_39j() {
3365         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
3366         start_full_debug_logging
3367         touch $DIR1/$tfile
3368         sleep 1
3369
3370         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
3371         lctl set_param fail_loc=0x80000412
3372         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
3373                 error "multiop failed"
3374         local multipid=$!
3375         local mtime1=`stat -c %Y $DIR1/$tfile`
3376
3377         mv $DIR1/$tfile $DIR1/$tfile-1
3378
3379         kill -USR1 $multipid
3380         wait $multipid || error "multiop close failed"
3381
3382         for (( i=0; i < 2; i++ )) ; do
3383                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
3384                 [ "$mtime1" = "$mtime2" ] ||
3385                         error "mtime is lost on close: $mtime2, " \
3386                               "should be $mtime1"
3387
3388                 cancel_lru_locks osc
3389                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3390         done
3391         lctl set_param fail_loc=0
3392         stop_full_debug_logging
3393 }
3394 run_test 39j "write, rename, close, stat ======================="
3395
3396 test_39k() {
3397         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
3398         touch $DIR1/$tfile
3399         sleep 1
3400
3401         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
3402         local multipid=$!
3403         local mtime1=`stat -c %Y $DIR1/$tfile`
3404
3405         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
3406
3407         kill -USR1 $multipid
3408         wait $multipid || error "multiop close failed"
3409
3410         for (( i=0; i < 2; i++ )) ; do
3411                 local mtime2=`stat -c %Y $DIR1/$tfile`
3412
3413                 [ "$mtime2" = $TEST_39_MTIME ] || \
3414                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
3415
3416                 cancel_lru_locks osc
3417                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3418         done
3419 }
3420 run_test 39k "write, utime, close, stat ========================"
3421
3422 # this should be set to future
3423 TEST_39_ATIME=`date -d "1 year" +%s`
3424
3425 test_39l() {
3426         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
3427         remote_mds_nodsh && skip "remote MDS with nodsh" && return
3428         local atime_diff=$(do_facet $SINGLEMDS \
3429                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
3430         rm -rf $DIR/$tdir
3431         mkdir -p $DIR/$tdir
3432
3433         # test setting directory atime to future
3434         touch -a -d @$TEST_39_ATIME $DIR/$tdir
3435         local atime=$(stat -c %X $DIR/$tdir)
3436         [ "$atime" = $TEST_39_ATIME ] ||
3437                 error "atime is not set to future: $atime, $TEST_39_ATIME"
3438
3439         # test setting directory atime from future to now
3440         local now=$(date +%s)
3441         touch -a -d @$now $DIR/$tdir
3442
3443         atime=$(stat -c %X $DIR/$tdir)
3444         [ "$atime" -eq "$now"  ] ||
3445                 error "atime is not updated from future: $atime, $now"
3446
3447         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
3448         sleep 3
3449
3450         # test setting directory atime when now > dir atime + atime_diff
3451         local d1=$(date +%s)
3452         ls $DIR/$tdir
3453         local d2=$(date +%s)
3454         cancel_lru_locks mdc
3455         atime=$(stat -c %X $DIR/$tdir)
3456         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
3457                 error "atime is not updated  : $atime, should be $d2"
3458
3459         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
3460         sleep 3
3461
3462         # test not setting directory atime when now < dir atime + atime_diff
3463         ls $DIR/$tdir
3464         cancel_lru_locks mdc
3465         atime=$(stat -c %X $DIR/$tdir)
3466         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
3467                 error "atime is updated to $atime, should remain $d1<atime<$d2"
3468
3469         do_facet $SINGLEMDS \
3470                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
3471 }
3472 run_test 39l "directory atime update ==========================="
3473
3474 test_39m() {
3475         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
3476         touch $DIR1/$tfile
3477         sleep 2
3478         local far_past_mtime=$(date -d "May 29 1953" +%s)
3479         local far_past_atime=$(date -d "Dec 17 1903" +%s)
3480
3481         touch -m -d @$far_past_mtime $DIR1/$tfile
3482         touch -a -d @$far_past_atime $DIR1/$tfile
3483
3484         for (( i=0; i < 2; i++ )) ; do
3485                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
3486                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
3487                         error "atime or mtime set incorrectly"
3488
3489                 cancel_lru_locks osc
3490                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3491         done
3492 }
3493 run_test 39m "test atime and mtime before 1970"
3494
3495 test_39n() { # LU-3832
3496         remote_mds_nodsh && skip "remote MDS with nodsh" && return
3497         local atime_diff=$(do_facet $SINGLEMDS \
3498                 lctl get_param -n mdd.*MDT0000*.atime_diff)
3499         local atime0
3500         local atime1
3501         local atime2
3502
3503         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
3504
3505         rm -rf $DIR/$tfile
3506         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
3507         atime0=$(stat -c %X $DIR/$tfile)
3508
3509         sleep 5
3510         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
3511         atime1=$(stat -c %X $DIR/$tfile)
3512
3513         sleep 5
3514         cancel_lru_locks mdc
3515         cancel_lru_locks osc
3516         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
3517         atime2=$(stat -c %X $DIR/$tfile)
3518
3519         do_facet $SINGLEMDS \
3520                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
3521
3522         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
3523         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
3524 }
3525 run_test 39n "check that O_NOATIME is honored"
3526
3527 test_39o() {
3528         TESTDIR=$DIR/$tdir/$tfile
3529         [ -e $TESTDIR ] && rm -rf $TESTDIR
3530         mkdir -p $TESTDIR
3531         cd $TESTDIR
3532         links1=2
3533         ls
3534         mkdir a b
3535         ls
3536         links2=$(stat -c %h .)
3537         [ $(($links1 + 2)) != $links2 ] &&
3538                 error "wrong links count $(($links1 + 2)) != $links2"
3539         rmdir b
3540         links3=$(stat -c %h .)
3541         [ $(($links1 + 1)) != $links3 ] &&
3542                 error "wrong links count $links1 != $links3"
3543         return 0
3544 }
3545 run_test 39o "directory cached attributes updated after create"
3546
3547 test_39p() {
3548         [[ $MDSCOUNT -lt 2 ]] && skip "needs >= 2 MDTs" && return
3549         local MDTIDX=1
3550         TESTDIR=$DIR/$tdir/$tdir
3551         [ -e $TESTDIR ] && rm -rf $TESTDIR
3552         test_mkdir -p $TESTDIR
3553         cd $TESTDIR
3554         links1=2
3555         ls
3556         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
3557         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
3558         ls
3559         links2=$(stat -c %h .)
3560         [ $(($links1 + 2)) != $links2 ] &&
3561                 error "wrong links count $(($links1 + 2)) != $links2"
3562         rmdir remote_dir2
3563         links3=$(stat -c %h .)
3564         [ $(($links1 + 1)) != $links3 ] &&
3565                 error "wrong links count $links1 != $links3"
3566         return 0
3567 }
3568 run_test 39p "remote directory cached attributes updated after create ========"
3569
3570
3571 test_39q() { # LU-8041
3572         local testdir=$DIR/$tdir
3573         mkdir -p $testdir
3574         multiop_bg_pause $testdir D_c || error "multiop failed"
3575         local multipid=$!
3576         cancel_lru_locks mdc
3577         kill -USR1 $multipid
3578         local atime=$(stat -c %X $testdir)
3579         [ "$atime" -ne 0 ] || error "atime is zero"
3580 }
3581 run_test 39q "close won't zero out atime"
3582
3583 test_40() {
3584         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
3585         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
3586                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
3587         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
3588                 error "$tfile is not 4096 bytes in size"
3589 }
3590 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
3591
3592 test_41() {
3593         # bug 1553
3594         small_write $DIR/f41 18
3595 }
3596 run_test 41 "test small file write + fstat ====================="
3597
3598 count_ost_writes() {
3599         lctl get_param -n ${OSC}.*.stats |
3600                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
3601                         END { printf("%0.0f", writes) }'
3602 }
3603
3604 # decent default
3605 WRITEBACK_SAVE=500
3606 DIRTY_RATIO_SAVE=40
3607 MAX_DIRTY_RATIO=50
3608 BG_DIRTY_RATIO_SAVE=10
3609 MAX_BG_DIRTY_RATIO=25
3610
3611 start_writeback() {
3612         trap 0
3613         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
3614         # dirty_ratio, dirty_background_ratio
3615         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
3616                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
3617                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
3618                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
3619         else
3620                 # if file not here, we are a 2.4 kernel
3621                 kill -CONT `pidof kupdated`
3622         fi
3623 }
3624
3625 stop_writeback() {
3626         # setup the trap first, so someone cannot exit the test at the
3627         # exact wrong time and mess up a machine
3628         trap start_writeback EXIT
3629         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
3630         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
3631                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
3632                 sysctl -w vm.dirty_writeback_centisecs=0
3633                 sysctl -w vm.dirty_writeback_centisecs=0
3634                 # save and increase /proc/sys/vm/dirty_ratio
3635                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
3636                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
3637                 # save and increase /proc/sys/vm/dirty_background_ratio
3638                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
3639                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
3640         else
3641                 # if file not here, we are a 2.4 kernel
3642                 kill -STOP `pidof kupdated`
3643         fi
3644 }
3645
3646 # ensure that all stripes have some grant before we test client-side cache
3647 setup_test42() {
3648         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
3649                 dd if=/dev/zero of=$i bs=4k count=1
3650                 rm $i
3651         done
3652 }
3653
3654 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
3655 # file truncation, and file removal.
3656 test_42a() {
3657         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
3658         setup_test42
3659         cancel_lru_locks $OSC
3660         stop_writeback
3661         sync; sleep 1; sync # just to be safe
3662         BEFOREWRITES=`count_ost_writes`
3663         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
3664         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
3665         AFTERWRITES=`count_ost_writes`
3666         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
3667                 error "$BEFOREWRITES < $AFTERWRITES"
3668         start_writeback
3669 }
3670 run_test 42a "ensure that we don't flush on close"
3671
3672 test_42b() {
3673         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
3674         setup_test42
3675         cancel_lru_locks $OSC
3676         stop_writeback
3677         sync
3678         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
3679         BEFOREWRITES=$(count_ost_writes)
3680         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
3681         AFTERWRITES=$(count_ost_writes)
3682         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
3683                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
3684         fi
3685         BEFOREWRITES=$(count_ost_writes)
3686         sync || error "sync: $?"
3687         AFTERWRITES=$(count_ost_writes)
3688         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
3689                 error "$BEFOREWRITES < $AFTERWRITES on sync"
3690         fi
3691         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
3692         start_writeback
3693         return 0
3694 }
3695 run_test 42b "test destroy of file with cached dirty data ======"
3696
3697 # if these tests just want to test the effect of truncation,
3698 # they have to be very careful.  consider:
3699 # - the first open gets a {0,EOF}PR lock
3700 # - the first write conflicts and gets a {0, count-1}PW
3701 # - the rest of the writes are under {count,EOF}PW
3702 # - the open for truncate tries to match a {0,EOF}PR
3703 #   for the filesize and cancels the PWs.
3704 # any number of fixes (don't get {0,EOF} on open, match
3705 # composite locks, do smarter file size management) fix
3706 # this, but for now we want these tests to verify that
3707 # the cancellation with truncate intent works, so we
3708 # start the file with a full-file pw lock to match against
3709 # until the truncate.
3710 trunc_test() {
3711         test=$1
3712         file=$DIR/$test
3713         offset=$2
3714         cancel_lru_locks $OSC
3715         stop_writeback
3716         # prime the file with 0,EOF PW to match
3717         touch $file
3718         $TRUNCATE $file 0
3719         sync; sync
3720         # now the real test..
3721         dd if=/dev/zero of=$file bs=1024 count=100
3722         BEFOREWRITES=`count_ost_writes`
3723         $TRUNCATE $file $offset
3724         cancel_lru_locks $OSC
3725         AFTERWRITES=`count_ost_writes`
3726         start_writeback
3727 }
3728
3729 test_42c() {
3730         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
3731         trunc_test 42c 1024
3732         [ $BEFOREWRITES -eq $AFTERWRITES ] && \
3733             error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
3734         rm $file
3735 }
3736 run_test 42c "test partial truncate of file with cached dirty data"
3737
3738 test_42d() {
3739         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
3740         trunc_test 42d 0
3741         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
3742             error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
3743         rm $file
3744 }
3745 run_test 42d "test complete truncate of file with cached dirty data"
3746
3747 test_42e() { # bug22074
3748         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
3749         local TDIR=$DIR/${tdir}e
3750         local pagesz=$(page_size)
3751         local pages=16 # hardcoded 16 pages, don't change it.
3752         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
3753         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
3754         local max_dirty_mb
3755         local warmup_files
3756
3757         test_mkdir $DIR/${tdir}e
3758         $SETSTRIPE -c 1 $TDIR
3759         createmany -o $TDIR/f $files
3760
3761         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
3762
3763         # we assume that with $OSTCOUNT files, at least one of them will
3764         # be allocated on OST0.
3765         warmup_files=$((OSTCOUNT * max_dirty_mb))
3766         createmany -o $TDIR/w $warmup_files
3767
3768         # write a large amount of data into one file and sync, to get good
3769         # avail_grant number from OST.
3770         for ((i=0; i<$warmup_files; i++)); do
3771                 idx=$($GETSTRIPE -i $TDIR/w$i)
3772                 [ $idx -ne 0 ] && continue
3773                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
3774                 break
3775         done
3776         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
3777         sync
3778         $LCTL get_param $proc_osc0/cur_dirty_bytes
3779         $LCTL get_param $proc_osc0/cur_grant_bytes
3780
3781         # create as much dirty pages as we can while not to trigger the actual
3782         # RPCs directly. but depends on the env, VFS may trigger flush during this
3783         # period, hopefully we are good.
3784         for ((i=0; i<$warmup_files; i++)); do
3785                 idx=$($GETSTRIPE -i $TDIR/w$i)
3786                 [ $idx -ne 0 ] && continue
3787                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
3788         done
3789         $LCTL get_param $proc_osc0/cur_dirty_bytes
3790         $LCTL get_param $proc_osc0/cur_grant_bytes
3791
3792         # perform the real test
3793         $LCTL set_param $proc_osc0/rpc_stats 0
3794         for ((;i<$files; i++)); do
3795                 [ $($GETSTRIPE -i $TDIR/f$i) -eq 0 ] || continue
3796                 dd if=/dev/zero of=$TDIR/f$i bs=$pagesz count=$pages 2>/dev/null
3797         done
3798         sync
3799         $LCTL get_param $proc_osc0/rpc_stats
3800
3801         local percent=0
3802         local have_ppr=false
3803         $LCTL get_param $proc_osc0/rpc_stats |
3804                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
3805                         # skip lines until we are at the RPC histogram data
3806                         [ "$PPR" == "pages" ] && have_ppr=true && continue
3807                         $have_ppr || continue
3808
3809                         # we only want the percent stat for < 16 pages
3810                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
3811
3812                         percent=$((percent + WPCT))
3813                         if [[ $percent -gt 15 ]]; then
3814                                 error "less than 16-pages write RPCs" \
3815                                       "$percent% > 15%"
3816                                 break
3817                         fi
3818                 done
3819         rm -rf $TDIR
3820 }
3821 run_test 42e "verify sub-RPC writes are not done synchronously"
3822
3823 test_43A() { # was test_43
3824         test_mkdir $DIR/$tdir
3825         cp -p /bin/ls $DIR/$tdir/$tfile
3826         $MULTIOP $DIR/$tdir/$tfile Ow_c &
3827         pid=$!
3828         # give multiop a chance to open
3829         sleep 1
3830
3831         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
3832         kill -USR1 $pid
3833 }
3834 run_test 43A "execution of file opened for write should return -ETXTBSY"
3835
3836 test_43a() {
3837         test_mkdir $DIR/$tdir
3838         cp -p $(which $MULTIOP) $DIR/$tdir/multiop ||
3839                 cp -p multiop $DIR/$tdir/multiop
3840         MULTIOP_PROG=$DIR/$tdir/multiop multiop_bg_pause $TMP/$tfile.junk O_c ||
3841                 error "multiop open $TMP/$tfile.junk failed"
3842         rm $TMP/$tfile.junk     # delete junk file on close (not part of test)
3843         MULTIOP_PID=$!
3844         $MULTIOP $DIR/$tdir/multiop Oc && error "expected error, got success"
3845         kill -USR1 $MULTIOP_PID || error "kill -USR1 PID $MULTIOP_PID failed"
3846         wait $MULTIOP_PID || error "wait PID $MULTIOP_PID failed"
3847 }
3848 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
3849
3850 test_43b() {
3851         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
3852         test_mkdir $DIR/$tdir
3853         cp -p $(which $MULTIOP) $DIR/$tdir/multiop ||
3854                 cp -p multiop $DIR/$tdir/multiop
3855         MULTIOP_PROG=$DIR/$tdir/multiop multiop_bg_pause $TMP/$tfile.junk O_c ||
3856                 error "multiop open $TMP/$tfile.junk failed"
3857         rm $TMP/$tfile.junk     # delete junk file on close (not part of test)
3858         MULTIOP_PID=$!
3859         $TRUNCATE $DIR/$tdir/multiop 0 && error "expected error, got success"
3860         kill -USR1 $MULTIOP_PID || error "kill -USR1 PID $MULTIOP_PID failed"
3861         wait $MULTIOP_PID || error "wait PID $MULTIOP_PID failed"
3862 }
3863 run_test 43b "truncate of file being executed should return -ETXTBSY"
3864
3865 test_43c() {
3866         local testdir="$DIR/$tdir"
3867         test_mkdir $testdir
3868         cp $SHELL $testdir/
3869         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
3870                 ( cd $testdir && md5sum -c )
3871 }
3872 run_test 43c "md5sum of copy into lustre"
3873
3874 test_44A() { # was test_44
3875         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs" && return
3876         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
3877         dd if=$DIR/f1 bs=4k count=1 > /dev/null
3878 }
3879 run_test 44A "zero length read from a sparse stripe"
3880
3881 test_44a() {
3882         local nstripe=$($LCTL lov_getconfig $DIR | grep default_stripe_count: |
3883                 awk '{ print $2 }')
3884         [ -z "$nstripe" ] && skip "can't get stripe info" && return
3885         [[ $nstripe -gt $OSTCOUNT ]] &&
3886             skip "Wrong default_stripe_count: $nstripe (OSTCOUNT: $OSTCOUNT)" &&
3887             return
3888         local stride=$($LCTL lov_getconfig $DIR | grep default_stripe_size: |
3889                 awk '{ print $2 }')
3890         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
3891                 nstripe=$($LCTL lov_getconfig $DIR | grep obd_count: |
3892                         awk '{ print $2 }')
3893         fi
3894
3895         OFFSETS="0 $((stride/2)) $((stride-1))"
3896         for offset in $OFFSETS; do
3897                 for i in $(seq 0 $((nstripe-1))); do
3898                         local GLOBALOFFSETS=""
3899                         # size in Bytes
3900                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
3901                         local myfn=$DIR/d44a-$size
3902                         echo "--------writing $myfn at $size"
3903                         ll_sparseness_write $myfn $size ||
3904                                 error "ll_sparseness_write"
3905                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
3906                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
3907                                 error "ll_sparseness_verify $GLOBALOFFSETS"
3908
3909                         for j in $(seq 0 $((nstripe-1))); do
3910                                 # size in Bytes
3911                                 size=$((((j + $nstripe )*$stride + $offset)))
3912                                 ll_sparseness_write $myfn $size ||
3913                                         error "ll_sparseness_write"
3914                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
3915                         done
3916                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
3917                                 error "ll_sparseness_verify $GLOBALOFFSETS"
3918                         rm -f $myfn
3919                 done
3920         done
3921 }
3922 run_test 44a "test sparse pwrite ==============================="
3923
3924 dirty_osc_total() {
3925         tot=0
3926         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
3927                 tot=$(($tot + $d))
3928         done
3929         echo $tot
3930 }
3931 do_dirty_record() {
3932         before=`dirty_osc_total`
3933         echo executing "\"$*\""
3934         eval $*
3935         after=`dirty_osc_total`
3936         echo before $before, after $after
3937 }
3938 test_45() {
3939         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
3940         f="$DIR/f45"
3941         # Obtain grants from OST if it supports it
3942         echo blah > ${f}_grant
3943         stop_writeback
3944         sync
3945         do_dirty_record "echo blah > $f"
3946         [[ $before -eq $after ]] && error "write wasn't cached"
3947         do_dirty_record "> $f"
3948         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
3949         do_dirty_record "echo blah > $f"
3950         [[ $before -eq $after ]] && error "write wasn't cached"
3951         do_dirty_record "sync"
3952         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
3953         do_dirty_record "echo blah > $f"
3954         [[ $before -eq $after ]] && error "write wasn't cached"
3955         do_dirty_record "cancel_lru_locks osc"
3956         [[ $before -gt $after ]] ||
3957                 error "lock cancellation didn't lower dirty count"
3958         start_writeback
3959 }
3960 run_test 45 "osc io page accounting ============================"
3961
3962 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
3963 # test tickles a bug where re-dirtying a page was failing to be mapped to the
3964 # objects offset and an assert hit when an rpc was built with 1023's mapped
3965 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
3966 test_46() {
3967         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
3968         f="$DIR/f46"
3969         stop_writeback
3970         sync
3971         dd if=/dev/zero of=$f bs=`page_size` seek=511 count=1
3972         sync
3973         dd conv=notrunc if=/dev/zero of=$f bs=`page_size` seek=1023 count=1
3974         dd conv=notrunc if=/dev/zero of=$f bs=`page_size` seek=511 count=1
3975         sync
3976         start_writeback
3977 }
3978 run_test 46 "dirtying a previously written page ================"
3979
3980 # test_47 is removed "Device nodes check" is moved to test_28
3981
3982 test_48a() { # bug 2399
3983         [ $(facet_fstype $SINGLEMDS) = "zfs" ] &&
3984         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.3.63) ] &&
3985                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly" &&
3986                 return
3987         test_mkdir $DIR/$tdir
3988         cd $DIR/$tdir
3989         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
3990         test_mkdir $DIR/$tdir
3991         touch foo || error "'touch foo' failed after recreating cwd"
3992         test_mkdir bar
3993         touch .foo || error "'touch .foo' failed after recreating cwd"
3994         test_mkdir .bar
3995         ls . > /dev/null || error "'ls .' failed after recreating cwd"
3996         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
3997         cd . || error "'cd .' failed after recreating cwd"
3998         mkdir . && error "'mkdir .' worked after recreating cwd"
3999         rmdir . && error "'rmdir .' worked after recreating cwd"
4000         ln -s . baz || error "'ln -s .' failed after recreating cwd"
4001         cd .. || error "'cd ..' failed after recreating cwd"
4002 }
4003 run_test 48a "Access renamed working dir (should return errors)="
4004
4005 test_48b() { # bug 2399
4006         rm -rf $DIR/$tdir
4007         test_mkdir $DIR/$tdir
4008         cd $DIR/$tdir
4009         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
4010         touch foo && error "'touch foo' worked after removing cwd"
4011         mkdir foo && error "'mkdir foo' worked after removing cwd"
4012         touch .foo && error "'touch .foo' worked after removing cwd"
4013         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
4014         ls . > /dev/null && error "'ls .' worked after removing cwd"
4015         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
4016         mkdir . && error "'mkdir .' worked after removing cwd"
4017         rmdir . && error "'rmdir .' worked after removing cwd"
4018         ln -s . foo && error "'ln -s .' worked after removing cwd"
4019         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
4020 }
4021 run_test 48b "Access removed working dir (should return errors)="
4022
4023 test_48c() { # bug 2350
4024         #lctl set_param debug=-1
4025         #set -vx
4026         rm -rf $DIR/$tdir
4027         test_mkdir -p $DIR/$tdir/dir
4028         cd $DIR/$tdir/dir
4029         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
4030         $TRACE touch foo && error "touch foo worked after removing cwd"
4031         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
4032         touch .foo && error "touch .foo worked after removing cwd"
4033         mkdir .foo && error "mkdir .foo worked after removing cwd"
4034         $TRACE ls . && error "'ls .' worked after removing cwd"
4035         $TRACE ls .. || error "'ls ..' failed after removing cwd"
4036         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
4037         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
4038         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
4039         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
4040 }
4041 run_test 48c "Access removed working subdir (should return errors)"
4042
4043 test_48d() { # bug 2350
4044         #lctl set_param debug=-1
4045         #set -vx
4046         rm -rf $DIR/$tdir
4047         test_mkdir -p $DIR/$tdir/dir
4048         cd $DIR/$tdir/dir
4049         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
4050         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
4051         $TRACE touch foo && error "'touch foo' worked after removing parent"
4052         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
4053         touch .foo && error "'touch .foo' worked after removing parent"
4054         mkdir .foo && error "mkdir .foo worked after removing parent"
4055         $TRACE ls . && error "'ls .' worked after removing parent"
4056         $TRACE ls .. && error "'ls ..' worked after removing parent"
4057         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
4058         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
4059         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
4060         true
4061 }
4062 run_test 48d "Access removed parent subdir (should return errors)"
4063
4064 test_48e() { # bug 4134
4065         #lctl set_param debug=-1
4066         #set -vx
4067         rm -rf $DIR/$tdir
4068         test_mkdir -p $DIR/$tdir/dir
4069         cd $DIR/$tdir/dir
4070         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
4071         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
4072         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
4073         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
4074         # On a buggy kernel addition of "touch foo" after cd .. will
4075         # produce kernel oops in lookup_hash_it
4076         touch ../foo && error "'cd ..' worked after recreate parent"
4077         cd $DIR
4078         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
4079 }
4080 run_test 48e "Access to recreated parent subdir (should return errors)"
4081
4082 test_49() { # LU-1030
4083         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
4084         remote_ost_nodsh && skip "remote OST with nodsh" && return
4085         # get ost1 size - lustre-OST0000
4086         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
4087                 awk '{ print $4 }')
4088         # write 800M at maximum
4089         [[ $ost1_size -lt 2 ]] && ost1_size=2
4090         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
4091
4092         $SETSTRIPE -c 1 -i 0 $DIR/$tfile
4093         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
4094         local dd_pid=$!
4095
4096         # change max_pages_per_rpc while writing the file
4097         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
4098         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
4099         # loop until dd process exits
4100         while ps ax -opid | grep -wq $dd_pid; do
4101                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
4102                 sleep $((RANDOM % 5 + 1))
4103         done
4104         # restore original max_pages_per_rpc
4105         $LCTL set_param $osc1_mppc=$orig_mppc
4106         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
4107 }
4108 run_test 49 "Change max_pages_per_rpc won't break osc extent"
4109
4110 test_50() {
4111         # bug 1485
4112         test_mkdir $DIR/$tdir
4113         cd $DIR/$tdir
4114         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
4115 }
4116 run_test 50 "special situations: /proc symlinks  ==============="
4117
4118 test_51a() {    # was test_51
4119         # bug 1516 - create an empty entry right after ".." then split dir
4120         test_mkdir -c1 $DIR/$tdir
4121         touch $DIR/$tdir/foo
4122         $MCREATE $DIR/$tdir/bar
4123         rm $DIR/$tdir/foo
4124         createmany -m $DIR/$tdir/longfile 201
4125         FNUM=202
4126         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
4127                 $MCREATE $DIR/$tdir/longfile$FNUM
4128                 FNUM=$(($FNUM + 1))
4129                 echo -n "+"
4130         done
4131         echo
4132         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
4133 }
4134 run_test 51a "special situations: split htree with empty entry =="
4135
4136 cleanup_print_lfs_df () {
4137         trap 0
4138         $LFS df
4139         $LFS df -i
4140 }
4141
4142 test_51b() {
4143         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
4144         local dir=$DIR/$tdir
4145
4146         local nrdirs=$((65536 + 100))
4147
4148         # cleanup the directory
4149         rm -fr $dir
4150
4151         test_mkdir -c1 $dir
4152
4153         $LFS df
4154         $LFS df -i
4155         local mdtidx=$(printf "%04x" $($LFS getstripe -M $dir))
4156         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
4157         [[ $numfree -lt $nrdirs ]] &&
4158                 skip "not enough free inodes ($numfree) on MDT$mdtidx" &&
4159                 return
4160
4161         # need to check free space for the directories as well
4162         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
4163         numfree=$(( blkfree / $(fs_inode_ksize) ))
4164         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)" &&
4165                 return
4166
4167         trap cleanup_print_lfs_df EXIT
4168
4169         # create files
4170         createmany -d $dir/d $nrdirs || {
4171                 unlinkmany $dir/d $nrdirs
4172                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
4173         }
4174
4175         # really created :
4176         nrdirs=$(ls -U $dir | wc -l)
4177
4178         # unlink all but 100 subdirectories, then check it still works
4179         local left=100
4180         local delete=$((nrdirs - left))
4181
4182         $LFS df
4183         $LFS df -i
4184
4185         # for ldiskfs the nlink count should be 1, but this is OSD specific
4186         # and so this is listed for informational purposes only
4187         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
4188         unlinkmany -d $dir/d $delete ||
4189                 error "unlink of first $delete subdirs failed"
4190
4191         echo "nlink between: $(stat -c %h $dir)"
4192         local found=$(ls -U $dir | wc -l)
4193         [ $found -ne $left ] &&
4194                 error "can't find subdirs: found only $found, expected $left"
4195
4196         unlinkmany -d $dir/d $delete $left ||
4197                 error "unlink of second $left subdirs failed"
4198         # regardless of whether the backing filesystem tracks nlink accurately
4199         # or not, the nlink count shouldn't be more than "." and ".." here
4200         local after=$(stat -c %h $dir)
4201         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
4202                 echo "nlink after: $after"
4203
4204         cleanup_print_lfs_df
4205 }
4206 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
4207
4208 test_51d() {
4209         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
4210         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs" && return
4211         test_mkdir $DIR/$tdir
4212         createmany -o $DIR/$tdir/t- 1000
4213         $LFS getstripe $DIR/$tdir > $TMP/$tfile
4214         for N in $(seq 0 $((OSTCOUNT - 1))); do
4215                 OBJS[$N]=$(awk -vobjs=0 '($1 == '$N') { objs += 1 } \
4216                         END { printf("%0.0f", objs) }' $TMP/$tfile)
4217                 OBJS0[$N]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
4218                         '($1 == '$N') { objs += 1 } \
4219                         END { printf("%0.0f", objs) }')
4220                 log "OST$N has ${OBJS[$N]} objects, ${OBJS0[$N]} are index 0"
4221         done
4222         unlinkmany $DIR/$tdir/t- 1000
4223
4224         NLAST=0
4225         for N in $(seq 1 $((OSTCOUNT - 1))); do
4226                 [[ ${OBJS[$N]} -lt $((${OBJS[$NLAST]} - 20)) ]] &&
4227                         error "OST $N has less objects vs OST $NLAST" \
4228                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
4229                 [[ ${OBJS[$N]} -gt $((${OBJS[$NLAST]} + 20)) ]] &&
4230                         error "OST $N has less objects vs OST $NLAST" \
4231                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
4232
4233                 [[ ${OBJS0[$N]} -lt $((${OBJS0[$NLAST]} - 20)) ]] &&
4234                         error "OST $N has less #0 objects vs OST $NLAST" \
4235                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
4236                 [[ ${OBJS0[$N]} -gt $((${OBJS0[$NLAST]} + 20)) ]] &&
4237                         error "OST $N has less #0 objects vs OST $NLAST" \
4238                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
4239                 NLAST=$N
4240         done
4241         rm -f $TMP/$tfile
4242 }
4243 run_test 51d "check object distribution"
4244
4245 test_51e() {
4246         if [ "$(facet_fstype $SINGLEMDS)" != ldiskfs ]; then
4247                 skip "ldiskfs only test"
4248                 return
4249         fi
4250
4251         test_mkdir -c1 $DIR/$tdir
4252         test_mkdir -c1 $DIR/$tdir/d0
4253
4254         touch $DIR/$tdir/d0/foo
4255         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
4256                 error "file exceed 65000 nlink limit!"
4257         unlinkmany $DIR/$tdir/d0/f- 65001
4258         return 0
4259 }
4260 run_test 51e "check file nlink limit"
4261
4262 test_51f() {
4263         test_mkdir $DIR/$tdir
4264
4265         local max=100000
4266         local ulimit_old=$(ulimit -n)
4267         local spare=20 # number of spare fd's for scripts/libraries, etc.
4268         local mdt=$(lfs getstripe -M $DIR/$tdir)
4269         local numfree=$(lfs df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
4270
4271         echo "MDT$mdt numfree=$numfree, max=$max"
4272         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
4273         if [ $((numfree + spare)) -gt $ulimit_old ]; then
4274                 while ! ulimit -n $((numfree + spare)); do
4275                         numfree=$((numfree * 3 / 4))
4276                 done
4277                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
4278         else
4279                 echo "left ulimit at $ulimit_old"
4280         fi
4281
4282         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
4283                 unlinkmany $DIR/$tdir/f $numfree
4284                 error "create+open $numfree files in $DIR/$tdir failed"
4285         }
4286         ulimit -n $ulimit_old
4287
4288         # if createmany exits at 120s there will be fewer than $numfree files
4289         unlinkmany $DIR/$tdir/f $numfree || true
4290 }
4291 run_test 51f "check many open files limit"
4292
4293 test_52a() {
4294         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
4295         test_mkdir $DIR/$tdir
4296         touch $DIR/$tdir/foo
4297         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
4298         echo bar >> $DIR/$tdir/foo || error "append bar failed"
4299         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
4300         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
4301         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
4302                                         error "link worked"
4303         echo foo >> $DIR/$tdir/foo || error "append foo failed"
4304         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
4305         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
4306                                                      error "lsattr"
4307         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
4308         cp -r $DIR/$tdir $TMP/
4309         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
4310 }
4311 run_test 52a "append-only flag test (should return errors)"
4312
4313 test_52b() {
4314         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
4315         test_mkdir $DIR/$tdir
4316         touch $DIR/$tdir/foo
4317         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
4318         cat test > $DIR/$tdir/foo && error "cat test worked"
4319         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
4320         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
4321         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
4322                                         error "link worked"
4323         echo foo >> $DIR/$tdir/foo && error "echo worked"
4324         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
4325         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
4326         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
4327         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
4328                                                         error "lsattr"
4329         chattr -i $DIR/$tdir/foo || error "chattr failed"
4330
4331         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
4332 }
4333 run_test 52b "immutable flag test (should return errors) ======="
4334
4335 test_53() {
4336         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
4337         remote_mds_nodsh && skip "remote MDS with nodsh" && return
4338         remote_ost_nodsh && skip "remote OST with nodsh" && return
4339
4340         local param
4341         local param_seq
4342         local ostname
4343         local mds_last
4344         local mds_last_seq
4345         local ost_last
4346         local ost_last_seq
4347         local ost_last_id
4348         local ostnum
4349         local node
4350         local found=false
4351         local support_last_seq=true
4352
4353         [[ $(lustre_version_code $SINGLEMDS) -ge $(version_code 2.3.60) ]] ||
4354                 support_last_seq=false
4355
4356         # only test MDT0000
4357         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
4358         local value
4359         for value in $(do_facet $SINGLEMDS \
4360                        $LCTL get_param osc.$mdtosc.prealloc_last_id) ; do
4361                 param=$(echo ${value[0]} | cut -d "=" -f1)
4362                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
4363
4364                 if $support_last_seq; then
4365                         param_seq=$(echo $param |
4366                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
4367                         mds_last_seq=$(do_facet $SINGLEMDS \
4368                                        $LCTL get_param -n $param_seq)
4369                 fi
4370                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
4371
4372                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
4373                 node=$(facet_active_host ost$((ostnum+1)))
4374                 param="obdfilter.$ostname.last_id"
4375                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
4376                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
4377                         ost_last_id=$ost_last
4378
4379                         if $support_last_seq; then
4380                                 ost_last_id=$(echo $ost_last |
4381                                               awk -F':' '{print $2}' |
4382                                               sed -e "s/^0x//g")
4383                                 ost_last_seq=$(echo $ost_last |
4384                                                awk -F':' '{print $1}')
4385                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
4386                         fi
4387
4388                         if [[ $ost_last_id != $mds_last ]]; then
4389                                 error "$ost_last_id != $mds_last"
4390                         else
4391                                 found=true
4392                                 break
4393                         fi
4394                 done
4395         done
4396         $found || error "can not match last_seq/last_id for $mdtosc"
4397         return 0
4398 }
4399 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
4400
4401 test_54a() {
4402         perl -MSocket -e ';' || { skip "no Socket perl module installed" && return; }
4403
4404         $SOCKETSERVER $DIR/socket ||
4405                 error "$SOCKETSERVER $DIR/socket failed: $?"
4406         $SOCKETCLIENT $DIR/socket ||
4407                 error "$SOCKETCLIENT $DIR/socket failed: $?"
4408         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
4409 }
4410 run_test 54a "unix domain socket test =========================="
4411
4412 test_54b() {
4413         f="$DIR/f54b"
4414         mknod $f c 1 3
4415         chmod 0666 $f
4416         dd if=/dev/zero of=$f bs=$(page_size) count=1
4417 }
4418 run_test 54b "char device works in lustre ======================"
4419
4420 find_loop_dev() {
4421         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
4422         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
4423         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
4424
4425         for i in $(seq 3 7); do
4426                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
4427                 LOOPDEV=$LOOPBASE$i
4428                 LOOPNUM=$i
4429                 break
4430         done
4431 }
4432
4433 cleanup_54c() {
4434         local rc=0
4435         loopdev="$DIR/loop54c"
4436
4437         trap 0
4438         $UMOUNT $DIR/$tdir || rc=$?
4439         losetup -d $loopdev || true
4440         losetup -d $LOOPDEV || true
4441         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
4442         return $rc
4443 }
4444
4445 test_54c() {
4446         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
4447         loopdev="$DIR/loop54c"
4448
4449         find_loop_dev
4450         [ -z "$LOOPNUM" ] && echo "couldn't find empty loop device" && return
4451         trap cleanup_54c EXIT
4452         mknod $loopdev b 7 $LOOPNUM
4453         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
4454         dd if=/dev/zero of=$DIR/$tfile bs=$(get_page_size client) seek=1024 count=1 > /dev/null
4455         losetup $loopdev $DIR/$tfile ||
4456                 error "can't set up $loopdev for $DIR/$tfile"
4457         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
4458         test_mkdir $DIR/$tdir
4459         mount -t ext2 $loopdev $DIR/$tdir ||
4460                 error "error mounting $loopdev on $DIR/$tdir"
4461         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$(get_page_size client) count=30 ||
4462                 error "dd write"
4463         df $DIR/$tdir
4464         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$(get_page_size client) count=30 ||
4465                 error "dd read"
4466         cleanup_54c
4467 }
4468 run_test 54c "block device works in lustre ====================="
4469
4470 test_54d() {
4471         f="$DIR/f54d"
4472         string="aaaaaa"
4473         mknod $f p
4474         [ "$string" = $(echo $string > $f | cat $f) ] || error "$f != $string"
4475 }
4476 run_test 54d "fifo device works in lustre ======================"
4477
4478 test_54e() {
4479         f="$DIR/f54e"
4480         string="aaaaaa"
4481         cp -aL /dev/console $f
4482         echo $string > $f || error "echo $string to $f failed"
4483 }
4484 run_test 54e "console/tty device works in lustre ======================"
4485
4486 test_56a() {
4487         local numfiles=3
4488         local dir=$DIR/$tdir
4489
4490         rm -rf $dir
4491         test_mkdir -p $dir/dir
4492         for i in $(seq $numfiles); do
4493                 touch $dir/file$i
4494                 touch $dir/dir/file$i
4495         done
4496
4497         local numcomp=$($LFS getstripe --component-count $dir)
4498
4499         [[ $numcomp == 0 ]] && numcomp=1
4500
4501         # test lfs getstripe with --recursive
4502         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
4503
4504         [[ $filenum -eq $((numfiles * 2)) ]] ||
4505                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
4506         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
4507         [[ $filenum -eq $numfiles ]] ||
4508                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
4509         echo "$LFS getstripe showed obdidx or l_ost_idx"
4510
4511         # test lfs getstripe with file instead of dir
4512         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
4513         [[ $filenum -eq 1 ]] ||
4514                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
4515         echo "$LFS getstripe file1 passed"
4516
4517         #test lfs getstripe with --verbose
4518         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
4519         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
4520                 error "$LFS getstripe --verbose $dir: "\
4521                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
4522         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
4523                 error "$LFS getstripe $dir: showed lmm_magic"
4524
4525         #test lfs getstripe with -v prints lmm_fid
4526         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
4527         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
4528                 error "$LFS getstripe -v $dir: "\
4529                       "got $filenum want $((numfiles * numcomp)) lmm_fid"
4530         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
4531                 error "$LFS getstripe $dir: showed lmm_fid by default"
4532         echo "$LFS getstripe --verbose passed"
4533
4534         #check for FID information
4535         local fid1=$($LFS getstripe --fid $dir/file1)
4536         local fid2=$($LFS getstripe --verbose $dir/file1 |
4537                      awk '/lmm_fid: / { print $2; exit; }')
4538         local fid3=$($LFS path2fid $dir/file1)
4539
4540         [ "$fid1" != "$fid2" ] &&
4541                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
4542         [ "$fid1" != "$fid3" ] &&
4543                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
4544         echo "$LFS getstripe --fid passed"
4545
4546         #test lfs getstripe with --obd
4547         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
4548                 error "$LFS getstripe --obd wrong_uuid: should return error"
4549
4550         [[ $OSTCOUNT -lt 2 ]] &&
4551                 skip_env "skip '$LFS getstripe --obd' tests: $OSTCOUNT < 2" &&
4552                 return
4553
4554         local ostidx=1
4555         local obduuid=$(ostuuid_from_index $ostidx)
4556         local found=$($LFS getstripe -r --obd $obduuid $dir |
4557                       egrep -c "obdidx|l_ost_idx")
4558
4559         filenum=$($LFS getstripe -ir $dir | grep "^$ostidx\$" | wc -l)
4560         [[ $found -eq $filenum ]] ||
4561                 error "$LFS getstripe --obd: found $found expect $filenum"
4562         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
4563                 sed '/^[         ]*'${ostidx}'[  ]/d' |
4564                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
4565                 error "$LFS getstripe --obd: should not show file on other obd"
4566         echo "$LFS getstripe --obd passed"
4567 }
4568 run_test 56a "check $LFS getstripe"
4569
4570 test_56b() {
4571         local dir=$DIR/$tdir
4572         local numdirs=3
4573
4574         test_mkdir $dir
4575         for i in $(seq $numdirs); do
4576                 test_mkdir $dir/dir$i
4577         done
4578
4579         # test lfs getdirstripe default mode is non-recursion, which is
4580         # different from lfs getstripe
4581         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
4582
4583         [[ $dircnt -eq 1 ]] ||
4584                 error "$LFS getdirstripe: found $dircnt, not 1"
4585         dircnt=$($LFS getdirstripe --recursive $dir |
4586                 grep -c lmv_stripe_count)
4587         [[ $dircnt -eq $((numdirs + 1)) ]] ||
4588                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
4589 }
4590 run_test 56b "check $LFS getdirstripe"
4591
4592 test_56c() {
4593         local ost_idx=0
4594         local ost_name=$(ostname_from_index $ost_idx)
4595         local old_status=$(ost_dev_status $ost_idx)
4596
4597         [[ -z "$old_status" ]] ||
4598                 { skip_env "OST $ost_name is in $old_status status"; return 0; }
4599
4600         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
4601         sleep_maxage
4602
4603         local new_status=$(ost_dev_status $ost_idx)
4604
4605         [[ "$new_status" = "D" ]] ||
4606                 error "OST $ost_name is in status of '$new_status', not 'D'"
4607
4608         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
4609         sleep_maxage
4610
4611         new_status=$(ost_dev_status $ost_idx)
4612         [[ -z "$new_status" ]] ||
4613                 error "OST $ost_name is in status of '$new_status', not ''"
4614 }
4615 run_test 56c "check 'lfs df' showing device status"
4616
4617 NUMFILES=3
4618 NUMDIRS=3
4619 setup_56() {
4620         local local_tdir="$1"
4621         local local_numfiles="$2"
4622         local local_numdirs="$3"
4623         local dir_params="$4"
4624         local dir_stripe_params="$5"
4625
4626         if [ ! -d "$local_tdir" ] ; then
4627                 test_mkdir -p $dir_stripe_params $local_tdir
4628                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
4629                 for i in $(seq $local_numfiles) ; do
4630                         touch $local_tdir/file$i
4631                 done
4632                 for i in $(seq $local_numdirs) ; do
4633                         test_mkdir $dir_stripe_params $local_tdir/dir$i
4634                         for j in $(seq $local_numfiles) ; do
4635                                 touch $local_tdir/dir$i/file$j
4636                         done
4637                 done
4638         fi
4639 }
4640
4641 setup_56_special() {
4642         local local_tdir=$1
4643         local local_numfiles=$2
4644         local local_numdirs=$3
4645
4646         setup_56 $local_tdir $local_numfiles $local_numdirs
4647
4648         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
4649                 for i in $(seq $local_numfiles) ; do
4650                         mknod $local_tdir/loop${i}b b 7 $i
4651                         mknod $local_tdir/null${i}c c 1 3
4652                         ln -s $local_tdir/file1 $local_tdir/link${i}
4653                 done
4654                 for i in $(seq $local_numdirs) ; do
4655                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
4656                         mknod $local_tdir/dir$i/null${i}c c 1 3
4657                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
4658                 done
4659         fi
4660 }
4661
4662 test_56g() {
4663         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
4664         local expected=$(($NUMDIRS + 2))
4665
4666         setup_56 $dir $NUMFILES $NUMDIRS
4667
4668         # test lfs find with -name
4669         for i in $(seq $NUMFILES) ; do
4670                 local nums=$($LFS find -name "*$i" $dir | wc -l)
4671
4672                 [ $nums -eq $expected ] ||
4673                         error "lfs find -name '*$i' $dir wrong: "\
4674                               "found $nums, expected $expected"
4675         done
4676 }
4677 run_test 56g "check lfs find -name"
4678
4679 test_56h() {
4680         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
4681         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
4682
4683         setup_56 $dir $NUMFILES $NUMDIRS
4684
4685         # test lfs find with ! -name
4686         for i in $(seq $NUMFILES) ; do
4687                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
4688
4689                 [ $nums -eq $expected ] ||
4690                         error "lfs find ! -name '*$i' $dir wrong: "\
4691                               "found $nums, expected $expected"
4692         done
4693 }
4694 run_test 56h "check lfs find ! -name"
4695
4696 test_56i() {
4697         local dir=$DIR/$tdir
4698
4699         test_mkdir $dir
4700
4701         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
4702         local out=$($cmd)
4703
4704         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
4705 }
4706 run_test 56i "check 'lfs find -ost UUID' skips directories"
4707
4708 test_56j() {
4709         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
4710
4711         setup_56_special $dir $NUMFILES $NUMDIRS
4712
4713         local expected=$((NUMDIRS + 1))
4714         local cmd="$LFS find -type d $dir"
4715         local nums=$($cmd | wc -l)
4716
4717         [ $nums -eq $expected ] ||
4718                 error "'$cmd' wrong: found $nums, expected $expected"
4719 }
4720 run_test 56j "check lfs find -type d"
4721
4722 test_56k() {
4723         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
4724
4725         setup_56_special $dir $NUMFILES $NUMDIRS
4726
4727         local expected=$(((NUMDIRS + 1) * NUMFILES))
4728         local cmd="$LFS find -type f $dir"
4729         local nums=$($cmd | wc -l)
4730
4731         [ $nums -eq $expected ] ||
4732                 error "'$cmd' wrong: found $nums, expected $expected"
4733 }
4734 run_test 56k "check lfs find -type f"
4735
4736 test_56l() {
4737         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
4738
4739         setup_56_special $dir $NUMFILES $NUMDIRS
4740
4741         local expected=$((NUMDIRS + NUMFILES))
4742         local cmd="$LFS find -type b $dir"
4743         local nums=$($cmd | wc -l)
4744
4745         [ $nums -eq $expected ] ||
4746                 error "'$cmd' wrong: found $nums, expected $expected"
4747 }
4748 run_test 56l "check lfs find -type b"
4749
4750 test_56m() {
4751         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
4752
4753         setup_56_special $dir $NUMFILES $NUMDIRS
4754
4755         local expected=$((NUMDIRS + NUMFILES))
4756         local cmd="$LFS find -type c $dir"
4757         local nums=$($cmd | wc -l)
4758         [ $nums -eq $expected ] ||
4759                 error "'$cmd' wrong: found $nums, expected $expected"
4760 }
4761 run_test 56m "check lfs find -type c"
4762
4763 test_56n() {
4764         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
4765         setup_56_special $dir $NUMFILES $NUMDIRS
4766
4767         local expected=$((NUMDIRS + NUMFILES))
4768         local cmd="$LFS find -type l $dir"
4769         local nums=$($cmd | wc -l)
4770
4771         [ $nums -eq $expected ] ||
4772                 error "'$cmd' wrong: found $nums, expected $expected"
4773 }
4774 run_test 56n "check lfs find -type l"
4775
4776 test_56o() {
4777         local dir=$DIR/$tdir
4778
4779         setup_56 $dir $NUMFILES $NUMDIRS
4780         utime $dir/file1 > /dev/null || error "utime (1)"
4781         utime $dir/file2 > /dev/null || error "utime (2)"
4782         utime $dir/dir1 > /dev/null || error "utime (3)"
4783         utime $dir/dir2 > /dev/null || error "utime (4)"
4784         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
4785         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
4786
4787         local expected=4
4788         local nums=$($LFS find -mtime +0 $dir | wc -l)
4789
4790         [ $nums -eq $expected ] ||
4791                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
4792
4793         expected=12
4794         cmd="$LFS find -mtime 0 $dir"
4795         nums=$($cmd | wc -l)
4796         [ $nums -eq $expected ] ||
4797                 error "'$cmd' wrong: found $nums, expected $expected"
4798 }
4799 run_test 56o "check lfs find -mtime for old files"
4800
4801 test_56p() {
4802         [ $RUNAS_ID -eq $UID ] &&
4803                 skip_env "RUNAS_ID = UID = $UID -- skipping" && return
4804
4805         local dir=$DIR/$tdir
4806
4807         setup_56 $dir $NUMFILES $NUMDIRS
4808         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
4809
4810         local expected=$NUMFILES
4811         local cmd="$LFS find -uid $RUNAS_ID $dir"
4812         local nums=$($cmd | wc -l)
4813
4814         [ $nums -eq $expected ] ||
4815                 error "'$cmd' wrong: found $nums, expected $expected"
4816
4817         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
4818         cmd="$LFS find ! -uid $RUNAS_ID $dir"
4819         nums=$($cmd | wc -l)
4820         [ $nums -eq $expected ] ||
4821                 error "'$cmd' wrong: found $nums, expected $expected"
4822 }
4823 run_test 56p "check lfs find -uid and ! -uid"
4824
4825 test_56q() {
4826         [ $RUNAS_ID -eq $UID ] &&
4827                 skip_env "RUNAS_ID = UID = $UID -- skipping" && return
4828
4829         local dir=$DIR/$tdir
4830
4831         setup_56 $dir $NUMFILES $NUMDIRS
4832         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
4833
4834         local expected=$NUMFILES
4835         local cmd="$LFS find -gid $RUNAS_GID $dir"
4836         local nums=$($cmd | wc -l)
4837
4838         [ $nums -eq $expected ] ||
4839                 error "'$cmd' wrong: found $nums, expected $expected"
4840
4841         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
4842         cmd="$LFS find ! -gid $RUNAS_GID $dir"
4843         nums=$($cmd | wc -l)
4844         [ $nums -eq $expected ] ||
4845                 error "'$cmd' wrong: found $nums, expected $expected"
4846 }
4847 run_test 56q "check lfs find -gid and ! -gid"
4848
4849 test_56r() {
4850         local dir=$DIR/$tdir
4851
4852         setup_56 $dir $NUMFILES $NUMDIRS
4853
4854         local expected=12
4855         local cmd="$LFS find -size 0 -type f $dir"
4856         local nums=$($cmd | wc -l)
4857
4858         [ $nums -eq $expected ] ||
4859                 error "'$cmd' wrong: found $nums, expected $expected"
4860         expected=0
4861         cmd="$LFS find ! -size 0 -type f $dir"
4862         nums=$($cmd | wc -l)
4863         [ $nums -eq $expected ] ||
4864                 error "'$cmd' wrong: found $nums, expected $expected"
4865         echo "test" > $dir/$tfile
4866         echo "test2" > $dir/$tfile.2 && sync
4867         expected=1
4868         cmd="$LFS find -size 5 -type f $dir"
4869         nums=$($cmd | wc -l)
4870         [ $nums -eq $expected ] ||
4871                 error "'$cmd' wrong: found $nums, expected $expected"
4872         expected=1
4873         cmd="$LFS find -size +5 -type f $dir"
4874         nums=$($cmd | wc -l)
4875         [ $nums -eq $expected ] ||
4876                 error "'$cmd' wrong: found $nums, expected $expected"
4877         expected=2
4878         cmd="$LFS find -size +0 -type f $dir"
4879         nums=$($cmd | wc -l)
4880         [ $nums -eq $expected ] ||
4881                 error "'$cmd' wrong: found $nums, expected $expected"
4882         expected=2
4883         cmd="$LFS find ! -size -5 -type f $dir"
4884         nums=$($cmd | wc -l)
4885         [ $nums -eq $expected ] ||
4886                 error "'$cmd' wrong: found $nums, expected $expected"
4887         expected=12
4888         cmd="$LFS find -size -5 -type f $dir"
4889         nums=$($cmd | wc -l)
4890         [ $nums -eq $expected ] ||
4891                 error "'$cmd' wrong: found $nums, expected $expected"
4892 }
4893 run_test 56r "check lfs find -size works"
4894
4895 test_56s() { # LU-611 #LU-9369
4896         [[ $OSTCOUNT -lt 2 ]] && skip "need at least 2 OSTs" && return 0
4897
4898         local dir=$DIR/$tdir
4899         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
4900
4901         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
4902         for i in $(seq $NUMDIRS); do
4903                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
4904         done
4905
4906         local expected=$NUMDIRS
4907         local cmd="$LFS find -c $OSTCOUNT $dir"
4908         local nums=$($cmd | wc -l)
4909
4910         [ $nums -eq $expected ] || {
4911                 $LFS getstripe -R $dir
4912                 error "'$cmd' wrong: found $nums, expected $expected"
4913         }
4914
4915         expected=$((NUMDIRS + onestripe))
4916         cmd="$LFS find -stripe-count +0 -type f $dir"
4917         nums=$($cmd | wc -l)
4918         [ $nums -eq $expected ] || {
4919                 $LFS getstripe -R $dir
4920                 error "'$cmd' wrong: found $nums, expected $expected"
4921         }
4922
4923         expected=$onestripe
4924         cmd="$LFS find -stripe-count 1 -type f $dir"
4925         nums=$($cmd | wc -l)
4926         [ $nums -eq $expected ] || {
4927                 $LFS getstripe -R $dir
4928                 error "'$cmd' wrong: found $nums, expected $expected"
4929         }
4930
4931         cmd="$LFS find -stripe-count -2 -type f $dir"
4932         nums=$($cmd | wc -l)
4933         [ $nums -eq $expected ] || {
4934                 $LFS getstripe -R $dir
4935                 error "'$cmd' wrong: found $nums, expected $expected"
4936         }
4937
4938         expected=0
4939         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
4940         nums=$($cmd | wc -l)
4941         [ $nums -eq $expected ] || {
4942                 $LFS getstripe -R $dir
4943                 error "'$cmd' wrong: found $nums, expected $expected"
4944         }
4945 }
4946 run_test 56s "check lfs find -stripe-count works"
4947
4948 test_56t() { # LU-611 #LU-9369
4949         local dir=$DIR/$tdir
4950
4951         setup_56 $dir 0 $NUMDIRS
4952         for i in $(seq $NUMDIRS); do
4953                 $LFS setstripe -S 4M $dir/dir$i/$tfile
4954         done
4955
4956         local expected=$NUMDIRS
4957         local cmd="$LFS find -S 4M $dir"
4958         local nums=$($cmd | wc -l)
4959
4960         [ $nums -eq $expected ] || {
4961                 $LFS getstripe -R $dir
4962                 error "'$cmd' wrong: found $nums, expected $expected"
4963         }
4964         rm -rf $dir
4965
4966         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
4967
4968         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
4969
4970         expected=$(((NUMDIRS + 1) * NUMFILES))
4971         cmd="$LFS find -stripe-size 512k -type f $dir"
4972         nums=$($cmd | wc -l)
4973         [ $nums -eq $expected ] ||
4974                 error "'$cmd' wrong: found $nums, expected $expected"
4975
4976         cmd="$LFS find -stripe-size +320k -type f $dir"
4977         nums=$($cmd | wc -l)
4978         [ $nums -eq $expected ] ||
4979                 error "'$cmd' wrong: found $nums, expected $expected"
4980
4981         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
4982         cmd="$LFS find -stripe-size +200k -type f $dir"
4983         nums=$($cmd | wc -l)
4984         [ $nums -eq $expected ] ||
4985                 error "'$cmd' wrong: found $nums, expected $expected"
4986
4987         cmd="$LFS find -stripe-size -640k -type f $dir"
4988         nums=$($cmd | wc -l)
4989         [ $nums -eq $expected ] ||
4990                 error "'$cmd' wrong: found $nums, expected $expected"
4991
4992         expected=4
4993         cmd="$LFS find -stripe-size 256k -type f $dir"
4994         nums=$($cmd | wc -l)
4995         [ $nums -eq $expected ] ||
4996                 error "'$cmd' wrong: found $nums, expected $expected"
4997
4998         cmd="$LFS find -stripe-size -320k -type f $dir"
4999         nums=$($cmd | wc -l)
5000         [ $nums -eq $expected ] ||
5001                 error "'$cmd' wrong: found $nums, expected $expected"
5002
5003         expected=0
5004         cmd="$LFS find -stripe-size 1024k -type f $dir"
5005         nums=$($cmd | wc -l)
5006         [ $nums -eq $expected ] ||
5007                 error "'$cmd' wrong: found $nums, expected $expected"
5008 }
5009 run_test 56t "check lfs find -stripe-size works"
5010
5011 test_56u() { # LU-611
5012         local dir=$DIR/$tdir
5013
5014         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
5015
5016         if [[ $OSTCOUNT -gt 1 ]]; then
5017                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
5018                 onestripe=4
5019         else
5020                 onestripe=0
5021         fi
5022
5023         local expected=$(((NUMDIRS + 1) * NUMFILES))
5024         local cmd="$LFS find -stripe-index 0 -type f $dir"
5025         local nums=$($cmd | wc -l)
5026
5027         [ $nums -eq $expected ] ||
5028                 error "'$cmd' wrong: found $nums, expected $expected"
5029
5030         expected=$onestripe
5031         cmd="$LFS find -stripe-index 1 -type f $dir"
5032         nums=$($cmd | wc -l)
5033         [ $nums -eq $expected ] ||
5034                 error "'$cmd' wrong: found $nums, expected $expected"
5035
5036         cmd="$LFS find ! -stripe-index 0 -type f $dir"
5037         nums=$($cmd | wc -l)
5038         [ $nums -eq $expected ] ||
5039                 error "'$cmd' wrong: found $nums, expected $expected"
5040
5041         expected=0
5042         # This should produce an error and not return any files
5043         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
5044         nums=$($cmd 2>/dev/null | wc -l)
5045         [ $nums -eq $expected ] ||
5046                 error "'$cmd' wrong: found $nums, expected $expected"
5047
5048         if [[ $OSTCOUNT -gt 1 ]]; then
5049                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
5050                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
5051                 nums=$($cmd | wc -l)
5052                 [ $nums -eq $expected ] ||
5053                         error "'$cmd' wrong: found $nums, expected $expected"
5054         fi
5055 }
5056 run_test 56u "check lfs find -stripe-index works"
5057
5058 test_56v() {
5059         local MDT_IDX=0
5060         local dir=$DIR/$tdir
5061
5062         setup_56 $dir $NUMFILES $NUMDIRS
5063
5064         UUID=$(mdtuuid_from_index $MDT_IDX $dir)
5065         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $MDT_IDX"
5066
5067         for file in $($LFS find -mdt $UUID $dir); do
5068                 file_mdt_idx=$($LFS getstripe -M $file)
5069                 [ $file_mdt_idx -eq $MDT_IDX ] ||
5070                         error "lfind -mdt $UUID != getstripe -M $file_mdt_idx"
5071         done
5072 }
5073 run_test 56v "check 'lfs find -mdt match with lfs getstripe -M' ======="
5074
5075 test_56w() {
5076         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs" && return
5077         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
5078         local dir=$DIR/$tdir
5079
5080         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
5081
5082         local stripe_size=$($LFS getstripe -S -d $dir) ||
5083                 error "$LFS getstripe -S -d $dir failed"
5084         stripe_size=${stripe_size%% *}
5085
5086         local file_size=$((stripe_size * OSTCOUNT))
5087         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
5088         local required_space=$((file_num * file_size))
5089         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
5090                            head -n1)
5091         [[ $free_space -le $((required_space / 1024)) ]] &&
5092                 skip_env "need $required_space, have $free_space kbytes" &&
5093                 return
5094
5095         local dd_bs=65536
5096         local dd_count=$((file_size / dd_bs))
5097
5098         # write data into the files
5099         local i
5100         local j
5101         local file
5102
5103         for i in $(seq $NUMFILES); do
5104                 file=$dir/file$i
5105                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
5106                         error "write data into $file failed"
5107         done
5108         for i in $(seq $NUMDIRS); do
5109                 for j in $(seq $NUMFILES); do
5110                         file=$dir/dir$i/file$j
5111                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
5112                                 error "write data into $file failed"
5113                 done
5114         done
5115
5116         # $LFS_MIGRATE will fail if hard link migration is unsupported
5117         if [[ $(lustre_version_code mds1) -gt $(version_code 2.5.55) ]]; then
5118                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
5119                         error "creating links to $dir/dir1/file1 failed"
5120         fi
5121
5122         local expected=-1
5123
5124         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
5125
5126         # lfs_migrate file
5127         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
5128
5129         echo "$cmd"
5130         eval $cmd || error "$cmd failed"
5131
5132         check_stripe_count $dir/file1 $expected
5133
5134         if [ $(lustre_version_code $SINGLEMDS) -ge $(version_code 2.6.90) ];
5135         then
5136                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
5137                 # OST 1 if it is on OST 0. This file is small enough to
5138                 # be on only one stripe.
5139                 file=$dir/migr_1_ost
5140                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
5141                         error "write data into $file failed"
5142                 local obdidx=$($LFS getstripe -i $file)
5143                 local oldmd5=$(md5sum $file)
5144                 local newobdidx=0
5145
5146                 [[ $obdidx -eq 0 ]] && newobdidx=1
5147                 cmd="$LFS migrate -i $newobdidx $file"
5148                 echo $cmd
5149                 eval $cmd || error "$cmd failed"
5150
5151                 local realobdix=$($LFS getstripe -i $file)
5152                 local newmd5=$(md5sum $file)
5153
5154                 [[ $newobdidx -ne $realobdix ]] &&
5155                         error "new OST is different (was=$obdidx, "\
5156                               "wanted=$newobdidx, got=$realobdix)"
5157                 [[ "$oldmd5" != "$newmd5" ]] &&
5158                         error "md5sum differ: $oldmd5, $newmd5"
5159         fi
5160
5161         # lfs_migrate dir
5162         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
5163         echo "$cmd"
5164         eval $cmd || error "$cmd failed"
5165
5166         for j in $(seq $NUMFILES); do
5167                 check_stripe_count $dir/dir1/file$j $expected
5168         done
5169
5170         # lfs_migrate works with lfs find
5171         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
5172              $LFS_MIGRATE -y -c $expected"
5173         echo "$cmd"
5174         eval $cmd || error "$cmd failed"
5175
5176         for i in $(seq 2 $NUMFILES); do
5177                 check_stripe_count $dir/file$i $expected
5178         done
5179         for i in $(seq 2 $NUMDIRS); do
5180                 for j in $(seq $NUMFILES); do
5181                 check_stripe_count $dir/dir$i/file$j $expected
5182                 done
5183         done
5184 }
5185 run_test 56w "check lfs_migrate -c stripe_count works"
5186
5187 test_56wb() {
5188         local file1=$DIR/$tdir/file1
5189         local create_pool=false
5190         local initial_pool=$($LFS getstripe -p $DIR)
5191         local pool_list=()
5192         local pool=""
5193
5194         echo -n "Creating test dir..."
5195         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
5196         echo "done."
5197
5198         echo -n "Creating test file..."
5199         touch $file1 || error "cannot create file"
5200         echo "done."
5201
5202         echo -n "Detecting existing pools..."
5203         while IFS='' read thispool; do
5204                 pool_list+=("$thispool")
5205         done < <($LFS pool_list $MOUNT | awk -F '.' 'NR>=2 { print $2 }')
5206
5207         if [ ${#pool_list[@]} -gt 0 ]; then
5208                 echo "${pool_list[@]}"
5209                 for thispool in "${pool_list[@]}"; do
5210                         if [[ -z "$initial_pool" ||
5211                               "$initial_pool" != "$thispool" ]]; then
5212                                 pool="$thispool"
5213                                 echo "Using existing pool '$pool'"
5214                                 break
5215                         fi
5216                 done
5217         else
5218                 echo "none detected."
5219         fi
5220         if [ -z "$pool" ]; then
5221                 pool=${POOL:-testpool}
5222                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
5223                 echo -n "Creating pool '$pool'..."
5224                 create_pool=true
5225                 pool_add $pool &> /dev/null ||
5226                         error "pool_add failed"
5227                 echo "done."
5228
5229                 echo -n "Adding target to pool..."
5230                 pool_add_targets $pool 0 0 1 &> /dev/null ||
5231                         error "pool_add_targets failed"
5232                 echo "done."
5233         fi
5234
5235         echo -n "Setting pool using -p option..."
5236         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
5237                 error "migrate failed rc = $?"
5238         echo "done."
5239
5240         echo -n "Verifying test file is in pool after migrating..."
5241         [ "$($LFS getstripe -p $file1)" = $pool ] ||
5242                 error "file was not migrated to pool $pool"
5243         echo "done."
5244
5245         echo -n "Removing test file from pool '$pool'..."
5246         $LFS migrate $file1 &> /dev/null ||
5247                 error "cannot remove from pool"
5248         [ "$($LFS getstripe -p $file1)" ] &&
5249                 error "pool still set"
5250         echo "done."
5251
5252         echo -n "Setting pool using --pool option..."
5253         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
5254                 error "migrate failed rc = $?"
5255         echo "done."
5256
5257         # Clean up
5258         rm -f $file1
5259         if $create_pool; then
5260                 destroy_test_pools 2> /dev/null ||
5261                         error "destroy test pools failed"
5262         fi
5263 }
5264 run_test 56wb "check lfs_migrate pool support"
5265
5266 test_56wc() {
5267         local file1="$DIR/$tdir/file 1"
5268
5269         echo -n "Creating test dir..."
5270         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
5271         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
5272                 error "cannot set stripe"
5273         echo "done"
5274
5275         echo -n "Setting initial stripe for test file..."
5276         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
5277                 error "cannot set stripe"
5278         [ $($LFS getstripe -S "$file1") -eq 524288 ] ||
5279                 error "stripe size not set"
5280         echo "done."
5281
5282         # File currently set to -S 512K -c 1
5283
5284         # Ensure -c and -S options are rejected when -R is set
5285         echo -n "Verifying incompatible options are detected..."
5286         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
5287                 error "incompatible -c and -R options not detected"
5288         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
5289                 error "incompatible -S and -R options not detected"
5290         echo "done."
5291
5292         # Ensure unrecognized options are passed through to 'lfs migrate'
5293         echo -n "Verifying -S option is passed through to lfs migrate..."
5294         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
5295                 error "migration failed"
5296         [ $($LFS getstripe -S "$file1") -eq 1048576 ] ||
5297                 error "file was not restriped"
5298         echo "done."
5299
5300         # File currently set to -S 1M -c 1
5301
5302         # Ensure long options are supported
5303         echo -n "Verifying long options supported..."
5304         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
5305                 error "long option without argument not supported"
5306         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
5307                 error "long option with argument not supported"
5308         [ $($LFS getstripe -S "$file1") -eq 524288 ] ||
5309                 error "file not restriped with --stripe-size option"
5310         echo "done."
5311
5312         # File currently set to -S 512K -c 1
5313
5314         if [ "$OSTCOUNT" -gt 1 ]; then
5315                 echo -n "Verifying explicit stripe count can be set..."
5316                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
5317                         error "migrate failed"
5318                 [ $($LFS getstripe -c "$file1") -eq 2 ] ||
5319                         error "file not restriped to explicit count"
5320                 echo "done."
5321         fi
5322
5323         # File currently set to -S 512K -c 1 or -S 512K -c 2
5324
5325         # Ensure parent striping is used if -R is set, and no stripe
5326         # count or size is specified
5327         echo -n "Setting stripe for parent directory..."
5328         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
5329                 error "cannot set stripe"
5330         echo "done."
5331
5332         echo -n "Verifying restripe option uses parent stripe settings..."
5333         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
5334                 error "migrate failed"
5335         [ $($LFS getstripe -S "$file1") -eq 1048576 ] ||
5336                 error "file not restriped to parent settings"
5337         [ $($LFS getstripe -c "$file1") -eq 1 ] ||
5338                 error "file not restriped to parent settings"
5339         echo "done."
5340
5341         # File currently set to -S 1M -c 1
5342
5343         # Ensure striping is preserved if -R is not set, and no stripe
5344         # count or size is specified
5345         echo -n "Verifying striping size preserved when not specified..."
5346         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
5347                 error "cannot set stripe on parent directory"
5348         $LFS_MIGRATE -y "$file1" &> /dev/null ||
5349                 error "migrate failed"
5350         [ $($LFS getstripe -S "$file1") -eq 1048576 ] ||
5351                 error "file was restriped"
5352         echo "done."
5353
5354         # Ensure file name properly detected when final option has no argument
5355         echo -n "Verifying file name properly detected..."
5356         $LFS_MIGRATE -y "$file1" &> /dev/null ||
5357                 error "file name interpreted as option argument"
5358         echo "done."
5359
5360         # Clean up
5361         rm -f "$file1"
5362 }
5363 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
5364
5365 test_56wd() {
5366         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs" && return
5367         local file1=$DIR/$tdir/file1
5368
5369         echo -n "Creating test dir..."
5370         test_mkdir $DIR/$tdir || error "cannot create dir"
5371         echo "done."
5372
5373         echo -n "Creating test file..."
5374         touch $file1
5375         echo "done."
5376
5377         # Ensure 'lfs migrate' will fail by using a non-existent option,
5378         # and make sure rsync is not called to recover
5379         echo -n "Make sure --no-rsync option works..."
5380         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
5381                 grep -q 'refusing to fall back to rsync' ||
5382                 error "rsync was called with --no-rsync set"
5383         echo "done."
5384
5385         # Ensure rsync is called without trying 'lfs migrate' first
5386         echo -n "Make sure --rsync option works..."
5387         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
5388                 grep -q 'falling back to rsync' &&
5389                 error "lfs migrate was called with --rsync set"
5390         echo "done."
5391
5392         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
5393         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
5394                 grep -q 'at the same time' ||
5395                 error "--rsync and --no-rsync accepted concurrently"
5396         echo "done."
5397
5398         # Clean up
5399         rm -f $file1
5400 }
5401 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
5402
5403 test_56x() {
5404         check_swap_layouts_support && return 0
5405         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs" && return
5406
5407         local dir=$DIR/$tdir
5408         local ref1=/etc/passwd
5409         local file1=$dir/file1
5410
5411         test_mkdir $dir || error "creating dir $dir"
5412         $LFS setstripe -c 2 $file1
5413         cp $ref1 $file1
5414         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
5415         stripe=$($LFS getstripe -c $file1)
5416         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
5417         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
5418
5419         # clean up
5420         rm -f $file1
5421 }
5422 run_test 56x "lfs migration support"
5423
5424 test_56xa() {
5425         check_swap_layouts_support && return 0
5426         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs" && return
5427
5428         local dir=$DIR/$tdir/$testnum
5429
5430         test_mkdir -p $dir
5431
5432         local ref1=/etc/passwd
5433         local file1=$dir/file1
5434
5435         $LFS setstripe -c 2 $file1
5436         cp $ref1 $file1
5437         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
5438
5439         local stripe=$($LFS getstripe -c $file1)
5440
5441         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
5442         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
5443
5444         # clean up
5445         rm -f $file1
5446 }
5447 run_test 56xa "lfs migration --block support"
5448
5449 check_migrate_links() {
5450         local dir="$1"
5451         local file1="$dir/file1"
5452         local begin="$2"
5453         local count="$3"
5454         local total_count=$(($begin + $count - 1))
5455         local symlink_count=10
5456         local uniq_count=10
5457
5458         if [ ! -f "$file1" ]; then
5459                 echo -n "creating initial file..."
5460                 $LFS setstripe -c 1 -S "512k" "$file1" ||
5461                         error "cannot setstripe initial file"
5462                 echo "done"
5463
5464                 echo -n "creating symlinks..."
5465                 for s in $(seq 1 $symlink_count); do
5466                         ln -s "$file1" "$dir/slink$s" ||
5467                                 error "cannot create symlinks"
5468                 done
5469                 echo "done"
5470
5471                 echo -n "creating nonlinked files..."
5472                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
5473                         error "cannot create nonlinked files"
5474                 echo "done"
5475         fi
5476
5477         # create hard links
5478         if [ ! -f "$dir/file$total_count" ]; then
5479                 echo -n "creating hard links $begin:$total_count..."
5480                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
5481                         /dev/null || error "cannot create hard links"
5482                 echo "done"
5483         fi
5484
5485         echo -n "checking number of hard links listed in xattrs..."
5486         local fid=$($LFS getstripe -F "$file1")
5487         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
5488
5489         echo "${#paths[*]}"
5490         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
5491                         echo "hard link list has unexpected size, skipping test"
5492                         return 0
5493         fi
5494         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
5495                         error "link names should exceed xattrs size"
5496         fi
5497
5498         echo -n "migrating files..."
5499         local migrate_out=$($LFS_MIGRATE -y -S '1m' $dir)
5500         local rc=$?
5501         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
5502         echo "done"
5503
5504         # make sure all links have been properly migrated
5505         echo -n "verifying files..."
5506         fid=$($LFS getstripe -F "$file1") ||
5507                 error "cannot get fid for file $file1"
5508         for i in $(seq 2 $total_count); do
5509                 local fid2=$($LFS getstripe -F $dir/file$i)
5510
5511                 [ "$fid2" == "$fid" ] ||
5512                         error "migrated hard link has mismatched FID"
5513         done
5514
5515         # make sure hard links were properly detected, and migration was
5516         # performed only once for the entire link set; nonlinked files should
5517         # also be migrated
5518         local actual=$(grep -c 'done migrate' <<< "$migrate_out")
5519         local expected=$(($uniq_count + 1))
5520
5521         [ "$actual" -eq  "$expected" ] ||
5522                 error "hard links individually migrated ($actual != $expected)"
5523
5524         # make sure the correct number of hard links are present
5525         local hardlinks=$(stat -c '%h' "$file1")
5526
5527         [ $hardlinks -eq $total_count ] ||
5528                 error "num hard links $hardlinks != $total_count"
5529         echo "done"
5530
5531         return 0
5532 }
5533
5534 test_56xb() {
5535         local dir="$DIR/$tdir"
5536
5537         test_mkdir "$dir" || error "cannot create dir $dir"
5538
5539         echo "testing lfs migrate mode when all links fit within xattrs"
5540         LFS_MIGRATE_RSYNC=false check_migrate_links "$dir" 2 99
5541
5542         echo "testing rsync mode when all links fit within xattrs"
5543         LFS_MIGRATE_RSYNC=true check_migrate_links "$dir" 2 99
5544
5545         echo "testing lfs migrate mode when all links do not fit within xattrs"
5546         LFS_MIGRATE_RSYNC=false check_migrate_links "$dir" 101 100
5547
5548         echo "testing rsync mode when all links do not fit within xattrs"
5549         LFS_MIGRATE_RSYNC=true check_migrate_links "$dir" 101 100
5550
5551         # clean up
5552         rm -rf $dir
5553 }
5554 run_test 56xb "lfs migration hard link support"
5555
5556 test_56y() {
5557         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.4.53) ] &&
5558                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53" &&
5559                 return
5560
5561         local res=""
5562         local dir=$DIR/$tdir
5563         local f1=$dir/file1
5564         local f2=$dir/file2
5565
5566         test_mkdir -p $dir || error "creating dir $dir"
5567         touch $f1 || error "creating std file $f1"
5568         $MULTIOP $f2 H2c || error "creating released file $f2"
5569
5570         # a directory can be raid0, so ask only for files
5571         res=$($LFS find $dir -L raid0 -type f | wc -l)
5572         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
5573
5574         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
5575         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
5576
5577         # only files can be released, so no need to force file search
5578         res=$($LFS find $dir -L released)
5579         [[ $res == $f2 ]] || error "search released: found $res != $f2"
5580
5581         res=$($LFS find $dir -type f \! -L released)
5582         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
5583 }
5584 run_test 56y "lfs find -L raid0|released"
5585
5586 test_56z() { # LU-4824
5587         # This checks to make sure 'lfs find' continues after errors
5588         # There are two classes of errors that should be caught:
5589         # - If multiple paths are provided, all should be searched even if one
5590         #   errors out
5591         # - If errors are encountered during the search, it should not terminate
5592         #   early
5593         local dir=$DIR/$tdir
5594         local i
5595
5596         test_mkdir $dir
5597         for i in d{0..9}; do
5598                 test_mkdir $dir/$i
5599         done
5600         touch $dir/d{0..9}/$tfile
5601         $LFS find $DIR/non_existent_dir $dir &&
5602                 error "$LFS find did not return an error"
5603         # Make a directory unsearchable. This should NOT be the last entry in
5604         # directory order.  Arbitrarily pick the 6th entry
5605         chmod 700 $($LFS find $dir -type d | sed '6!d')
5606
5607         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
5608
5609         # The user should be able to see 10 directories and 9 files
5610         [ $count == 19 ] || error "$LFS find did not continue after error"
5611 }
5612 run_test 56z "lfs find should continue after an error"
5613
5614 test_56aa() { # LU-5937
5615         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
5616
5617         local dir=$DIR/$tdir
5618
5619         mkdir $dir
5620         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
5621
5622         createmany -o $dir/striped_dir/${tfile}- 1024
5623         local dirs=$(lfs find --size +8k $dir/)
5624
5625         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
5626 }
5627 run_test 56aa "lfs find --size under striped dir"
5628
5629 test_56ba() {
5630         # Create composite files with one component
5631         local dir=$DIR/$tdir
5632
5633         setup_56 $dir/1Mfiles 5 1 "--component-end 1M"
5634         # Create composite files with three components
5635         setup_56 $dir/2Mfiles 5 2 "-E 2M -E 4M -E 6M"
5636         # Create non-composite files
5637         createmany -o $dir/${tfile}- 10
5638
5639         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
5640
5641         [[ $nfiles == 10 ]] ||
5642                 error "lfs find -E 1M found $nfiles != 10 files"
5643
5644         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
5645         [[ $nfiles == 25 ]] ||
5646                 error "lfs find ! -E 1M found $nfiles != 25 files"
5647
5648         # All files have a component that starts at 0
5649         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
5650         [[ $nfiles == 35 ]] ||
5651                 error "lfs find --component-start 0 - $nfiles != 35 files"
5652
5653         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
5654         [[ $nfiles == 15 ]] ||
5655                 error "lfs find --component-start 2M - $nfiles != 15 files"
5656
5657         # All files created here have a componenet that does not starts at 2M
5658         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
5659         [[ $nfiles == 35 ]] ||
5660                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
5661
5662         # Find files with a specified number of components
5663         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
5664         [[ $nfiles == 15 ]] ||
5665                 error "lfs find --component-count 3 - $nfiles != 15 files"
5666
5667         # Remember non-composite files have a component count of zero
5668         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
5669         [[ $nfiles == 10 ]] ||
5670                 error "lfs find --component-count 0 - $nfiles != 10 files"
5671
5672         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
5673         [[ $nfiles == 20 ]] ||
5674                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
5675
5676         # All files have a flag called "init"
5677         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
5678         [[ $nfiles == 35 ]] ||
5679                 error "lfs find --component-flags init - $nfiles != 35 files"
5680
5681         # Multi-component files will have a component not initialized
5682         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
5683         [[ $nfiles == 15 ]] ||
5684                 error "lfs find !--component-flags init - $nfiles != 15 files"
5685
5686         rm -rf $dir
5687
5688 }
5689 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
5690
5691 test_57a() {
5692         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
5693         # note test will not do anything if MDS is not local
5694         if [ "$(facet_fstype $SINGLEMDS)" != ldiskfs ]; then
5695                 skip "ldiskfs only test"
5696                 return
5697         fi
5698
5699         remote_mds_nodsh && skip "remote MDS with nodsh" && return
5700         local MNTDEV="osd*.*MDT*.mntdev"
5701         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
5702         [ -z "$DEV" ] && error "can't access $MNTDEV"
5703         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
5704                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
5705                         error "can't access $DEV"
5706                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
5707                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
5708                 rm $TMP/t57a.dump
5709         done
5710 }
5711 run_test 57a "verify MDS filesystem created with large inodes =="
5712
5713 test_57b() {
5714         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
5715         if [ "$(facet_fstype $SINGLEMDS)" != ldiskfs ]; then
5716                 skip "ldiskfs only test"
5717                 return
5718         fi
5719
5720         remote_mds_nodsh && skip "remote MDS with nodsh" && return
5721         local dir=$DIR/$tdir
5722
5723         local FILECOUNT=100
5724         local FILE1=$dir/f1
5725         local FILEN=$dir/f$FILECOUNT
5726
5727         rm -rf $dir || error "removing $dir"
5728         test_mkdir -c1 $dir
5729         local mdtidx=$($LFS getstripe -M $dir)
5730         local mdtname=MDT$(printf %04x $mdtidx)
5731         local facet=mds$((mdtidx + 1))
5732
5733         echo "mcreating $FILECOUNT files"
5734         createmany -m $dir/f 1 $FILECOUNT || \
5735                 error "creating files in $dir"
5736
5737         # verify that files do not have EAs yet
5738         $GETSTRIPE $FILE1 2>&1 | grep -q "no stripe" || error "$FILE1 has an EA"
5739         $GETSTRIPE $FILEN 2>&1 | grep -q "no stripe" || error "$FILEN has an EA"
5740
5741         sync
5742         sleep 1
5743         df $dir  #make sure we get new statfs data
5744         local MDSFREE=$(do_facet $facet \
5745                 lctl get_param -n osd*.*$mdtname.kbytesfree)
5746         local MDCFREE=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
5747         echo "opening files to create objects/EAs"
5748         local FILE
5749         for FILE in `seq -f $dir/f%g 1 $FILECOUNT`; do
5750                 $OPENFILE -f O_RDWR $FILE > /dev/null 2>&1 || error "opening $FILE"
5751         done
5752
5753         # verify that files have EAs now
5754         $GETSTRIPE $FILE1 | grep -q "obdidx" || error "$FILE1 missing EA"
5755         $GETSTRIPE $FILEN | grep -q "obdidx" || error "$FILEN missing EA"
5756
5757         sleep 1  #make sure we get new statfs data
5758         df $dir
5759         local MDSFREE2=$(do_facet $facet \
5760                 lctl get_param -n osd*.*$mdtname.kbytesfree)
5761         local MDCFREE2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
5762         if [[ $MDCFREE2 -lt $((MDCFREE - 16)) ]]; then
5763                 if [ "$MDSFREE" != "$MDSFREE2" ]; then
5764                         error "MDC before $MDCFREE != after $MDCFREE2"
5765                 else
5766                         echo "MDC before $MDCFREE != after $MDCFREE2"
5767                         echo "unable to confirm if MDS has large inodes"
5768                 fi
5769         fi
5770         rm -rf $dir
5771 }
5772 run_test 57b "default LOV EAs are stored inside large inodes ==="
5773
5774 test_58() {
5775         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
5776         [ -z "$(which wiretest 2>/dev/null)" ] &&
5777                         skip_env "could not find wiretest" && return
5778         wiretest
5779 }
5780 run_test 58 "verify cross-platform wire constants =============="
5781
5782 test_59() {
5783         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
5784         echo "touch 130 files"
5785         createmany -o $DIR/f59- 130
5786         echo "rm 130 files"
5787         unlinkmany $DIR/f59- 130
5788         sync
5789         # wait for commitment of removal
5790         wait_delete_completed
5791 }
5792 run_test 59 "verify cancellation of llog records async ========="
5793
5794 TEST60_HEAD="test_60 run $RANDOM"
5795 test_60a() {
5796         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
5797         remote_mgs_nodsh && skip "remote MGS with nodsh" && return
5798         do_facet mgs "! which run-llog.sh &> /dev/null" &&
5799                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
5800                         skip_env "missing subtest run-llog.sh" && return
5801
5802         log "$TEST60_HEAD - from kernel mode"
5803         do_facet mgs "$LCTL set_param debug=warning; $LCTL dk > /dev/null"
5804         do_facet mgs "sh run-llog.sh" || error "run-llog.sh failed"
5805         do_facet mgs $LCTL dk > $TMP/$tfile
5806
5807         # LU-6388: test llog_reader
5808         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
5809         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
5810         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
5811                         skip_env "missing llog_reader" && return
5812         local fstype=$(facet_fstype mgs)
5813         [ $fstype != ldiskfs -a $fstype != zfs ] &&
5814                 skip_env "Only for ldiskfs or zfs type mgs" && return
5815
5816         local mntpt=$(facet_mntpt mgs)
5817         local mgsdev=$(mgsdevname 1)
5818         local fid_list
5819         local fid
5820         local rec_list
5821         local rec
5822         local rec_type
5823         local obj_file
5824         local path
5825         local seq
5826         local oid
5827         local pass=true
5828
5829         #get fid and record list
5830         fid_list=($(awk '/9_sub.*record/ { print $NF }' /$TMP/$tfile |
5831                 tail -n 4))
5832         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' /$TMP/$tfile |
5833                 tail -n 4))
5834         #remount mgs as ldiskfs or zfs type
5835         stop mgs || error "stop mgs failed"
5836         mount_fstype mgs || error "remount mgs failed"
5837         for ((i = 0; i < ${#fid_list[@]}; i++)); do
5838                 fid=${fid_list[i]}
5839                 rec=${rec_list[i]}
5840                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
5841                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
5842                 oid=$((16#$oid))
5843
5844                 case $fstype in
5845                         ldiskfs )
5846                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
5847                         zfs )
5848                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
5849                 esac
5850                 echo "obj_file is $obj_file"
5851                 do_facet mgs $llog_reader $obj_file
5852
5853                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
5854                         awk '{ print $3 }' | sed -e "s/^type=//g")
5855                 if [ $rec_type != $rec ]; then
5856                         echo "FAILED test_60a wrong record type $rec_type," \
5857                               "should be $rec"
5858                         pass=false
5859                         break
5860                 fi
5861
5862                 #check obj path if record type is LLOG_LOGID_MAGIC
5863                 if [ "$rec" == "1064553b" ]; then
5864                         path=$(do_facet mgs $llog_reader $obj_file |
5865                                 grep "path=" | awk '{ print $NF }' |
5866                                 sed -e "s/^path=//g")
5867                         if [ $obj_file != $mntpt/$path ]; then
5868                                 echo "FAILED test_60a wrong obj path" \
5869                                       "$montpt/$path, should be $obj_file"
5870                                 pass=false
5871                                 break
5872                         fi
5873                 fi
5874         done
5875         rm -f $TMP/$tfile
5876         #restart mgs before "error", otherwise it will block the next test
5877         stop mgs || error "stop mgs failed"
5878         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
5879         $pass || error "test failed, see FAILED test_60a messages for specifics"
5880 }
5881 run_test 60a "llog_test run from kernel module and test llog_reader"
5882
5883 test_60aa() {
5884         # test old logid format
5885         if [ $(lustre_version_code mgs) -le $(version_code 3.1.53) ]; then
5886                 do_facet mgs $LCTL dl | grep MGS
5887                 do_facet mgs "$LCTL --device %MGS llog_print \\\\\\\$$FSNAME-client" ||
5888                         error "old llog_print failed"
5889         fi
5890
5891         # test new logid format
5892         if [ $(lustre_version_code mgs) -ge $(version_code 2.9.53) ]; then
5893                 do_facet mgs "$LCTL --device MGS llog_print $FSNAME-client" ||
5894                         error "new llog_print failed"
5895         fi
5896 }
5897 run_test 60aa "llog_print works with FIDs and simple names"
5898
5899 test_60b() { # bug 6411
5900         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
5901         dmesg > $DIR/$tfile
5902         LLOG_COUNT=$(dmesg | awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
5903                                 /llog.test/ {
5904                                         if (marker)
5905                                                 from_marker++
5906                                         from_begin++
5907                                 }
5908                                 END {
5909                                         if (marker)
5910                                                 print from_marker
5911                                         else
5912                                                 print from_begin
5913                                 }")
5914         [[ $LLOG_COUNT -gt 100 ]] &&
5915                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
5916 }
5917 run_test 60b "limit repeated messages from CERROR/CWARN ========"
5918
5919 test_60c() {
5920         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
5921         echo "create 5000 files"
5922         createmany -o $DIR/f60c- 5000
5923 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
5924         lctl set_param fail_loc=0x80000137
5925         unlinkmany $DIR/f60c- 5000
5926         lctl set_param fail_loc=0
5927 }
5928 run_test 60c "unlink file when mds full"
5929
5930 test_60d() {
5931         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
5932         SAVEPRINTK=$(lctl get_param -n printk)
5933
5934         # verify "lctl mark" is even working"
5935         MESSAGE="test message ID $RANDOM $$"
5936         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
5937         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
5938
5939         lctl set_param printk=0 || error "set lnet.printk failed"
5940         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
5941         MESSAGE="new test message ID $RANDOM $$"
5942         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
5943         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
5944         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
5945
5946         lctl set_param -n printk="$SAVEPRINTK"
5947 }
5948 run_test 60d "test printk console message masking"
5949
5950 test_60e() {
5951         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
5952         remote_mds_nodsh && skip "remote MDS with nodsh" && return
5953         touch $DIR/$tfile
5954 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
5955         do_facet mds1 lctl set_param fail_loc=0x15b
5956         rm $DIR/$tfile
5957 }
5958 run_test 60e "no space while new llog is being created"
5959
5960 test_61() {
5961         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
5962         f="$DIR/f61"
5963         dd if=/dev/zero of=$f bs=$(page_size) count=1 || error "dd $f failed"
5964         cancel_lru_locks osc
5965         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
5966         sync
5967 }
5968 run_test 61 "mmap() writes don't make sync hang ================"
5969
5970 # bug 2330 - insufficient obd_match error checking causes LBUG
5971 test_62() {
5972         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
5973         f="$DIR/f62"
5974         echo foo > $f
5975         cancel_lru_locks osc
5976         lctl set_param fail_loc=0x405
5977         cat $f && error "cat succeeded, expect -EIO"
5978         lctl set_param fail_loc=0
5979 }
5980 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
5981 # match every page all of the time.
5982 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
5983
5984 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
5985 # Though this test is irrelevant anymore, it helped to reveal some
5986 # other grant bugs (LU-4482), let's keep it.
5987 test_63a() {   # was test_63
5988         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
5989         MAX_DIRTY_MB=`lctl get_param -n osc.*.max_dirty_mb | head -n 1`
5990         for i in `seq 10` ; do
5991                 dd if=/dev/zero of=$DIR/f63 bs=8k &
5992                 sleep 5
5993                 kill $!
5994                 sleep 1
5995         done
5996
5997         rm -f $DIR/f63 || true
5998 }
5999 run_test 63a "Verify oig_wait interruption does not crash ======="
6000
6001 # bug 2248 - async write errors didn't return to application on sync
6002 # bug 3677 - async write errors left page locked
6003 test_63b() {
6004         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
6005         debugsave
6006         lctl set_param debug=-1
6007
6008         # ensure we have a grant to do async writes
6009         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
6010         rm $DIR/$tfile
6011
6012         sync    # sync lest earlier test intercept the fail_loc
6013
6014         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
6015         lctl set_param fail_loc=0x80000406
6016         $MULTIOP $DIR/$tfile Owy && \
6017                 error "sync didn't return ENOMEM"
6018         sync; sleep 2; sync     # do a real sync this time to flush page
6019         lctl get_param -n llite.*.dump_page_cache | grep locked && \
6020                 error "locked page left in cache after async error" || true
6021         debugrestore
6022 }
6023 run_test 63b "async write errors should be returned to fsync ==="
6024
6025 test_64a () {
6026         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
6027         df $DIR
6028         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur* | grep "[0-9]"
6029 }
6030 run_test 64a "verify filter grant calculations (in kernel) ====="
6031
6032 test_64b () {
6033         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
6034         sh oos.sh $MOUNT || error "oos.sh failed: $?"
6035 }
6036 run_test 64b "check out-of-space detection on client"
6037
6038 test_64c() {
6039         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
6040 }
6041 run_test 64c "verify grant shrink"
6042
6043 # this does exactly what osc_request.c:osc_announce_cached() does in
6044 # order to calculate max amount of grants to ask from server
6045 want_grant() {
6046         local tgt=$1
6047
6048         local page_size=$(get_page_size client)
6049
6050         local nrpages=$($LCTL get_param -n osc.${tgt}.max_pages_per_rpc)
6051         local rpc_in_flight=$($LCTL get_param -n osc.${tgt}.max_rpcs_in_flight)
6052
6053         ((rpc_in_flight ++));
6054         nrpages=$((nrpages * rpc_in_flight))
6055
6056         local dirty_max_pages=$($LCTL get_param -n osc.${tgt}.max_dirty_mb)
6057
6058         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / page_size))
6059
6060         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
6061         local undirty=$((nrpages * page_size))
6062
6063         local max_extent_pages
6064         max_extent_pages=$($LCTL get_param osc.${tgt}.import |
6065             grep grant_max_extent_size | awk '{print $2}')
6066         max_extent_pages=$((max_extent_pages / page_size))
6067         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
6068         local grant_extent_tax
6069         grant_extent_tax=$($LCTL get_param osc.${tgt}.import |
6070             grep grant_extent_tax | awk '{print $2}')
6071
6072         undirty=$((undirty + nrextents * grant_extent_tax))
6073
6074         echo $undirty
6075 }
6076
6077 # this is size of unit for grant allocation. It should be equal to
6078 # what tgt_grant.c:tgt_grant_chunk() calculates
6079 grant_chunk() {
6080         local tgt=$1
6081         local max_brw_size
6082         local grant_extent_tax
6083
6084         max_brw_size=$($LCTL get_param osc.${tgt}.import |
6085             grep max_brw_size | awk '{print $2}')
6086
6087         grant_extent_tax=$($LCTL get_param osc.${tgt}.import |
6088             grep grant_extent_tax | awk '{print $2}')
6089
6090         echo $(((max_brw_size + grant_extent_tax) * 2))
6091 }
6092
6093 test_64d() {
6094         [ $(lustre_version_code ost1) -lt $(version_code 2.10.56) ] &&
6095                 skip "OST < 2.10.55 doesn't limit grants enough" && return 0
6096
6097         local tgt=$($LCTL dl | grep "0000-osc-[^mM]" | awk '{print $4}')
6098
6099         [[ $($LCTL get_param osc.${tgt}.import |
6100                     grep "connect_flags:.*grant_param") ]] || \
6101                         { skip "no grant_param connect flag"; return; }
6102
6103         local olddebug=$($LCTL get_param -n debug 2> /dev/null)
6104
6105         $LCTL set_param debug="$OLDDEBUG" 2> /dev/null || true
6106
6107         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
6108
6109         $SETSTRIPE $DIR/$tfile -i 0 -c 1
6110         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
6111         ddpid=$!
6112
6113         while true
6114         do
6115                 local cur_grant=$($LCTL get_param -n osc.${tgt}.cur_grant_bytes)
6116                 if [[ $cur_grant -gt $max_cur_granted ]]
6117                 then
6118                         kill $ddpid
6119                         error "cur_grant $cur_grant > $max_cur_granted"
6120                 fi
6121                 kill -0 $ddpid
6122                 [[ $? -ne 0 ]] && break;
6123                 sleep 2
6124         done
6125         $LCTL set_param debug="$olddebug" 2> /dev/null || true
6126 }
6127 run_test 64d "check grant limit exceed"
6128
6129 # bug 1414 - set/get directories' stripe info
6130 test_65a() {
6131         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
6132         test_mkdir $DIR/$tdir
6133         touch $DIR/$tdir/f1
6134         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
6135 }
6136 run_test 65a "directory with no stripe info"
6137
6138 test_65b() {
6139         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
6140         test_mkdir $DIR/$tdir
6141         local STRIPESIZE=$($GETSTRIPE -S $DIR/$tdir)
6142
6143         $SETSTRIPE -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
6144                                                 error "setstripe"
6145         touch $DIR/$tdir/f2
6146         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
6147 }
6148 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
6149
6150 test_65c() {
6151         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
6152         [ $OSTCOUNT -lt 2 ] && skip "need at least 2 OSTs" && return
6153         test_mkdir $DIR/$tdir
6154         local stripesize=$($GETSTRIPE -S $DIR/$tdir)
6155
6156         $LFS setstripe -S $((stripesize * 4)) -i 1 \
6157                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
6158         touch $DIR/$tdir/f3
6159         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
6160 }
6161 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
6162
6163 test_65d() {
6164         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
6165         test_mkdir $DIR/$tdir
6166         local STRIPECOUNT=$($GETSTRIPE -c $DIR/$tdir)
6167         local STRIPESIZE=$($GETSTRIPE -S $DIR/$tdir)
6168
6169         if [[ $STRIPECOUNT -le 0 ]]; then
6170                 sc=1
6171         elif [[ $STRIPECOUNT -gt 2000 ]]; then
6172 #LOV_MAX_STRIPE_COUNT is 2000
6173                 [[ $OSTCOUNT -gt 2000 ]] && sc=2000 || sc=$(($OSTCOUNT - 1))
6174         else
6175                 sc=$(($STRIPECOUNT - 1))
6176         fi
6177         $SETSTRIPE -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
6178         touch $DIR/$tdir/f4 $DIR/$tdir/f5
6179         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
6180                 error "lverify failed"
6181 }
6182 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
6183
6184 test_65e() {
6185         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
6186         test_mkdir $DIR/$tdir
6187
6188         $SETSTRIPE $DIR/$tdir || error "setstripe"
6189         $GETSTRIPE -v $DIR/$tdir | grep "Default" ||
6190                                         error "no stripe info failed"
6191         touch $DIR/$tdir/f6
6192         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
6193 }
6194 run_test 65e "directory setstripe defaults"
6195
6196 test_65f() {
6197         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
6198         test_mkdir $DIR/${tdir}f
6199         $RUNAS $SETSTRIPE $DIR/${tdir}f && error "setstripe succeeded" || true
6200 }
6201 run_test 65f "dir setstripe permission (should return error) ==="
6202
6203 test_65g() {
6204         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
6205         test_mkdir $DIR/$tdir
6206         local STRIPESIZE=$($GETSTRIPE -S $DIR/$tdir)
6207
6208         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
6209                 error "setstripe -S failed"
6210         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
6211         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
6212                 error "delete default stripe failed"
6213 }
6214 run_test 65g "directory setstripe -d"
6215
6216 test_65h() {
6217         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
6218         test_mkdir $DIR/$tdir
6219         local STRIPESIZE=$($GETSTRIPE -S $DIR/$tdir)
6220
6221         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
6222                 error "setstripe -S failed"
6223         test_mkdir $DIR/$tdir/dd1
6224         [ $($LFS getstripe -c $DIR/$tdir) = $($GETSTRIPE -c $DIR/$tdir/dd1) ] ||
6225                 error "stripe info inherit failed"
6226 }
6227 run_test 65h "directory stripe info inherit ===================="
6228
6229 test_65i() { # bug6367
6230         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
6231         $SETSTRIPE -S 65536 -c -1 $MOUNT
6232 }
6233 run_test 65i "set non-default striping on root directory (bug 6367)="
6234
6235 test_65ia() { # bug12836
6236         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
6237         $GETSTRIPE $MOUNT || error "getstripe $MOUNT failed"
6238 }
6239 run_test 65ia "getstripe on -1 default directory striping"
6240
6241 test_65ib() { # bug12836
6242         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
6243         $GETSTRIPE -v $MOUNT || error "getstripe -v $MOUNT failed"
6244 }
6245 run_test 65ib "getstripe -v on -1 default directory striping"
6246
6247 test_65ic() { # bug12836
6248         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
6249         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
6250 }
6251 run_test 65ic "new find on -1 default directory striping"
6252
6253 test_65j() { # bug6367
6254         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
6255         [ $($LFS getstripe --component-count $MOUNT) -gt 1 ] &&
6256                 skip "don't delete default PFL layout" && return
6257         sync; sleep 1
6258         # if we aren't already remounting for each test, do so for this test
6259         if [ "$CLEANUP" = ":" -a "$I_MOUNTED" = "yes" ]; then
6260                 cleanup || error "failed to unmount"
6261                 setup
6262         fi
6263         $SETSTRIPE -d $MOUNT || error "setstripe failed"
6264 }
6265 run_test 65j "set default striping on root directory (bug 6367)="
6266
6267 test_65k() { # bug11679
6268         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
6269         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs" && return
6270         remote_mds_nodsh && skip "remote MDS with nodsh" && return
6271
6272         local disable_precreate=true
6273         [ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.8.54) ] &&
6274                 disable_precreate=false
6275
6276         echo "Check OST status: "
6277         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
6278                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
6279
6280         for OSC in $MDS_OSCS; do
6281                 echo $OSC "is active"
6282                 do_facet $SINGLEMDS lctl --device %$OSC activate
6283         done
6284
6285         for INACTIVE_OSC in $MDS_OSCS; do
6286                 local ost=$(osc_to_ost $INACTIVE_OSC)
6287                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
6288                                lov.*md*.target_obd |
6289                                awk -F: /$ost/'{ print $1 }' | head -n 1)
6290
6291                 mkdir -p $DIR/$tdir
6292                 $SETSTRIPE -i $ostnum -c 1 $DIR/$tdir
6293                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
6294
6295                 echo "Deactivate: " $INACTIVE_OSC
6296                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
6297
6298                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
6299                               osp.$ost*MDT0000.create_count")
6300                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
6301                                   osp.$ost*MDT0000.max_create_count")
6302                 $disable_precreate &&
6303                         do_facet $SINGLEMDS "lctl set_param -n \
6304                                 osp.$ost*MDT0000.max_create_count=0"
6305
6306                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
6307                         [ -f $DIR/$tdir/$idx ] && continue
6308                         echo "$SETSTRIPE -i $idx -c 1 $DIR/$tdir/$idx"
6309                         $SETSTRIPE -i $idx -c 1 $DIR/$tdir/$idx ||
6310                                 error "setstripe $idx should succeed"
6311                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
6312                 done
6313                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
6314                 rmdir $DIR/$tdir
6315
6316                 do_facet $SINGLEMDS "lctl set_param -n \
6317                         osp.$ost*MDT0000.max_create_count=$max_count"
6318                 do_facet $SINGLEMDS "lctl set_param -n \
6319                         osp.$ost*MDT0000.create_count=$count"
6320                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
6321                 echo $INACTIVE_OSC "is Activate"
6322
6323                 wait_osc_import_state mds ost$ostnum FULL
6324         done
6325 }
6326 run_test 65k "validate manual striping works properly with deactivated OSCs"
6327
6328 test_65l() { # bug 12836
6329         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
6330         test_mkdir -p $DIR/$tdir/test_dir
6331         $SETSTRIPE -c -1 $DIR/$tdir/test_dir
6332         $LFS find -mtime -1 $DIR/$tdir >/dev/null
6333 }
6334 run_test 65l "lfs find on -1 stripe dir ========================"
6335
6336 test_65m() {
6337         $RUNAS $SETSTRIPE -c 2 $MOUNT && error "setstripe should fail"
6338         true
6339 }
6340 run_test 65m "normal user can't set filesystem default stripe"
6341
6342 # bug 2543 - update blocks count on client
6343 test_66() {
6344         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
6345         COUNT=${COUNT:-8}
6346         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
6347         sync; sync_all_data; sync; sync_all_data
6348         cancel_lru_locks osc
6349         BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
6350         [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
6351 }
6352 run_test 66 "update inode blocks count on client ==============="
6353
6354 meminfo() {
6355         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
6356 }
6357
6358 swap_used() {
6359         swapon -s | awk '($1 == "'$1'") { print $4 }'
6360 }
6361
6362 # bug5265, obdfilter oa2dentry return -ENOENT
6363 # #define OBD_FAIL_SRV_ENOENT 0x217
6364 test_69() {
6365         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
6366         remote_ost_nodsh && skip "remote OST with nodsh" && return
6367
6368         f="$DIR/$tfile"
6369         $SETSTRIPE -c 1 -i 0 $f
6370
6371         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
6372
6373         do_facet ost1 lctl set_param fail_loc=0x217
6374         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
6375         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
6376
6377         do_facet ost1 lctl set_param fail_loc=0
6378         $DIRECTIO write $f 0 2 || error "write error"
6379
6380         cancel_lru_locks osc
6381         $DIRECTIO read $f 0 1 || error "read error"
6382
6383         do_facet ost1 lctl set_param fail_loc=0x217
6384         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
6385
6386         do_facet ost1 lctl set_param fail_loc=0
6387         rm -f $f
6388 }
6389 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
6390
6391 test_71() {
6392         test_mkdir $DIR/$tdir
6393         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
6394         sh rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
6395 }
6396 run_test 71 "Running dbench on lustre (don't segment fault) ===="
6397
6398 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
6399         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
6400         [ "$RUNAS_ID" = "$UID" ] &&
6401                 skip_env "RUNAS_ID = UID = $UID -- skipping" && return
6402
6403         # Check that testing environment is properly set up. Skip if not
6404         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS || {
6405                 skip_env "User $RUNAS_ID does not exist - skipping"
6406                 return 0
6407         }
6408         touch $DIR/$tfile
6409         chmod 777 $DIR/$tfile
6410         chmod ug+s $DIR/$tfile
6411         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
6412                 error "$RUNAS dd $DIR/$tfile failed"
6413         # See if we are still setuid/sgid
6414         test -u $DIR/$tfile -o -g $DIR/$tfile &&
6415                 error "S/gid is not dropped on write"
6416         # Now test that MDS is updated too
6417         cancel_lru_locks mdc
6418         test -u $DIR/$tfile -o -g $DIR/$tfile &&
6419                 error "S/gid is not dropped on MDS"
6420         rm -f $DIR/$tfile
6421 }
6422 run_test 72a "Test that remove suid works properly (bug5695) ===="
6423
6424 test_72b() { # bug 24226 -- keep mode setting when size is not changing
6425         local perm
6426
6427         [ "$RUNAS_ID" = "$UID" ] && \
6428                 skip_env "RUNAS_ID = UID = $UID -- skipping" && return
6429         [ "$RUNAS_ID" -eq 0 ] && \
6430                 skip_env "RUNAS_ID = 0 -- skipping" && return
6431
6432         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
6433         # Check that testing environment is properly set up. Skip if not
6434         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS || {
6435                 skip_env "User $RUNAS_ID does not exist - skipping"
6436                 return 0
6437         }
6438         touch $DIR/${tfile}-f{g,u}
6439         test_mkdir $DIR/${tfile}-dg
6440         test_mkdir $DIR/${tfile}-du
6441         chmod 770 $DIR/${tfile}-{f,d}{g,u}
6442         chmod g+s $DIR/${tfile}-{f,d}g
6443         chmod u+s $DIR/${tfile}-{f,d}u
6444         for perm in 777 2777 4777; do
6445                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
6446                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
6447                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
6448                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
6449         done
6450         true
6451 }
6452 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
6453
6454 # bug 3462 - multiple simultaneous MDC requests
6455 test_73() {
6456         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
6457         test_mkdir $DIR/d73-1
6458         test_mkdir $DIR/d73-2
6459         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
6460         pid1=$!
6461
6462         lctl set_param fail_loc=0x80000129
6463         $MULTIOP $DIR/d73-1/f73-2 Oc &
6464         sleep 1
6465         lctl set_param fail_loc=0
6466
6467         $MULTIOP $DIR/d73-2/f73-3 Oc &
6468         pid3=$!
6469
6470         kill -USR1 $pid1
6471         wait $pid1 || return 1
6472
6473         sleep 25
6474
6475         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
6476         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
6477         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
6478
6479         rm -rf $DIR/d73-*
6480 }
6481 run_test 73 "multiple MDC requests (should not deadlock)"
6482
6483 test_74a() { # bug 6149, 6184
6484         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
6485         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
6486         #
6487         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
6488         # will spin in a tight reconnection loop
6489         touch $DIR/f74a
6490         $LCTL set_param fail_loc=0x8000030e
6491         # get any lock that won't be difficult - lookup works.
6492         ls $DIR/f74a
6493         $LCTL set_param fail_loc=0
6494         rm -f $DIR/f74a
6495         true
6496 }
6497 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
6498
6499 test_74b() { # bug 13310
6500         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
6501         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
6502         #
6503         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
6504         # will spin in a tight reconnection loop
6505         $LCTL set_param fail_loc=0x8000030e
6506         # get a "difficult" lock
6507         touch $DIR/f74b
6508         $LCTL set_param fail_loc=0
6509         rm -f $DIR/f74b
6510         true
6511 }
6512 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
6513
6514 test_74c() {
6515         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
6516         #define OBD_FAIL_LDLM_NEW_LOCK
6517         $LCTL set_param fail_loc=0x319
6518         touch $DIR/$tfile && error "touch successful"
6519         $LCTL set_param fail_loc=0
6520         true
6521 }
6522 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
6523
6524 num_inodes() {
6525         awk '/lustre_inode_cache/ {print $2; exit}' /proc/slabinfo
6526 }
6527
6528 test_76() { # Now for bug 20433, added originally in bug 1443
6529         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
6530         local CPUS=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
6531         cancel_lru_locks osc
6532         BEFORE_INODES=$(num_inodes)
6533         echo "before inodes: $BEFORE_INODES"
6534         local COUNT=1000
6535         [ "$SLOW" = "no" ] && COUNT=100
6536         for i in $(seq $COUNT); do
6537                 touch $DIR/$tfile
6538                 rm -f $DIR/$tfile
6539         done
6540         cancel_lru_locks osc
6541         AFTER_INODES=$(num_inodes)
6542         echo "after inodes: $AFTER_INODES"
6543         local wait=0
6544         while [[ $((AFTER_INODES-1*${CPUS:-1})) -gt $BEFORE_INODES ]]; do
6545                 sleep 2
6546                 AFTER_INODES=$(num_inodes)
6547                 wait=$((wait+2))
6548                 echo "wait $wait seconds inodes: $AFTER_INODES"
6549                 if [ $wait -gt 30 ]; then
6550                         error "inode slab grew from $BEFORE_INODES to $AFTER_INODES"
6551                 fi
6552         done
6553 }
6554 run_test 76 "confirm clients recycle inodes properly ===="
6555
6556
6557 export ORIG_CSUM=""
6558 set_checksums()
6559 {
6560         # Note: in sptlrpc modes which enable its own bulk checksum, the
6561         # original crc32_le bulk checksum will be automatically disabled,
6562         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
6563         # will be checked by sptlrpc code against sptlrpc bulk checksum.
6564         # In this case set_checksums() will not be no-op, because sptlrpc
6565         # bulk checksum will be enabled all through the test.
6566
6567         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
6568         lctl set_param -n osc.*.checksums $1
6569         return 0
6570 }
6571
6572 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
6573                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
6574 CKSUM_TYPES=${CKSUM_TYPES:-"crc32 adler"}
6575 [ "$ORIG_CSUM_TYPE" = "crc32c" ] && CKSUM_TYPES="$CKSUM_TYPES crc32c"
6576 set_checksum_type()
6577 {
6578         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
6579         log "set checksum type to $1"
6580         return 0
6581 }
6582 F77_TMP=$TMP/f77-temp
6583 F77SZ=8
6584 setup_f77() {
6585         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
6586                 error "error writing to $F77_TMP"
6587 }
6588
6589 test_77a() { # bug 10889
6590         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
6591         $GSS && skip "could not run with gss" && return
6592         [ ! -f $F77_TMP ] && setup_f77
6593         set_checksums 1
6594         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
6595         set_checksums 0
6596         rm -f $DIR/$tfile
6597 }
6598 run_test 77a "normal checksum read/write operation"
6599
6600 test_77b() { # bug 10889
6601         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
6602         $GSS && skip "could not run with gss" && return
6603         [ ! -f $F77_TMP ] && setup_f77
6604         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
6605         $LCTL set_param fail_loc=0x80000409
6606         set_checksums 1
6607
6608         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
6609                 error "dd error: $?"
6610         $LCTL set_param fail_loc=0
6611
6612         for algo in $CKSUM_TYPES; do
6613                 cancel_lru_locks osc
6614                 set_checksum_type $algo
6615                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
6616                 $LCTL set_param fail_loc=0x80000408
6617                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
6618                 $LCTL set_param fail_loc=0
6619         done
6620         set_checksums 0
6621         set_checksum_type $ORIG_CSUM_TYPE
6622         rm -f $DIR/$tfile
6623 }
6624 run_test 77b "checksum error on client write, read"
6625
6626 cleanup_77c() {
6627         trap 0
6628         set_checksums 0
6629         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
6630         $check_ost &&
6631                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
6632         [ -n $osc_file_prefix ] && rm -f ${osc_file_prefix}*
6633         $check_ost && [ -n $ost_file_prefix ] &&
6634                 do_facet ost1 rm -f ${ost_file_prefix}\*
6635 }
6636
6637 test_77c() {
6638         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
6639         $GSS && skip "could not run with gss" && return
6640
6641         local bad1
6642         local osc_file_prefix
6643         local osc_file
6644         local check_ost=false
6645         local ost_file_prefix
6646         local ost_file
6647         local orig_cksum
6648         local dump_cksum
6649         local fid
6650
6651         # ensure corruption will occur on first OSS/OST
6652         $LFS setstripe -i 0 $DIR/$tfile
6653
6654         [ ! -f $F77_TMP ] && setup_f77
6655         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
6656                 error "dd write error: $?"
6657         fid=$($LFS path2fid $DIR/$tfile)
6658
6659         if [ $(lustre_version_code ost1) -ge $(version_code 2.9.57) ]
6660         then
6661                 check_ost=true
6662                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
6663                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
6664         else
6665                 echo "OSS do not support bulk pages dump upon error"
6666         fi
6667
6668         osc_file_prefix=$($LCTL get_param -n debug_path)
6669         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
6670
6671         trap cleanup_77c EXIT
6672
6673         set_checksums 1
6674         # enable bulk pages dump upon error on Client
6675         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
6676         # enable bulk pages dump upon error on OSS
6677         $check_ost &&
6678                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
6679
6680         # flush Client cache to allow next read to reach OSS
6681         cancel_lru_locks osc
6682
6683         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
6684         $LCTL set_param fail_loc=0x80000408
6685         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
6686         $LCTL set_param fail_loc=0
6687
6688         rm -f $DIR/$tfile
6689
6690         # check cksum dump on Client
6691         osc_file=$(ls ${osc_file_prefix}*)
6692         [ -n "$osc_file" ] || error "no checksum dump file on Client"
6693         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
6694         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
6695         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
6696         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
6697                      cksum)
6698         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
6699         [[ "$orig_cksum" == "$dump_cksum" ]] ||
6700                 error "dump content does not match on Client"
6701
6702         $check_ost || { skip "No need to check cksum dump on OSS"; return 0; }
6703
6704         # check cksum dump on OSS
6705         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
6706         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
6707         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
6708         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
6709         [[ "$orig_cksum" == "$dump_cksum" ]] ||
6710                 error "dump content does not match on OSS"
6711
6712         cleanup_77c
6713 }
6714 run_test 77c "checksum error on client read with debug"
6715
6716 test_77d() { # bug 10889
6717         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
6718         $GSS && skip "could not run with gss" && return
6719         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
6720         $LCTL set_param fail_loc=0x80000409
6721         set_checksums 1
6722         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
6723                 error "direct write: rc=$?"
6724         $LCTL set_param fail_loc=0
6725         set_checksums 0
6726
6727         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
6728         $LCTL set_param fail_loc=0x80000408
6729         set_checksums 1
6730         cancel_lru_locks osc
6731         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
6732                 error "direct read: rc=$?"
6733         $LCTL set_param fail_loc=0
6734         set_checksums 0
6735 }
6736 run_test 77d "checksum error on OST direct write, read"
6737
6738 test_77f() { # bug 10889
6739         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
6740         $GSS && skip "could not run with gss" && return
6741         set_checksums 1
6742         for algo in $CKSUM_TYPES; do
6743                 cancel_lru_locks osc
6744                 set_checksum_type $algo
6745                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
6746                 $LCTL set_param fail_loc=0x409
6747                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
6748                         error "direct write succeeded"
6749                 $LCTL set_param fail_loc=0
6750         done
6751         set_checksum_type $ORIG_CSUM_TYPE
6752         set_checksums 0
6753 }
6754 run_test 77f "repeat checksum error on write (expect error)"
6755
6756 test_77g() { # bug 10889
6757         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
6758         $GSS && skip "could not run with gss" && return
6759         remote_ost_nodsh && skip "remote OST with nodsh" && return
6760
6761         [ ! -f $F77_TMP ] && setup_f77
6762
6763         $SETSTRIPE -c 1 -i 0 $DIR/$tfile
6764         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
6765         do_facet ost1 lctl set_param fail_loc=0x8000021a
6766         set_checksums 1
6767         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ ||
6768                 error "write error: rc=$?"
6769         do_facet ost1 lctl set_param fail_loc=0
6770         set_checksums 0
6771
6772         cancel_lru_locks osc
6773         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
6774         do_facet ost1 lctl set_param fail_loc=0x8000021b
6775         set_checksums 1
6776         cmp $F77_TMP $DIR/$tfile || error "file compare failed"
6777         do_facet ost1 lctl set_param fail_loc=0
6778         set_checksums 0
6779 }
6780 run_test 77g "checksum error on OST write, read"
6781
6782 test_77j() { # bug 13805
6783         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
6784         $GSS && skip "could not run with gss" && return
6785         #define OBD_FAIL_OSC_CKSUM_ADLER_ONLY    0x40c
6786         lctl set_param fail_loc=0x40c
6787         remount_client $MOUNT
6788         lctl set_param fail_loc=0
6789         # wait async osc connect to finish and reflect updated state value
6790         local i
6791         for (( i=0; i < OSTCOUNT; i++ )) ; do
6792                 wait_osc_import_state client ost$((i+1)) FULL
6793         done
6794
6795         for VALUE in $(lctl get_param osc.*osc-[^mM]*.checksum_type); do
6796                 PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
6797                 algo=$(lctl get_param -n $PARAM | sed 's/.*\[\(.*\)\].*/\1/g')
6798                 [ "$algo" = "adler" ] || error "algo set to $algo instead of adler"
6799         done
6800         remount_client $MOUNT
6801 }
6802 run_test 77j "client only supporting ADLER32"
6803
6804 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
6805 rm -f $F77_TMP
6806 unset F77_TMP
6807
6808 cleanup_test_78() {
6809         trap 0
6810         rm -f $DIR/$tfile
6811 }
6812
6813 test_78() { # bug 10901
6814         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
6815         remote_ost || { skip_env "local OST" && return; }
6816
6817         NSEQ=5
6818         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
6819         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
6820         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
6821         echo "MemTotal: $MEMTOTAL"
6822
6823         # reserve 256MB of memory for the kernel and other running processes,
6824         # and then take 1/2 of the remaining memory for the read/write buffers.
6825         if [ $MEMTOTAL -gt 512 ] ;then
6826                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
6827         else
6828                 # for those poor memory-starved high-end clusters...
6829                 MEMTOTAL=$((MEMTOTAL / 2))
6830         fi
6831         echo "Mem to use for directio: $MEMTOTAL"
6832
6833         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
6834         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
6835         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
6836         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
6837                 head -n1)
6838         echo "Smallest OST: $SMALLESTOST"
6839         [[ $SMALLESTOST -lt 10240 ]] &&
6840                 skip "too small OSTSIZE, useless to run large O_DIRECT test" && return 0
6841
6842         trap cleanup_test_78 EXIT
6843
6844         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
6845                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
6846
6847         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
6848         echo "File size: $F78SIZE"
6849         $SETSTRIPE -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
6850         for i in $(seq 1 $NSEQ); do
6851                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
6852                 echo directIO rdwr round $i of $NSEQ
6853                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
6854         done
6855
6856         cleanup_test_78
6857 }
6858 run_test 78 "handle large O_DIRECT writes correctly ============"
6859
6860 test_79() { # bug 12743
6861         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
6862         wait_delete_completed
6863
6864         BKTOTAL=$(calc_osc_kbytes kbytestotal)
6865         BKFREE=$(calc_osc_kbytes kbytesfree)
6866         BKAVAIL=$(calc_osc_kbytes kbytesavail)
6867
6868         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
6869         DFTOTAL=`echo $STRING | cut -d, -f1`
6870         DFUSED=`echo $STRING  | cut -d, -f2`
6871         DFAVAIL=`echo $STRING | cut -d, -f3`
6872         DFFREE=$(($DFTOTAL - $DFUSED))
6873
6874         ALLOWANCE=$((64 * $OSTCOUNT))
6875
6876         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
6877            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
6878                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
6879         fi
6880         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
6881            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
6882                 error "df free($DFFREE) mismatch OST free($BKFREE)"
6883         fi
6884         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
6885            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
6886                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
6887         fi
6888 }
6889 run_test 79 "df report consistency check ======================="
6890
6891 test_80() { # bug 10718
6892         remote_ost_nodsh && skip "remote OST with nodsh" && return
6893         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
6894         # relax strong synchronous semantics for slow backends like ZFS
6895         local soc="obdfilter.*.sync_on_lock_cancel"
6896         local soc_old=$(do_facet ost1 lctl get_param -n $soc | head -n1)
6897         local hosts=
6898         if [ "$soc_old" != "never" -a "$(facet_fstype ost1)" != "ldiskfs" ]; then
6899                 hosts=$(for host in $(seq -f "ost%g" 1 $OSTCOUNT); do
6900                           facet_active_host $host; done | sort -u)
6901                 do_nodes $hosts lctl set_param $soc=never
6902         fi
6903
6904         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
6905         sync; sleep 1; sync
6906         local BEFORE=`date +%s`
6907         cancel_lru_locks osc
6908         local AFTER=`date +%s`
6909         local DIFF=$((AFTER-BEFORE))
6910         if [ $DIFF -gt 1 ] ; then
6911                 error "elapsed for 1M@1T = $DIFF"
6912         fi
6913
6914         [ -n "$hosts" ] && do_nodes $hosts lctl set_param $soc=$soc_old
6915
6916         rm -f $DIR/$tfile
6917 }
6918 run_test 80 "Page eviction is equally fast at high offsets too  ===="
6919
6920 test_81a() { # LU-456
6921         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
6922         remote_ost_nodsh && skip "remote OST with nodsh" && return
6923         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
6924         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
6925         do_facet ost1 lctl set_param fail_loc=0x80000228
6926
6927         # write should trigger a retry and success
6928         $SETSTRIPE -i 0 -c 1 $DIR/$tfile
6929         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
6930         RC=$?
6931         if [ $RC -ne 0 ] ; then
6932                 error "write should success, but failed for $RC"
6933         fi
6934 }
6935 run_test 81a "OST should retry write when get -ENOSPC ==============="
6936
6937 test_81b() { # LU-456
6938         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
6939         remote_ost_nodsh && skip "remote OST with nodsh" && return
6940         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
6941         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
6942         do_facet ost1 lctl set_param fail_loc=0x228
6943
6944         # write should retry several times and return -ENOSPC finally
6945         $SETSTRIPE -i 0 -c 1 $DIR/$tfile
6946         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
6947         RC=$?
6948         ENOSPC=28
6949         if [ $RC -ne $ENOSPC ] ; then
6950                 error "dd should fail for -ENOSPC, but succeed."
6951         fi
6952 }
6953 run_test 81b "OST should return -ENOSPC when retry still fails ======="
6954
6955 test_82() { # LU-1031
6956         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10
6957         local gid1=14091995
6958         local gid2=16022000
6959
6960         multiop_bg_pause $DIR/$tfile OG${gid1}_g${gid1}c || return 1
6961         local MULTIPID1=$!
6962         multiop_bg_pause $DIR/$tfile O_G${gid2}r10g${gid2}c || return 2
6963         local MULTIPID2=$!
6964         kill -USR1 $MULTIPID2
6965         sleep 2
6966         if [[ `ps h -o comm -p $MULTIPID2` == "" ]]; then
6967                 error "First grouplock does not block second one"
6968         else
6969                 echo "Second grouplock blocks first one"
6970         fi
6971         kill -USR1 $MULTIPID1
6972         wait $MULTIPID1
6973         wait $MULTIPID2
6974 }
6975 run_test 82 "Basic grouplock test"
6976
6977 test_83() {
6978         local sfile="/boot/System.map-$(uname -r)"
6979         # define OBD_FAIL_LLITE_PTASK_IO_FAIL 0x140d
6980         $LCTL set_param fail_loc=0x140d
6981         cp $sfile $DIR/$tfile || error "write failed"
6982         diff -c $sfile $DIR/$tfile || error "files are different"
6983         $LCTL set_param fail_loc=0
6984         rm -f $DIR/$tfile
6985 }
6986 run_test 83 "Short write in ptask ==============================="
6987
6988 test_99() {
6989         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs" &&
6990                 return
6991         test_mkdir $DIR/$tdir.cvsroot
6992         chown $RUNAS_ID $DIR/$tdir.cvsroot
6993
6994         cd $TMP
6995         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
6996
6997         cd /etc/init.d
6998         # some versions of cvs import exit(1) when asked to import links or
6999         # files they can't read.  ignore those files.
7000         local toignore=$(find . -type l -printf '-I %f\n' -o \
7001                          ! -perm /4 -printf '-I %f\n')
7002         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
7003                 $tdir.reposname vtag rtag
7004
7005         cd $DIR
7006         test_mkdir $DIR/$tdir.reposname
7007         chown $RUNAS_ID $DIR/$tdir.reposname
7008         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
7009
7010         cd $DIR/$tdir.reposname
7011         $RUNAS touch foo99
7012         $RUNAS cvs add -m 'addmsg' foo99
7013         $RUNAS cvs update
7014         $RUNAS cvs commit -m 'nomsg' foo99
7015         rm -fr $DIR/$tdir.cvsroot
7016 }
7017 run_test 99 "cvs strange file/directory operations"
7018
7019 test_100() {
7020         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
7021         [[ "$NETTYPE" =~ tcp ]] ||
7022                 { skip "TCP secure port test, not useful for NETTYPE=$NETTYPE" &&
7023                         return ; }
7024
7025         remote_ost_nodsh && skip "remote OST with nodsh" && return
7026         remote_mds_nodsh && skip "remote MDS with nodsh" && return
7027         remote_servers ||
7028                 { skip "useless for local single node setup" && return; }
7029
7030         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
7031                 [ "$PROT" != "tcp" ] && continue
7032                 RPORT=$(echo $REMOTE | cut -d: -f2)
7033                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
7034
7035                 rc=0
7036                 LPORT=`echo $LOCAL | cut -d: -f2`
7037                 if [ $LPORT -ge 1024 ]; then
7038                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
7039                         netstat -tna
7040                         error_exit "local: $LPORT > 1024, remote: $RPORT"
7041                 fi
7042         done
7043         [ "$rc" = 0 ] || error_exit "privileged port not found" )
7044 }
7045 run_test 100 "check local port using privileged port ==========="
7046
7047 function get_named_value()
7048 {
7049     local tag
7050
7051     tag=$1
7052     while read ;do
7053         line=$REPLY
7054         case $line in
7055         $tag*)
7056             echo $line | sed "s/^$tag[ ]*//"
7057             break
7058             ;;
7059         esac
7060     done
7061 }
7062
7063 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
7064                    awk '/^max_cached_mb/ { print $2 }')
7065
7066 cleanup_101a() {
7067         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
7068         trap 0
7069 }
7070
7071 test_101a() {
7072         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
7073         [ $MDSCOUNT -ge 2 ] && skip "needs < 2 MDTs" && return #LU-4322
7074         local s
7075         local discard
7076         local nreads=10000
7077         local cache_limit=32
7078
7079         $LCTL set_param -n osc.*-osc*.rpc_stats 0
7080         trap cleanup_101a EXIT
7081         $LCTL set_param -n llite.*.read_ahead_stats 0
7082         $LCTL set_param -n llite.*.max_cached_mb $cache_limit
7083
7084         #
7085         # randomly read 10000 of 64K chunks from file 3x 32MB in size
7086         #
7087         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
7088         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
7089
7090         discard=0
7091         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
7092                 get_named_value 'read but discarded' | cut -d" " -f1); do
7093                         discard=$(($discard + $s))
7094         done
7095         cleanup_101a
7096
7097         if [[ $(($discard * 10)) -gt $nreads ]]; then
7098                 $LCTL get_param osc.*-osc*.rpc_stats
7099                 $LCTL get_param llite.*.read_ahead_stats
7100                 error "too many ($discard) discarded pages"
7101         fi
7102         rm -f $DIR/$tfile || true
7103 }
7104 run_test 101a "check read-ahead for random reads"
7105
7106 setup_test101bc() {
7107         test_mkdir $DIR/$tdir
7108         local STRIPE_SIZE=$1
7109         local FILE_LENGTH=$2
7110         STRIPE_OFFSET=0
7111
7112         local FILE_SIZE_MB=$((FILE_LENGTH / STRIPE_SIZE))
7113
7114         local list=$(comma_list $(osts_nodes))
7115         set_osd_param $list '' read_cache_enable 0
7116         set_osd_param $list '' writethrough_cache_enable 0
7117
7118         trap cleanup_test101bc EXIT
7119         # prepare the read-ahead file
7120         $SETSTRIPE -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
7121
7122         dd if=/dev/zero of=$DIR/$tfile bs=$STRIPE_SIZE \
7123                                 count=$FILE_SIZE_MB 2> /dev/null
7124
7125 }
7126
7127 cleanup_test101bc() {
7128         trap 0
7129         rm -rf $DIR/$tdir
7130         rm -f $DIR/$tfile
7131
7132         local list=$(comma_list $(osts_nodes))
7133         set_osd_param $list '' read_cache_enable 1
7134         set_osd_param $list '' writethrough_cache_enable 1
7135 }
7136
7137 calc_total() {
7138         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
7139 }
7140
7141 ra_check_101() {
7142         local READ_SIZE=$1
7143         local STRIPE_SIZE=$2
7144         local FILE_LENGTH=$3
7145         local RA_INC=1048576
7146         local STRIDE_LENGTH=$((STRIPE_SIZE/READ_SIZE))
7147         local discard_limit=$((((STRIDE_LENGTH - 1)*3/(STRIDE_LENGTH*OSTCOUNT))* \
7148                              (STRIDE_LENGTH*OSTCOUNT - STRIDE_LENGTH)))
7149         DISCARD=$($LCTL get_param -n llite.*.read_ahead_stats |
7150                         get_named_value 'read but discarded' |
7151                         cut -d" " -f1 | calc_total)
7152         if [[ $DISCARD -gt $discard_limit ]]; then
7153                 $LCTL get_param llite.*.read_ahead_stats
7154                 error "Too many ($DISCARD) discarded pages with size (${READ_SIZE})"
7155         else
7156                 echo "Read-ahead success for size ${READ_SIZE}"
7157         fi
7158 }
7159
7160 test_101b() {
7161         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
7162         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs" && return
7163         local STRIPE_SIZE=1048576
7164         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
7165         if [ $SLOW == "yes" ]; then
7166                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
7167         else
7168                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
7169         fi
7170
7171         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
7172
7173         # prepare the read-ahead file
7174         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
7175         cancel_lru_locks osc
7176         for BIDX in 2 4 8 16 32 64 128 256
7177         do
7178                 local BSIZE=$((BIDX*4096))
7179                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
7180                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
7181                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
7182                 $LCTL set_param -n llite.*.read_ahead_stats 0
7183                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
7184                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
7185                 cancel_lru_locks osc
7186                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
7187         done
7188         cleanup_test101bc
7189         true
7190 }
7191 run_test 101b "check stride-io mode read-ahead ================="
7192
7193 test_101c() {
7194         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
7195         local STRIPE_SIZE=1048576
7196         local FILE_LENGTH=$((STRIPE_SIZE*100))
7197         local nreads=10000
7198         local osc_rpc_stats
7199
7200         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
7201
7202         cancel_lru_locks osc
7203         $LCTL set_param osc.*.rpc_stats 0
7204         $READS -f $DIR/$tfile -s$FILE_LENGTH -b65536 -n$nreads -t 180
7205         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
7206                 local stats=$($LCTL get_param -n $osc_rpc_stats)
7207                 local lines=$(echo "$stats" | awk 'END {print NR;}')
7208                 local size
7209
7210                 if [ $lines -le 20 ]; then
7211                         continue
7212                 fi
7213                 for size in 1 2 4 8; do
7214                         local rpc=$(echo "$stats" |
7215                                     awk '($1 == "'$size':") {print $2; exit; }')
7216                         [ $rpc != 0 ] &&
7217                                 error "Small $((size*4))k read IO $rpc !"
7218                 done
7219                 echo "$osc_rpc_stats check passed!"
7220         done
7221         cleanup_test101bc
7222         true
7223 }
7224 run_test 101c "check stripe_size aligned read-ahead ================="
7225
7226 set_read_ahead() {
7227         $LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1
7228         $LCTL set_param -n llite.*.max_read_ahead_mb $1 > /dev/null 2>&1
7229 }
7230
7231 test_101d() {
7232         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
7233         local file=$DIR/$tfile
7234         local sz_MB=${FILESIZE_101d:-500}
7235         local ra_MB=${READAHEAD_MB:-40}
7236
7237         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
7238         [ $free_MB -lt $sz_MB ] &&
7239                 skip "Need free space ${sz_MB}M, have ${free_MB}M" && return
7240
7241         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
7242         $SETSTRIPE -c -1 $file || error "setstripe failed"
7243
7244         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
7245         echo Cancel LRU locks on lustre client to flush the client cache
7246         cancel_lru_locks osc
7247
7248         echo Disable read-ahead
7249         local old_READAHEAD=$(set_read_ahead 0)
7250
7251         echo Reading the test file $file with read-ahead disabled
7252         local raOFF=$(do_and_time "dd if=$file of=/dev/null bs=1M count=$sz_MB")
7253
7254         echo Cancel LRU locks on lustre client to flush the client cache
7255         cancel_lru_locks osc
7256         echo Enable read-ahead with ${ra_MB}MB
7257         set_read_ahead $ra_MB
7258
7259         echo Reading the test file $file with read-ahead enabled
7260         local raON=$(do_and_time "dd if=$file of=/dev/null bs=1M count=$sz_MB")
7261
7262         echo "read-ahead disabled time read $raOFF"
7263         echo "read-ahead enabled  time read $raON"
7264
7265         set_read_ahead $old_READAHEAD
7266         rm -f $file
7267         wait_delete_completed
7268
7269         [ $raOFF -le 1 -o $raON -lt $raOFF ] ||
7270                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
7271 }
7272 run_test 101d "file read with and without read-ahead enabled"
7273
7274 test_101e() {
7275         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
7276         local file=$DIR/$tfile
7277         local size_KB=500  #KB
7278         local count=100
7279         local bsize=1024
7280
7281         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
7282         local need_KB=$((count * size_KB))
7283         [[ $free_KB -le $need_KB ]] &&
7284                 skip_env "Need free space $need_KB, have $free_KB" && return
7285
7286         echo "Creating $count ${size_KB}K test files"
7287         for ((i = 0; i < $count; i++)); do
7288                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
7289         done
7290
7291         echo "Cancel LRU locks on lustre client to flush the client cache"
7292         cancel_lru_locks $OSC
7293
7294         echo "Reset readahead stats"
7295         $LCTL set_param -n llite.*.read_ahead_stats 0
7296
7297         for ((i = 0; i < $count; i++)); do
7298                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
7299         done
7300
7301         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
7302                      get_named_value 'misses' | cut -d" " -f1 | calc_total)
7303
7304         for ((i = 0; i < $count; i++)); do
7305                 rm -rf $file.$i 2>/dev/null
7306         done
7307
7308         #10000 means 20% reads are missing in readahead
7309         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
7310 }
7311 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
7312
7313 test_101f() {
7314         which iozone || { skip "no iozone installed" && return; }
7315
7316         local old_debug=$($LCTL get_param debug)
7317         old_debug=${old_debug#*=}
7318         $LCTL set_param debug="reada mmap"
7319
7320         # create a test file
7321         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
7322
7323         echo Cancel LRU locks on lustre client to flush the client cache
7324         cancel_lru_locks osc
7325
7326         echo Reset readahead stats
7327         $LCTL set_param -n llite.*.read_ahead_stats 0
7328
7329         echo mmap read the file with small block size
7330         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
7331                 > /dev/null 2>&1
7332
7333         echo checking missing pages
7334         $LCTL get_param llite.*.read_ahead_stats
7335         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
7336                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
7337
7338         $LCTL set_param debug="$old_debug"
7339         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
7340         rm -f $DIR/$tfile
7341 }
7342 run_test 101f "check mmap read performance"
7343
7344 test_101g_brw_size_test() {
7345         local mb=$1
7346         local pages=$((mb * 1048576 / $(page_size)))
7347
7348         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
7349                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
7350         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
7351                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
7352                         return 2
7353         done
7354
7355         $LCTL set_param -n osc.*.rpc_stats=0
7356
7357         # 10 RPCs should be enough for the test
7358         local count=10
7359         dd if=/dev/zero of=$DIR/$tfile bs=${mb}M count=$count ||
7360                 { error "dd write ${mb} MB blocks failed"; return 3; }
7361         cancel_lru_locks osc
7362         dd of=/dev/null if=$DIR/$tfile bs=${mb}M count=$count ||
7363                 { error "dd write ${mb} MB blocks failed"; return 4; }
7364
7365         # calculate number of full-sized read and write RPCs
7366         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
7367                 sed -n '/pages per rpc/,/^$/p' |
7368                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
7369                 END { print reads,writes }'))
7370         [ ${rpcs[0]} -ne $count ] && error "${rpcs[0]} != $count read RPCs" &&
7371                 return 5
7372         [ ${rpcs[1]} -ne $count ] && error "${rpcs[1]} != $count write RPCs" &&
7373                 return 6
7374
7375         return 0
7376 }
7377
7378 test_101g() {
7379         local rpcs
7380         local osts=$(get_facets OST)
7381         local list=$(comma_list $(osts_nodes))
7382         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
7383         local brw_size="obdfilter.*.brw_size"
7384         local ostver=$(lustre_version_code ost1)
7385         local cliver=$(lustre_version_code client)
7386
7387         $LFS setstripe -i 0 -c 1 $DIR/$tfile
7388
7389         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
7390         if [ $ostver -ge $(version_code 2.8.52) -o \
7391              \( $ostver -ge $(version_code 2.7.17) -a \
7392                 $ostver -lt $(version_code 2.7.50) \) ] &&
7393            [ $cliver -ge $(version_code 2.8.52) -o \
7394              \( $cliver -ge $(version_code 2.7.17) -a \
7395                 $cliver -lt $(version_code 2.7.50) \) ]; then
7396                 [ $ostver -ge $(version_code 2.9.52) ] && suffix="M"
7397                 if [[ $orig_mb -lt 16 ]]; then
7398                         save_lustre_params $osts "$brw_size" > $p
7399                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
7400                                 error "set 16MB RPC size failed"
7401
7402                         echo "remount client to enable new RPC size"
7403                         remount_client $MOUNT || error "remount_client failed"
7404                 fi
7405
7406                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
7407                 # should be able to set brw_size=12, but no rpc_stats for that
7408                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
7409         fi
7410
7411         test_101g_brw_size_test 4 || error "4MB RPC test failed"
7412
7413         if [[ $orig_mb -lt 16 ]]; then
7414                 restore_lustre_params < $p
7415                 remount_client $MOUNT || error "remount_client restore failed"
7416         fi
7417
7418         rm -f $p $DIR/$tfile
7419 }
7420 run_test 101g "Big bulk(4/16 MiB) readahead"
7421
7422 setup_test102() {
7423         test_mkdir $DIR/$tdir
7424         chown $RUNAS_ID $DIR/$tdir
7425         STRIPE_SIZE=65536
7426         STRIPE_OFFSET=1
7427         STRIPE_COUNT=$OSTCOUNT
7428         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
7429
7430         trap cleanup_test102 EXIT
7431         cd $DIR
7432         $1 $SETSTRIPE -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
7433         cd $DIR/$tdir
7434         for num in 1 2 3 4; do
7435                 for count in $(seq 1 $STRIPE_COUNT); do
7436                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
7437                                 local size=`expr $STRIPE_SIZE \* $num`
7438                                 local file=file"$num-$idx-$count"
7439                                 $1 $SETSTRIPE -S $size -i $idx -c $count $file
7440                         done
7441                 done
7442         done
7443
7444         cd $DIR
7445         $1 tar cf $TMP/f102.tar $tdir --xattrs
7446 }
7447
7448 cleanup_test102() {
7449         trap 0
7450         rm -f $TMP/f102.tar
7451         rm -rf $DIR/d0.sanity/d102
7452 }
7453
7454 test_102a() {
7455         local testfile=$DIR/$tfile
7456
7457         touch $testfile
7458
7459         [ "$UID" != 0 ] && skip_env "must run as root" && return
7460         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
7461                 skip_env "must have user_xattr" && return
7462
7463         [ -z "$(which setfattr 2>/dev/null)" ] &&
7464                 skip_env "could not find setfattr" && return
7465
7466         echo "set/get xattr..."
7467         setfattr -n trusted.name1 -v value1 $testfile ||
7468                 error "setfattr -n trusted.name1=value1 $testfile failed"
7469         getfattr -n trusted.name1 $testfile 2> /dev/null |
7470           grep "trusted.name1=.value1" ||
7471                 error "$testfile missing trusted.name1=value1"
7472
7473         setfattr -n user.author1 -v author1 $testfile ||
7474                 error "setfattr -n user.author1=author1 $testfile failed"
7475         getfattr -n user.author1 $testfile 2> /dev/null |
7476           grep "user.author1=.author1" ||
7477                 error "$testfile missing trusted.author1=author1"
7478
7479         echo "listxattr..."
7480         setfattr -n trusted.name2 -v value2 $testfile ||
7481                 error "$testfile unable to set trusted.name2"
7482         setfattr -n trusted.name3 -v value3 $testfile ||
7483                 error "$testfile unable to set trusted.name3"
7484         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
7485             grep "trusted.name" | wc -l) -eq 3 ] ||
7486                 error "$testfile missing 3 trusted.name xattrs"
7487
7488         setfattr -n user.author2 -v author2 $testfile ||
7489                 error "$testfile unable to set user.author2"
7490         setfattr -n user.author3 -v author3 $testfile ||
7491                 error "$testfile unable to set user.author3"
7492         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
7493             grep "user.author" | wc -l) -eq 3 ] ||
7494                 error "$testfile missing 3 user.author xattrs"
7495
7496         echo "remove xattr..."
7497         setfattr -x trusted.name1 $testfile ||
7498                 error "$testfile error deleting trusted.name1"
7499         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
7500                 error "$testfile did not delete trusted.name1 xattr"
7501
7502         setfattr -x user.author1 $testfile ||
7503                 error "$testfile error deleting user.author1"
7504         echo "set lustre special xattr ..."
7505         $LFS setstripe -c1 $testfile
7506         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
7507                 awk -F "=" '/trusted.lov/ { print $2 }' )
7508         setfattr -n "trusted.lov" -v $lovea $testfile ||
7509                 error "$testfile doesn't ignore setting trusted.lov again"
7510         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
7511                 error "$testfile allow setting invalid trusted.lov"
7512         rm -f $testfile
7513 }
7514 run_test 102a "user xattr test =================================="
7515
7516 test_102b() {
7517         [ -z "$(which setfattr 2>/dev/null)" ] &&
7518                 skip_env "could not find setfattr" && return
7519
7520         # b10930: get/set/list trusted.lov xattr
7521         echo "get/set/list trusted.lov xattr ..."
7522         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs" && return
7523         local testfile=$DIR/$tfile
7524         $SETSTRIPE -S 65536 -i 1 -c $OSTCOUNT $testfile ||
7525                 error "setstripe failed"
7526         local STRIPECOUNT=$($GETSTRIPE -c $testfile) ||
7527                 error "getstripe failed"
7528         getfattr -d -m "^trusted" $testfile 2>/dev/null | grep "trusted.lov" ||
7529                 error "can't get trusted.lov from $testfile"
7530
7531         local testfile2=${testfile}2
7532         local value=$(getfattr -n trusted.lov $testfile 2>/dev/null |
7533                         grep "trusted.lov" | sed -e 's/[^=]\+=//')
7534
7535         $MCREATE $testfile2
7536         setfattr -n trusted.lov -v $value $testfile2
7537         local stripe_size=$($GETSTRIPE -S $testfile2)
7538         local stripe_count=$($GETSTRIPE -c $testfile2)
7539         [[ $stripe_size -eq 65536 ]] ||
7540                 error "stripe size $stripe_size != 65536"
7541         [[ $stripe_count -eq $STRIPECOUNT ]] ||
7542                 error "stripe count $stripe_count != $STRIPECOUNT"
7543         rm -f $DIR/$tfile
7544 }
7545 run_test 102b "getfattr/setfattr for trusted.lov EAs ============"
7546
7547 test_102c() {
7548         [ -z "$(which setfattr 2>/dev/null)" ] &&
7549                 skip_env "could not find setfattr" && return
7550
7551         # b10930: get/set/list lustre.lov xattr
7552         echo "get/set/list lustre.lov xattr ..."
7553         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs" && return
7554         test_mkdir $DIR/$tdir
7555         chown $RUNAS_ID $DIR/$tdir
7556         local testfile=$DIR/$tdir/$tfile
7557         $RUNAS $SETSTRIPE -S 65536 -i 1 -c $OSTCOUNT $testfile ||
7558                 error "setstripe failed"
7559         local STRIPECOUNT=$($RUNAS $GETSTRIPE -c $testfile) ||
7560                 error "getstripe failed"
7561         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
7562         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
7563
7564         local testfile2=${testfile}2
7565         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
7566                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
7567
7568         $RUNAS $MCREATE $testfile2
7569         $RUNAS setfattr -n lustre.lov -v $value $testfile2
7570         local stripe_size=$($RUNAS $GETSTRIPE -S $testfile2)
7571         local stripe_count=$($RUNAS $GETSTRIPE -c $testfile2)
7572         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
7573         [ $stripe_count -eq $STRIPECOUNT ] ||
7574                 error "stripe count $stripe_count != $STRIPECOUNT"
7575 }
7576 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
7577
7578 compare_stripe_info1() {
7579         local stripe_index_all_zero=true
7580
7581         for num in 1 2 3 4; do
7582                 for count in $(seq 1 $STRIPE_COUNT); do
7583                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
7584                                 local size=$((STRIPE_SIZE * num))
7585                                 local file=file"$num-$offset-$count"
7586                                 stripe_size=$($LFS getstripe -S $PWD/$file)
7587                                 [[ $stripe_size -ne $size ]] &&
7588                                     error "$file: size $stripe_size != $size"
7589                                 stripe_count=$($LFS getstripe -c $PWD/$file)
7590                                 # allow fewer stripes to be created, ORI-601
7591                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
7592                                     error "$file: count $stripe_count != $count"
7593                                 stripe_index=$($LFS getstripe -i $PWD/$file)
7594                                 [[ $stripe_index -ne 0 ]] &&
7595                                         stripe_index_all_zero=false
7596                         done
7597                 done
7598         done
7599         $stripe_index_all_zero &&
7600                 error "all files are being extracted starting from OST index 0"
7601         return 0
7602 }
7603
7604 have_xattrs_include() {
7605         tar --help | grep -q xattrs-include &&
7606                 echo --xattrs-include="lustre.*"
7607 }
7608
7609 test_102d() {
7610         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
7611         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs" && return
7612         XINC=$(have_xattrs_include)
7613         setup_test102
7614         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
7615         cd $DIR/$tdir/$tdir
7616         compare_stripe_info1
7617 }
7618 run_test 102d "tar restore stripe info from tarfile,not keep osts"
7619
7620 test_102f() {
7621         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
7622         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs" && return
7623         XINC=$(have_xattrs_include)
7624         setup_test102
7625         test_mkdir $DIR/$tdir.restore
7626         cd $DIR
7627         tar cf - --xattrs $tdir | tar xf - \
7628                 -C $DIR/$tdir.restore --xattrs $XINC
7629         cd $DIR/$tdir.restore/$tdir
7630         compare_stripe_info1
7631 }
7632 run_test 102f "tar copy files, not keep osts"
7633
7634 grow_xattr() {
7635         local xsize=${1:-1024}  # in bytes
7636         local file=$DIR/$tfile
7637
7638         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
7639                 skip "must have user_xattr" && return 0
7640         [ -z "$(which setfattr 2>/dev/null)" ] &&
7641                 skip_env "could not find setfattr" && return 0
7642         [ -z "$(which getfattr 2>/dev/null)" ] &&
7643                 skip_env "could not find getfattr" && return 0
7644
7645         touch $file
7646
7647         local value="$(generate_string $xsize)"
7648
7649         local xbig=trusted.big
7650         log "save $xbig on $file"
7651         setfattr -n $xbig -v $value $file ||
7652                 error "saving $xbig on $file failed"
7653
7654         local orig=$(get_xattr_value $xbig $file)
7655         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
7656
7657         local xsml=trusted.sml
7658         log "save $xsml on $file"
7659         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
7660
7661         local new=$(get_xattr_value $xbig $file)
7662         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
7663
7664         log "grow $xsml on $file"
7665         setfattr -n $xsml -v "$value" $file ||
7666                 error "growing $xsml on $file failed"
7667
7668         new=$(get_xattr_value $xbig $file)
7669         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
7670         log "$xbig still valid after growing $xsml"
7671
7672         rm -f $file
7673 }
7674
7675 test_102h() { # bug 15777
7676         grow_xattr 1024
7677 }
7678 run_test 102h "grow xattr from inside inode to external block"
7679
7680 test_102ha() {
7681         large_xattr_enabled || { skip "large_xattr disabled" && return; }
7682         grow_xattr $(max_xattr_size)
7683 }
7684 run_test 102ha "grow xattr from inside inode to external inode"
7685
7686 test_102i() { # bug 17038
7687         [ -z "$(which getfattr 2>/dev/null)" ] &&
7688                 skip "could not find getfattr" && return
7689         touch $DIR/$tfile
7690         ln -s $DIR/$tfile $DIR/${tfile}link
7691         getfattr -n trusted.lov $DIR/$tfile ||
7692                 error "lgetxattr on $DIR/$tfile failed"
7693         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
7694                 grep -i "no such attr" ||
7695                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
7696         rm -f $DIR/$tfile $DIR/${tfile}link
7697 }
7698 run_test 102i "lgetxattr test on symbolic link ============"
7699
7700 test_102j() {
7701         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
7702         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs" && return
7703         XINC=$(have_xattrs_include)
7704         setup_test102 "$RUNAS"
7705         chown $RUNAS_ID $DIR/$tdir
7706         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
7707         cd $DIR/$tdir/$tdir
7708         compare_stripe_info1 "$RUNAS"
7709 }
7710 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
7711
7712 test_102k() {
7713         [ -z "$(which setfattr 2>/dev/null)" ] &&
7714                 skip "could not find setfattr" && return
7715         touch $DIR/$tfile
7716         # b22187 just check that does not crash for regular file.
7717         setfattr -n trusted.lov $DIR/$tfile
7718         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
7719         local test_kdir=$DIR/$tdir
7720         test_mkdir $test_kdir
7721         local default_size=$($LFS getstripe -S $test_kdir)
7722         local default_count=$($LFS getstripe -c $test_kdir)
7723         local default_offset=$($LFS getstripe -i $test_kdir)
7724         $SETSTRIPE -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
7725                 error 'dir setstripe failed'
7726         setfattr -n trusted.lov $test_kdir
7727         local stripe_size=$($LFS getstripe -S $test_kdir)
7728         local stripe_count=$($LFS getstripe -c $test_kdir)
7729         local stripe_offset=$($LFS getstripe -i $test_kdir)
7730         [ $stripe_size -eq $default_size ] ||
7731                 error "stripe size $stripe_size != $default_size"
7732         [ $stripe_count -eq $default_count ] ||
7733                 error "stripe count $stripe_count != $default_count"
7734         [ $stripe_offset -eq $default_offset ] ||
7735                 error "stripe offset $stripe_offset != $default_offset"
7736         rm -rf $DIR/$tfile $test_kdir
7737 }
7738 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
7739
7740 test_102l() {
7741         [ -z "$(which getfattr 2>/dev/null)" ] &&
7742                 skip "could not find getfattr" && return
7743
7744         # LU-532 trusted. xattr is invisible to non-root
7745         local testfile=$DIR/$tfile
7746
7747         touch $testfile
7748
7749         echo "listxattr as user..."
7750         chown $RUNAS_ID $testfile
7751         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
7752             grep -q "trusted" &&
7753                 error "$testfile trusted xattrs are user visible"
7754
7755         return 0;
7756 }
7757 run_test 102l "listxattr size test =================================="
7758
7759 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
7760         local path=$DIR/$tfile
7761         touch $path
7762
7763         listxattr_size_check $path || error "listattr_size_check $path failed"
7764 }
7765 run_test 102m "Ensure listxattr fails on small bufffer ========"
7766
7767 cleanup_test102
7768
7769 getxattr() { # getxattr path name
7770         # Return the base64 encoding of the value of xattr name on path.
7771         local path=$1
7772         local name=$2
7773
7774         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
7775         # file: $path
7776         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
7777         #
7778         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
7779
7780         getfattr --absolute-names --encoding=base64 --name=$name $path |
7781                 awk -F= -v name=$name '$1 == name {
7782                         print substr($0, index($0, "=") + 1);
7783         }'
7784 }
7785
7786 test_102n() { # LU-4101 mdt: protect internal xattrs
7787         [ -z "$(which setfattr 2>/dev/null)" ] &&
7788                 skip "could not find setfattr" && return
7789         if [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.5.50) ]
7790         then
7791                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
7792                 return
7793         fi
7794
7795         local file0=$DIR/$tfile.0
7796         local file1=$DIR/$tfile.1
7797         local xattr0=$TMP/$tfile.0
7798         local xattr1=$TMP/$tfile.1
7799         local namelist="lov lma lmv link fid version som hsm"
7800         local name
7801         local value
7802
7803         rm -rf $file0 $file1 $xattr0 $xattr1
7804         touch $file0 $file1
7805
7806         # Get 'before' xattrs of $file1.
7807         getfattr --absolute-names --dump --match=- $file1 > $xattr0
7808
7809         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.8.53) ] &&
7810                 namelist+=" lfsck_namespace"
7811         for name in $namelist; do
7812                 # Try to copy xattr from $file0 to $file1.
7813                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
7814
7815                 setfattr --name=trusted.$name --value="$value" $file1 ||
7816                         error "setxattr 'trusted.$name' failed"
7817
7818                 # Try to set a garbage xattr.
7819                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
7820
7821                 if [[ x$name == "xlov" ]]; then
7822                         setfattr --name=trusted.lov --value="$value" $file1 &&
7823                         error "setxattr invalid 'trusted.lov' success"
7824                 else
7825                         setfattr --name=trusted.$name --value="$value" $file1 ||
7826                                 error "setxattr invalid 'trusted.$name' failed"
7827                 fi
7828
7829                 # Try to remove the xattr from $file1. We don't care if this
7830                 # appears to succeed or fail, we just don't want there to be
7831                 # any changes or crashes.
7832                 setfattr --remove=$trusted.$name $file1 2> /dev/null
7833         done
7834
7835         if [ $(lustre_version_code $SINGLEMDS) -gt $(version_code 2.6.50) ]
7836         then
7837                 name="lfsck_ns"
7838                 # Try to copy xattr from $file0 to $file1.
7839                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
7840
7841                 setfattr --name=trusted.$name --value="$value" $file1 ||
7842                         error "setxattr 'trusted.$name' failed"
7843
7844                 # Try to set a garbage xattr.
7845                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
7846
7847                 setfattr --name=trusted.$name --value="$value" $file1 ||
7848                         error "setxattr 'trusted.$name' failed"
7849
7850                 # Try to remove the xattr from $file1. We don't care if this
7851                 # appears to succeed or fail, we just don't want there to be
7852                 # any changes or crashes.
7853                 setfattr --remove=$trusted.$name $file1 2> /dev/null
7854         fi
7855
7856         # Get 'after' xattrs of file1.
7857         getfattr --absolute-names --dump --match=- $file1 > $xattr1
7858
7859         if ! diff $xattr0 $xattr1; then
7860                 error "before and after xattrs of '$file1' differ"
7861         fi
7862
7863         rm -rf $file0 $file1 $xattr0 $xattr1
7864
7865         return 0
7866 }
7867 run_test 102n "silently ignore setxattr on internal trusted xattrs"
7868
7869 test_102p() { # LU-4703 setxattr did not check ownership
7870         local testfile=$DIR/$tfile
7871
7872         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.5.56) ] &&
7873                 skip "MDS needs to be at least 2.5.56" && return
7874
7875         touch $testfile
7876
7877         echo "setfacl as user..."
7878         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
7879         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
7880
7881         echo "setfattr as user..."
7882         setfacl -m "u:$RUNAS_ID:---" $testfile
7883         $RUNAS setfattr -x system.posix_acl_access $testfile
7884         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
7885 }
7886 run_test 102p "check setxattr(2) correctly fails without permission"
7887
7888 test_102q() {
7889         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.6.92) ] &&
7890                 skip "MDS needs to be at least 2.6.92" && return
7891         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
7892 }
7893 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
7894
7895 test_102r() {
7896         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.6.93) ] &&
7897                 skip "MDS needs to be at least 2.6.93" && return
7898         touch $DIR/$tfile || error "touch"
7899         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
7900         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
7901         rm $DIR/$tfile || error "rm"
7902
7903         #normal directory
7904         mkdir -p $DIR/$tdir || error "mkdir"
7905         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
7906         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
7907         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
7908                 error "$testfile error deleting user.author1"
7909         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
7910                 grep "user.$(basename $tdir)" &&
7911                 error "$tdir did not delete user.$(basename $tdir)"
7912         rmdir $DIR/$tdir || error "rmdir"
7913
7914         #striped directory
7915         test_mkdir $DIR/$tdir
7916         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
7917         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
7918         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
7919                 error "$testfile error deleting user.author1"
7920         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
7921                 grep "user.$(basename $tdir)" &&
7922                 error "$tdir did not delete user.$(basename $tdir)"
7923         rmdir $DIR/$tdir || error "rm striped dir"
7924 }
7925 run_test 102r "set EAs with empty values"
7926
7927 run_acl_subtest()
7928 {
7929     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
7930     return $?
7931 }
7932
7933 test_103a() {
7934         [ "$UID" != 0 ] && skip_env "must run as root" && return
7935         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
7936                 skip "must have acl enabled" && return
7937         [ -z "$(which setfacl 2>/dev/null)" ] &&
7938                 skip_env "could not find setfacl" && return
7939         $GSS && skip "could not run under gss" && return
7940         remote_mds_nodsh && skip "remote MDS with nodsh" && return
7941
7942         gpasswd -a daemon bin                           # LU-5641
7943         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
7944
7945         declare -a identity_old
7946
7947         for num in $(seq $MDSCOUNT); do
7948                 switch_identity $num true || identity_old[$num]=$?
7949         done
7950
7951         SAVE_UMASK=$(umask)
7952         umask 0022
7953         mkdir -p $DIR/$tdir
7954         cd $DIR/$tdir
7955
7956         echo "performing cp ..."
7957         run_acl_subtest cp || error "run_acl_subtest cp failed"
7958         echo "performing getfacl-noacl..."
7959         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
7960         echo "performing misc..."
7961         run_acl_subtest misc || error  "misc test failed"
7962         echo "performing permissions..."
7963         run_acl_subtest permissions || error "permissions failed"
7964         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
7965         if [ $(lustre_version_code $SINGLEMDS) -gt $(version_code 2.8.55) -o \
7966              \( $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.6) -a \
7967              $(lustre_version_code $SINGLEMDS) -ge $(version_code 2.5.29) \) ]
7968         then
7969                 echo "performing permissions xattr..."
7970                 run_acl_subtest permissions_xattr ||
7971                         error "permissions_xattr failed"
7972         fi
7973         echo "performing setfacl..."
7974         run_acl_subtest setfacl || error  "setfacl test failed"
7975
7976         # inheritance test got from HP
7977         echo "performing inheritance..."
7978         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
7979         chmod +x make-tree || error "chmod +x failed"
7980         run_acl_subtest inheritance || error "inheritance test failed"
7981         rm -f make-tree
7982
7983         echo "LU-974 ignore umask when acl is enabled..."
7984         run_acl_subtest 974 || error "LU-974 umask test failed"
7985         if [ $MDSCOUNT -ge 2 ]; then
7986                 run_acl_subtest 974_remote ||
7987                         error "LU-974 umask test failed under remote dir"
7988         fi
7989
7990         echo "LU-2561 newly created file is same size as directory..."
7991         if [ $(facet_fstype $SINGLEMDS) != "zfs" ]; then
7992                 run_acl_subtest 2561 || error "LU-2561 test failed"
7993         else
7994                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
7995         fi
7996
7997         run_acl_subtest 4924 || error "LU-4924 test failed"
7998
7999         cd $SAVE_PWD
8000         umask $SAVE_UMASK
8001
8002         for num in $(seq $MDSCOUNT); do
8003                 if [ "${identity_old[$num]}" = 1 ]; then
8004                         switch_identity $num false || identity_old[$num]=$?
8005                 fi
8006         done
8007 }
8008 run_test 103a "acl test ========================================="
8009
8010 test_103c() {
8011         mkdir -p $DIR/$tdir
8012         cp -rp $DIR/$tdir $DIR/$tdir.bak
8013
8014         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
8015                 error "$DIR/$tdir shouldn't contain default ACL"
8016         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
8017                 error "$DIR/$tdir.bak shouldn't contain default ACL"
8018         true
8019 }
8020 run_test 103c "'cp -rp' won't set empty acl"
8021
8022 test_104a() {
8023         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
8024         touch $DIR/$tfile
8025         lfs df || error "lfs df failed"
8026         lfs df -ih || error "lfs df -ih failed"
8027         lfs df -h $DIR || error "lfs df -h $DIR failed"
8028         lfs df -i $DIR || error "lfs df -i $DIR failed"
8029         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
8030         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
8031
8032         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
8033         lctl --device %$OSC deactivate
8034         lfs df || error "lfs df with deactivated OSC failed"
8035         lctl --device %$OSC activate
8036         # wait the osc back to normal
8037         wait_osc_import_state client ost FULL
8038
8039         lfs df || error "lfs df with reactivated OSC failed"
8040         rm -f $DIR/$tfile
8041 }
8042 run_test 104a "lfs df [-ih] [path] test ========================="
8043
8044 test_104b() {
8045         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
8046         [ $RUNAS_ID -eq $UID ] &&
8047                 skip_env "RUNAS_ID = UID = $UID -- skipping" && return
8048         chmod 666 /dev/obd
8049         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
8050                         grep "Permission denied" | wc -l)))
8051         if [ $denied_cnt -ne 0 ]; then
8052                 error "lfs check servers test failed"
8053         fi
8054 }
8055 run_test 104b "$RUNAS lfs check servers test ===================="
8056
8057 test_105a() {
8058         # doesn't work on 2.4 kernels
8059         touch $DIR/$tfile
8060         if $(flock_is_enabled); then
8061                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
8062         else
8063                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
8064         fi
8065         rm -f $DIR/$tfile
8066 }
8067 run_test 105a "flock when mounted without -o flock test ========"
8068
8069 test_105b() {
8070         touch $DIR/$tfile
8071         if $(flock_is_enabled); then
8072                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
8073         else
8074                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
8075         fi
8076         rm -f $DIR/$tfile
8077 }
8078 run_test 105b "fcntl when mounted without -o flock test ========"
8079
8080 test_105c() {
8081         touch $DIR/$tfile
8082         if $(flock_is_enabled); then
8083                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
8084         else
8085                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
8086         fi
8087         rm -f $DIR/$tfile
8088 }
8089 run_test 105c "lockf when mounted without -o flock test"
8090
8091 test_105d() { # bug 15924
8092         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
8093         test_mkdir $DIR/$tdir
8094         flock_is_enabled || { skip "mount w/o flock enabled" && return; }
8095         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
8096         $LCTL set_param fail_loc=0x80000315
8097         flocks_test 2 $DIR/$tdir
8098 }
8099 run_test 105d "flock race (should not freeze) ========"
8100
8101 test_105e() { # bug 22660 && 22040
8102         flock_is_enabled || { skip "mount w/o flock enabled" && return; }
8103         touch $DIR/$tfile
8104         flocks_test 3 $DIR/$tfile
8105 }
8106 run_test 105e "Two conflicting flocks from same process"
8107
8108 test_106() { #bug 10921
8109         test_mkdir $DIR/$tdir
8110         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
8111         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
8112 }
8113 run_test 106 "attempt exec of dir followed by chown of that dir"
8114
8115 test_107() {
8116         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
8117         CDIR=`pwd`
8118         cd $DIR
8119
8120         local file=core
8121         rm -f $file
8122
8123         local save_pattern=$(sysctl -n kernel.core_pattern)
8124         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
8125         sysctl -w kernel.core_pattern=$file
8126         sysctl -w kernel.core_uses_pid=0
8127
8128         ulimit -c unlimited
8129         sleep 60 &
8130         SLEEPPID=$!
8131
8132         sleep 1
8133
8134         kill -s 11 $SLEEPPID
8135         wait $SLEEPPID
8136         if [ -e $file ]; then
8137                 size=`stat -c%s $file`
8138                 [ $size -eq 0 ] && error "Fail to create core file $file"
8139         else
8140                 error "Fail to create core file $file"
8141         fi
8142         rm -f $file
8143         sysctl -w kernel.core_pattern=$save_pattern
8144         sysctl -w kernel.core_uses_pid=$save_uses_pid
8145         cd $CDIR
8146 }
8147 run_test 107 "Coredump on SIG"
8148
8149 test_110() {
8150         test_mkdir $DIR/$tdir
8151         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
8152         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
8153                 error "mkdir with 256 char should fail, but did not"
8154         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
8155                 error "create with 255 char failed"
8156         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
8157                 error "create with 256 char should fail, but did not"
8158
8159         ls -l $DIR/$tdir
8160         rm -rf $DIR/$tdir
8161 }
8162 run_test 110 "filename length checking"
8163
8164 #
8165 # Purpose: To verify dynamic thread (OSS) creation.
8166 #
8167 test_115() {
8168         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
8169         remote_ost_nodsh && skip "remote OST with nodsh" && return
8170
8171         # Lustre does not stop service threads once they are started.
8172         # Reset number of running threads to default.
8173         stopall
8174         setupall
8175
8176         local OSTIO_pre
8177         local save_params="$TMP/sanity-$TESTNAME.parameters"
8178
8179         # Get ll_ost_io count before I/O
8180         OSTIO_pre=$(do_facet ost1 \
8181                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
8182         # Exit if lustre is not running (ll_ost_io not running).
8183         [ -z "$OSTIO_pre" ] && error "no OSS threads"
8184
8185         echo "Starting with $OSTIO_pre threads"
8186         local thread_max=$((OSTIO_pre * 2))
8187         local rpc_in_flight=$((thread_max * 2))
8188         # Number of I/O Process proposed to be started.
8189         local nfiles
8190         local facets=$(get_facets OST)
8191
8192         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
8193         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
8194
8195         # Set in_flight to $rpc_in_flight
8196         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
8197                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
8198         nfiles=${rpc_in_flight}
8199         # Set ost thread_max to $thread_max
8200         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
8201
8202         # 5 Minutes should be sufficient for max number of OSS
8203         # threads(thread_max) to be created.
8204         local timeout=300
8205
8206         # Start I/O.
8207         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
8208         test_mkdir $DIR/$tdir
8209         for i in $(seq $nfiles); do
8210                 local file=$DIR/$tdir/${tfile}-$i
8211                 $LFS setstripe -c -1 -i 0 $file
8212                 ($WTL $file $timeout)&
8213         done
8214
8215         # I/O Started - Wait for thread_started to reach thread_max or report
8216         # error if thread_started is more than thread_max.
8217         echo "Waiting for thread_started to reach thread_max"
8218         local thread_started=0
8219         local end_time=$((SECONDS + timeout))
8220
8221         while [ $SECONDS -le $end_time ] ; do
8222                 echo -n "."
8223                 # Get ost i/o thread_started count.
8224                 thread_started=$(do_facet ost1 \
8225                         "$LCTL get_param \
8226                         ost.OSS.ost_io.threads_started | cut -d= -f2")
8227                 # Break out if thread_started is equal/greater than thread_max
8228                 if [[ $thread_started -ge $thread_max ]]; then
8229                         echo ll_ost_io thread_started $thread_started, \
8230                                 equal/greater than thread_max $thread_max
8231                         break
8232                 fi
8233                 sleep 1
8234         done
8235
8236         # Cleanup - We have the numbers, Kill i/o jobs if running.
8237         jobcount=($(jobs -p))
8238         for i in $(seq 0 $((${#jobcount[@]}-1)))
8239         do
8240                 kill -9 ${jobcount[$i]}
8241                 if [ $? -ne 0 ] ; then
8242                         echo Warning: \
8243                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
8244                 fi
8245         done
8246
8247         # Cleanup files left by WTL binary.
8248         for i in $(seq $nfiles); do
8249                 local file=$DIR/$tdir/${tfile}-$i
8250                 rm -rf $file
8251                 if [ $? -ne 0 ] ; then
8252                         echo "Warning: Failed to delete file $file"
8253                 fi
8254         done
8255
8256         restore_lustre_params <$save_params
8257         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
8258
8259         # Error out if no new thread has started or Thread started is greater
8260         # than thread max.
8261         if [[ $thread_started -le $OSTIO_pre ||
8262                         $thread_started -gt $thread_max ]]; then
8263                 error "ll_ost_io: thread_started $thread_started" \
8264                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
8265                       "No new thread started or thread started greater " \
8266                       "than thread_max."
8267         fi
8268 }
8269 run_test 115 "verify dynamic thread creation===================="
8270
8271 free_min_max () {
8272         wait_delete_completed
8273         AVAIL=($(lctl get_param -n osc.*[oO][sS][cC]-[^M]*.kbytesavail))
8274         echo "OST kbytes available: ${AVAIL[@]}"
8275         MAXV=${AVAIL[0]}
8276         MAXI=0
8277         MINV=${AVAIL[0]}
8278         MINI=0
8279         for ((i = 0; i < ${#AVAIL[@]}; i++)); do
8280                 #echo OST $i: ${AVAIL[i]}kb
8281                 if [[ ${AVAIL[i]} -gt $MAXV ]]; then
8282                         MAXV=${AVAIL[i]}
8283                         MAXI=$i
8284                 fi
8285                 if [[ ${AVAIL[i]} -lt $MINV ]]; then
8286                         MINV=${AVAIL[i]}
8287                         MINI=$i
8288                 fi
8289         done
8290         echo "Min free space: OST $MINI: $MINV"
8291         echo "Max free space: OST $MAXI: $MAXV"
8292 }
8293
8294 test_116a() { # was previously test_116()
8295         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
8296         remote_mds_nodsh && skip "remote MDS with nodsh" && return
8297
8298         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs" && return
8299
8300         echo -n "Free space priority "
8301         do_facet $SINGLEMDS lctl get_param -n lo*.*-mdtlov.qos_prio_free |
8302                 head -n1
8303         declare -a AVAIL
8304         free_min_max
8305
8306         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip" && return
8307         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip" \
8308                 && return
8309         trap simple_cleanup_common EXIT
8310
8311
8312         # Check if we need to generate uneven OSTs
8313         test_mkdir -p $DIR/$tdir/OST${MINI}
8314         local FILL=$((MINV / 4))
8315         local DIFF=$((MAXV - MINV))
8316         local DIFF2=$((DIFF * 100 / MINV))
8317
8318         local threshold=$(do_facet $SINGLEMDS \
8319                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
8320         threshold=${threshold%%%}
8321         echo -n "Check for uneven OSTs: "
8322         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
8323
8324         if [[ $DIFF2 -gt $threshold ]]; then
8325                 echo "ok"
8326                 echo "Don't need to fill OST$MINI"
8327         else
8328                 # generate uneven OSTs. Write 2% over the QOS threshold value
8329                 echo "no"
8330                 DIFF=$((threshold - DIFF2 + 2))
8331                 DIFF2=$((MINV * DIFF / 100))
8332                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
8333                 $SETSTRIPE -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
8334                         error "setstripe failed"
8335                 DIFF=$((DIFF2 / 2048))
8336                 i=0
8337                 while [ $i -lt $DIFF ]; do
8338                         i=$((i + 1))
8339                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
8340                                 bs=2M count=1 2>/dev/null
8341                         echo -n .
8342                 done
8343                 echo .
8344                 sync
8345                 sleep_maxage
8346                 free_min_max
8347         fi
8348
8349         DIFF=$((MAXV - MINV))
8350         DIFF2=$((DIFF * 100 / MINV))
8351         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
8352         if [ $DIFF2 -gt $threshold ]; then
8353                 echo "ok"
8354         else
8355                 echo "failed - QOS mode won't be used"
8356                 skip "QOS imbalance criteria not met"
8357                 simple_cleanup_common
8358                 return
8359         fi
8360
8361         MINI1=$MINI
8362         MINV1=$MINV
8363         MAXI1=$MAXI
8364         MAXV1=$MAXV
8365
8366         # now fill using QOS
8367         $SETSTRIPE -c 1 $DIR/$tdir
8368         FILL=$((FILL / 200))
8369         if [ $FILL -gt 600 ]; then
8370                 FILL=600
8371         fi
8372         echo "writing $FILL files to QOS-assigned OSTs"
8373         i=0
8374         while [ $i -lt $FILL ]; do
8375                 i=$((i + 1))
8376                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
8377                         count=1 2>/dev/null
8378                 echo -n .
8379         done
8380         echo "wrote $i 200k files"
8381         sync
8382         sleep_maxage
8383
8384         echo "Note: free space may not be updated, so measurements might be off"
8385         free_min_max
8386         DIFF2=$((MAXV - MINV))
8387         echo "free space delta: orig $DIFF final $DIFF2"
8388         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
8389         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
8390         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
8391         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
8392         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
8393         if [[ $DIFF -gt 0 ]]; then
8394                 FILL=$((DIFF2 * 100 / DIFF - 100))
8395                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
8396         fi
8397
8398         # Figure out which files were written where
8399         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
8400                awk '/'$MINI1': / {print $2; exit}')
8401         echo $UUID
8402         MINC=$($GETSTRIPE --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
8403         echo "$MINC files created on smaller OST $MINI1"
8404         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
8405                awk '/'$MAXI1': / {print $2; exit}')
8406         echo $UUID
8407         MAXC=$($GETSTRIPE --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
8408         echo "$MAXC files created on larger OST $MAXI1"
8409         if [[ $MINC -gt 0 ]]; then
8410                 FILL=$((MAXC * 100 / MINC - 100))
8411                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
8412         fi
8413         [[ $MAXC -gt $MINC ]] ||
8414                 error_ignore LU-9 "stripe QOS didn't balance free space"
8415         simple_cleanup_common
8416 }
8417 run_test 116a "stripe QOS: free space balance ==================="
8418
8419 test_116b() { # LU-2093
8420         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
8421         remote_mds_nodsh && skip "remote MDS with nodsh" && return
8422
8423 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
8424         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
8425                        lo*.$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
8426         [ -z "$old_rr" ] && skip "no QOS" && return 0
8427         do_facet $SINGLEMDS lctl set_param \
8428                 lo*.$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
8429         mkdir -p $DIR/$tdir
8430         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
8431         createmany -o $DIR/$tdir/f- 20 || error "can't create"
8432         do_facet $SINGLEMDS lctl set_param fail_loc=0
8433         rm -rf $DIR/$tdir
8434         do_facet $SINGLEMDS lctl set_param \
8435                 lo*.$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
8436 }
8437 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
8438
8439 test_117() # bug 10891
8440 {
8441         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
8442         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
8443         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
8444         lctl set_param fail_loc=0x21e
8445         > $DIR/$tfile || error "truncate failed"
8446         lctl set_param fail_loc=0
8447         echo "Truncate succeeded."
8448         rm -f $DIR/$tfile
8449 }
8450 run_test 117 "verify osd extend =========="
8451
8452 NO_SLOW_RESENDCOUNT=4
8453 export OLD_RESENDCOUNT=""
8454 set_resend_count () {
8455         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
8456         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
8457         lctl set_param -n $PROC_RESENDCOUNT $1
8458         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
8459 }
8460
8461 # for reduce test_118* time (b=14842)
8462 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
8463
8464 # Reset async IO behavior after error case
8465 reset_async() {
8466         FILE=$DIR/reset_async
8467
8468         # Ensure all OSCs are cleared
8469         $SETSTRIPE -c -1 $FILE
8470         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
8471         sync
8472         rm $FILE
8473 }
8474
8475 test_118a() #bug 11710
8476 {
8477         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
8478         reset_async
8479
8480         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
8481         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
8482         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
8483
8484         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
8485                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
8486                 return 1;
8487         fi
8488         rm -f $DIR/$tfile
8489 }
8490 run_test 118a "verify O_SYNC works =========="
8491
8492 test_118b()
8493 {
8494         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
8495         remote_ost_nodsh && skip "remote OST with nodsh" && return
8496
8497         reset_async
8498
8499         #define OBD_FAIL_SRV_ENOENT 0x217
8500         set_nodes_failloc "$(osts_nodes)" 0x217
8501         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
8502         RC=$?
8503         set_nodes_failloc "$(osts_nodes)" 0
8504         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
8505         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
8506                     grep -c writeback)
8507
8508         if [[ $RC -eq 0 ]]; then
8509                 error "Must return error due to dropped pages, rc=$RC"
8510                 return 1;
8511         fi
8512
8513         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
8514                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
8515                 return 1;
8516         fi
8517
8518         echo "Dirty pages not leaked on ENOENT"
8519
8520         # Due to the above error the OSC will issue all RPCs syncronously
8521         # until a subsequent RPC completes successfully without error.
8522         $MULTIOP $DIR/$tfile Ow4096yc
8523         rm -f $DIR/$tfile
8524
8525         return 0
8526 }
8527 run_test 118b "Reclaim dirty pages on fatal error =========="
8528
8529 test_118c()
8530 {
8531         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
8532
8533         # for 118c, restore the original resend count, LU-1940
8534         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
8535                                 set_resend_count $OLD_RESENDCOUNT
8536         remote_ost_nodsh && skip "remote OST with nodsh" && return
8537
8538         reset_async
8539
8540         #define OBD_FAIL_OST_EROFS               0x216
8541         set_nodes_failloc "$(osts_nodes)" 0x216
8542
8543         # multiop should block due to fsync until pages are written
8544         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
8545         MULTIPID=$!
8546         sleep 1
8547
8548         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
8549                 error "Multiop failed to block on fsync, pid=$MULTIPID"
8550         fi
8551
8552         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
8553                     grep -c writeback)
8554         if [[ $WRITEBACK -eq 0 ]]; then
8555                 error "No page in writeback, writeback=$WRITEBACK"
8556         fi
8557
8558         set_nodes_failloc "$(osts_nodes)" 0
8559         wait $MULTIPID
8560         RC=$?
8561         if [[ $RC -ne 0 ]]; then
8562                 error "Multiop fsync failed, rc=$RC"
8563         fi
8564
8565         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
8566         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
8567                     grep -c writeback)
8568         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
8569                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
8570         fi
8571
8572         rm -f $DIR/$tfile
8573         echo "Dirty pages flushed via fsync on EROFS"
8574         return 0
8575 }
8576 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
8577
8578 # continue to use small resend count to reduce test_118* time (b=14842)
8579 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
8580
8581 test_118d()
8582 {
8583         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
8584         remote_ost_nodsh && skip "remote OST with nodsh" && return
8585
8586         reset_async
8587
8588         #define OBD_FAIL_OST_BRW_PAUSE_BULK
8589         set_nodes_failloc "$(osts_nodes)" 0x214
8590         # multiop should block due to fsync until pages are written
8591         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
8592         MULTIPID=$!
8593         sleep 1
8594
8595         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
8596                 error "Multiop failed to block on fsync, pid=$MULTIPID"
8597         fi
8598
8599         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
8600                     grep -c writeback)
8601         if [[ $WRITEBACK -eq 0 ]]; then
8602                 error "No page in writeback, writeback=$WRITEBACK"
8603         fi
8604
8605         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
8606         set_nodes_failloc "$(osts_nodes)" 0
8607
8608         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
8609         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
8610                     grep -c writeback)
8611         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
8612                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
8613         fi
8614
8615         rm -f $DIR/$tfile
8616         echo "Dirty pages gaurenteed flushed via fsync"
8617         return 0
8618 }
8619 run_test 118d "Fsync validation inject a delay of the bulk =========="
8620
8621 test_118f() {
8622         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
8623         reset_async
8624
8625         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
8626         lctl set_param fail_loc=0x8000040a
8627
8628         # Should simulate EINVAL error which is fatal
8629         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
8630         RC=$?
8631         if [[ $RC -eq 0 ]]; then
8632                 error "Must return error due to dropped pages, rc=$RC"
8633         fi
8634
8635         lctl set_param fail_loc=0x0
8636
8637         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
8638         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
8639         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
8640                     grep -c writeback)
8641         if [[ $LOCKED -ne 0 ]]; then
8642                 error "Locked pages remain in cache, locked=$LOCKED"
8643         fi
8644
8645         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
8646                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
8647         fi
8648
8649         rm -f $DIR/$tfile
8650         echo "No pages locked after fsync"
8651
8652         reset_async
8653         return 0
8654 }
8655 run_test 118f "Simulate unrecoverable OSC side error =========="
8656
8657 test_118g() {
8658         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
8659         reset_async
8660
8661         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
8662         lctl set_param fail_loc=0x406
8663
8664         # simulate local -ENOMEM
8665         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
8666         RC=$?
8667
8668         lctl set_param fail_loc=0
8669         if [[ $RC -eq 0 ]]; then
8670                 error "Must return error due to dropped pages, rc=$RC"
8671         fi
8672
8673         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
8674         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
8675         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
8676                         grep -c writeback)
8677         if [[ $LOCKED -ne 0 ]]; then
8678                 error "Locked pages remain in cache, locked=$LOCKED"
8679         fi
8680
8681         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
8682                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
8683         fi
8684
8685         rm -f $DIR/$tfile
8686         echo "No pages locked after fsync"
8687
8688         reset_async
8689         return 0
8690 }
8691 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
8692
8693 test_118h() {
8694         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
8695         remote_ost_nodsh && skip "remote OST with nodsh" && return
8696
8697         reset_async
8698
8699         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
8700         set_nodes_failloc "$(osts_nodes)" 0x20e
8701         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
8702         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
8703         RC=$?
8704
8705         set_nodes_failloc "$(osts_nodes)" 0
8706         if [[ $RC -eq 0 ]]; then
8707                 error "Must return error due to dropped pages, rc=$RC"
8708         fi
8709
8710         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
8711         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
8712         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
8713                     grep -c writeback)
8714         if [[ $LOCKED -ne 0 ]]; then
8715                 error "Locked pages remain in cache, locked=$LOCKED"
8716         fi
8717
8718         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
8719                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
8720         fi
8721
8722         rm -f $DIR/$tfile
8723         echo "No pages locked after fsync"
8724
8725         return 0
8726 }
8727 run_test 118h "Verify timeout in handling recoverables errors  =========="
8728
8729 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
8730
8731 test_118i() {
8732         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
8733         remote_ost_nodsh && skip "remote OST with nodsh" && return
8734
8735         reset_async
8736
8737         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
8738         set_nodes_failloc "$(osts_nodes)" 0x20e
8739
8740         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
8741         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
8742         PID=$!
8743         sleep 5
8744         set_nodes_failloc "$(osts_nodes)" 0
8745
8746         wait $PID
8747         RC=$?
8748         if [[ $RC -ne 0 ]]; then
8749                 error "got error, but should be not, rc=$RC"
8750         fi
8751
8752         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
8753         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
8754         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
8755         if [[ $LOCKED -ne 0 ]]; then
8756                 error "Locked pages remain in cache, locked=$LOCKED"
8757         fi
8758
8759         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
8760                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
8761         fi
8762
8763         rm -f $DIR/$tfile
8764         echo "No pages locked after fsync"
8765
8766         return 0
8767 }
8768 run_test 118i "Fix error before timeout in recoverable error  =========="
8769
8770 [ "$SLOW" = "no" ] && set_resend_count 4
8771
8772 test_118j() {
8773         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
8774         remote_ost_nodsh && skip "remote OST with nodsh" && return
8775
8776         reset_async
8777
8778         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
8779         set_nodes_failloc "$(osts_nodes)" 0x220
8780
8781         # return -EIO from OST
8782         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
8783         RC=$?
8784         set_nodes_failloc "$(osts_nodes)" 0x0
8785         if [[ $RC -eq 0 ]]; then
8786                 error "Must return error due to dropped pages, rc=$RC"
8787         fi
8788
8789         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
8790         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
8791         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
8792         if [[ $LOCKED -ne 0 ]]; then
8793                 error "Locked pages remain in cache, locked=$LOCKED"
8794         fi
8795
8796         # in recoverable error on OST we want resend and stay until it finished
8797         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
8798                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
8799         fi
8800
8801         rm -f $DIR/$tfile
8802         echo "No pages locked after fsync"
8803
8804         return 0
8805 }
8806 run_test 118j "Simulate unrecoverable OST side error =========="
8807
8808 test_118k()
8809 {
8810         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
8811         remote_ost_nodsh && skip "remote OSTs with nodsh" && return
8812
8813         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
8814         set_nodes_failloc "$(osts_nodes)" 0x20e
8815         test_mkdir $DIR/$tdir
8816
8817         for ((i=0;i<10;i++)); do
8818                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
8819                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
8820                 SLEEPPID=$!
8821                 sleep 0.500s
8822                 kill $SLEEPPID
8823                 wait $SLEEPPID
8824         done
8825
8826         set_nodes_failloc "$(osts_nodes)" 0
8827         rm -rf $DIR/$tdir
8828 }
8829 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
8830
8831 test_118l()
8832 {
8833         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
8834         # LU-646
8835         test_mkdir $DIR/$tdir
8836         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
8837         rm -rf $DIR/$tdir
8838 }
8839 run_test 118l "fsync dir"
8840
8841 test_118m() # LU-3066
8842 {
8843         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
8844         test_mkdir $DIR/$tdir
8845         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
8846         rm -rf $DIR/$tdir
8847 }
8848 run_test 118m "fdatasync dir ========="
8849
8850 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
8851
8852 test_118n()
8853 {
8854         local begin
8855         local end
8856
8857         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
8858         remote_ost_nodsh && skip "remote OSTs with nodsh" && return
8859
8860         # Sleep to avoid a cached response.
8861         #define OBD_STATFS_CACHE_SECONDS 1
8862         sleep 2
8863
8864         # Inject a 10 second delay in the OST_STATFS handler.
8865         #define OBD_FAIL_OST_STATFS_DELAY 0x242
8866         set_nodes_failloc "$(osts_nodes)" 0x242
8867
8868         begin=$SECONDS
8869         stat --file-system $MOUNT > /dev/null
8870         end=$SECONDS
8871
8872         set_nodes_failloc "$(osts_nodes)" 0
8873
8874         if ((end - begin > 20)); then
8875             error "statfs took $((end - begin)) seconds, expected 10"
8876         fi
8877 }
8878 run_test 118n "statfs() sends OST_STATFS requests in parallel"
8879
8880 test_119a() # bug 11737
8881 {
8882         BSIZE=$((512 * 1024))
8883         directio write $DIR/$tfile 0 1 $BSIZE
8884         # We ask to read two blocks, which is more than a file size.
8885         # directio will indicate an error when requested and actual
8886         # sizes aren't equeal (a normal situation in this case) and
8887         # print actual read amount.
8888         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
8889         if [ "$NOB" != "$BSIZE" ]; then
8890                 error "read $NOB bytes instead of $BSIZE"
8891         fi
8892         rm -f $DIR/$tfile
8893 }
8894 run_test 119a "Short directIO read must return actual read amount"
8895
8896 test_119b() # bug 11737
8897 {
8898         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs" && return
8899
8900         $SETSTRIPE -c 2 $DIR/$tfile || error "setstripe failed"
8901         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
8902         sync
8903         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) || \
8904                 error "direct read failed"
8905         rm -f $DIR/$tfile
8906 }
8907 run_test 119b "Sparse directIO read must return actual read amount"
8908
8909 test_119c() # bug 13099
8910 {
8911         BSIZE=1048576
8912         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
8913         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
8914         rm -f $DIR/$tfile
8915 }
8916 run_test 119c "Testing for direct read hitting hole"
8917
8918 test_119d() # bug 15950
8919 {
8920         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
8921         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
8922         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
8923         BSIZE=1048576
8924         $SETSTRIPE $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
8925         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
8926         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
8927         lctl set_param fail_loc=0x40d
8928         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
8929         pid_dio=$!
8930         sleep 1
8931         cat $DIR/$tfile > /dev/null &
8932         lctl set_param fail_loc=0
8933         pid_reads=$!
8934         wait $pid_dio
8935         log "the DIO writes have completed, now wait for the reads (should not block very long)"
8936         sleep 2
8937         [ -n "`ps h -p $pid_reads -o comm`" ] && \
8938         error "the read rpcs have not completed in 2s"
8939         rm -f $DIR/$tfile
8940         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
8941 }
8942 run_test 119d "The DIO path should try to send a new rpc once one is completed"
8943
8944 test_120a() {
8945         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
8946         remote_mds_nodsh && skip "remote MDS with nodsh" && return
8947         test_mkdir $DIR/$tdir
8948         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
8949                 { skip "no early lock cancel on server"; return 0; }
8950
8951         lru_resize_disable mdc
8952         lru_resize_disable osc
8953         cancel_lru_locks mdc
8954         # asynchronous object destroy at MDT could cause bl ast to client
8955         cancel_lru_locks osc
8956
8957         stat $DIR/$tdir > /dev/null
8958         can1=$(do_facet $SINGLEMDS \
8959                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
8960                awk '/ldlm_cancel/ {print $2}')
8961         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
8962                awk '/ldlm_bl_callback/ {print $2}')
8963         test_mkdir -c1 $DIR/$tdir/d1
8964         can2=$(do_facet $SINGLEMDS \
8965                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
8966                awk '/ldlm_cancel/ {print $2}')
8967         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
8968                awk '/ldlm_bl_callback/ {print $2}')
8969         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
8970         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
8971         lru_resize_enable mdc
8972         lru_resize_enable osc
8973 }
8974 run_test 120a "Early Lock Cancel: mkdir test"
8975
8976 test_120b() {
8977         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
8978         remote_mds_nodsh && skip "remote MDS with nodsh" && return
8979         test_mkdir $DIR/$tdir
8980         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
8981                 { skip "no early lock cancel on server"; return 0; }
8982         lru_resize_disable mdc
8983         lru_resize_disable osc
8984         cancel_lru_locks mdc
8985         stat $DIR/$tdir > /dev/null
8986         can1=$(do_facet $SINGLEMDS \
8987                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
8988                awk '/ldlm_cancel/ {print $2}')
8989         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
8990                awk '/ldlm_bl_callback/ {print $2}')
8991         touch $DIR/$tdir/f1
8992         can2=$(do_facet $SINGLEMDS \
8993                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
8994                awk '/ldlm_cancel/ {print $2}')
8995         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
8996                awk '/ldlm_bl_callback/ {print $2}')
8997         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
8998         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
8999         lru_resize_enable mdc
9000         lru_resize_enable osc
9001 }
9002 run_test 120b "Early Lock Cancel: create test"
9003
9004 test_120c() {
9005         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
9006         remote_mds_nodsh && skip "remote MDS with nodsh" && return
9007         test_mkdir -c1 $DIR/$tdir
9008         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
9009                 { skip "no early lock cancel on server"; return 0; }
9010         lru_resize_disable mdc
9011         lru_resize_disable osc
9012         test_mkdir -c1 $DIR/$tdir/d1
9013         test_mkdir -c1 $DIR/$tdir/d2
9014         touch $DIR/$tdir/d1/f1
9015         cancel_lru_locks mdc
9016         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
9017         can1=$(do_facet $SINGLEMDS \
9018                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9019                awk '/ldlm_cancel/ {print $2}')
9020         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9021                awk '/ldlm_bl_callback/ {print $2}')
9022         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
9023         can2=$(do_facet $SINGLEMDS \
9024                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9025                awk '/ldlm_cancel/ {print $2}')
9026         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9027                awk '/ldlm_bl_callback/ {print $2}')
9028         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
9029         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
9030         lru_resize_enable mdc
9031         lru_resize_enable osc
9032 }
9033 run_test 120c "Early Lock Cancel: link test"
9034
9035 test_120d() {
9036         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
9037         remote_mds_nodsh && skip "remote MDS with nodsh" && return
9038         test_mkdir -c1 $DIR/$tdir
9039         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
9040                 { skip "no early lock cancel on server"; return 0; }
9041         lru_resize_disable mdc
9042         lru_resize_disable osc
9043         touch $DIR/$tdir
9044         cancel_lru_locks mdc
9045         stat $DIR/$tdir > /dev/null
9046         can1=$(do_facet $SINGLEMDS \
9047                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9048                awk '/ldlm_cancel/ {print $2}')
9049         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9050                awk '/ldlm_bl_callback/ {print $2}')
9051         chmod a+x $DIR/$tdir
9052         can2=$(do_facet $SINGLEMDS \
9053                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9054                awk '/ldlm_cancel/ {print $2}')
9055         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9056                awk '/ldlm_bl_callback/ {print $2}')
9057         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
9058         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
9059         lru_resize_enable mdc
9060         lru_resize_enable osc
9061 }
9062 run_test 120d "Early Lock Cancel: setattr test"
9063
9064 test_120e() {
9065         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
9066         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
9067                 { skip "no early lock cancel on server"; return 0; }
9068         remote_mds_nodsh && skip "remote MDS with nodsh" && return
9069         local dlmtrace_set=false
9070
9071         test_mkdir -c1 $DIR/$tdir
9072         lru_resize_disable mdc
9073         lru_resize_disable osc
9074         ! $LCTL get_param debug | grep -q dlmtrace &&
9075                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
9076         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
9077         cancel_lru_locks mdc
9078         cancel_lru_locks osc
9079         dd if=$DIR/$tdir/f1 of=/dev/null
9080         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
9081         # XXX client can not do early lock cancel of OST lock
9082         # during unlink (LU-4206), so cancel osc lock now.
9083         sleep 2
9084         cancel_lru_locks osc
9085         can1=$(do_facet $SINGLEMDS \
9086                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9087                awk '/ldlm_cancel/ {print $2}')
9088         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9089                awk '/ldlm_bl_callback/ {print $2}')
9090         unlink $DIR/$tdir/f1
9091         sleep 5
9092         can2=$(do_facet $SINGLEMDS \
9093                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9094                awk '/ldlm_cancel/ {print $2}')
9095         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9096                awk '/ldlm_bl_callback/ {print $2}')
9097         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
9098                 $LCTL dk $TMP/cancel.debug.txt
9099         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
9100                 $LCTL dk $TMP/blocking.debug.txt
9101         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
9102         lru_resize_enable mdc
9103         lru_resize_enable osc
9104 }
9105 run_test 120e "Early Lock Cancel: unlink test"
9106
9107 test_120f() {
9108         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
9109         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
9110                 { skip "no early lock cancel on server"; return 0; }
9111         remote_mds_nodsh && skip "remote MDS with nodsh" && return
9112         test_mkdir -c1 $DIR/$tdir
9113         lru_resize_disable mdc
9114         lru_resize_disable osc
9115         test_mkdir -c1 $DIR/$tdir/d1
9116         test_mkdir -c1 $DIR/$tdir/d2
9117         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
9118         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
9119         cancel_lru_locks mdc
9120         cancel_lru_locks osc
9121         dd if=$DIR/$tdir/d1/f1 of=/dev/null
9122         dd if=$DIR/$tdir/d2/f2 of=/dev/null
9123         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
9124         # XXX client can not do early lock cancel of OST lock
9125         # during rename (LU-4206), so cancel osc lock now.
9126         sleep 2
9127         cancel_lru_locks osc
9128         can1=$(do_facet $SINGLEMDS \
9129                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9130                awk '/ldlm_cancel/ {print $2}')
9131         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9132                awk '/ldlm_bl_callback/ {print $2}')
9133         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
9134         sleep 5
9135         can2=$(do_facet $SINGLEMDS \
9136                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9137                awk '/ldlm_cancel/ {print $2}')
9138         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9139                awk '/ldlm_bl_callback/ {print $2}')
9140         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
9141         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
9142         lru_resize_enable mdc
9143         lru_resize_enable osc
9144 }
9145 run_test 120f "Early Lock Cancel: rename test"
9146
9147 test_120g() {
9148         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
9149         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
9150                 { skip "no early lock cancel on server"; return 0; }
9151         remote_mds_nodsh && skip "remote MDS with nodsh" && return
9152         lru_resize_disable mdc
9153         lru_resize_disable osc
9154         count=10000
9155         echo create $count files
9156         test_mkdir $DIR/$tdir
9157         cancel_lru_locks mdc
9158         cancel_lru_locks osc
9159         t0=$(date +%s)
9160
9161         can0=$(do_facet $SINGLEMDS \
9162                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9163                awk '/ldlm_cancel/ {print $2}')
9164         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9165                awk '/ldlm_bl_callback/ {print $2}')
9166         createmany -o $DIR/$tdir/f $count
9167         sync
9168         can1=$(do_facet $SINGLEMDS \
9169                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9170                awk '/ldlm_cancel/ {print $2}')
9171         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9172                awk '/ldlm_bl_callback/ {print $2}')
9173         t1=$(date +%s)
9174         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
9175         echo rm $count files
9176         rm -r $DIR/$tdir
9177         sync
9178         can2=$(do_facet $SINGLEMDS \
9179                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9180                awk '/ldlm_cancel/ {print $2}')
9181         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9182                awk '/ldlm_bl_callback/ {print $2}')
9183         t2=$(date +%s)
9184         echo total: $count removes in $((t2-t1))
9185         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
9186         sleep 2
9187         # wait for commitment of removal
9188         lru_resize_enable mdc
9189         lru_resize_enable osc
9190 }
9191 run_test 120g "Early Lock Cancel: performance test"
9192
9193 test_121() { #bug #10589
9194         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
9195         rm -rf $DIR/$tfile
9196         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
9197 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
9198         lctl set_param fail_loc=0x310
9199         cancel_lru_locks osc > /dev/null
9200         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
9201         lctl set_param fail_loc=0
9202         [[ $reads -eq $writes ]] ||
9203                 error "read $reads blocks, must be $writes blocks"
9204 }
9205 run_test 121 "read cancel race ========="
9206
9207 test_123a() { # was test 123, statahead(bug 11401)
9208         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
9209         SLOWOK=0
9210         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
9211                 log "testing UP system. Performance may be lower than expected."
9212                 SLOWOK=1
9213         fi
9214
9215         rm -rf $DIR/$tdir
9216         test_mkdir $DIR/$tdir
9217         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
9218         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
9219         MULT=10
9220         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
9221                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
9222
9223                 max=`lctl get_param -n llite.*.statahead_max | head -n 1`
9224                 lctl set_param -n llite.*.statahead_max 0
9225                 lctl get_param llite.*.statahead_max
9226                 cancel_lru_locks mdc
9227                 cancel_lru_locks osc
9228                 stime=`date +%s`
9229                 time ls -l $DIR/$tdir | wc -l
9230                 etime=`date +%s`
9231                 delta=$((etime - stime))
9232                 log "ls $i files without statahead: $delta sec"
9233                 lctl set_param llite.*.statahead_max=$max
9234
9235                 swrong=`lctl get_param -n llite.*.statahead_stats | grep "statahead wrong:" | awk '{print $3}'`
9236                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
9237                 cancel_lru_locks mdc
9238                 cancel_lru_locks osc
9239                 stime=`date +%s`
9240                 time ls -l $DIR/$tdir | wc -l
9241                 etime=`date +%s`
9242                 delta_sa=$((etime - stime))
9243                 log "ls $i files with statahead: $delta_sa sec"
9244                 lctl get_param -n llite.*.statahead_stats
9245                 ewrong=`lctl get_param -n llite.*.statahead_stats | grep "statahead wrong:" | awk '{print $3}'`
9246
9247                 [[ $swrong -lt $ewrong ]] &&
9248                         log "statahead was stopped, maybe too many locks held!"
9249                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
9250
9251                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
9252                     max=`lctl get_param -n llite.*.statahead_max | head -n 1`
9253                     lctl set_param -n llite.*.statahead_max 0
9254                     lctl get_param llite.*.statahead_max
9255                     cancel_lru_locks mdc
9256                     cancel_lru_locks osc
9257                     stime=`date +%s`
9258                     time ls -l $DIR/$tdir | wc -l
9259                     etime=`date +%s`
9260                     delta=$((etime - stime))
9261                     log "ls $i files again without statahead: $delta sec"
9262                     lctl set_param llite.*.statahead_max=$max
9263                     if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
9264                         if [  $SLOWOK -eq 0 ]; then
9265                                 error "ls $i files is slower with statahead!"
9266                         else
9267                                 log "ls $i files is slower with statahead!"
9268                         fi
9269                         break
9270                     fi
9271                 fi
9272
9273                 [ $delta -gt 20 ] && break
9274                 [ $delta -gt 8 ] && MULT=$((50 / delta))
9275                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
9276         done
9277         log "ls done"
9278
9279         stime=`date +%s`
9280         rm -r $DIR/$tdir
9281         sync
9282         etime=`date +%s`
9283         delta=$((etime - stime))
9284         log "rm -r $DIR/$tdir/: $delta seconds"
9285         log "rm done"
9286         lctl get_param -n llite.*.statahead_stats
9287 }
9288 run_test 123a "verify statahead work"
9289
9290 test_123b () { # statahead(bug 15027)
9291         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
9292         test_mkdir $DIR/$tdir
9293         createmany -o $DIR/$tdir/$tfile-%d 1000
9294
9295         cancel_lru_locks mdc
9296         cancel_lru_locks osc
9297
9298 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
9299         lctl set_param fail_loc=0x80000803
9300         ls -lR $DIR/$tdir > /dev/null
9301         log "ls done"
9302         lctl set_param fail_loc=0x0
9303         lctl get_param -n llite.*.statahead_stats
9304         rm -r $DIR/$tdir
9305         sync
9306
9307 }
9308 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
9309
9310 test_124a() {
9311         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
9312         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
9313                 { skip "no lru resize on server"; return 0; }
9314         local NR=2000
9315         test_mkdir $DIR/$tdir
9316
9317         log "create $NR files at $DIR/$tdir"
9318         createmany -o $DIR/$tdir/f $NR ||
9319                 error "failed to create $NR files in $DIR/$tdir"
9320
9321         cancel_lru_locks mdc
9322         ls -l $DIR/$tdir > /dev/null
9323
9324         local NSDIR=""
9325         local LRU_SIZE=0
9326         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
9327                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
9328                 LRU_SIZE=$($LCTL get_param -n $PARAM)
9329                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
9330                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
9331                         log "NSDIR=$NSDIR"
9332                         log "NS=$(basename $NSDIR)"
9333                         break
9334                 fi
9335         done
9336
9337         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
9338                 skip "Not enough cached locks created!"
9339                 return 0
9340         fi
9341         log "LRU=$LRU_SIZE"
9342
9343         local SLEEP=30
9344
9345         # We know that lru resize allows one client to hold $LIMIT locks
9346         # for 10h. After that locks begin to be killed by client.
9347         local MAX_HRS=10
9348         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
9349         log "LIMIT=$LIMIT"
9350         if [ $LIMIT -lt $LRU_SIZE ]; then
9351             skip "Limit is too small $LIMIT"
9352             return 0
9353         fi
9354
9355         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
9356         # killing locks. Some time was spent for creating locks. This means
9357         # that up to the moment of sleep finish we must have killed some of
9358         # them (10-100 locks). This depends on how fast ther were created.
9359         # Many of them were touched in almost the same moment and thus will
9360         # be killed in groups.
9361         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE))
9362
9363         # Use $LRU_SIZE_B here to take into account real number of locks
9364         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
9365         local LRU_SIZE_B=$LRU_SIZE
9366         log "LVF=$LVF"
9367         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
9368         log "OLD_LVF=$OLD_LVF"
9369         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
9370
9371         # Let's make sure that we really have some margin. Client checks
9372         # cached locks every 10 sec.
9373         SLEEP=$((SLEEP+20))
9374         log "Sleep ${SLEEP} sec"
9375         local SEC=0
9376         while ((SEC<$SLEEP)); do
9377                 echo -n "..."
9378                 sleep 5
9379                 SEC=$((SEC+5))
9380                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
9381                 echo -n "$LRU_SIZE"
9382         done
9383         echo ""
9384         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
9385         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
9386
9387         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
9388                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
9389                 unlinkmany $DIR/$tdir/f $NR
9390                 return
9391         }
9392
9393         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
9394         log "unlink $NR files at $DIR/$tdir"
9395         unlinkmany $DIR/$tdir/f $NR
9396 }
9397 run_test 124a "lru resize ======================================="
9398
9399 get_max_pool_limit()
9400 {
9401         local limit=$($LCTL get_param \
9402                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
9403         local max=0
9404         for l in $limit; do
9405                 if [[ $l -gt $max ]]; then
9406                         max=$l
9407                 fi
9408         done
9409         echo $max
9410 }
9411
9412 test_124b() {
9413         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
9414         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
9415                 { skip "no lru resize on server"; return 0; }
9416
9417         LIMIT=$(get_max_pool_limit)
9418
9419         NR=$(($(default_lru_size)*20))
9420         if [[ $NR -gt $LIMIT ]]; then
9421                 log "Limit lock number by $LIMIT locks"
9422                 NR=$LIMIT
9423         fi
9424
9425         IFree=$(mdsrate_inodes_available)
9426         if [ $IFree -lt $NR ]; then
9427                 log "Limit lock number by $IFree inodes"
9428                 NR=$IFree
9429         fi
9430
9431         lru_resize_disable mdc
9432         test_mkdir -p $DIR/$tdir/disable_lru_resize
9433
9434         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
9435         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
9436         cancel_lru_locks mdc
9437         stime=`date +%s`
9438         PID=""
9439         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
9440         PID="$PID $!"
9441         sleep 2
9442         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
9443         PID="$PID $!"
9444         sleep 2
9445         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
9446         PID="$PID $!"
9447         wait $PID
9448         etime=`date +%s`
9449         nolruresize_delta=$((etime-stime))
9450         log "ls -la time: $nolruresize_delta seconds"
9451         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
9452         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
9453
9454         lru_resize_enable mdc
9455         test_mkdir -p $DIR/$tdir/enable_lru_resize
9456
9457         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
9458         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
9459         cancel_lru_locks mdc
9460         stime=`date +%s`
9461         PID=""
9462         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
9463         PID="$PID $!"
9464         sleep 2
9465         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
9466         PID="$PID $!"
9467         sleep 2
9468         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
9469         PID="$PID $!"
9470         wait $PID
9471         etime=`date +%s`
9472         lruresize_delta=$((etime-stime))
9473         log "ls -la time: $lruresize_delta seconds"
9474         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
9475
9476         if [ $lruresize_delta -gt $nolruresize_delta ]; then
9477                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
9478         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
9479                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
9480         else
9481                 log "lru resize performs the same with no lru resize"
9482         fi
9483         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
9484 }
9485 run_test 124b "lru resize (performance test) ======================="
9486
9487 test_124c() {
9488         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
9489         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
9490                 { skip "no lru resize on server"; return 0; }
9491
9492         # cache ununsed locks on client
9493         local nr=100
9494         cancel_lru_locks mdc
9495         test_mkdir $DIR/$tdir
9496         createmany -o $DIR/$tdir/f $nr ||
9497                 error "failed to create $nr files in $DIR/$tdir"
9498         ls -l $DIR/$tdir > /dev/null
9499
9500         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
9501         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
9502         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
9503         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
9504         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
9505
9506         # set lru_max_age to 1 sec
9507         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
9508         echo "sleep $((recalc_p * 2)) seconds..."
9509         sleep $((recalc_p * 2))
9510
9511         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
9512         # restore lru_max_age
9513         $LCTL set_param -n $nsdir.lru_max_age $max_age
9514         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
9515         unlinkmany $DIR/$tdir/f $nr
9516 }
9517 run_test 124c "LRUR cancel very aged locks"
9518
9519 test_125() { # 13358
9520         $LCTL get_param -n llite.*.client_type | grep -q local ||
9521                 { skip "must run as local client"; return; }
9522         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
9523                 { skip "must have acl enabled"; return; }
9524         [ -z "$(which setfacl)" ] && skip "must have setfacl tool" && return
9525         test_mkdir $DIR/$tdir
9526         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
9527         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
9528         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
9529 }
9530 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
9531
9532 test_126() { # bug 12829/13455
9533         $LCTL get_param -n llite.*.client_type | grep -q local ||
9534                 { skip "must run as local client"; return; }
9535         [ "$UID" != 0 ] && skip_env "$TESTNAME (must run as root)" && return
9536         $GSS && skip "must run as gss disabled" && return
9537
9538         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
9539         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
9540         rm -f $DIR/$tfile
9541         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
9542 }
9543 run_test 126 "check that the fsgid provided by the client is taken into account"
9544
9545 test_127a() { # bug 15521
9546         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
9547         $SETSTRIPE -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
9548         $LCTL set_param osc.*.stats=0
9549         FSIZE=$((2048 * 1024))
9550         dd if=/dev/zero of=$DIR/$tfile bs=$FSIZE count=1
9551         cancel_lru_locks osc
9552         dd if=$DIR/$tfile of=/dev/null bs=$FSIZE
9553
9554         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/${tfile}.tmp
9555         while read NAME COUNT SAMP UNIT MIN MAX SUM SUMSQ; do
9556                 echo "got $COUNT $NAME"
9557                 [ ! $MIN ] && error "Missing min value for $NAME proc entry"
9558                 eval $NAME=$COUNT || error "Wrong proc format"
9559
9560                 case $NAME in
9561                         read_bytes|write_bytes)
9562                         [ $MIN -lt 4096 ] && error "min is too small: $MIN"
9563                         [ $MIN -gt $FSIZE ] && error "min is too big: $MIN"
9564                         [ $MAX -lt 4096 ] && error "max is too small: $MAX"
9565                         [ $MAX -gt $FSIZE ] && error "max is too big: $MAX"
9566                         [ $SUM -ne $FSIZE ] && error "sum is wrong: $SUM"
9567                         [ $SUMSQ -lt $(((FSIZE /4096) * (4096 * 4096))) ] &&
9568                                 error "sumsquare is too small: $SUMSQ"
9569                         [ $SUMSQ -gt $((FSIZE * FSIZE)) ] &&
9570                                 error "sumsquare is too big: $SUMSQ"
9571                         ;;
9572                         *) ;;
9573                 esac
9574         done < $DIR/${tfile}.tmp
9575
9576         #check that we actually got some stats
9577         [ "$read_bytes" ] || error "Missing read_bytes stats"
9578         [ "$write_bytes" ] || error "Missing write_bytes stats"
9579         [ "$read_bytes" != 0 ] || error "no read done"
9580         [ "$write_bytes" != 0 ] || error "no write done"
9581 }
9582 run_test 127a "verify the client stats are sane"
9583
9584 test_127b() { # bug LU-333
9585         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
9586         $LCTL set_param llite.*.stats=0
9587         FSIZE=65536 # sized fixed to match PAGE_SIZE for most clients
9588         # perform 2 reads and writes so MAX is different from SUM.
9589         dd if=/dev/zero of=$DIR/$tfile bs=$FSIZE count=1
9590         dd if=/dev/zero of=$DIR/$tfile bs=$FSIZE count=1
9591         cancel_lru_locks osc
9592         dd if=$DIR/$tfile of=/dev/null bs=$FSIZE count=1
9593         dd if=$DIR/$tfile of=/dev/null bs=$FSIZE count=1
9594
9595         $LCTL get_param llite.*.stats | grep samples > $TMP/${tfile}.tmp
9596         while read NAME COUNT SAMP UNIT MIN MAX SUM SUMSQ; do
9597                 echo "got $COUNT $NAME"
9598                 eval $NAME=$COUNT || error "Wrong proc format"
9599
9600         case $NAME in
9601                 read_bytes)
9602                         [ $COUNT -ne 2 ] && error "count is not 2: $COUNT"
9603                         [ $MIN -ne $FSIZE ] && error "min is not $FSIZE: $MIN"
9604                         [ $MAX -ne $FSIZE ] && error "max is incorrect: $MAX"
9605                         [ $SUM -ne $((FSIZE * 2)) ] && error "sum is wrong: $SUM"
9606                         ;;
9607                 write_bytes)
9608                         [ $COUNT -ne 2 ] && error "count is not 2: $COUNT"
9609                         [ $MIN -ne $FSIZE ] && error "min is not $FSIZE: $MIN"
9610                         [ $MAX -ne $FSIZE ] && error "max is incorrect: $MAX"
9611                         [ $SUM -ne $((FSIZE * 2)) ] && error "sum is wrong: $SUM"
9612                         ;;
9613                         *) ;;
9614                 esac
9615         done < $TMP/${tfile}.tmp
9616
9617         #check that we actually got some stats
9618         [ "$read_bytes" ] || error "Missing read_bytes stats"
9619         [ "$write_bytes" ] || error "Missing write_bytes stats"
9620         [ "$read_bytes" != 0 ] || error "no read done"
9621         [ "$write_bytes" != 0 ] || error "no write done"
9622
9623         rm -f $TMP/${tfile}.tmp
9624 }
9625 run_test 127b "verify the llite client stats are sane"
9626
9627 test_128() { # bug 15212
9628         touch $DIR/$tfile
9629         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
9630                 find $DIR/$tfile
9631                 find $DIR/$tfile
9632         EOF
9633
9634         result=$(grep error $TMP/$tfile.log)
9635         rm -f $DIR/$tfile $TMP/$tfile.log
9636         [ -z "$result" ] ||
9637                 error "consecutive find's under interactive lfs failed"
9638 }
9639 run_test 128 "interactive lfs for 2 consecutive find's"
9640
9641 set_dir_limits () {
9642         local mntdev
9643         local canondev
9644         local node
9645
9646         local ldproc=/proc/fs/ldiskfs
9647         local facets=$(get_facets MDS)
9648
9649         for facet in ${facets//,/ }; do
9650                 canondev=$(ldiskfs_canon \
9651                            *.$(convert_facet2label $facet).mntdev $facet)
9652                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
9653                         ldproc=/sys/fs/ldiskfs
9654                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
9655                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
9656         done
9657 }
9658
9659 check_mds_dmesg() {
9660         local facets=$(get_facets MDS)
9661         for facet in ${facets//,/ }; do
9662                 do_facet $facet "dmesg | tail -3 | grep -q $1" && return 0
9663         done
9664         return 1
9665 }
9666
9667 test_129() {
9668         [[ $(lustre_version_code $SINGLEMDS) -ge $(version_code 2.5.56) ]] ||
9669                 { skip "Need MDS version with at least 2.5.56"; return 0; }
9670
9671         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
9672         if [ "$(facet_fstype $SINGLEMDS)" != ldiskfs ]; then
9673                 skip "ldiskfs only test"
9674                 return
9675         fi
9676         remote_mds_nodsh && skip "remote MDS with nodsh" && return
9677         local ENOSPC=28
9678         local EFBIG=27
9679         local has_warning=false
9680
9681         rm -rf $DIR/$tdir
9682         mkdir -p $DIR/$tdir
9683
9684         # block size of mds1
9685         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 5))
9686         set_dir_limits $maxsize $maxsize
9687         local dirsize=$(stat -c%s "$DIR/$tdir")
9688         local nfiles=0
9689         while [[ $dirsize -le $maxsize ]]; do
9690                 $MULTIOP $DIR/$tdir/file_base_$nfiles Oc
9691                 rc=$?
9692                 if ! $has_warning; then
9693                         check_mds_dmesg '"is approaching"' && has_warning=true
9694                 fi
9695                 # check two errors:
9696                 # ENOSPC for new ext4 max_dir_size (kernel commit df981d03ee)
9697                 # EFBIG for previous versions included in ldiskfs series
9698                 if [ $rc -eq $EFBIG -o $rc -eq $ENOSPC ]; then
9699                         set_dir_limits 0 0
9700                         echo "return code $rc received as expected"
9701
9702                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
9703                                 error_exit "create failed w/o dir size limit"
9704
9705                         check_mds_dmesg '"has reached"' ||
9706                                 error_exit "reached message should be output"
9707
9708                         [ $has_warning = "false" ] &&
9709                                 error_exit "warning message should be output"
9710
9711                         dirsize=$(stat -c%s "$DIR/$tdir")
9712
9713                         [[ $dirsize -ge $maxsize ]] && return 0
9714                         error_exit "current dir size $dirsize, " \
9715                                    "previous limit $maxsize"
9716                 elif [ $rc -ne 0 ]; then
9717                         set_dir_limits 0 0
9718                         error_exit "return $rc received instead of expected " \
9719                                    "$EFBIG or $ENOSPC, files in dir $dirsize"
9720                 fi
9721                 nfiles=$((nfiles + 1))
9722                 dirsize=$(stat -c%s "$DIR/$tdir")
9723         done
9724
9725         set_dir_limits 0 0
9726         error "exceeded dir size limit $maxsize($MDSCOUNT) : $dirsize bytes"
9727 }
9728 run_test 129 "test directory size limit ========================"
9729
9730 OLDIFS="$IFS"
9731 cleanup_130() {
9732         trap 0
9733         IFS="$OLDIFS"
9734 }
9735
9736 test_130a() {
9737         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
9738         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP" &&
9739                 return
9740
9741         trap cleanup_130 EXIT RETURN
9742
9743         local fm_file=$DIR/$tfile
9744         $SETSTRIPE -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
9745         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
9746                 error "dd failed for $fm_file"
9747
9748         # LU-1795: test filefrag/FIEMAP once, even if unsupported
9749         filefrag -ves $fm_file
9750         RC=$?
9751         [ "$(facet_fstype ost$(($($GETSTRIPE -i $fm_file) + 1)))" = "zfs" ] &&
9752                 skip "ORI-366/LU-1941: FIEMAP unimplemented on ZFS" && return
9753         [ $RC != 0 ] && error "filefrag $fm_file failed"
9754
9755         filefrag_op=$(filefrag -ve -k $fm_file |
9756                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
9757         lun=$($GETSTRIPE -i $fm_file)
9758
9759         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
9760         IFS=$'\n'
9761         tot_len=0
9762         for line in $filefrag_op
9763         do
9764                 frag_lun=`echo $line | cut -d: -f5`
9765                 ext_len=`echo $line | cut -d: -f4`
9766                 if (( $frag_lun != $lun )); then
9767                         cleanup_130
9768                         error "FIEMAP on 1-stripe file($fm_file) failed"
9769                         return
9770                 fi
9771                 (( tot_len += ext_len ))
9772         done
9773
9774         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
9775                 cleanup_130
9776                 error "FIEMAP on 1-stripe file($fm_file) failed;"
9777                 return
9778         fi
9779
9780         cleanup_130
9781
9782         echo "FIEMAP on single striped file succeeded"
9783 }
9784 run_test 130a "FIEMAP (1-stripe file)"
9785
9786 test_130b() {
9787         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs" && return
9788
9789         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
9790         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP" &&
9791                 return
9792
9793         trap cleanup_130 EXIT RETURN
9794
9795         local fm_file=$DIR/$tfile
9796         $SETSTRIPE -S 65536 -c $OSTCOUNT $fm_file ||
9797                         error "setstripe on $fm_file"
9798         [ "$(facet_fstype ost$(($($GETSTRIPE -i $fm_file) + 1)))" = "zfs" ] &&
9799                 skip "ORI-366/LU-1941: FIEMAP unimplemented on ZFS" && return
9800
9801         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
9802                 error "dd failed on $fm_file"
9803
9804         filefrag -ves $fm_file || error "filefrag $fm_file failed"
9805         filefrag_op=$(filefrag -ve -k $fm_file |
9806                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
9807
9808         last_lun=$(echo $filefrag_op | cut -d: -f5 |
9809                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
9810
9811         IFS=$'\n'
9812         tot_len=0
9813         num_luns=1
9814         for line in $filefrag_op
9815         do
9816                 frag_lun=$(echo $line | cut -d: -f5 |
9817                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
9818                 ext_len=$(echo $line | cut -d: -f4)
9819                 if (( $frag_lun != $last_lun )); then
9820                         if (( tot_len != 1024 )); then
9821                                 cleanup_130
9822                                 error "FIEMAP on $fm_file failed; returned " \
9823                                 "len $tot_len for OST $last_lun instead of 1024"
9824                                 return
9825                         else
9826                                 (( num_luns += 1 ))
9827                                 tot_len=0
9828                         fi
9829                 fi
9830                 (( tot_len += ext_len ))
9831                 last_lun=$frag_lun
9832         done
9833         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
9834                 cleanup_130
9835                 error "FIEMAP on $fm_file failed; returned wrong number of " \
9836                         "luns or wrong len for OST $last_lun"
9837                 return
9838         fi
9839
9840         cleanup_130
9841
9842         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
9843 }
9844 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
9845
9846 test_130c() {
9847         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs" && return
9848
9849         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
9850         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP" &&
9851                 return
9852
9853         trap cleanup_130 EXIT RETURN
9854
9855         local fm_file=$DIR/$tfile
9856         $SETSTRIPE -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
9857         [ "$(facet_fstype ost$(($($GETSTRIPE -i $fm_file) + 1)))" = "zfs" ] &&
9858                 skip "ORI-366/LU-1941: FIEMAP unimplemented on ZFS" && return
9859
9860         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
9861                         error "dd failed on $fm_file"
9862
9863         filefrag -ves $fm_file || error "filefrag $fm_file failed"
9864         filefrag_op=$(filefrag -ve -k $fm_file |
9865                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
9866
9867         last_lun=$(echo $filefrag_op | cut -d: -f5 |
9868                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
9869
9870         IFS=$'\n'
9871         tot_len=0
9872         num_luns=1
9873         for line in $filefrag_op
9874         do
9875                 frag_lun=$(echo $line | cut -d: -f5 |
9876                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
9877                 ext_len=$(echo $line | cut -d: -f4)
9878                 if (( $frag_lun != $last_lun )); then
9879                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
9880                         if (( logical != 512 )); then
9881                                 cleanup_130
9882                                 error "FIEMAP on $fm_file failed; returned " \
9883                                 "logical start for lun $logical instead of 512"
9884                                 return
9885                         fi
9886                         if (( tot_len != 512 )); then
9887                                 cleanup_130
9888                                 error "FIEMAP on $fm_file failed; returned " \
9889                                 "len $tot_len for OST $last_lun instead of 1024"
9890                                 return
9891                         else
9892                                 (( num_luns += 1 ))
9893                                 tot_len=0
9894                         fi
9895                 fi
9896                 (( tot_len += ext_len ))
9897                 last_lun=$frag_lun
9898         done
9899         if (( num_luns != 2 || tot_len != 512 )); then
9900                 cleanup_130
9901                 error "FIEMAP on $fm_file failed; returned wrong number of " \
9902                         "luns or wrong len for OST $last_lun"
9903                 return
9904         fi
9905
9906         cleanup_130
9907
9908         echo "FIEMAP on 2-stripe file with hole succeeded"
9909 }
9910 run_test 130c "FIEMAP (2-stripe file with hole)"
9911
9912 test_130d() {
9913         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs" && return
9914
9915         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
9916         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP" &&
9917                 return
9918
9919         trap cleanup_130 EXIT RETURN
9920
9921         local fm_file=$DIR/$tfile
9922         $SETSTRIPE -S 65536 -c $OSTCOUNT $fm_file ||
9923                         error "setstripe on $fm_file"
9924         [ "$(facet_fstype ost$(($($GETSTRIPE -i $fm_file) + 1)))" = "zfs" ] &&
9925                 skip "ORI-366/LU-1941: FIEMAP unimplemented on ZFS" && return
9926
9927         local actual_stripe_count=$($GETSTRIPE -c $fm_file)
9928         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
9929                 error "dd failed on $fm_file"
9930
9931         filefrag -ves $fm_file || error "filefrag $fm_file failed"
9932         filefrag_op=$(filefrag -ve -k $fm_file |
9933                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
9934
9935         last_lun=$(echo $filefrag_op | cut -d: -f5 |
9936                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
9937
9938         IFS=$'\n'
9939         tot_len=0
9940         num_luns=1
9941         for line in $filefrag_op
9942         do
9943                 frag_lun=$(echo $line | cut -d: -f5 |
9944                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
9945                 ext_len=$(echo $line | cut -d: -f4)
9946                 if (( $frag_lun != $last_lun )); then
9947                         if (( tot_len != 1024 )); then
9948                                 cleanup_130
9949                                 error "FIEMAP on $fm_file failed; returned " \
9950                                 "len $tot_len for OST $last_lun instead of 1024"
9951                                 return
9952                         else
9953                                 (( num_luns += 1 ))
9954                                 tot_len=0
9955                         fi
9956                 fi
9957                 (( tot_len += ext_len ))
9958                 last_lun=$frag_lun
9959         done
9960         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
9961                 cleanup_130
9962                 error "FIEMAP on $fm_file failed; returned wrong number of " \
9963                         "luns or wrong len for OST $last_lun"
9964                 return
9965         fi
9966
9967         cleanup_130
9968
9969         echo "FIEMAP on N-stripe file succeeded"
9970 }
9971 run_test 130d "FIEMAP (N-stripe file)"
9972
9973 test_130e() {
9974         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs" && return
9975
9976         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
9977         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP" && return
9978
9979         trap cleanup_130 EXIT RETURN
9980
9981         local fm_file=$DIR/$tfile
9982         $SETSTRIPE -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
9983         [ "$(facet_fstype ost$(($($GETSTRIPE -i $fm_file) + 1)))" = "zfs" ] &&
9984                 skip "ORI-366/LU-1941: FIEMAP unimplemented on ZFS" && return
9985
9986         NUM_BLKS=512
9987         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
9988         for ((i = 0; i < $NUM_BLKS; i++))
9989         do
9990                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) conv=notrunc > /dev/null 2>&1
9991         done
9992
9993         filefrag -ves $fm_file || error "filefrag $fm_file failed"
9994         filefrag_op=$(filefrag -ve -k $fm_file |
9995                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
9996
9997         last_lun=$(echo $filefrag_op | cut -d: -f5 |
9998                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
9999
10000         IFS=$'\n'
10001         tot_len=0
10002         num_luns=1
10003         for line in $filefrag_op
10004         do
10005                 frag_lun=$(echo $line | cut -d: -f5 |
10006                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
10007                 ext_len=$(echo $line | cut -d: -f4)
10008                 if (( $frag_lun != $last_lun )); then
10009                         if (( tot_len != $EXPECTED_LEN )); then
10010                                 cleanup_130
10011                                 error "FIEMAP on $fm_file failed; returned " \
10012                                 "len $tot_len for OST $last_lun instead " \
10013                                 "of $EXPECTED_LEN"
10014                                 return
10015                         else
10016                                 (( num_luns += 1 ))
10017                                 tot_len=0
10018                         fi
10019                 fi
10020                 (( tot_len += ext_len ))
10021                 last_lun=$frag_lun
10022         done
10023         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
10024                 cleanup_130
10025                 error "FIEMAP on $fm_file failed; returned wrong number " \
10026                         "of luns or wrong len for OST $last_lun"
10027                 return
10028         fi
10029
10030         cleanup_130
10031
10032         echo "FIEMAP with continuation calls succeeded"
10033 }
10034 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
10035
10036 # Test for writev/readv
10037 test_131a() {
10038         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
10039                 error "writev test failed"
10040         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
10041                 error "readv failed"
10042         rm -f $DIR/$tfile
10043 }
10044 run_test 131a "test iov's crossing stripe boundary for writev/readv"
10045
10046 test_131b() {
10047         local fsize=$((524288 + 1048576 + 1572864))
10048         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
10049                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
10050                         error "append writev test failed"
10051
10052         ((fsize += 1572864 + 1048576))
10053         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
10054                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
10055                         error "append writev test failed"
10056         rm -f $DIR/$tfile
10057 }
10058 run_test 131b "test append writev"
10059
10060 test_131c() {
10061         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
10062         error "NOT PASS"
10063 }
10064 run_test 131c "test read/write on file w/o objects"
10065
10066 test_131d() {
10067         rwv -f $DIR/$tfile -w -n 1 1572864
10068         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
10069         if [ "$NOB" != 1572864 ]; then
10070                 error "Short read filed: read $NOB bytes instead of 1572864"
10071         fi
10072         rm -f $DIR/$tfile
10073 }
10074 run_test 131d "test short read"
10075
10076 test_131e() {
10077         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
10078         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
10079         error "read hitting hole failed"
10080         rm -f $DIR/$tfile
10081 }
10082 run_test 131e "test read hitting hole"
10083
10084 check_stats() {
10085         local facet=$1
10086         local op=$2
10087         local want=${3:-0}
10088         local res
10089
10090         case $facet in
10091         mds*) res=$(do_facet $facet \
10092                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
10093                  ;;
10094         ost*) res=$(do_facet $facet \
10095                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
10096                  ;;
10097         *) error "Wrong facet '$facet'" ;;
10098         esac
10099         echo $res
10100         [ "$res" ] || error "The counter for $op on $facet was not incremented"
10101         # if the argument $3 is zero, it means any stat increment is ok.
10102         if [[ $want -gt 0 ]]; then
10103                 local count=$(echo $res | awk '{ print $2 }')
10104                 [[ $count -ne $want ]] &&
10105                         error "The $op counter on $facet is $count, not $want"
10106         fi
10107 }
10108
10109 test_133a() {
10110         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
10111         remote_ost_nodsh && skip "remote OST with nodsh" && return
10112         remote_mds_nodsh && skip "remote MDS with nodsh" && return
10113
10114         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
10115                 { skip "MDS doesn't support rename stats"; return; }
10116         local testdir=$DIR/${tdir}/stats_testdir
10117         mkdir -p $DIR/${tdir}
10118
10119         # clear stats.
10120         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
10121         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
10122
10123         # verify mdt stats first.
10124         mkdir ${testdir} || error "mkdir failed"
10125         check_stats $SINGLEMDS "mkdir" 1
10126         touch ${testdir}/${tfile} || error "touch failed"
10127         check_stats $SINGLEMDS "open" 1
10128         check_stats $SINGLEMDS "close" 1
10129         [ $(lustre_version_code $SINGLEMDS) -ge $(version_code 2.8.54) ] && {
10130                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
10131                 check_stats $SINGLEMDS "mknod" 2
10132         }
10133         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
10134         check_stats $SINGLEMDS "unlink" 1
10135         rm -f ${testdir}/${tfile} || error "file remove failed"
10136         check_stats $SINGLEMDS "unlink" 2
10137
10138         # remove working dir and check mdt stats again.
10139         rmdir ${testdir} || error "rmdir failed"
10140         check_stats $SINGLEMDS "rmdir" 1
10141
10142         local testdir1=$DIR/${tdir}/stats_testdir1
10143         mkdir -p ${testdir}
10144         mkdir -p ${testdir1}
10145         touch ${testdir1}/test1
10146         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
10147         check_stats $SINGLEMDS "crossdir_rename" 1
10148
10149         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
10150         check_stats $SINGLEMDS "samedir_rename" 1
10151
10152         rm -rf $DIR/${tdir}
10153 }
10154 run_test 133a "Verifying MDT stats ========================================"
10155
10156 test_133b() {
10157         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
10158         remote_ost_nodsh && skip "remote OST with nodsh" && return
10159         remote_mds_nodsh && skip "remote MDS with nodsh" && return
10160         local testdir=$DIR/${tdir}/stats_testdir
10161         mkdir -p ${testdir} || error "mkdir failed"
10162         touch ${testdir}/${tfile} || error "touch failed"
10163         cancel_lru_locks mdc
10164
10165         # clear stats.
10166         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
10167         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
10168
10169         # extra mdt stats verification.
10170         chmod 444 ${testdir}/${tfile} || error "chmod failed"
10171         check_stats $SINGLEMDS "setattr" 1
10172         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
10173         if [ $(lustre_version_code $SINGLEMDS) -ne $(version_code 2.2.0) ]
10174         then            # LU-1740
10175                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
10176                 check_stats $SINGLEMDS "getattr" 1
10177         fi
10178         $LFS df || error "lfs failed"
10179         check_stats $SINGLEMDS "statfs" 1
10180
10181         rm -rf $DIR/${tdir}
10182 }
10183 run_test 133b "Verifying extra MDT stats =================================="
10184
10185 test_133c() {
10186         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
10187         remote_ost_nodsh && skip "remote OST with nodsh" && return
10188         remote_mds_nodsh && skip "remote MDS with nodsh" && return
10189         local testdir=$DIR/$tdir/stats_testdir
10190         test_mkdir -p $testdir
10191
10192         # verify obdfilter stats.
10193         $SETSTRIPE -c 1 -i 0 $testdir/$tfile
10194         sync
10195         cancel_lru_locks osc
10196         wait_delete_completed
10197
10198         # clear stats.
10199         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
10200         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
10201
10202         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
10203                 error "dd failed"
10204         sync
10205         cancel_lru_locks osc
10206         check_stats ost1 "write" 1
10207
10208         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
10209         check_stats ost1 "read" 1
10210
10211         > $testdir/$tfile || error "truncate failed"
10212         check_stats ost1 "punch" 1
10213
10214         rm -f $testdir/$tfile || error "file remove failed"
10215         wait_delete_completed
10216         check_stats ost1 "destroy" 1
10217
10218         rm -rf $DIR/$tdir
10219 }
10220 run_test 133c "Verifying OST stats ========================================"
10221
10222 order_2() {
10223         local value=$1
10224         local orig=$value
10225         local order=1
10226
10227         while [ $value -ge 2 ]; do
10228                 order=$((order*2))
10229                 value=$((value/2))
10230         done
10231
10232         if [ $orig -gt $order ]; then
10233                 order=$((order*2))
10234         fi
10235         echo $order
10236 }
10237
10238 size_in_KMGT() {
10239     local value=$1
10240     local size=('K' 'M' 'G' 'T');
10241     local i=0
10242     local size_string=$value
10243
10244     while [ $value -ge 1024 ]; do
10245         if [ $i -gt 3 ]; then
10246             #T is the biggest unit we get here, if that is bigger,
10247             #just return XXXT
10248             size_string=${value}T
10249             break
10250         fi
10251         value=$((value >> 10))
10252         if [ $value -lt 1024 ]; then
10253             size_string=${value}${size[$i]}
10254             break
10255         fi
10256         i=$((i + 1))
10257     done
10258
10259     echo $size_string
10260 }
10261
10262 get_rename_size() {
10263     local size=$1
10264     local context=${2:-.}
10265     local sample=$(do_facet $SINGLEMDS $LCTL get_param mdt.*.rename_stats |
10266                 grep -A1 $context |
10267                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
10268     echo $sample
10269 }
10270
10271 test_133d() {
10272         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
10273         remote_ost_nodsh && skip "remote OST with nodsh" && return
10274         remote_mds_nodsh && skip "remote MDS with nodsh" && return
10275         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
10276         { skip "MDS doesn't support rename stats"; return; }
10277
10278         local testdir1=$DIR/${tdir}/stats_testdir1
10279         local testdir2=$DIR/${tdir}/stats_testdir2
10280
10281         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
10282
10283         mkdir -p ${testdir1} || error "mkdir failed"
10284         mkdir -p ${testdir2} || error "mkdir failed"
10285
10286         createmany -o $testdir1/test 512 || error "createmany failed"
10287
10288         # check samedir rename size
10289         mv ${testdir1}/test0 ${testdir1}/test_0
10290
10291         local testdir1_size=$(ls -l $DIR/${tdir} |
10292                 awk '/stats_testdir1/ {print $5}')
10293         local testdir2_size=$(ls -l $DIR/${tdir} |
10294                 awk '/stats_testdir2/ {print $5}')
10295
10296         testdir1_size=$(order_2 $testdir1_size)
10297         testdir2_size=$(order_2 $testdir2_size)
10298
10299         testdir1_size=$(size_in_KMGT $testdir1_size)
10300         testdir2_size=$(size_in_KMGT $testdir2_size)
10301
10302         echo "source rename dir size: ${testdir1_size}"
10303         echo "target rename dir size: ${testdir2_size}"
10304
10305         local cmd="do_facet $SINGLEMDS $LCTL get_param mdt.*.rename_stats"
10306         eval $cmd || error "$cmd failed"
10307         local samedir=$($cmd | grep 'same_dir')
10308         local same_sample=$(get_rename_size $testdir1_size)
10309         [ -z "$samedir" ] && error "samedir_rename_size count error"
10310         [[ $same_sample -eq 1 ]] ||
10311                 error "samedir_rename_size error $same_sample"
10312         echo "Check same dir rename stats success"
10313
10314         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
10315
10316         # check crossdir rename size
10317         mv ${testdir1}/test_0 ${testdir2}/test_0
10318
10319         testdir1_size=$(ls -l $DIR/${tdir} |
10320                 awk '/stats_testdir1/ {print $5}')
10321         testdir2_size=$(ls -l $DIR/${tdir} |
10322                 awk '/stats_testdir2/ {print $5}')
10323
10324         testdir1_size=$(order_2 $testdir1_size)
10325         testdir2_size=$(order_2 $testdir2_size)
10326
10327         testdir1_size=$(size_in_KMGT $testdir1_size)
10328         testdir2_size=$(size_in_KMGT $testdir2_size)
10329
10330         echo "source rename dir size: ${testdir1_size}"
10331         echo "target rename dir size: ${testdir2_size}"
10332
10333         eval $cmd || error "$cmd failed"
10334         local crossdir=$($cmd | grep 'crossdir')
10335         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
10336         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
10337         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
10338         [[ $src_sample -eq 1 ]] ||
10339                 error "crossdir_rename_size error $src_sample"
10340         [[ $tgt_sample -eq 1 ]] ||
10341                 error "crossdir_rename_size error $tgt_sample"
10342         echo "Check cross dir rename stats success"
10343         rm -rf $DIR/${tdir}
10344 }
10345 run_test 133d "Verifying rename_stats ========================================"
10346
10347 test_133e() {
10348         remote_mds_nodsh && skip "remote MDS with nodsh" && return
10349         remote_ost_nodsh && skip "remote OST with nodsh" && return
10350         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
10351         local testdir=$DIR/${tdir}/stats_testdir
10352         local ctr f0 f1 bs=32768 count=42 sum
10353
10354         mkdir -p ${testdir} || error "mkdir failed"
10355
10356         $SETSTRIPE -c 1 -i 0 ${testdir}/${tfile}
10357
10358         for ctr in {write,read}_bytes; do
10359                 sync
10360                 cancel_lru_locks osc
10361
10362                 do_facet ost1 $LCTL set_param -n \
10363                         "obdfilter.*.exports.clear=clear"
10364
10365                 if [ $ctr = write_bytes ]; then
10366                         f0=/dev/zero
10367                         f1=${testdir}/${tfile}
10368                 else
10369                         f0=${testdir}/${tfile}
10370                         f1=/dev/null
10371                 fi
10372
10373                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
10374                         error "dd failed"
10375                 sync
10376                 cancel_lru_locks osc
10377
10378                 sum=$(do_facet ost1 $LCTL get_param \
10379                         "obdfilter.*.exports.*.stats" |
10380                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
10381                                 $1 == ctr { sum += $7 }
10382                                 END { printf("%0.0f", sum) }')
10383
10384                 if ((sum != bs * count)); then
10385                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
10386                 fi
10387         done
10388
10389         rm -rf $DIR/${tdir}
10390 }
10391 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
10392
10393 proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
10394
10395 test_133f() {
10396         remote_mds_nodsh && skip "remote MDS with nodsh" && return
10397         remote_ost_nodsh && skip "remote OST with nodsh" && return
10398         # First without trusting modes.
10399         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
10400         echo "proc_dirs='$proc_dirs'"
10401         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
10402         find $proc_dirs -exec cat '{}' \; &> /dev/null
10403
10404         # Second verifying readability.
10405         $LCTL get_param -R '*' &> /dev/null || error "proc file read failed"
10406
10407         # eventually, this can also be replaced with "lctl get_param -R",
10408         # but not until that option is always available on the server
10409         local facet
10410         for facet in mds1 ost1; do
10411                 local facet_proc_dirs=$(do_facet $facet \
10412                                         \\\ls -d $proc_regexp 2>/dev/null)
10413                 echo "${facet}_proc_dirs='$facet_proc_dirs'"
10414                 [ -z "$facet_proc_dirs" ] && error "no proc_dirs on $facet"
10415                 do_facet $facet find $facet_proc_dirs \
10416                         ! -name req_history \
10417                         -exec cat '{}' \\\; &> /dev/null
10418
10419                 do_facet $facet find $facet_proc_dirs \
10420                         ! -name req_history \
10421                         -type f \
10422                         -exec cat '{}' \\\; &> /dev/null ||
10423                                 error "proc file read failed"
10424         done
10425 }
10426 run_test 133f "Check for LBUGs/Oopses/unreadable files in /proc"
10427
10428 test_133g() {
10429         remote_mds_nodsh && skip "remote MDS with nodsh" && return
10430         remote_ost_nodsh && skip "remote OST with nodsh" && return
10431         # Second verifying writability.
10432         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
10433         echo "proc_dirs='$proc_dirs'"
10434         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
10435         find $proc_dirs \
10436                 -ignore_readdir_race \
10437                 -type f \
10438                 -not -name force_lbug \
10439                 -not -name changelog_mask \
10440                 -exec badarea_io '{}' \; ||
10441                 error "find $proc_dirs failed"
10442
10443         local facet
10444         for facet in mds1 ost1; do
10445                 [ $(lustre_version_code $facet) -le $(version_code 2.5.54) ] &&
10446                         skip "Too old lustre on $facet" && continue
10447                 local facet_proc_dirs=$(do_facet $facet \
10448                                         \\\ls -d $proc_regexp 2> /dev/null)
10449                 echo "${facet}_proc_dirs='$facet_proc_dirs'"
10450                 [ -z "$facet_proc_dirs" ] && error "no proc_dirs on $facet"
10451                 do_facet $facet find $facet_proc_dirs \
10452                         -ignore_readdir_race \
10453                         -type f \
10454                         -not -name force_lbug \
10455                         -not -name changelog_mask \
10456                         -exec badarea_io '{}' \\\; ||
10457                                 error "$facet find $facet_proc_dirs failed"
10458         done
10459
10460         # remount the FS in case writes/reads /proc break the FS
10461         cleanup || error "failed to unmount"
10462         setup || error "failed to setup"
10463         true
10464 }
10465 run_test 133g "Check for Oopses on bad io area writes/reads in /proc"
10466
10467 test_133h() {
10468         remote_mds_nodsh && skip "remote MDS with nodsh" && return
10469         remote_ost_nodsh && skip "remote OST with nodsh" && return
10470         [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.9.54) ]] &&
10471                 skip "Need MDS version at least 2.9.54" && return
10472
10473         local facet
10474         for facet in client mds1 ost1; do
10475                 local facet_proc_dirs=$(do_facet $facet \
10476                                         \\\ls -d $proc_regexp 2> /dev/null)
10477                 [ -z "$facet_proc_dirs" ] && error "no proc_dirs on $facet"
10478                 echo "${facet}_proc_dirs='$facet_proc_dirs'"
10479                 # Get the list of files that are missing the terminating newline
10480                 local missing=($(do_facet $facet \
10481                         find ${facet_proc_dirs} -type f \|              \
10482                                 while read F\; do                       \
10483                                         awk -v FS='\v' -v RS='\v\v'     \
10484                                         "'END { if(NR>0 &&              \
10485                                         \\\$NF !~ /.*\\\n\$/)           \
10486                                                 print FILENAME}'"       \
10487                                         '\$F'\;                         \
10488                                 done 2>/dev/null))
10489                 [ ${#missing[*]} -eq 0 ] ||
10490                         error "files do not end with newline: ${missing[*]}"
10491         done
10492 }
10493 run_test 133h "Proc files should end with newlines"
10494
10495 test_134a() {
10496         remote_mds_nodsh && skip "remote MDS with nodsh" && return
10497         [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.7.54) ]] &&
10498                 skip "Need MDS version at least 2.7.54" && return
10499
10500         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
10501         cancel_lru_locks mdc
10502
10503         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
10504         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
10505         [ $unused -eq 0 ] || error "$unused locks are not cleared"
10506
10507         local nr=1000
10508         createmany -o $DIR/$tdir/f $nr ||
10509                 error "failed to create $nr files in $DIR/$tdir"
10510         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
10511
10512         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
10513         do_facet mds1 $LCTL set_param fail_loc=0x327
10514         do_facet mds1 $LCTL set_param fail_val=500
10515         touch $DIR/$tdir/m
10516
10517         echo "sleep 10 seconds ..."
10518         sleep 10
10519         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
10520
10521         do_facet mds1 $LCTL set_param fail_loc=0
10522         do_facet mds1 $LCTL set_param fail_val=0
10523         [ $lck_cnt -lt $unused ] ||
10524                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
10525
10526         rm $DIR/$tdir/m
10527         unlinkmany $DIR/$tdir/f $nr
10528 }
10529 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
10530
10531 test_134b() {
10532         remote_mds_nodsh && skip "remote MDS with nodsh" && return
10533         [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.7.54) ]] &&
10534                 skip "Need MDS version at least 2.7.54" && return
10535
10536         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
10537         cancel_lru_locks mdc
10538
10539         local low_wm=$(do_facet mds1 $LCTL get_param -n \
10540                         ldlm.lock_reclaim_threshold_mb)
10541         # disable reclaim temporarily
10542         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
10543
10544         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
10545         do_facet mds1 $LCTL set_param fail_loc=0x328
10546         do_facet mds1 $LCTL set_param fail_val=500
10547
10548         $LCTL set_param debug=+trace
10549
10550         local nr=600
10551         createmany -o $DIR/$tdir/f $nr &
10552         local create_pid=$!
10553
10554         echo "Sleep $TIMEOUT seconds ..."
10555         sleep $TIMEOUT
10556         if ! ps -p $create_pid  > /dev/null 2>&1; then
10557                 do_facet mds1 $LCTL set_param fail_loc=0
10558                 do_facet mds1 $LCTL set_param fail_val=0
10559                 do_facet mds1 $LCTL set_param \
10560                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
10561                 error "createmany finished incorrectly!"
10562         fi
10563         do_facet mds1 $LCTL set_param fail_loc=0
10564         do_facet mds1 $LCTL set_param fail_val=0
10565         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
10566         wait $create_pid || return 1
10567
10568         unlinkmany $DIR/$tdir/f $nr
10569 }
10570 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
10571
10572 test_140() { #bug-17379
10573         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
10574         test_mkdir $DIR/$tdir
10575         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
10576         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
10577
10578         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
10579         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
10580         local i=0
10581         while i=$((i + 1)); do
10582                 test_mkdir $i
10583                 cd $i || error "Changing to $i"
10584                 ln -s ../stat stat || error "Creating stat symlink"
10585                 # Read the symlink until ELOOP present,
10586                 # not LBUGing the system is considered success,
10587                 # we didn't overrun the stack.
10588                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
10589                 if [ $ret -ne 0 ]; then
10590                         if [ $ret -eq 40 ]; then
10591                                 break  # -ELOOP
10592                         else
10593                                 error "Open stat symlink"
10594                                         return
10595                         fi
10596                 fi
10597         done
10598         i=$((i - 1))
10599         echo "The symlink depth = $i"
10600         [ $i -eq 5 -o $i -eq 7 -o $i -eq 8 -o $i -eq 40 ] ||
10601                                         error "Invalid symlink depth"
10602
10603         # Test recursive symlink
10604         ln -s symlink_self symlink_self
10605         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
10606         echo "open symlink_self returns $ret"
10607         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
10608 }
10609 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
10610
10611 test_150() {
10612         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
10613         local TF="$TMP/$tfile"
10614
10615         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
10616         cp $TF $DIR/$tfile
10617         cancel_lru_locks $OSC
10618         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
10619         remount_client $MOUNT
10620         df -P $MOUNT
10621         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
10622
10623         $TRUNCATE $TF 6000
10624         $TRUNCATE $DIR/$tfile 6000
10625         cancel_lru_locks $OSC
10626         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
10627
10628         echo "12345" >>$TF
10629         echo "12345" >>$DIR/$tfile
10630         cancel_lru_locks $OSC
10631         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
10632
10633         echo "12345" >>$TF
10634         echo "12345" >>$DIR/$tfile
10635         cancel_lru_locks $OSC
10636         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
10637
10638         rm -f $TF
10639         true
10640 }
10641 run_test 150 "truncate/append tests"
10642
10643 #LU-2902 roc_hit was not able to read all values from lproc
10644 function roc_hit_init() {
10645         local list=$(comma_list $(osts_nodes))
10646         local dir=$DIR/$tdir-check
10647         local file=$dir/$tfile
10648         local BEFORE
10649         local AFTER
10650         local idx
10651
10652         test_mkdir $dir
10653         #use setstripe to do a write to every ost
10654         for i in $(seq 0 $((OSTCOUNT-1))); do
10655                 $SETSTRIPE -c 1 -i $i $dir || error "$SETSTRIPE $file failed"
10656                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
10657                 idx=$(printf %04x $i)
10658                 BEFORE=$(get_osd_param $list *OST*$idx stats |
10659                         awk '$1 == "cache_access" {sum += $7}
10660                                 END { printf("%0.0f", sum) }')
10661
10662                 cancel_lru_locks osc
10663                 cat $file >/dev/null
10664
10665                 AFTER=$(get_osd_param $list *OST*$idx stats |
10666                         awk '$1 == "cache_access" {sum += $7}
10667                                 END { printf("%0.0f", sum) }')
10668
10669                 echo BEFORE:$BEFORE AFTER:$AFTER
10670                 if ! let "AFTER - BEFORE == 4"; then
10671                         rm -rf $dir
10672                         error "roc_hit is not safe to use"
10673                 fi
10674                 rm $file
10675         done
10676
10677         rm -rf $dir
10678 }
10679
10680 function roc_hit() {
10681         local list=$(comma_list $(osts_nodes))
10682         echo $(get_osd_param $list '' stats |
10683                 awk '$1 == "cache_hit" {sum += $7}
10684                         END { printf("%0.0f", sum) }')
10685 }
10686
10687 function set_cache() {
10688         local on=1
10689
10690         if [ "$2" == "off" ]; then
10691                 on=0;
10692         fi
10693         local list=$(comma_list $(osts_nodes))
10694         set_osd_param $list '' $1_cache_enable $on
10695
10696         cancel_lru_locks osc
10697 }
10698
10699 test_151() {
10700         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
10701         remote_ost_nodsh && skip "remote OST with nodsh" && return
10702
10703         local CPAGES=3
10704         local list=$(comma_list $(osts_nodes))
10705
10706         # check whether obdfilter is cache capable at all
10707         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
10708                 echo "not cache-capable obdfilter"
10709                 return 0
10710         fi
10711
10712         # check cache is enabled on all obdfilters
10713         if get_osd_param $list '' read_cache_enable | grep 0; then
10714                 echo "oss cache is disabled"
10715                 return 0
10716         fi
10717
10718         set_osd_param $list '' writethrough_cache_enable 1
10719
10720         # check write cache is enabled on all obdfilters
10721         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
10722                 echo "oss write cache is NOT enabled"
10723                 return 0
10724         fi
10725
10726         roc_hit_init
10727
10728         #define OBD_FAIL_OBD_NO_LRU  0x609
10729         do_nodes $list $LCTL set_param fail_loc=0x609
10730
10731         # pages should be in the case right after write
10732         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
10733                 error "dd failed"
10734
10735         local BEFORE=$(roc_hit)
10736         cancel_lru_locks osc
10737         cat $DIR/$tfile >/dev/null
10738         local AFTER=$(roc_hit)
10739
10740         do_nodes $list $LCTL set_param fail_loc=0
10741
10742         if ! let "AFTER - BEFORE == CPAGES"; then
10743                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
10744         fi
10745
10746         # the following read invalidates the cache
10747         cancel_lru_locks osc
10748         set_osd_param $list '' read_cache_enable 0
10749         cat $DIR/$tfile >/dev/null
10750
10751         # now data shouldn't be found in the cache
10752         BEFORE=$(roc_hit)
10753         cancel_lru_locks osc
10754         cat $DIR/$tfile >/dev/null
10755         AFTER=$(roc_hit)
10756         if let "AFTER - BEFORE != 0"; then
10757                 error "IN CACHE: before: $BEFORE, after: $AFTER"
10758         fi
10759
10760         set_osd_param $list '' read_cache_enable 1
10761         rm -f $DIR/$tfile
10762 }
10763 run_test 151 "test cache on oss and controls ==============================="
10764
10765 test_152() {
10766         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
10767         local TF="$TMP/$tfile"
10768
10769         # simulate ENOMEM during write
10770 #define OBD_FAIL_OST_NOMEM      0x226
10771         lctl set_param fail_loc=0x80000226
10772         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
10773         cp $TF $DIR/$tfile
10774         sync || error "sync failed"
10775         lctl set_param fail_loc=0
10776
10777         # discard client's cache
10778         cancel_lru_locks osc
10779
10780         # simulate ENOMEM during read
10781         lctl set_param fail_loc=0x80000226
10782         cmp $TF $DIR/$tfile || error "cmp failed"
10783         lctl set_param fail_loc=0
10784
10785         rm -f $TF
10786 }
10787 run_test 152 "test read/write with enomem ============================"
10788
10789 test_153() {
10790         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
10791 }
10792 run_test 153 "test if fdatasync does not crash ======================="
10793
10794 dot_lustre_fid_permission_check() {
10795         local fid=$1
10796         local ffid=$MOUNT/.lustre/fid/$fid
10797         local test_dir=$2
10798
10799         echo "stat fid $fid"
10800         stat $ffid > /dev/null || error "stat $ffid failed."
10801         echo "touch fid $fid"
10802         touch $ffid || error "touch $ffid failed."
10803         echo "write to fid $fid"
10804         cat /etc/hosts > $ffid || error "write $ffid failed."
10805         echo "read fid $fid"
10806         diff /etc/hosts $ffid || error "read $ffid failed."
10807         echo "append write to fid $fid"
10808         cat /etc/hosts >> $ffid || error "append write $ffid failed."
10809         echo "rename fid $fid"
10810         mv $ffid $test_dir/$tfile.1 &&
10811                 error "rename $ffid to $tfile.1 should fail."
10812         touch $test_dir/$tfile.1
10813         mv $test_dir/$tfile.1 $ffid &&
10814                 error "rename $tfile.1 to $ffid should fail."
10815         rm -f $test_dir/$tfile.1
10816         echo "truncate fid $fid"
10817         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
10818         if [ $MDSCOUNT -lt 2 ]; then #FIXME when cross-MDT hard link is working
10819                 echo "link fid $fid"
10820                 ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
10821         fi
10822         if [ -n $(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl) ]; then
10823                 echo "setfacl fid $fid"
10824                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
10825                 echo "getfacl fid $fid"
10826                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
10827         fi
10828         echo "unlink fid $fid"
10829         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
10830         echo "mknod fid $fid"
10831         mknod $ffid c 1 3 && error "mknod $ffid should fail."
10832
10833         fid=[0xf00000400:0x1:0x0]
10834         ffid=$MOUNT/.lustre/fid/$fid
10835
10836         echo "stat non-exist fid $fid"
10837         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
10838         echo "write to non-exist fid $fid"
10839         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
10840         echo "link new fid $fid"
10841         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
10842
10843         mkdir -p $test_dir/$tdir
10844         touch $test_dir/$tdir/$tfile
10845         fid=$($LFS path2fid $test_dir/$tdir)
10846         rc=$?
10847         [ $rc -ne 0 ] &&
10848                 error "error: could not get fid for $test_dir/$dir/$tfile."
10849
10850         ffid=$MOUNT/.lustre/fid/$fid
10851
10852         echo "ls $fid"
10853         ls $ffid > /dev/null || error "ls $ffid failed."
10854         echo "touch $fid/$tfile.1"
10855         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
10856
10857         echo "touch $MOUNT/.lustre/fid/$tfile"
10858         touch $MOUNT/.lustre/fid/$tfile && \
10859                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
10860
10861         echo "setxattr to $MOUNT/.lustre/fid"
10862         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
10863
10864         echo "listxattr for $MOUNT/.lustre/fid"
10865         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
10866
10867         echo "delxattr from $MOUNT/.lustre/fid"
10868         setfattr -x trusted.name1 $MOUNT/.lustre/fid
10869
10870         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
10871         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
10872                 error "touch invalid fid should fail."
10873
10874         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
10875         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
10876                 error "touch non-normal fid should fail."
10877
10878         echo "rename $tdir to $MOUNT/.lustre/fid"
10879         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
10880                 error "rename to $MOUNT/.lustre/fid should fail."
10881
10882         if [ $(lustre_version_code $SINGLEMDS) -ge $(version_code 2.3.51) ]
10883         then            # LU-3547
10884                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
10885                 local new_obf_mode=777
10886
10887                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
10888                 chmod $new_obf_mode $DIR/.lustre/fid ||
10889                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
10890
10891                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
10892                 [ $obf_mode -eq $new_obf_mode ] ||
10893                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
10894
10895                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
10896                 chmod $old_obf_mode $DIR/.lustre/fid ||
10897                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
10898         fi
10899
10900         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
10901         fid=$($LFS path2fid $test_dir/$tfile-2)
10902
10903         if [ $(lustre_version_code $SINGLEMDS) -ge $(version_code 2.6.50) ]
10904         then # LU-5424
10905                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
10906                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
10907                         error "create lov data thru .lustre failed"
10908         fi
10909         echo "cp /etc/passwd $test_dir/$tfile-2"
10910         cp /etc/passwd $test_dir/$tfile-2 ||
10911                 error "copy to $test_dir/$tfile-2 failed."
10912         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
10913         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
10914                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
10915
10916         rm -rf $test_dir/tfile.lnk
10917         rm -rf $test_dir/$tfile-2
10918 }
10919
10920 test_154A() {
10921         [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.4.1) ]] &&
10922                 skip "Need MDS version at least 2.4.1" && return
10923
10924         local tf=$DIR/$tfile
10925         touch $tf
10926
10927         local fid=$($LFS path2fid $tf)
10928         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
10929
10930         # check that we get the same pathname back
10931         local found=$($LFS fid2path $MOUNT "$fid")
10932         [ -z "$found" ] && error "fid2path unable to get '$fid' path"
10933         [ "$found" == "$tf" ] ||
10934                 error "fid2path($fid=path2fid($tf)) = $found != $tf"
10935 }
10936 run_test 154A "lfs path2fid and fid2path basic checks"
10937
10938 test_154B() {
10939         [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.4.1) ]] &&
10940                 skip "Need MDS version at least 2.4.1" && return
10941
10942         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
10943         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
10944         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
10945         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
10946
10947         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
10948         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
10949
10950         # check that we get the same pathname
10951         echo "PFID: $PFID, name: $name"
10952         local FOUND=$($LFS fid2path $MOUNT "$PFID")
10953         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
10954         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
10955                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
10956
10957         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
10958 }
10959 run_test 154B "verify the ll_decode_linkea tool"
10960
10961 test_154a() {
10962         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
10963         [[ $(lustre_version_code $SINGLEMDS) -ge $(version_code 2.2.51) ]] ||
10964                 { skip "Need MDS version at least 2.2.51"; return 0; }
10965         [ -z "$(which setfacl)" ] && skip "must have setfacl tool" && return
10966         [ -n "$FILESET" ] && skip "SKIP due to FILESET set" && return
10967
10968         cp /etc/hosts $DIR/$tfile
10969
10970         fid=$($LFS path2fid $DIR/$tfile)
10971         rc=$?
10972         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
10973
10974         dot_lustre_fid_permission_check "$fid" $DIR ||
10975                 error "dot lustre permission check $fid failed"
10976
10977         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
10978
10979         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
10980
10981         touch $MOUNT/.lustre/file &&
10982                 error "creation is not allowed under .lustre"
10983
10984         mkdir $MOUNT/.lustre/dir &&
10985                 error "mkdir is not allowed under .lustre"
10986
10987         rm -rf $DIR/$tfile
10988 }
10989 run_test 154a "Open-by-FID"
10990
10991 test_154b() {
10992         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
10993         [[ $(lustre_version_code $SINGLEMDS) -ge $(version_code 2.2.51) ]] ||
10994                 { skip "Need MDS version at least 2.2.51"; return 0; }
10995         [ -n "$FILESET" ] && skip "SKIP due to FILESET set" && return
10996
10997         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
10998
10999         local remote_dir=$DIR/$tdir/remote_dir
11000         local MDTIDX=1
11001         local rc=0
11002
11003         mkdir -p $DIR/$tdir
11004         $LFS mkdir -i $MDTIDX $remote_dir ||
11005                 error "create remote directory failed"
11006
11007         cp /etc/hosts $remote_dir/$tfile
11008
11009         fid=$($LFS path2fid $remote_dir/$tfile)
11010         rc=$?
11011         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
11012
11013         dot_lustre_fid_permission_check "$fid" $remote_dir ||
11014                 error "dot lustre permission check $fid failed"
11015         rm -rf $DIR/$tdir
11016 }
11017 run_test 154b "Open-by-FID for remote directory"
11018
11019 test_154c() {
11020         [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.4.1) ]] &&
11021                 skip "Need MDS version at least 2.4.1" && return
11022
11023         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
11024         local FID1=$($LFS path2fid $DIR/$tfile.1)
11025         local FID2=$($LFS path2fid $DIR/$tfile.2)
11026         local FID3=$($LFS path2fid $DIR/$tfile.3)
11027
11028         local N=1
11029         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
11030                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
11031                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
11032                 local want=FID$N
11033                 [ "$FID" = "${!want}" ] ||
11034                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
11035                 N=$((N + 1))
11036         done
11037
11038         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
11039         do
11040                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
11041                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
11042                 N=$((N + 1))
11043         done
11044 }
11045 run_test 154c "lfs path2fid and fid2path multiple arguments"
11046
11047 test_154d() {
11048         remote_mds_nodsh && skip "remote MDS with nodsh" && return
11049         [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.5.53) ]] &&
11050                 skip "Need MDS version at least 2.5.53" && return
11051
11052         if remote_mds; then
11053                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
11054         else
11055                 nid="0@lo"
11056         fi
11057         local proc_ofile="mdt.*.exports.'$nid'.open_files"
11058         local fd
11059         local cmd
11060
11061         rm -f $DIR/$tfile
11062         touch $DIR/$tfile
11063
11064         local fid=$($LFS path2fid $DIR/$tfile)
11065         # Open the file
11066         fd=$(free_fd)
11067         cmd="exec $fd<$DIR/$tfile"
11068         eval $cmd
11069         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
11070         echo "$fid_list" | grep "$fid"
11071         rc=$?
11072
11073         cmd="exec $fd>/dev/null"
11074         eval $cmd
11075         if [ $rc -ne 0 ]; then
11076                 error "FID $fid not found in open files list $fid_list"
11077         fi
11078 }
11079 run_test 154d "Verify open file fid"
11080
11081 test_154e()
11082 {
11083         [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.6.50) ]] &&
11084                 skip "Need MDS version at least 2.6.50" && return
11085
11086         if ls -a $MOUNT | grep -q '^\.lustre$'; then
11087                 error ".lustre returned by readdir"
11088         fi
11089 }
11090 run_test 154e ".lustre is not returned by readdir"
11091
11092 test_154f() {
11093         [ -n "$FILESET" ] && skip "SKIP due to FILESET set" && return
11094         # create parent directory on a single MDT to avoid cross-MDT hardlinks
11095         test_mkdir -p -c1 $DIR/$tdir/d
11096         # test dirs inherit from its stripe
11097         mkdir -p $DIR/$tdir/d/foo1 || error "mkdir error"
11098         mkdir -p $DIR/$tdir/d/foo2 || error "mkdir error"
11099         cp /etc/hosts $DIR/$tdir/d/foo1/$tfile
11100         ln $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/link
11101         touch $DIR/f
11102
11103         # get fid of parents
11104         local FID0=$($LFS path2fid $DIR/$tdir/d)
11105         local FID1=$($LFS path2fid $DIR/$tdir/d/foo1)
11106         local FID2=$($LFS path2fid $DIR/$tdir/d/foo2)
11107         local FID3=$($LFS path2fid $DIR)
11108
11109         # check that path2fid --parents returns expected <parent_fid>/name
11110         # 1) test for a directory (single parent)
11111         local parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1)
11112         [ "$parent" == "$FID0/foo1" ] ||
11113                 error "expected parent: $FID0/foo1, got: $parent"
11114
11115         # 2) test for a file with nlink > 1 (multiple parents)
11116         parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1/$tfile)
11117         echo "$parent" | grep -F "$FID1/$tfile" ||
11118                 error "$FID1/$tfile not returned in parent list"
11119         echo "$parent" | grep -F "$FID2/link" ||
11120                 error "$FID2/link not returned in parent list"
11121
11122         # 3) get parent by fid
11123         local file_fid=$($LFS path2fid $DIR/$tdir/d/foo1/$tfile)
11124         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
11125         echo "$parent" | grep -F "$FID1/$tfile" ||
11126                 error "$FID1/$tfile not returned in parent list (by fid)"
11127         echo "$parent" | grep -F "$FID2/link" ||
11128                 error "$FID2/link not returned in parent list (by fid)"
11129
11130         # 4) test for entry in root directory
11131         parent=$($LFS path2fid --parents $DIR/f)
11132         echo "$parent" | grep -F "$FID3/f" ||
11133                 error "$FID3/f not returned in parent list"
11134
11135         # 5) test it on root directory
11136         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
11137                 error "$MOUNT should not have parents"
11138
11139         # enable xattr caching and check that linkea is correctly updated
11140         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
11141         save_lustre_params client "llite.*.xattr_cache" > $save
11142         lctl set_param llite.*.xattr_cache 1
11143
11144         # 6.1) linkea update on rename
11145         mv $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/$tfile.moved
11146
11147         # get parents by fid
11148         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
11149         # foo1 should no longer be returned in parent list
11150         echo "$parent" | grep -F "$FID1" &&
11151                 error "$FID1 should no longer be in parent list"
11152         # the new path should appear
11153         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
11154                 error "$FID2/$tfile.moved is not in parent list"
11155
11156         # 6.2) linkea update on unlink
11157         rm -f $DIR/$tdir/d/foo2/link
11158         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
11159         # foo2/link should no longer be returned in parent list
11160         echo "$parent" | grep -F "$FID2/link" &&
11161                 error "$FID2/link should no longer be in parent list"
11162         true
11163
11164         rm -f $DIR/f
11165         restore_lustre_params < $save
11166         rm -f $save
11167 }
11168 run_test 154f "get parent fids by reading link ea"
11169
11170 test_154g()
11171 {
11172         [[ $(lustre_version_code $SINGLEMDS) -ge $(version_code 2.6.92) && \
11173            $(lustre_version_code client) -gt $(version_code 2.6.99) ]] ||
11174                 { skip "Need MDS version at least 2.6.92"; return 0; }
11175         [ -n "$FILESET" ] && skip "SKIP due to FILESET set" && return
11176
11177         mkdir -p $DIR/$tdir
11178         llapi_fid_test -d $DIR/$tdir
11179 }
11180 run_test 154g "various llapi FID tests"
11181
11182 test_155_small_load() {
11183     local temp=$TMP/$tfile
11184     local file=$DIR/$tfile
11185
11186     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
11187         error "dd of=$temp bs=6096 count=1 failed"
11188     cp $temp $file
11189     cancel_lru_locks $OSC
11190     cmp $temp $file || error "$temp $file differ"
11191
11192     $TRUNCATE $temp 6000
11193     $TRUNCATE $file 6000
11194     cmp $temp $file || error "$temp $file differ (truncate1)"
11195
11196     echo "12345" >>$temp
11197     echo "12345" >>$file
11198     cmp $temp $file || error "$temp $file differ (append1)"
11199
11200     echo "12345" >>$temp
11201     echo "12345" >>$file
11202     cmp $temp $file || error "$temp $file differ (append2)"
11203
11204     rm -f $temp $file
11205     true
11206 }
11207
11208 test_155_big_load() {
11209     remote_ost_nodsh && skip "remote OST with nodsh" && return
11210     local temp=$TMP/$tfile
11211     local file=$DIR/$tfile
11212
11213     free_min_max
11214     local cache_size=$(do_facet ost$((MAXI+1)) \
11215         "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
11216     local large_file_size=$((cache_size * 2))
11217
11218     echo "OSS cache size: $cache_size KB"
11219     echo "Large file size: $large_file_size KB"
11220
11221     [ $MAXV -le $large_file_size ] && \
11222         skip_env "max available OST size needs > $large_file_size KB" && \
11223         return 0
11224
11225     $SETSTRIPE $file -c 1 -i $MAXI || error "$SETSTRIPE $file failed"
11226
11227     dd if=/dev/urandom of=$temp bs=$large_file_size count=1k || \
11228         error "dd of=$temp bs=$large_file_size count=1k failed"
11229     cp $temp $file
11230     ls -lh $temp $file
11231     cancel_lru_locks osc
11232     cmp $temp $file || error "$temp $file differ"
11233
11234     rm -f $temp $file
11235     true
11236 }
11237
11238 save_writethrough() {
11239         local facets=$(get_facets OST)
11240
11241         save_lustre_params $facets "obdfilter.*.writethrough_cache_enable" > $1
11242         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" >> $1
11243 }
11244
11245 test_155a() {
11246         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
11247         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
11248         save_writethrough $p
11249
11250         set_cache read on
11251         set_cache writethrough on
11252         test_155_small_load
11253         restore_lustre_params < $p
11254         rm -f $p
11255 }
11256 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
11257
11258 test_155b() {
11259         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
11260         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
11261         save_writethrough $p
11262
11263         set_cache read on
11264         set_cache writethrough off
11265         test_155_small_load
11266         restore_lustre_params < $p
11267         rm -f $p
11268 }
11269 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
11270
11271 test_155c() {
11272         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
11273         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
11274         save_writethrough $p
11275
11276         set_cache read off
11277         set_cache writethrough on
11278         test_155_small_load
11279         restore_lustre_params < $p
11280         rm -f $p
11281 }
11282 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
11283
11284 test_155d() {
11285         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
11286         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
11287         save_writethrough $p
11288
11289         set_cache read off
11290         set_cache writethrough off
11291         test_155_small_load
11292         restore_lustre_params < $p
11293         rm -f $p
11294 }
11295 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
11296
11297 test_155e() {
11298         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
11299         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
11300         save_writethrough $p
11301
11302         set_cache read on
11303         set_cache writethrough on
11304         test_155_big_load
11305         restore_lustre_params < $p
11306         rm -f $p
11307 }
11308 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
11309
11310 test_155f() {
11311         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
11312         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
11313         save_writethrough $p
11314
11315         set_cache read on
11316         set_cache writethrough off
11317         test_155_big_load
11318         restore_lustre_params < $p
11319         rm -f $p
11320 }
11321 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
11322
11323 test_155g() {
11324         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
11325         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
11326         save_writethrough $p
11327
11328         set_cache read off
11329         set_cache writethrough on
11330         test_155_big_load
11331         restore_lustre_params < $p
11332         rm -f $p
11333 }
11334 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
11335
11336 test_155h() {
11337         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
11338         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
11339         save_writethrough $p
11340
11341         set_cache read off
11342         set_cache writethrough off
11343         test_155_big_load
11344         restore_lustre_params < $p
11345         rm -f $p
11346 }
11347 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
11348
11349 test_156() {
11350         remote_ost_nodsh && skip "remote OST with nodsh" && return
11351         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
11352         local CPAGES=3
11353         local BEFORE
11354         local AFTER
11355         local file="$DIR/$tfile"
11356         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
11357
11358         [ "$(facet_fstype ost1)" = "zfs" -a \
11359            $(lustre_version_code ost1 -lt $(version_code 2.6.93)) ] &&
11360                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS" &&
11361                 return
11362
11363         save_writethrough $p
11364         roc_hit_init
11365
11366         log "Turn on read and write cache"
11367         set_cache read on
11368         set_cache writethrough on
11369
11370         log "Write data and read it back."
11371         log "Read should be satisfied from the cache."
11372         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
11373         BEFORE=$(roc_hit)
11374         cancel_lru_locks osc
11375         cat $file >/dev/null
11376         AFTER=$(roc_hit)
11377         if ! let "AFTER - BEFORE == CPAGES"; then
11378                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
11379         else
11380                 log "cache hits:: before: $BEFORE, after: $AFTER"
11381         fi
11382
11383         log "Read again; it should be satisfied from the cache."
11384         BEFORE=$AFTER
11385         cancel_lru_locks osc
11386         cat $file >/dev/null
11387         AFTER=$(roc_hit)
11388         if ! let "AFTER - BEFORE == CPAGES"; then
11389                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
11390         else
11391                 log "cache hits:: before: $BEFORE, after: $AFTER"
11392         fi
11393
11394         log "Turn off the read cache and turn on the write cache"
11395         set_cache read off
11396         set_cache writethrough on
11397
11398         log "Read again; it should be satisfied from the cache."
11399         BEFORE=$(roc_hit)
11400         cancel_lru_locks osc
11401         cat $file >/dev/null
11402         AFTER=$(roc_hit)
11403         if ! let "AFTER - BEFORE == CPAGES"; then
11404                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
11405         else
11406                 log "cache hits:: before: $BEFORE, after: $AFTER"
11407         fi
11408
11409         log "Read again; it should not be satisfied from the cache."
11410         BEFORE=$AFTER
11411         cancel_lru_locks osc
11412         cat $file >/dev/null
11413         AFTER=$(roc_hit)
11414         if ! let "AFTER - BEFORE == 0"; then
11415                 error "IN CACHE: before: $BEFORE, after: $AFTER"
11416         else
11417                 log "cache hits:: before: $BEFORE, after: $AFTER"
11418         fi
11419
11420         log "Write data and read it back."
11421         log "Read should be satisfied from the cache."
11422         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
11423         BEFORE=$(roc_hit)
11424         cancel_lru_locks osc
11425         cat $file >/dev/null
11426         AFTER=$(roc_hit)
11427         if ! let "AFTER - BEFORE == CPAGES"; then
11428                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
11429         else
11430                 log "cache hits:: before: $BEFORE, after: $AFTER"
11431         fi
11432
11433         log "Read again; it should not be satisfied from the cache."
11434         BEFORE=$AFTER
11435         cancel_lru_locks osc
11436         cat $file >/dev/null
11437         AFTER=$(roc_hit)
11438         if ! let "AFTER - BEFORE == 0"; then
11439                 error "IN CACHE: before: $BEFORE, after: $AFTER"
11440         else
11441                 log "cache hits:: before: $BEFORE, after: $AFTER"
11442         fi
11443
11444         log "Turn off read and write cache"
11445         set_cache read off
11446         set_cache writethrough off
11447
11448         log "Write data and read it back"
11449         log "It should not be satisfied from the cache."
11450         rm -f $file
11451         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
11452         cancel_lru_locks osc
11453         BEFORE=$(roc_hit)
11454         cat $file >/dev/null
11455         AFTER=$(roc_hit)
11456         if ! let "AFTER - BEFORE == 0"; then
11457                 error_ignore bz20762 "IN CACHE: before: $BEFORE, after: $AFTER"
11458         else
11459                 log "cache hits:: before: $BEFORE, after: $AFTER"
11460         fi
11461
11462         log "Turn on the read cache and turn off the write cache"
11463         set_cache read on
11464         set_cache writethrough off
11465
11466         log "Write data and read it back"
11467         log "It should not be satisfied from the cache."
11468         rm -f $file
11469         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
11470         BEFORE=$(roc_hit)
11471         cancel_lru_locks osc
11472         cat $file >/dev/null
11473         AFTER=$(roc_hit)
11474         if ! let "AFTER - BEFORE == 0"; then
11475                 error_ignore bz20762 "IN CACHE: before: $BEFORE, after: $AFTER"
11476         else
11477                 log "cache hits:: before: $BEFORE, after: $AFTER"
11478         fi
11479
11480         log "Read again; it should be satisfied from the cache."
11481         BEFORE=$(roc_hit)
11482         cancel_lru_locks osc
11483         cat $file >/dev/null
11484         AFTER=$(roc_hit)
11485         if ! let "AFTER - BEFORE == CPAGES"; then
11486                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
11487         else
11488                 log "cache hits:: before: $BEFORE, after: $AFTER"
11489         fi
11490
11491         restore_lustre_params < $p
11492         rm -f $p $file
11493 }
11494 run_test 156 "Verification of tunables"
11495
11496 #Changelogs
11497 cleanup_changelog () {
11498         trap 0
11499         echo "Deregistering changelog client $CL_USER"
11500         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister $CL_USER
11501 }
11502
11503 err17935 () {
11504         if [[ $MDSCOUNT -gt 1 ]]; then
11505                 error_ignore bz17935 $*
11506         else
11507                 error $*
11508         fi
11509 }
11510
11511 changelog_chmask()
11512 {
11513         local CL_MASK_PARAM="mdd.$MDT0.changelog_mask"
11514
11515         MASK=$(do_facet $SINGLEMDS $LCTL get_param $CL_MASK_PARAM| grep -c "$1")
11516
11517         if [ $MASK -eq 1 ]; then
11518                 do_facet $SINGLEMDS $LCTL set_param $CL_MASK_PARAM="-$1"
11519         else
11520                 do_facet $SINGLEMDS $LCTL set_param $CL_MASK_PARAM="+$1"
11521         fi
11522 }
11523
11524 changelog_extract_field() {
11525         local mdt=$1
11526         local cltype=$2
11527         local file=$3
11528         local identifier=$4
11529
11530         $LFS changelog $mdt | gawk "/$cltype.*$file$/ {
11531                 print gensub(/^.* "$identifier'(\[[^\]]*\]).*$/,"\\1",1)}' |
11532                 tail -1
11533 }
11534
11535 test_160a() {
11536         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
11537         remote_mds_nodsh && skip "remote MDS with nodsh" && return
11538         [ $(lustre_version_code $SINGLEMDS) -ge $(version_code 2.2.0) ] ||
11539                 { skip "Need MDS version at least 2.2.0"; return; }
11540
11541         local CL_USERS="mdd.$MDT0.changelog_users"
11542         local GET_CL_USERS="do_facet $SINGLEMDS $LCTL get_param -n $CL_USERS"
11543         CL_USER=$(do_facet $SINGLEMDS $LCTL --device $MDT0 \
11544                 changelog_register -n)
11545         echo "Registered as changelog user $CL_USER"
11546         trap cleanup_changelog EXIT
11547         $GET_CL_USERS | grep -q $CL_USER ||
11548                 error "User $CL_USER not found in changelog_users"
11549
11550         # change something
11551         test_mkdir -p $DIR/$tdir/pics/2008/zachy
11552         touch $DIR/$tdir/pics/2008/zachy/timestamp
11553         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
11554         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
11555         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
11556         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
11557         rm $DIR/$tdir/pics/desktop.jpg
11558
11559         $LFS changelog $MDT0 | tail -5
11560
11561         echo "verifying changelog mask"
11562         changelog_chmask "MKDIR"
11563         changelog_chmask "CLOSE"
11564
11565         test_mkdir -p $DIR/$tdir/pics/zach/sofia
11566         echo "zzzzzz" > $DIR/$tdir/pics/zach/file
11567
11568         changelog_chmask "MKDIR"
11569         changelog_chmask "CLOSE"
11570
11571         test_mkdir -p $DIR/$tdir/pics/2008/sofia
11572         echo "zzzzzz" > $DIR/$tdir/pics/zach/file
11573
11574         $LFS changelog $MDT0
11575         MKDIRS=$($LFS changelog $MDT0 | tail -5 | grep -c "MKDIR")
11576         CLOSES=$($LFS changelog $MDT0 | tail -5 | grep -c "CLOSE")
11577         [ $MKDIRS -eq 1 ] || err17935 "MKDIR changelog mask count $DIRS != 1"
11578         [ $CLOSES -eq 1 ] || err17935 "CLOSE changelog mask count $DIRS != 1"
11579
11580         # verify contents
11581         echo "verifying target fid"
11582         fidc=$(changelog_extract_field $MDT0 "CREAT" "timestamp" "t=")
11583         fidf=$($LFS path2fid $DIR/$tdir/pics/zach/timestamp)
11584         [ "$fidc" == "$fidf" ] ||
11585                 err17935 "fid in changelog $fidc != file fid $fidf"
11586         echo "verifying parent fid"
11587         fidc=$(changelog_extract_field $MDT0 "CREAT" "timestamp" "p=")
11588         fidf=$($LFS path2fid $DIR/$tdir/pics/zach)
11589         [ "$fidc" == "$fidf" ] ||
11590                 err17935 "pfid in changelog $fidc != dir fid $fidf"
11591
11592         USER_REC1=$($GET_CL_USERS | awk "\$1 == \"$CL_USER\" {print \$2}")
11593         $LFS changelog_clear $MDT0 $CL_USER $(($USER_REC1 + 5))
11594         USER_REC2=$($GET_CL_USERS | awk "\$1 == \"$CL_USER\" {print \$2}")
11595         echo "verifying user clear: $(( $USER_REC1 + 5 )) == $USER_REC2"
11596         [ $USER_REC2 == $(($USER_REC1 + 5)) ] ||
11597                 err17935 "user index expected $(($USER_REC1 + 5)) is $USER_REC2"
11598
11599         MIN_REC=$($GET_CL_USERS |
11600                 awk 'min == "" || $2 < min {min = $2}; END {print min}')
11601         FIRST_REC=$($LFS changelog $MDT0 | head -n1 | awk '{print $1}')
11602         echo "verifying min purge: $(( $MIN_REC + 1 )) == $FIRST_REC"
11603         [ $FIRST_REC == $(($MIN_REC + 1)) ] ||
11604                 err17935 "first index should be $(($MIN_REC + 1)) is $FIRST_REC"
11605
11606         # LU-3446 changelog index reset on MDT restart
11607         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
11608         CUR_REC1=$($GET_CL_USERS | head -n1 | cut -f3 -d' ')
11609         $LFS changelog_clear $MDT0 $CL_USER 0
11610         stop $SINGLEMDS || error "Fail to stop MDT."
11611         start $SINGLEMDS $MDT_DEV $MDS_MOUNT_OPTS || error "Fail to start MDT."
11612         CUR_REC2=$($GET_CL_USERS | head -n1 | cut -f3 -d' ')
11613         echo "verifying index survives MDT restart: $CUR_REC1 == $CUR_REC2"
11614         [ $CUR_REC1 == $CUR_REC2 ] ||
11615                 err17935 "current index should be $CUR_REC1 is $CUR_REC2"
11616
11617         echo "verifying user deregister"
11618         cleanup_changelog
11619         $GET_CL_USERS | grep -q $CL_USER &&
11620                 error "User $CL_USER still in changelog_users"
11621
11622         USERS=$(( $($GET_CL_USERS | wc -l) - 2 ))
11623         if [ $CL_USER -eq 0 ]; then
11624                 LAST_REC1=$($GET_CL_USERS | head -n1 | cut -f3 -d' ')
11625                 touch $DIR/$tdir/chloe
11626                 LAST_REC2=$($GET_CL_USERS | head -n1 | cut -f3 -d' ')
11627                 echo "verify changelogs are off: $LAST_REC1 == $LAST_REC2"
11628                 [ $LAST_REC1 == $LAST_REC2 ] || error "changelogs not off"
11629         else
11630                 echo "$CL_USER other changelog users; can't verify off"
11631         fi
11632 }
11633 run_test 160a "changelog sanity"
11634
11635 test_160b() { # LU-3587
11636         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
11637         remote_mds_nodsh && skip "remote MDS with nodsh" && return
11638         [ $(lustre_version_code $SINGLEMDS) -ge $(version_code 2.2.0) ] ||
11639                 { skip "Need MDS version at least 2.2.0"; return; }
11640
11641         local CL_USERS="mdd.$MDT0.changelog_users"
11642         local GET_CL_USERS="do_facet $SINGLEMDS $LCTL get_param -n $CL_USERS"
11643         CL_USER=$(do_facet $SINGLEMDS $LCTL --device $MDT0 \
11644                 changelog_register -n)
11645         echo "Registered as changelog user $CL_USER"
11646         trap cleanup_changelog EXIT
11647         $GET_CL_USERS | grep -q $CL_USER ||
11648                 error "User $CL_USER not found in changelog_users"
11649
11650         local LONGNAME1=$(str_repeat a 255)
11651         local LONGNAME2=$(str_repeat b 255)
11652
11653         cd $DIR
11654         echo "creating very long named file"
11655         touch $LONGNAME1 || error "create of $LONGNAME1 failed"
11656         echo "moving very long named file"
11657         mv $LONGNAME1 $LONGNAME2
11658
11659         $LFS changelog $MDT0 | grep RENME
11660         rm -f $LONGNAME2
11661         cleanup_changelog
11662 }
11663 run_test 160b "Verify that very long rename doesn't crash in changelog"
11664
11665 test_160c() {
11666         remote_mds_nodsh && skip "remote MDS with nodsh" && return
11667
11668         local rc=0
11669         local server_version=$(lustre_version_code $SINGLEMDS)
11670
11671         [[ $server_version -gt $(version_code 2.5.57) ]] ||
11672                 [[ $server_version -gt $(version_code 2.5.1) &&
11673                    $server_version -lt $(version_code 2.5.50) ]] ||
11674                 { skip "Need MDS version at least 2.5.58 or 2.5.2+"; return; }
11675         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
11676
11677         # Registration step
11678         CL_USER=$(do_facet $SINGLEMDS $LCTL --device $MDT0 \
11679                 changelog_register -n)
11680         trap cleanup_changelog EXIT
11681
11682         rm -rf $DIR/$tdir
11683         mkdir -p $DIR/$tdir
11684         $MCREATE $DIR/$tdir/foo_160c
11685         changelog_chmask "TRUNC"
11686         $TRUNCATE $DIR/$tdir/foo_160c 200
11687         changelog_chmask "TRUNC"
11688         $TRUNCATE $DIR/$tdir/foo_160c 199
11689         $LFS changelog $MDT0
11690         TRUNCS=$($LFS changelog $MDT0 | tail -5 | grep -c "TRUNC")
11691         [ $TRUNCS -eq 1 ] || err17935 "TRUNC changelog mask count $TRUNCS != 1"
11692         $LFS changelog_clear $MDT0 $CL_USER 0
11693
11694         # Deregistration step
11695         cleanup_changelog
11696 }
11697 run_test 160c "verify that changelog log catch the truncate event"
11698
11699 test_160d() {
11700         remote_mds_nodsh && skip "remote MDS with nodsh" && return
11701         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
11702
11703         local server_version=$(lustre_version_code mds1)
11704         local CL_MASK_PARAM="mdd.$MDT0.changelog_mask"
11705
11706         [[ $server_version -ge $(version_code 2.7.60) ]] ||
11707                 { skip "Need MDS version at least 2.7.60+"; return; }
11708         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
11709
11710         # Registration step
11711         CL_USER=$(do_facet mds1 $LCTL --device $MDT0 \
11712                 changelog_register -n)
11713
11714         trap cleanup_changelog EXIT
11715         mkdir -p $DIR/$tdir/migrate_dir
11716         $LFS changelog_clear $MDT0 $CL_USER 0
11717
11718         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
11719         $LFS changelog $MDT0
11720         MIGRATES=$($LFS changelog $MDT0 | tail -5 | grep -c "MIGRT")
11721         $LFS changelog_clear $MDT0 $CL_USER 0
11722         [ $MIGRATES -eq 1 ] ||
11723                 error "MIGRATE changelog mask count $MIGRATES != 1"
11724
11725         # Deregistration step
11726         cleanup_changelog
11727 }
11728 run_test 160d "verify that changelog log catch the migrate event"
11729
11730 test_160e() {
11731         remote_mds_nodsh && skip "remote MDS with nodsh" && return
11732
11733         # Create a user
11734         CL_USER=$(do_facet $SINGLEMDS $LCTL --device $MDT0 \
11735                 changelog_register -n)
11736         echo "Registered as changelog user $CL_USER"
11737         trap cleanup_changelog EXIT
11738
11739         # Delete a future user (expect fail)
11740         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister cl77
11741         local rc=$?
11742
11743         if [ $rc -eq 0 ]; then
11744                 error "Deleted non-existant user cl77"
11745         elif [ $rc -ne 2 ]; then
11746                 error "changelog_deregister failed with $rc, " \
11747                         "expected 2 (ENOENT)"
11748         fi
11749
11750         # Clear to a bad index (1 billion should be safe)
11751         $LFS changelog_clear $MDT0 $CL_USER 1000000000
11752         rc=$?
11753
11754         if [ $rc -eq 0 ]; then
11755                 error "Successfully cleared to invalid CL index"
11756         elif [ $rc -ne 22 ]; then
11757                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
11758         fi
11759 }
11760 run_test 160e "changelog negative testing"
11761
11762 cleanup_160f() {
11763         trap 0
11764         do_facet $SINGLEMDS $LCTL set_param fail_loc=0 fail_val=0
11765         echo "Deregistering changelog client $CL_USER"
11766         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister $CL_USER
11767         echo "Deregistering changelog client $CL_USER2"
11768         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister $CL_USER2
11769         restore_lustre_params < $save_params
11770         rm -f $save_params
11771 }
11772
11773 test_160f() {
11774         # do_facet $SINGLEMDS $LCTL set_param mdd.$MDT0.changelog_gc=1
11775         # should be set by default
11776
11777         local CL_USERS="mdd.$MDT0.changelog_users"
11778         local GET_CL_USERS="do_facet $SINGLEMDS $LCTL get_param -n $CL_USERS"
11779         local save_params="$TMP/sanity-$TESTNAME.parameters"
11780
11781         save_lustre_params $SINGLEMDS \
11782                 "mdd.$MDT0.changelog_max_idle_time" > $save_params
11783         save_lustre_params $SINGLEMDS \
11784                 "mdd.$MDT0.changelog_min_gc_interval" >> $save_params
11785         save_lustre_params $SINGLEMDS \
11786                 "mdd.$MDT0.changelog_min_free_cat_entries" >> $save_params
11787
11788         trap cleanup_160f EXIT
11789
11790         # Create a user
11791         CL_USER=$(do_facet $SINGLEMDS $LCTL --device $MDT0 \
11792                 changelog_register -n)
11793         echo "Registered as changelog user $CL_USER"
11794         CL_USER2=$(do_facet $SINGLEMDS $LCTL --device $MDT0 \
11795                 changelog_register -n)
11796         echo "Registered as changelog user $CL_USER2"
11797         $GET_CL_USERS | grep -q $CL_USER ||
11798                 error "User $CL_USER not found in changelog_users"
11799         $GET_CL_USERS | grep -q $CL_USER2 ||
11800                 error "User $CL_USER2 not found in changelog_users"
11801
11802         # generate some changelogs to accumulate
11803         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
11804         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
11805         touch $DIR/$tdir/${tfile}2 || error "touch $DIR/$tdir/${tfile}2 failed"
11806         rm -f $DIR/$tdir/$tfile || error "rm -f $tfile failed"
11807
11808         # check changelogs have been generated
11809         nbcl=$($LFS changelog $MDT0 | wc -l)
11810         [[ $nbcl -eq 0 ]] && error "no changelogs found"
11811
11812         do_facet $SINGLEMDS $LCTL set_param \
11813                 mdd.$MDT0.changelog_max_idle_time=10
11814         do_facet $SINGLEMDS $LCTL set_param \
11815                 mdd.$MDT0.changelog_min_gc_interval=2
11816         do_facet $SINGLEMDS $LCTL set_param \
11817                 mdd.$MDT0.changelog_min_free_cat_entries=3
11818
11819         # simulate changelog catalog almost full
11820 #define OBD_FAIL_CAT_FREE_RECORDS                  0x1313
11821         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1313
11822         do_facet $SINGLEMDS $LCTL set_param fail_val=3
11823
11824         sleep 6
11825         USER_REC1=$($GET_CL_USERS | awk "\$1 == \"$CL_USER\" {print \$2}")
11826         $LFS changelog_clear $MDT0 $CL_USER $(($USER_REC1 + 2))
11827         USER_REC2=$($GET_CL_USERS | awk "\$1 == \"$CL_USER\" {print \$2}")
11828         echo "verifying user clear: $(( $USER_REC1 + 2 )) == $USER_REC2"
11829         [ $USER_REC2 == $(($USER_REC1 + 2)) ] ||
11830                 error "user index expected $(($USER_REC1 + 2)) is $USER_REC2"
11831         sleep 5
11832
11833         # generate one more changelog to trigger fail_loc
11834         rm -rf $DIR/$tdir || error "rm -rf $tdir failed"
11835
11836         # ensure gc thread is done
11837         wait_update_facet $SINGLEMDS \
11838                           "ps -e -o comm= | grep chlg_gc_thread" "" 20
11839
11840         # check user still registered
11841         $GET_CL_USERS | grep -q $CL_USER ||
11842                 error "User $CL_USER not found in changelog_users"
11843         # check user2 unregistered
11844         $GET_CL_USERS | grep -q $CL_USER2 &&
11845                 error "User $CL_USER2 still found in changelog_users"
11846
11847         # check changelogs are present and starting at $USER_REC2 + 1
11848         FIRST_REC=$($LFS changelog $MDT0 | head -n1 | awk '{print $1}')
11849         echo "verifying min purge: $(( $USER_REC2 + 1 )) == $FIRST_REC"
11850         [ $FIRST_REC == $(($USER_REC2 + 1)) ] ||
11851                 error "first index should be $(($USER_REC2 + 1)) is $FIRST_REC"
11852
11853         cleanup_160f
11854 }
11855 run_test 160f "changelog garbage collect (timestamped users)"
11856
11857 test_160g() {
11858         # do_facet $SINGLEMDS $LCTL set_param mdd.$MDT0.changelog_gc=1
11859         # should be set by default
11860
11861         local CL_USERS="mdd.$MDT0.changelog_users"
11862         local GET_CL_USERS="do_facet $SINGLEMDS $LCTL get_param -n $CL_USERS"
11863         local save_params="$TMP/sanity-$TESTNAME.parameters"
11864
11865         save_lustre_params $SINGLEMDS \
11866                 "mdd.$MDT0.changelog_max_idle_indexes" > $save_params
11867         save_lustre_params $SINGLEMDS \
11868                 "mdd.$MDT0.changelog_min_gc_interval" >> $save_params
11869         save_lustre_params $SINGLEMDS \
11870                 "mdd.$MDT0.changelog_min_free_cat_entries" >> $save_params
11871
11872         trap cleanup_160f EXIT
11873
11874 #define OBD_FAIL_TIME_IN_CHLOG_USER                 0x1314
11875         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1314
11876
11877         # Create a user
11878         CL_USER=$(do_facet $SINGLEMDS $LCTL --device $MDT0 \
11879                 changelog_register -n)
11880         echo "Registered as changelog user $CL_USER"
11881         CL_USER2=$(do_facet $SINGLEMDS $LCTL --device $MDT0 \
11882                 changelog_register -n)
11883         echo "Registered as changelog user $CL_USER2"
11884         $GET_CL_USERS | grep -q $CL_USER ||
11885                 error "User $CL_USER not found in changelog_users"
11886         $GET_CL_USERS | grep -q $CL_USER2 ||
11887                 error "User $CL_USER2 not found in changelog_users"
11888
11889         # generate some changelogs to accumulate
11890         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
11891         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
11892         touch $DIR/$tdir/${tfile}2 || error "touch $DIR/$tdir/${tfile}2 failed"
11893         rm -f $DIR/$tdir/$tfile || error "rm -f $tfile failed"
11894
11895         # check changelogs have been generated
11896         nbcl=$($LFS changelog $MDT0 | wc -l)
11897         [[ $nbcl -eq 0 ]] && error "no changelogs found"
11898
11899         do_facet $SINGLEMDS $LCTL set_param \
11900                 mdd.$MDT0.changelog_max_idle_indexes=$((nbcl - 1))
11901         do_facet $SINGLEMDS $LCTL set_param \
11902                 mdd.$MDT0.changelog_min_gc_interval=2
11903         do_facet $SINGLEMDS $LCTL set_param \
11904                 mdd.$MDT0.changelog_min_free_cat_entries=3
11905
11906         # simulate changelog catalog almost full
11907 #define OBD_FAIL_CAT_FREE_RECORDS                  0x1313
11908         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1313
11909         do_facet $SINGLEMDS $LCTL set_param fail_val=3
11910
11911         USER_REC1=$($GET_CL_USERS | awk "\$1 == \"$CL_USER\" {print \$2}")
11912         $LFS changelog_clear $MDT0 $CL_USER $(($USER_REC1 + 3))
11913         USER_REC2=$($GET_CL_USERS | awk "\$1 == \"$CL_USER\" {print \$2}")
11914         echo "verifying user clear: $(( $USER_REC1 + 3 )) == $USER_REC2"
11915         [ $USER_REC2 == $(($USER_REC1 + 3)) ] ||
11916                 error "user index expected $(($USER_REC1 + 3)) is $USER_REC2"
11917
11918         # generate one more changelog to trigger fail_loc
11919         rm -rf $DIR/$tdir || error "rm -rf $tdir failed"
11920
11921         # ensure gc thread is done
11922         wait_update_facet $SINGLEMDS \
11923                           "ps -e -o comm= | grep chlg_gc_thread" "" 20
11924
11925         # check user still registered
11926         $GET_CL_USERS | grep -q $CL_USER ||
11927                 error "User $CL_USER not found in changelog_users"
11928         # check user2 unregistered
11929         $GET_CL_USERS | grep -q $CL_USER2 &&
11930                 error "User $CL_USER2 still found in changelog_users"
11931
11932         # check changelogs are present and starting at $USER_REC2 + 1
11933         FIRST_REC=$($LFS changelog $MDT0 | head -n1 | awk '{print $1}')
11934         echo "verifying min purge: $(( $USER_REC2 + 1 )) == $FIRST_REC"
11935         [ $FIRST_REC == $(($USER_REC2 + 1)) ] ||
11936                 error "first index should be $(($USER_REC2 + 1)) is $FIRST_REC"
11937
11938         cleanup_160f
11939 }
11940 run_test 160g "changelog garbage collect (old users)"
11941
11942 test_161a() {
11943         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
11944         test_mkdir -c1 $DIR/$tdir
11945         cp /etc/hosts $DIR/$tdir/$tfile
11946         test_mkdir -c1 $DIR/$tdir/foo1
11947         test_mkdir -c1 $DIR/$tdir/foo2
11948         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
11949         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
11950         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
11951         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
11952         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
11953         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
11954                 $LFS fid2path $DIR $FID
11955                 err17935 "bad link ea"
11956         fi
11957     # middle
11958     rm $DIR/$tdir/foo2/zachary
11959     # last
11960     rm $DIR/$tdir/foo2/thor
11961     # first
11962     rm $DIR/$tdir/$tfile
11963     # rename
11964     mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
11965     if [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ]
11966         then
11967         $LFS fid2path $DIR $FID
11968         err17935 "bad link rename"
11969     fi
11970     rm $DIR/$tdir/foo2/maggie
11971
11972         # overflow the EA
11973         local longname=filename_avg_len_is_thirty_two_
11974         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
11975                 error "failed to hardlink many files"
11976         links=$($LFS fid2path $DIR $FID | wc -l)
11977         echo -n "${links}/1000 links in link EA"
11978         [[ $links -gt 60 ]] ||
11979                 err17935 "expected at least 60 links in link EA"
11980         unlinkmany $DIR/$tdir/foo2/$longname 1000 ||
11981                 error "failed to unlink many hardlinks"
11982 }
11983 run_test 161a "link ea sanity"
11984
11985 test_161b() {
11986         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
11987         [ $MDSCOUNT -lt 2 ] && skip "skipping remote directory test" && return
11988         local MDTIDX=1
11989         local remote_dir=$DIR/$tdir/remote_dir
11990
11991         mkdir -p $DIR/$tdir
11992         $LFS mkdir -i $MDTIDX $remote_dir ||
11993                 error "create remote directory failed"
11994
11995         cp /etc/hosts $remote_dir/$tfile
11996         mkdir -p $remote_dir/foo1
11997         mkdir -p $remote_dir/foo2
11998         ln $remote_dir/$tfile $remote_dir/foo1/sofia
11999         ln $remote_dir/$tfile $remote_dir/foo2/zachary
12000         ln $remote_dir/$tfile $remote_dir/foo1/luna
12001         ln $remote_dir/$tfile $remote_dir/foo2/thor
12002
12003         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
12004                      tr -d ']')
12005         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
12006                 $LFS fid2path $DIR $FID
12007                 err17935 "bad link ea"
12008         fi
12009         # middle
12010         rm $remote_dir/foo2/zachary
12011         # last
12012         rm $remote_dir/foo2/thor
12013         # first
12014         rm $remote_dir/$tfile
12015         # rename
12016         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
12017         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
12018         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
12019                 $LFS fid2path $DIR $FID
12020                 err17935 "bad link rename"
12021         fi
12022         rm $remote_dir/foo2/maggie
12023
12024         # overflow the EA
12025         local longname=filename_avg_len_is_thirty_two_
12026         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
12027                 error "failed to hardlink many files"
12028         links=$($LFS fid2path $DIR $FID | wc -l)
12029         echo -n "${links}/1000 links in link EA"
12030         [[ ${links} -gt 60 ]] ||
12031                 err17935 "expected at least 60 links in link EA"
12032         unlinkmany $remote_dir/foo2/$longname 1000 ||
12033         error "failed to unlink many hardlinks"
12034 }
12035 run_test 161b "link ea sanity under remote directory"
12036
12037 test_161c() {
12038         remote_mds_nodsh && skip "remote MDS with nodsh" && return
12039         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
12040         [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.1.5) ]] &&
12041                 skip "Need MDS version at least 2.1.5" && return
12042
12043         # define CLF_RENAME_LAST 0x0001
12044         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
12045         CL_USER=$(do_facet $SINGLEMDS $LCTL --device $MDT0 \
12046                 changelog_register -n)
12047
12048         trap cleanup_changelog EXIT
12049         rm -rf $DIR/$tdir
12050         mkdir -p $DIR/$tdir
12051         touch $DIR/$tdir/foo_161c
12052         touch $DIR/$tdir/bar_161c
12053         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
12054         $LFS changelog $MDT0 | grep RENME
12055         local flags=$($LFS changelog $MDT0 | grep RENME | tail -1 | \
12056                 cut -f5 -d' ')
12057         $LFS changelog_clear $MDT0 $CL_USER 0
12058         if [ x$flags != "x0x1" ]; then
12059                 error "flag $flags is not 0x1"
12060         fi
12061         echo "rename overwrite a target having nlink = 1," \
12062                 "changelog record has flags of $flags"
12063
12064         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
12065         touch $DIR/$tdir/foo_161c
12066         touch $DIR/$tdir/bar_161c
12067         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
12068         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
12069         $LFS changelog $MDT0 | grep RENME
12070         flags=$($LFS changelog $MDT0 | grep RENME | tail -1 | cut -f5 -d' ')
12071         $LFS changelog_clear $MDT0 $CL_USER 0
12072         if [ x$flags != "x0x0" ]; then
12073                 error "flag $flags is not 0x0"
12074         fi
12075         echo "rename overwrite a target having nlink > 1," \
12076                 "changelog record has flags of $flags"
12077
12078         # rename doesn't overwrite a target (changelog flag 0x0)
12079         touch $DIR/$tdir/foo_161c
12080         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
12081         $LFS changelog $MDT0 | grep RENME
12082         flags=$($LFS changelog $MDT0 | grep RENME | tail -1 | cut -f5 -d' ')
12083         $LFS changelog_clear $MDT0 $CL_USER 0
12084         if [ x$flags != "x0x0" ]; then
12085                 error "flag $flags is not 0x0"
12086         fi
12087         echo "rename doesn't overwrite a target," \
12088                 "changelog record has flags of $flags"
12089
12090         # define CLF_UNLINK_LAST 0x0001
12091         # unlink a file having nlink = 1 (changelog flag 0x1)
12092         rm -f $DIR/$tdir/foo2_161c
12093         $LFS changelog $MDT0 | grep UNLNK
12094         flags=$($LFS changelog $MDT0 | grep UNLNK | tail -1 | cut -f5 -d' ')
12095         $LFS changelog_clear $MDT0 $CL_USER 0
12096         if [ x$flags != "x0x1" ]; then
12097                 error "flag $flags is not 0x1"
12098         fi
12099         echo "unlink a file having nlink = 1," \
12100                 "changelog record has flags of $flags"
12101
12102         # unlink a file having nlink > 1 (changelog flag 0x0)
12103         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
12104         rm -f $DIR/$tdir/foobar_161c
12105         $LFS changelog $MDT0 | grep UNLNK
12106         flags=$($LFS changelog $MDT0 | grep UNLNK | tail -1 | cut -f5 -d' ')
12107         $LFS changelog_clear $MDT0 $CL_USER 0
12108         if [ x$flags != "x0x0" ]; then
12109                 error "flag $flags is not 0x0"
12110         fi
12111         echo "unlink a file having nlink > 1," \
12112                 "changelog record has flags of $flags"
12113         cleanup_changelog
12114 }
12115 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
12116
12117 test_161d() {
12118         local user
12119         local pid
12120         local fid
12121
12122         # cleanup previous run
12123         rm -rf $DIR/$tdir/$tfile
12124
12125         user=$(do_facet $SINGLEMDS $LCTL --device $MDT0 \
12126                 changelog_register -n)
12127         [[ $? -eq 0 ]] || error "changelog_register failed"
12128
12129         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
12130         # interfer with $MOUNT/.lustre/fid/ access
12131         mkdir $DIR/$tdir
12132         [[ $? -eq 0 ]] || error "mkdir failed"
12133
12134         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
12135         $LCTL set_param fail_loc=0x8000140c
12136         # 5s pause
12137         $LCTL set_param fail_val=5
12138
12139         # create file
12140         echo foofoo > $DIR/$tdir/$tfile &
12141         pid=$!
12142
12143         # wait for create to be delayed
12144         sleep 2
12145
12146         ps -p $pid
12147         [[ $? -eq 0 ]] || error "create should be blocked"
12148
12149         local tempfile=$(mktemp)
12150         fid=$(changelog_extract_field $MDT0 "CREAT" "$tfile" "t=")
12151         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
12152         # some delay may occur during ChangeLog publishing and file read just
12153         # above, that could allow file write to happen finally
12154         [[ -s $tempfile ]] && echo "file should be empty"
12155
12156         $LCTL set_param fail_loc=0
12157
12158         wait $pid
12159         [[ $? -eq 0 ]] || error "create failed"
12160
12161         $LFS changelog_clear $MDT0 $user 0
12162         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister $user
12163 }
12164 run_test 161d "create with concurrent .lustre/fid access"
12165
12166 check_path() {
12167     local expected=$1
12168     shift
12169     local fid=$2
12170
12171     local path=$(${LFS} fid2path $*)
12172     # Remove the '//' indicating a remote directory
12173     path=$(echo $path | sed 's#//#/#g')
12174     RC=$?
12175
12176     if [ $RC -ne 0 ]; then
12177         err17935 "path looked up of $expected failed. Error $RC"
12178         return $RC
12179     elif [ "${path}" != "${expected}" ]; then
12180         err17935 "path looked up \"${path}\" instead of \"${expected}\""
12181         return 2
12182     fi
12183     echo "fid $fid resolves to path $path (expected $expected)"
12184 }
12185
12186 test_162a() { # was test_162
12187         # Make changes to filesystem
12188         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
12189         test_mkdir -p -c1 $DIR/$tdir/d2
12190         touch $DIR/$tdir/d2/$tfile
12191         touch $DIR/$tdir/d2/x1
12192         touch $DIR/$tdir/d2/x2
12193         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
12194         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
12195         # regular file
12196         FID=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
12197         check_path "$tdir/d2/$tfile" $FSNAME $FID --link 0 ||
12198                 error "check path $tdir/d2/$tfile failed"
12199
12200         # softlink
12201         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
12202         FID=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
12203         check_path "$tdir/d2/p/q/r/slink" $FSNAME $FID --link 0 ||
12204                 error "check path $tdir/d2/p/q/r/slink failed"
12205
12206         # softlink to wrong file
12207         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
12208         FID=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
12209         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME $FID --link 0 ||
12210                 error "check path $tdir/d2/p/q/r/slink.wrong failed"
12211
12212         # hardlink
12213         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
12214         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
12215         FID=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
12216         # fid2path dir/fsname should both work
12217         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $FID --link 1 ||
12218                 error "check path $tdir/d2/a/b/c/new_file failed"
12219         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR $FID --link 0 ||
12220                 error "check path $DIR/$tdir/d2/p/q/r/hlink failed"
12221
12222         # hardlink count: check that there are 2 links
12223         # Doesnt work with CMD yet: 17935
12224         ${LFS} fid2path $DIR $FID | wc -l | grep -q 2 || \
12225                 err17935 "expected 2 links"
12226
12227         # hardlink indexing: remove the first link
12228         rm $DIR/$tdir/d2/p/q/r/hlink
12229         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $FID --link 0 ||
12230                 error "check path $DIR/$tdir/d2/a/b/c/new_file failed"
12231
12232         return 0
12233 }
12234 run_test 162a "path lookup sanity"
12235
12236 test_162b() {
12237         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
12238         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
12239
12240         mkdir $DIR/$tdir
12241         $LFS setdirstripe -i0 -c$MDSCOUNT -t all_char $DIR/$tdir/striped_dir ||
12242                                 error "create striped dir failed"
12243
12244         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
12245                                         tail -n 1 | awk '{print $2}')
12246         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
12247
12248         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
12249         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
12250
12251         # regular file
12252         for ((i=0;i<5;i++)); do
12253                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
12254                         error "get fid for f$i failed"
12255                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0 ||
12256                         error "check path $tdir/striped_dir/f$i failed"
12257
12258                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
12259                         error "get fid for d$i failed"
12260                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0 ||
12261                         error "check path $tdir/striped_dir/d$i failed"
12262         done
12263
12264         return 0
12265 }
12266 run_test 162b "striped directory path lookup sanity"
12267
12268 # LU-4239: Verify fid2path works with paths 100 or more directories deep
12269 test_162c() {
12270         [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.7.51) ]] &&
12271                 skip "Need MDS version at least 2.7.51" && return
12272         test_mkdir $DIR/$tdir.local
12273         test_mkdir $DIR/$tdir.remote
12274         local lpath=$tdir.local
12275         local rpath=$tdir.remote
12276
12277         for ((i = 0; i <= 101; i++)); do
12278                 lpath="$lpath/$i"
12279                 mkdir $DIR/$lpath
12280                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
12281                         error "get fid for local directory $DIR/$lpath failed"
12282                 check_path "$DIR/$lpath" $MOUNT $FID --link 0 ||
12283                         error "check path for local directory $DIR/$lpath failed"
12284
12285                 rpath="$rpath/$i"
12286                 test_mkdir $DIR/$rpath
12287                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
12288                         error "get fid for remote directory $DIR/$rpath failed"
12289                 check_path "$DIR/$rpath" $MOUNT $FID --link 0 ||
12290                         error "check path for remote directory $DIR/$rpath failed"
12291         done
12292
12293         return 0
12294 }
12295 run_test 162c "fid2path works with paths 100 or more directories deep"
12296
12297 test_169() {
12298         # do directio so as not to populate the page cache
12299         log "creating a 10 Mb file"
12300         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
12301         log "starting reads"
12302         dd if=$DIR/$tfile of=/dev/null bs=4096 &
12303         log "truncating the file"
12304         $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
12305         log "killing dd"
12306         kill %+ || true # reads might have finished
12307         echo "wait until dd is finished"
12308         wait
12309         log "removing the temporary file"
12310         rm -rf $DIR/$tfile || error "tmp file removal failed"
12311 }
12312 run_test 169 "parallel read and truncate should not deadlock"
12313
12314 test_170() {
12315         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
12316         $LCTL clear     # bug 18514
12317         $LCTL debug_daemon start $TMP/${tfile}_log_good
12318         touch $DIR/$tfile
12319         $LCTL debug_daemon stop
12320         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
12321                error "sed failed to read log_good"
12322
12323         $LCTL debug_daemon start $TMP/${tfile}_log_good
12324         rm -rf $DIR/$tfile
12325         $LCTL debug_daemon stop
12326
12327         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
12328                error "lctl df log_bad failed"
12329
12330         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
12331         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
12332
12333         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
12334         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
12335
12336         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
12337                 error "bad_line good_line1 good_line2 are empty"
12338
12339         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
12340         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
12341         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
12342
12343         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
12344         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
12345         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
12346
12347         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
12348                 error "bad_line_new good_line_new are empty"
12349
12350         local expected_good=$((good_line1 + good_line2*2))
12351
12352         rm -f $TMP/${tfile}*
12353         # LU-231, short malformed line may not be counted into bad lines
12354         if [ $bad_line -ne $bad_line_new ] &&
12355                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
12356                 error "expected $bad_line bad lines, but got $bad_line_new"
12357                 return 1
12358         fi
12359
12360         if [ $expected_good -ne $good_line_new ]; then
12361                 error "expected $expected_good good lines, but got $good_line_new"
12362                 return 2
12363         fi
12364         true
12365 }
12366 run_test 170 "test lctl df to handle corrupted log ====================="
12367
12368 test_171() { # bug20592
12369         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
12370 #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
12371         $LCTL set_param fail_loc=0x50e
12372         $LCTL set_param fail_val=3000
12373         multiop_bg_pause $DIR/$tfile O_s || true
12374         local MULTIPID=$!
12375         kill -USR1 $MULTIPID
12376         # cause log dump
12377         sleep 3
12378         wait $MULTIPID
12379         if dmesg | grep "recursive fault"; then
12380                 error "caught a recursive fault"
12381         fi
12382         $LCTL set_param fail_loc=0
12383         true
12384 }
12385 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
12386
12387 # it would be good to share it with obdfilter-survey/iokit-libecho code
12388 setup_obdecho_osc () {
12389         local rc=0
12390         local ost_nid=$1
12391         local obdfilter_name=$2
12392         echo "Creating new osc for $obdfilter_name on $ost_nid"
12393         # make sure we can find loopback nid
12394         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
12395
12396         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
12397                            ${obdfilter_name}_osc_UUID || rc=2; }
12398         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
12399                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
12400         return $rc
12401 }
12402
12403 cleanup_obdecho_osc () {
12404         local obdfilter_name=$1
12405         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
12406         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
12407         return 0
12408 }
12409
12410 obdecho_test() {
12411         local OBD=$1
12412         local node=$2
12413         local pages=${3:-64}
12414         local rc=0
12415         local id
12416
12417         local count=10
12418         local obd_size=$(get_obd_size $node $OBD)
12419         local page_size=$(get_page_size $node)
12420         if [[ -n "$obd_size" ]]; then
12421                 local new_count=$((obd_size / (pages * page_size / 1024)))
12422                 [[ $new_count -ge $count ]] || count=$new_count
12423         fi
12424
12425         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
12426         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
12427                            rc=2; }
12428         if [ $rc -eq 0 ]; then
12429             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
12430             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
12431         fi
12432         echo "New object id is $id"
12433         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
12434                            rc=4; }
12435         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
12436                            "test_brw $count w v $pages $id" || rc=4; }
12437         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
12438                            rc=4; }
12439         [ $rc -eq 0 -o $rc -gt 2 ] && { do_facet $node "$LCTL --device ec "    \
12440                                         "cleanup" || rc=5; }
12441         [ $rc -eq 0 -o $rc -gt 1 ] && { do_facet $node "$LCTL --device ec "    \
12442                                         "detach" || rc=6; }
12443         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
12444         return $rc
12445 }
12446
12447 test_180a() {
12448         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
12449         remote_ost_nodsh && skip "remote OST with nodsh" && return
12450         local rc=0
12451         local rmmod_local=0
12452
12453         if ! module_loaded obdecho; then
12454             load_module obdecho/obdecho
12455             rmmod_local=1
12456         fi
12457
12458         local osc=$($LCTL dl | grep -v mdt | awk '$3 == "osc" {print $4; exit}')
12459         local host=$(lctl get_param -n osc.$osc.import |
12460                              awk '/current_connection:/ {print $2}' )
12461         local target=$(lctl get_param -n osc.$osc.import |
12462                              awk '/target:/ {print $2}' )
12463         target=${target%_UUID}
12464
12465         [[ -n $target ]]  && { setup_obdecho_osc $host $target || rc=1; } || rc=1
12466         [ $rc -eq 0 ] && { obdecho_test ${target}_osc client || rc=2; }
12467         [[ -n $target ]] && cleanup_obdecho_osc $target
12468         [ $rmmod_local -eq 1 ] && rmmod obdecho
12469         return $rc
12470 }
12471 run_test 180a "test obdecho on osc"
12472
12473 test_180b() {
12474         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
12475         remote_ost_nodsh && skip "remote OST with nodsh" && return
12476         local rc=0
12477         local rmmod_remote=0
12478
12479         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
12480                 rmmod_remote=true || error "failed to load module obdecho"
12481         target=$(do_facet ost1 $LCTL dl | awk '/obdfilter/ {print $4;exit}')
12482         [[ -n $target ]] && { obdecho_test $target ost1 || rc=1; }
12483         $rmmod_remote && do_facet ost1 "rmmod obdecho"
12484         return $rc
12485 }
12486 run_test 180b "test obdecho directly on obdfilter"
12487
12488 test_180c() { # LU-2598
12489         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
12490         remote_ost_nodsh && skip "remote OST with nodsh" && return
12491         [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.4.0) ]] &&
12492                 skip "Need MDS version at least 2.4.0" && return
12493
12494         local rc=0
12495         local rmmod_remote=false
12496         local pages=16384 # 64MB bulk I/O RPC size
12497         local target
12498
12499         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
12500                 rmmod_remote=true || error "failed to load module obdecho"
12501
12502         target=$(do_facet ost1 $LCTL dl | awk '/obdfilter/ { print $4 }' |
12503                 head -n1)
12504         if [ -n "$target" ]; then
12505                 obdecho_test "$target" ost1 "$pages" || rc=${PIPESTATUS[0]}
12506         else
12507                 echo "there is no obdfilter target on ost1"
12508                 rc=2
12509         fi
12510         $rmmod_remote && do_facet ost1 "rmmod obdecho" || true
12511         return $rc
12512 }
12513 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
12514
12515 test_181() { # bug 22177
12516         test_mkdir $DIR/$tdir
12517         # create enough files to index the directory
12518         createmany -o $DIR/$tdir/foobar 4000
12519         # print attributes for debug purpose
12520         lsattr -d .
12521         # open dir
12522         multiop_bg_pause $DIR/$tdir D_Sc || return 1
12523         MULTIPID=$!
12524         # remove the files & current working dir
12525         unlinkmany $DIR/$tdir/foobar 4000
12526         rmdir $DIR/$tdir
12527         kill -USR1 $MULTIPID
12528         wait $MULTIPID
12529         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
12530         return 0
12531 }
12532 run_test 181 "Test open-unlinked dir ========================"
12533
12534 test_182() {
12535         local fcount=1000
12536         local tcount=10
12537
12538         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
12539
12540         $LCTL set_param mdc.*.rpc_stats=clear
12541
12542         for (( i = 0; i < $tcount; i++ )) ; do
12543                 mkdir $DIR/$tdir/$i
12544         done
12545
12546         for (( i = 0; i < $tcount; i++ )) ; do
12547                 createmany -o $DIR/$tdir/$i/f- $fcount &
12548         done
12549         wait
12550
12551         for (( i = 0; i < $tcount; i++ )) ; do
12552                 unlinkmany $DIR/$tdir/$i/f- $fcount &
12553         done
12554         wait
12555
12556         $LCTL get_param mdc.*.rpc_stats
12557
12558         rm -rf $DIR/$tdir
12559 }
12560 run_test 182 "Test parallel modify metadata operations ================"
12561
12562 test_183() { # LU-2275
12563         remote_mds_nodsh && skip "remote MDS with nodsh" && return
12564         [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.3.56) ]] &&
12565                 skip "Need MDS version at least 2.3.56" && return
12566
12567         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
12568         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
12569         echo aaa > $DIR/$tdir/$tfile
12570
12571 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
12572         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
12573
12574         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
12575         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
12576
12577         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
12578
12579         # Flush negative dentry cache
12580         touch $DIR/$tdir/$tfile
12581
12582         # We are not checking for any leaked references here, they'll
12583         # become evident next time we do cleanup with module unload.
12584         rm -rf $DIR/$tdir
12585 }
12586 run_test 183 "No crash or request leak in case of strange dispositions ========"
12587
12588 # test suite 184 is for LU-2016, LU-2017
12589 test_184a() {
12590         check_swap_layouts_support && return 0
12591
12592         dir0=$DIR/$tdir/$testnum
12593         test_mkdir -p -c1 $dir0
12594         ref1=/etc/passwd
12595         ref2=/etc/group
12596         file1=$dir0/f1
12597         file2=$dir0/f2
12598         $SETSTRIPE -c1 $file1
12599         cp $ref1 $file1
12600         $SETSTRIPE -c2 $file2
12601         cp $ref2 $file2
12602         gen1=$($GETSTRIPE -g $file1)
12603         gen2=$($GETSTRIPE -g $file2)
12604
12605         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
12606         gen=$($GETSTRIPE -g $file1)
12607         [[ $gen1 != $gen ]] ||
12608                 "Layout generation on $file1 does not change"
12609         gen=$($GETSTRIPE -g $file2)
12610         [[ $gen2 != $gen ]] ||
12611                 "Layout generation on $file2 does not change"
12612
12613         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
12614         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
12615
12616         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
12617 }
12618 run_test 184a "Basic layout swap"
12619
12620 test_184b() {
12621         check_swap_layouts_support && return 0
12622
12623         dir0=$DIR/$tdir/$testnum
12624         mkdir -p $dir0 || error "creating dir $dir0"
12625         file1=$dir0/f1
12626         file2=$dir0/f2
12627         file3=$dir0/f3
12628         dir1=$dir0/d1
12629         dir2=$dir0/d2
12630         mkdir $dir1 $dir2
12631         $SETSTRIPE -c1 $file1
12632         $SETSTRIPE -c2 $file2
12633         $SETSTRIPE -c1 $file3
12634         chown $RUNAS_ID $file3
12635         gen1=$($GETSTRIPE -g $file1)
12636         gen2=$($GETSTRIPE -g $file2)
12637
12638         $LFS swap_layouts $dir1 $dir2 &&
12639                 error "swap of directories layouts should fail"
12640         $LFS swap_layouts $dir1 $file1 &&
12641                 error "swap of directory and file layouts should fail"
12642         $RUNAS $LFS swap_layouts $file1 $file2 &&
12643                 error "swap of file we cannot write should fail"
12644         $LFS swap_layouts $file1 $file3 &&
12645                 error "swap of file with different owner should fail"
12646         /bin/true # to clear error code
12647 }
12648 run_test 184b "Forbidden layout swap (will generate errors)"
12649
12650 test_184c() {
12651         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
12652         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n" && return
12653         check_swap_layouts_support && return 0
12654
12655         local dir0=$DIR/$tdir/$testnum
12656         mkdir -p $dir0 || error "creating dir $dir0"
12657
12658         local ref1=$dir0/ref1
12659         local ref2=$dir0/ref2
12660         local file1=$dir0/file1
12661         local file2=$dir0/file2
12662         # create a file large enough for the concurrent test
12663         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
12664         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
12665         echo "ref file size: ref1($(stat -c %s $ref1))," \
12666              "ref2($(stat -c %s $ref2))"
12667
12668         cp $ref2 $file2
12669         dd if=$ref1 of=$file1 bs=16k &
12670         local DD_PID=$!
12671
12672         # Make sure dd starts to copy file
12673         while [ ! -f $file1 ]; do sleep 0.1; done
12674
12675         $LFS swap_layouts $file1 $file2
12676         local rc=$?
12677         wait $DD_PID
12678         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
12679         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
12680
12681         # how many bytes copied before swapping layout
12682         local copied=$(stat -c %s $file2)
12683         local remaining=$(stat -c %s $ref1)
12684         remaining=$((remaining - copied))
12685         echo "Copied $copied bytes before swapping layout..."
12686
12687         cmp -n $copied $file1 $ref2 | grep differ &&
12688                 error "Content mismatch [0, $copied) of ref2 and file1"
12689         cmp -n $copied $file2 $ref1 ||
12690                 error "Content mismatch [0, $copied) of ref1 and file2"
12691         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
12692                 error "Content mismatch [$copied, EOF) of ref1 and file1"
12693
12694         # clean up
12695         rm -f $ref1 $ref2 $file1 $file2
12696 }
12697 run_test 184c "Concurrent write and layout swap"
12698
12699 test_184d() {
12700         check_swap_layouts_support && return 0
12701         [ -z "$(which getfattr 2>/dev/null)" ] &&
12702                 skip "no getfattr command" && return 0
12703
12704         local file1=$DIR/$tdir/$tfile-1
12705         local file2=$DIR/$tdir/$tfile-2
12706         local file3=$DIR/$tdir/$tfile-3
12707         local lovea1
12708         local lovea2
12709
12710         mkdir -p $DIR/$tdir
12711         touch $file1 || error "create $file1 failed"
12712         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
12713                 error "create $file2 failed"
12714         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
12715                 error "create $file3 failed"
12716         lovea1=$(get_layout_param $file1)
12717
12718         $LFS swap_layouts $file2 $file3 ||
12719                 error "swap $file2 $file3 layouts failed"
12720         $LFS swap_layouts $file1 $file2 ||
12721                 error "swap $file1 $file2 layouts failed"
12722
12723         lovea2=$(get_layout_param $file2)
12724         echo "$lovea1"
12725         echo "$lovea2"
12726         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
12727
12728         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
12729         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
12730 }
12731 run_test 184d "allow stripeless layouts swap"
12732
12733 test_184e() {
12734         [[ $(lustre_version_code $SINGLEMDS) -ge $(version_code 2.6.94) ]] ||
12735                 { skip "Need MDS version at least 2.6.94"; return 0; }
12736         check_swap_layouts_support && return 0
12737         [ -z "$(which getfattr 2>/dev/null)" ] &&
12738                 skip "no getfattr command" && return 0
12739
12740         local file1=$DIR/$tdir/$tfile-1
12741         local file2=$DIR/$tdir/$tfile-2
12742         local file3=$DIR/$tdir/$tfile-3
12743         local lovea
12744
12745         mkdir -p $DIR/$tdir
12746         touch $file1 || error "create $file1 failed"
12747         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
12748                 error "create $file2 failed"
12749         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
12750                 error "create $file3 failed"
12751
12752         $LFS swap_layouts $file1 $file2 ||
12753                 error "swap $file1 $file2 layouts failed"
12754
12755         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
12756         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
12757
12758         echo 123 > $file1 || error "Should be able to write into $file1"
12759
12760         $LFS swap_layouts $file1 $file3 ||
12761                 error "swap $file1 $file3 layouts failed"
12762
12763         echo 123 > $file1 || error "Should be able to write into $file1"
12764
12765         rm -rf $file1 $file2 $file3
12766 }
12767 run_test 184e "Recreate layout after stripeless layout swaps"
12768
12769 test_185() { # LU-2441
12770         # LU-3553 - no volatile file support in old servers
12771         [[ $(lustre_version_code $SINGLEMDS) -ge $(version_code 2.3.60) ]] ||
12772                 { skip "Need MDS version at least 2.3.60"; return 0; }
12773
12774         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
12775         touch $DIR/$tdir/spoo
12776         local mtime1=$(stat -c "%Y" $DIR/$tdir)
12777         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
12778                 error "cannot create/write a volatile file"
12779         [ "$FILESET" == "" ] &&
12780         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
12781                 error "FID is still valid after close"
12782
12783         multiop_bg_pause $DIR/$tdir vVw4096_c
12784         local multi_pid=$!
12785
12786         local OLD_IFS=$IFS
12787         IFS=":"
12788         local fidv=($fid)
12789         IFS=$OLD_IFS
12790         # assume that the next FID for this client is sequential, since stdout
12791         # is unfortunately eaten by multiop_bg_pause
12792         local n=$((${fidv[1]} + 1))
12793         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
12794         if [ "$FILESET" == "" ]; then
12795                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
12796                         error "FID is missing before close"
12797         fi
12798         kill -USR1 $multi_pid
12799         # 1 second delay, so if mtime change we will see it
12800         sleep 1
12801         local mtime2=$(stat -c "%Y" $DIR/$tdir)
12802         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
12803 }
12804 run_test 185 "Volatile file support"
12805
12806 test_187a() {
12807         remote_mds_nodsh && skip "remote MDS with nodsh" && return
12808         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.3.0) ] &&
12809                 skip "Need MDS version at least 2.3.0" && return
12810
12811         local dir0=$DIR/$tdir/$testnum
12812         mkdir -p $dir0 || error "creating dir $dir0"
12813
12814         local file=$dir0/file1
12815         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
12816         local dv1=$($LFS data_version $file)
12817         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
12818         local dv2=$($LFS data_version $file)
12819         [[ $dv1 != $dv2 ]] ||
12820                 error "data version did not change on write $dv1 == $dv2"
12821
12822         # clean up
12823         rm -f $file1
12824 }
12825 run_test 187a "Test data version change"
12826
12827 test_187b() {
12828         remote_mds_nodsh && skip "remote MDS with nodsh" && return
12829         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.3.0) ] &&
12830                 skip "Need MDS version at least 2.3.0" && return
12831
12832         local dir0=$DIR/$tdir/$testnum
12833         mkdir -p $dir0 || error "creating dir $dir0"
12834
12835         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
12836         [[ ${DV[0]} != ${DV[1]} ]] ||
12837                 error "data version did not change on write"\
12838                       " ${DV[0]} == ${DV[1]}"
12839
12840         # clean up
12841         rm -f $file1
12842 }
12843 run_test 187b "Test data version change on volatile file"
12844
12845 test_200() {
12846         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
12847         remote_mgs_nodsh && skip "remote MGS with nodsh" && return
12848         [ -n "$FILESET" ] && skip "SKIP due to FILESET set" && return
12849
12850         local POOL=${POOL:-cea1}
12851         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
12852         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
12853         # Pool OST targets
12854         local first_ost=0
12855         local last_ost=$(($OSTCOUNT - 1))
12856         local ost_step=2
12857         local ost_list=$(seq $first_ost $ost_step $last_ost)
12858         local ost_range="$first_ost $last_ost $ost_step"
12859         local test_path=$POOL_ROOT/$POOL_DIR_NAME
12860         local file_dir=$POOL_ROOT/file_tst
12861         local subdir=$test_path/subdir
12862         local rc=0
12863
12864         if ! combined_mgs_mds ; then
12865                 mount_mgs_client
12866         fi
12867
12868         while : ; do
12869                 # former test_200a test_200b
12870                 pool_add $POOL                          || { rc=$? ; break; }
12871                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
12872                 # former test_200c test_200d
12873                 mkdir -p $test_path
12874                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
12875                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
12876                 mkdir -p $subdir
12877                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
12878                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
12879                                                         || { rc=$? ; break; }
12880                 # former test_200e test_200f
12881                 local files=$((OSTCOUNT*3))
12882                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
12883                                                         || { rc=$? ; break; }
12884                 pool_create_files $POOL $file_dir $files "$ost_list" \
12885                                                         || { rc=$? ; break; }
12886                 # former test_200g test_200h
12887                 pool_lfs_df $POOL                       || { rc=$? ; break; }
12888                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
12889
12890                 # former test_201a test_201b test_201c
12891                 pool_remove_first_target $POOL          || { rc=$? ; break; }
12892
12893                 local f=$test_path/$tfile
12894                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
12895                 pool_remove $POOL $f                    || { rc=$? ; break; }
12896                 break
12897         done
12898
12899         destroy_test_pools
12900
12901         if ! combined_mgs_mds ; then
12902                 umount_mgs_client
12903         fi
12904         return $rc
12905 }
12906 run_test 200 "OST pools"
12907
12908 # usage: default_attr <count | size | offset>
12909 default_attr() {
12910         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
12911 }
12912
12913 # usage: check_default_stripe_attr
12914 check_default_stripe_attr() {
12915         ACTUAL=$($GETSTRIPE $* $DIR/$tdir)
12916         case $1 in
12917         --stripe-count|-c)
12918                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
12919         --stripe-size|-S)
12920                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
12921         --stripe-index|-i)
12922                 EXPECTED=-1;;
12923         *)
12924                 error "unknown getstripe attr '$1'"
12925         esac
12926
12927         [ $ACTUAL == $EXPECTED ] ||
12928                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
12929 }
12930
12931 test_204a() {
12932         test_mkdir $DIR/$tdir
12933         $SETSTRIPE --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
12934
12935         check_default_stripe_attr --stripe-count
12936         check_default_stripe_attr --stripe-size
12937         check_default_stripe_attr --stripe-index
12938 }
12939 run_test 204a "Print default stripe attributes"
12940
12941 test_204b() {
12942         test_mkdir $DIR/$tdir
12943         $SETSTRIPE --stripe-count 1 $DIR/$tdir
12944
12945         check_default_stripe_attr --stripe-size
12946         check_default_stripe_attr --stripe-index
12947 }
12948 run_test 204b "Print default stripe size and offset"
12949
12950 test_204c() {
12951         test_mkdir $DIR/$tdir
12952         $SETSTRIPE --stripe-size 65536 $DIR/$tdir
12953
12954         check_default_stripe_attr --stripe-count
12955         check_default_stripe_attr --stripe-index
12956 }
12957 run_test 204c "Print default stripe count and offset"
12958
12959 test_204d() {
12960         test_mkdir $DIR/$tdir
12961         $SETSTRIPE --stripe-index 0 $DIR/$tdir
12962
12963         check_default_stripe_attr --stripe-count
12964         check_default_stripe_attr --stripe-size
12965 }
12966 run_test 204d "Print default stripe count and size"
12967
12968 test_204e() {
12969         test_mkdir $DIR/$tdir
12970         $SETSTRIPE -d $DIR/$tdir
12971
12972         check_default_stripe_attr --stripe-count --raw
12973         check_default_stripe_attr --stripe-size --raw
12974         check_default_stripe_attr --stripe-index --raw
12975 }
12976 run_test 204e "Print raw stripe attributes"
12977
12978 test_204f() {
12979         test_mkdir $DIR/$tdir
12980         $SETSTRIPE --stripe-count 1 $DIR/$tdir
12981
12982         check_default_stripe_attr --stripe-size --raw
12983         check_default_stripe_attr --stripe-index --raw
12984 }
12985 run_test 204f "Print raw stripe size and offset"
12986
12987 test_204g() {
12988         test_mkdir $DIR/$tdir
12989         $SETSTRIPE --stripe-size 65536 $DIR/$tdir
12990
12991         check_default_stripe_attr --stripe-count --raw
12992         check_default_stripe_attr --stripe-index --raw
12993 }
12994 run_test 204g "Print raw stripe count and offset"
12995
12996 test_204h() {
12997         test_mkdir $DIR/$tdir
12998         $SETSTRIPE --stripe-index 0 $DIR/$tdir
12999
13000         check_default_stripe_attr --stripe-count --raw
13001         check_default_stripe_attr --stripe-size --raw
13002 }
13003 run_test 204h "Print raw stripe count and size"
13004
13005 # Figure out which job scheduler is being used, if any,
13006 # or use a fake one
13007 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
13008         JOBENV=SLURM_JOB_ID
13009 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
13010         JOBENV=LSB_JOBID
13011 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
13012         JOBENV=PBS_JOBID
13013 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
13014         JOBENV=LOADL_STEP_ID
13015 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
13016         JOBENV=JOB_ID
13017 else
13018         $LCTL list_param jobid_name > /dev/null 2>&1
13019         if [ $? -eq 0 ]; then
13020                 JOBENV=nodelocal
13021         else
13022                 JOBENV=FAKE_JOBID
13023         fi
13024 fi
13025
13026 verify_jobstats() {
13027         local cmd=($1)
13028         shift
13029         local facets="$@"
13030
13031 # we don't really need to clear the stats for this test to work, since each
13032 # command has a unique jobid, but it makes debugging easier if needed.
13033 #       for facet in $facets; do
13034 #               local dev=$(convert_facet2label $facet)
13035 #               # clear old jobstats
13036 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
13037 #       done
13038
13039         # use a new JobID for each test, or we might see an old one
13040         [ "$JOBENV" = "FAKE_JOBID" ] &&
13041                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
13042
13043         JOBVAL=${!JOBENV}
13044
13045         [ "$JOBENV" = "nodelocal" ] && {
13046                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
13047                 $LCTL set_param jobid_name=$FAKE_JOBID
13048                 JOBVAL=$FAKE_JOBID
13049         }
13050
13051         log "Test: ${cmd[*]}"
13052         log "Using JobID environment variable $JOBENV=$JOBVAL"
13053
13054         if [ $JOBENV = "FAKE_JOBID" ]; then
13055                 FAKE_JOBID=$JOBVAL ${cmd[*]}
13056         else
13057                 ${cmd[*]}
13058         fi
13059
13060         # all files are created on OST0000
13061         for facet in $facets; do
13062                 local stats="*.$(convert_facet2label $facet).job_stats"
13063                 if [ $(do_facet $facet lctl get_param $stats |
13064                        grep -c $JOBVAL) -ne 1 ]; then
13065                         do_facet $facet lctl get_param $stats
13066                         error "No jobstats for $JOBVAL found on $facet::$stats"
13067                 fi
13068         done
13069 }
13070
13071 jobstats_set() {
13072         trap 0
13073         NEW_JOBENV=${1:-$OLD_JOBENV}
13074         do_facet mgs $LCTL conf_param $FSNAME.sys.jobid_var=$NEW_JOBENV
13075         wait_update $HOSTNAME "$LCTL get_param -n jobid_var" $NEW_JOBENV
13076 }
13077
13078 cleanup_205() {
13079         trap 0
13080         do_facet $SINGLEMDS \
13081                 $LCTL set_param mdt.*.job_cleanup_interval=$OLD_INTERVAL
13082         [ $OLD_JOBENV != $JOBENV ] && jobstats_set $OLD_JOBENV
13083         cleanup_changelog
13084 }
13085
13086 test_205() { # Job stats
13087         [[ $(lustre_version_code $SINGLEMDS) -ge $(version_code 2.7.1) ]] ||
13088                 { skip "Need MDS version with at least 2.7.1"; return 0; }
13089
13090         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
13091         remote_mgs_nodsh && skip "remote MGS with nodsh" && return
13092         remote_mds_nodsh && skip "remote MDS with nodsh" && return
13093         remote_ost_nodsh && skip "remote OST with nodsh" && return
13094
13095         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
13096                 skip "Server doesn't support jobstats" && return 0
13097         [[ $JOBID_VAR = disable ]] && skip "jobstats is disabled" && return
13098
13099         OLD_JOBENV=$($LCTL get_param -n jobid_var)
13100         if [ $OLD_JOBENV != $JOBENV ]; then
13101                 jobstats_set $JOBENV
13102                 trap cleanup_205 EXIT
13103         fi
13104
13105         CL_USER=$(do_facet $SINGLEMDS lctl --device $MDT0 changelog_register -n)
13106         echo "Registered as changelog user $CL_USER"
13107
13108         OLD_INTERVAL=$(do_facet $SINGLEMDS \
13109                        lctl get_param -n mdt.*.job_cleanup_interval)
13110         local interval_new=5
13111         do_facet $SINGLEMDS \
13112                 $LCTL set_param mdt.*.job_cleanup_interval=$interval_new
13113         local start=$SECONDS
13114
13115         local cmd
13116         # mkdir
13117         cmd="mkdir $DIR/$tdir"
13118         verify_jobstats "$cmd" "$SINGLEMDS"
13119         # rmdir
13120         cmd="rmdir $DIR/$tdir"
13121         verify_jobstats "$cmd" "$SINGLEMDS"
13122         # mkdir on secondary MDT
13123         if [ $MDSCOUNT -gt 1 ]; then
13124                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
13125                 verify_jobstats "$cmd" "mds2"
13126         fi
13127         # mknod
13128         cmd="mknod $DIR/$tfile c 1 3"
13129         verify_jobstats "$cmd" "$SINGLEMDS"
13130         # unlink
13131         cmd="rm -f $DIR/$tfile"
13132         verify_jobstats "$cmd" "$SINGLEMDS"
13133         # create all files on OST0000 so verify_jobstats can find OST stats
13134         # open & close
13135         cmd="$SETSTRIPE -i 0 -c 1 $DIR/$tfile"
13136         verify_jobstats "$cmd" "$SINGLEMDS"
13137         # setattr
13138         cmd="touch $DIR/$tfile"
13139         verify_jobstats "$cmd" "$SINGLEMDS ost1"
13140         # write
13141         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
13142         verify_jobstats "$cmd" "ost1"
13143         # read
13144         cancel_lru_locks osc
13145         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
13146         verify_jobstats "$cmd" "ost1"
13147         # truncate
13148         cmd="$TRUNCATE $DIR/$tfile 0"
13149         verify_jobstats "$cmd" "$SINGLEMDS ost1"
13150         # rename
13151         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
13152         verify_jobstats "$cmd" "$SINGLEMDS"
13153         # jobstats expiry - sleep until old stats should be expired
13154         local left=$((interval_new + 5 - (SECONDS - start)))
13155         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
13156                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
13157                         "0" $left
13158         cmd="mkdir $DIR/$tdir.expire"
13159         verify_jobstats "$cmd" "$SINGLEMDS"
13160         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
13161             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
13162
13163         # Ensure that jobid are present in changelog (if supported by MDS)
13164         if [ $(lustre_version_code $SINGLEMDS) -ge $(version_code 2.6.52) ]
13165         then
13166                 $LFS changelog $MDT0 | tail -9
13167                 jobids=$($LFS changelog $MDT0 | tail -9 | grep -c "j=")
13168                 [ $jobids -eq 9 ] ||
13169                         error "Wrong changelog jobid count $jobids != 9"
13170
13171                 # LU-5862
13172                 JOBENV="disable"
13173                 jobstats_set $JOBENV
13174                 touch $DIR/$tfile
13175                 $LFS changelog $MDT0 | tail -1
13176                 jobids=$($LFS changelog $MDT0 | tail -1 | grep -c "j=")
13177                 [ $jobids -eq 0 ] ||
13178                         error "Unexpected jobids when jobid_var=$JOBENV"
13179         fi
13180
13181         cleanup_205
13182 }
13183 run_test 205 "Verify job stats"
13184
13185 # LU-1480, LU-1773 and LU-1657
13186 test_206() {
13187         mkdir -p $DIR/$tdir
13188         $SETSTRIPE -c -1 $DIR/$tdir
13189 #define OBD_FAIL_LOV_INIT 0x1403
13190         $LCTL set_param fail_loc=0xa0001403
13191         $LCTL set_param fail_val=1
13192         touch $DIR/$tdir/$tfile || true
13193 }
13194 run_test 206 "fail lov_init_raid0() doesn't lbug"
13195
13196 test_207a() {
13197         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
13198         local fsz=`stat -c %s $DIR/$tfile`
13199         cancel_lru_locks mdc
13200
13201         # do not return layout in getattr intent
13202 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
13203         $LCTL set_param fail_loc=0x170
13204         local sz=`stat -c %s $DIR/$tfile`
13205
13206         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
13207
13208         rm -rf $DIR/$tfile
13209 }
13210 run_test 207a "can refresh layout at glimpse"
13211
13212 test_207b() {
13213         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
13214         local cksum=`md5sum $DIR/$tfile`
13215         local fsz=`stat -c %s $DIR/$tfile`
13216         cancel_lru_locks mdc
13217         cancel_lru_locks osc
13218
13219         # do not return layout in getattr intent
13220 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
13221         $LCTL set_param fail_loc=0x171
13222
13223         # it will refresh layout after the file is opened but before read issues
13224         echo checksum is "$cksum"
13225         echo "$cksum" |md5sum -c --quiet || error "file differs"
13226
13227         rm -rf $DIR/$tfile
13228 }
13229 run_test 207b "can refresh layout at open"
13230
13231 test_208() {
13232         # FIXME: in this test suite, only RD lease is used. This is okay
13233         # for now as only exclusive open is supported. After generic lease
13234         # is done, this test suite should be revised. - Jinshan
13235
13236         remote_mds_nodsh && skip "remote MDS with nodsh" && return
13237         [[ $(lustre_version_code $SINGLEMDS) -ge $(version_code 2.4.52) ]] ||
13238                 { skip "Need MDS version at least 2.4.52"; return 0; }
13239
13240         echo "==== test 1: verify get lease work"
13241         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
13242
13243         echo "==== test 2: verify lease can be broken by upcoming open"
13244         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
13245         local PID=$!
13246         sleep 1
13247
13248         $MULTIOP $DIR/$tfile oO_RDONLY:c
13249         kill -USR1 $PID && wait $PID || error "break lease error"
13250
13251         echo "==== test 3: verify lease can't be granted if an open already exists"
13252         $MULTIOP $DIR/$tfile oO_RDONLY:_c &
13253         local PID=$!
13254         sleep 1
13255
13256         $MULTIOP $DIR/$tfile oO_RDONLY:eReUc && error "apply lease should fail"
13257         kill -USR1 $PID && wait $PID || error "open file error"
13258
13259         echo "==== test 4: lease can sustain over recovery"
13260         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
13261         PID=$!
13262         sleep 1
13263
13264         fail mds1
13265
13266         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
13267
13268         echo "==== test 5: lease broken can't be regained by replay"
13269         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
13270         PID=$!
13271         sleep 1
13272
13273         # open file to break lease and then recovery
13274         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
13275         fail mds1
13276
13277         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
13278
13279         rm -f $DIR/$tfile
13280 }
13281 run_test 208 "Exclusive open"
13282
13283 test_209() {
13284         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
13285                 skip_env "must have disp_stripe" && return
13286
13287         touch $DIR/$tfile
13288         sync; sleep 5; sync;
13289
13290         echo 3 > /proc/sys/vm/drop_caches
13291         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
13292
13293         # open/close 500 times
13294         for i in $(seq 500); do
13295                 cat $DIR/$tfile
13296         done
13297
13298         echo 3 > /proc/sys/vm/drop_caches
13299         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
13300
13301         echo "before: $req_before, after: $req_after"
13302         [ $((req_after - req_before)) -ge 300 ] &&
13303                 error "open/close requests are not freed"
13304         return 0
13305 }
13306 run_test 209 "read-only open/close requests should be freed promptly"
13307
13308 test_212() {
13309         size=`date +%s`
13310         size=$((size % 8192 + 1))
13311         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
13312         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
13313         rm -f $DIR/f212 $DIR/f212.xyz
13314 }
13315 run_test 212 "Sendfile test ============================================"
13316
13317 test_213() {
13318         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
13319         cancel_lru_locks osc
13320         lctl set_param fail_loc=0x8000040f
13321         # generate a read lock
13322         cat $DIR/$tfile > /dev/null
13323         # write to the file, it will try to cancel the above read lock.
13324         cat /etc/hosts >> $DIR/$tfile
13325 }
13326 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
13327
13328 test_214() { # for bug 20133
13329         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
13330         for (( i=0; i < 340; i++ )) ; do
13331                 touch $DIR/$tdir/d214c/a$i
13332         done
13333
13334         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
13335         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
13336         ls $DIR/d214c || error "ls $DIR/d214c failed"
13337         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
13338         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
13339 }
13340 run_test 214 "hash-indexed directory test - bug 20133"
13341
13342 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
13343 create_lnet_proc_files() {
13344         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
13345 }
13346
13347 # counterpart of create_lnet_proc_files
13348 remove_lnet_proc_files() {
13349         rm -f $TMP/lnet_$1.sys
13350 }
13351
13352 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
13353 # 3rd arg as regexp for body
13354 check_lnet_proc_stats() {
13355         local l=$(cat "$TMP/lnet_$1" |wc -l)
13356         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
13357
13358         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
13359 }
13360
13361 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
13362 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
13363 # optional and can be regexp for 2nd line (lnet.routes case)
13364 check_lnet_proc_entry() {
13365         local blp=2          # blp stands for 'position of 1st line of body'
13366         [ -z "$5" ] || blp=3 # lnet.routes case
13367
13368         local l=$(cat "$TMP/lnet_$1" |wc -l)
13369         # subtracting one from $blp because the body can be empty
13370         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
13371
13372         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
13373                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
13374
13375         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
13376                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
13377
13378         # bail out if any unexpected line happened
13379         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
13380         [ "$?" != 0 ] || error "$2 misformatted"
13381 }
13382
13383 test_215() { # for bugs 18102, 21079, 21517
13384         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
13385         local N='(0|[1-9][0-9]*)'       # non-negative numeric
13386         local P='[1-9][0-9]*'           # positive numeric
13387         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
13388         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
13389         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
13390         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
13391
13392         local L1 # regexp for 1st line
13393         local L2 # regexp for 2nd line (optional)
13394         local BR # regexp for the rest (body)
13395
13396         # lnet.stats should look as 11 space-separated non-negative numerics
13397         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
13398         create_lnet_proc_files "stats"
13399         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
13400         remove_lnet_proc_files "stats"
13401
13402         # lnet.routes should look like this:
13403         # Routing disabled/enabled
13404         # net hops priority state router
13405         # where net is a string like tcp0, hops > 0, priority >= 0,
13406         # state is up/down,
13407         # router is a string like 192.168.1.1@tcp2
13408         L1="^Routing (disabled|enabled)$"
13409         L2="^net +hops +priority +state +router$"
13410         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
13411         create_lnet_proc_files "routes"
13412         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
13413         remove_lnet_proc_files "routes"
13414
13415         # lnet.routers should look like this:
13416         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
13417         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
13418         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
13419         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
13420         L1="^ref +rtr_ref +alive_cnt +state +last_ping +ping_sent +deadline +down_ni +router$"
13421         BR="^$P +$P +$N +(up|down) +$N +(0|1) +$I +$I +$NID$"
13422         create_lnet_proc_files "routers"
13423         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
13424         remove_lnet_proc_files "routers"
13425
13426         # lnet.peers should look like this:
13427         # nid refs state last max rtr min tx min queue
13428         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
13429         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
13430         # numeric (0 or >0 or <0), queue >= 0.
13431         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
13432         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
13433         create_lnet_proc_files "peers"
13434         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
13435         remove_lnet_proc_files "peers"
13436
13437         # lnet.buffers  should look like this:
13438         # pages count credits min
13439         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
13440         L1="^pages +count +credits +min$"
13441         BR="^ +$N +$N +$I +$I$"
13442         create_lnet_proc_files "buffers"
13443         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
13444         remove_lnet_proc_files "buffers"
13445
13446         # lnet.nis should look like this:
13447         # nid status alive refs peer rtr max tx min
13448         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
13449         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
13450         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
13451         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
13452         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
13453         create_lnet_proc_files "nis"
13454         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
13455         remove_lnet_proc_files "nis"
13456
13457         # can we successfully write to lnet.stats?
13458         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
13459 }
13460 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
13461
13462 test_216() { # bug 20317
13463         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
13464         remote_ost_nodsh && skip "remote OST with nodsh" && return
13465
13466         local node
13467         local facets=$(get_facets OST)
13468         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13469
13470         save_lustre_params client "osc.*.contention_seconds" > $p
13471         save_lustre_params $facets \
13472                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
13473         save_lustre_params $facets \
13474                 "ldlm.namespaces.filter-*.contended_locks" >> $p
13475         save_lustre_params $facets \
13476                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
13477         clear_stats osc.*.osc_stats
13478
13479         # agressive lockless i/o settings
13480         do_nodes $(comma_list $(osts_nodes)) \
13481                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
13482                         ldlm.namespaces.filter-*.contended_locks=0 \
13483                         ldlm.namespaces.filter-*.contention_seconds=60"
13484         lctl set_param -n osc.*.contention_seconds=60
13485
13486         $DIRECTIO write $DIR/$tfile 0 10 4096
13487         $CHECKSTAT -s 40960 $DIR/$tfile
13488
13489         # disable lockless i/o
13490         do_nodes $(comma_list $(osts_nodes)) \
13491                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
13492                         ldlm.namespaces.filter-*.contended_locks=32 \
13493                         ldlm.namespaces.filter-*.contention_seconds=0"
13494         lctl set_param -n osc.*.contention_seconds=0
13495         clear_stats osc.*.osc_stats
13496
13497         dd if=/dev/zero of=$DIR/$tfile count=0
13498         $CHECKSTAT -s 0 $DIR/$tfile
13499
13500         restore_lustre_params <$p
13501         rm -f $p
13502         rm $DIR/$tfile
13503 }
13504 run_test 216 "check lockless direct write updates file size and kms correctly"
13505
13506 test_217() { # bug 22430
13507         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
13508         local node
13509         local nid
13510
13511         for node in $(nodes_list); do
13512                 nid=$(host_nids_address $node $NETTYPE)
13513                 if [[ $nid = *-* ]] ; then
13514                         echo "lctl ping $(h2nettype $nid)"
13515                         lctl ping $(h2nettype $nid)
13516                 else
13517                         echo "skipping $node (no hyphen detected)"
13518                 fi
13519         done
13520 }
13521 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
13522
13523 test_218() {
13524        # do directio so as not to populate the page cache
13525        log "creating a 10 Mb file"
13526        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
13527        log "starting reads"
13528        dd if=$DIR/$tfile of=/dev/null bs=4096 &
13529        log "truncating the file"
13530        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
13531        log "killing dd"
13532        kill %+ || true # reads might have finished
13533        echo "wait until dd is finished"
13534        wait
13535        log "removing the temporary file"
13536        rm -rf $DIR/$tfile || error "tmp file removal failed"
13537 }
13538 run_test 218 "parallel read and truncate should not deadlock ======================="
13539
13540 test_219() {
13541         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
13542         # write one partial page
13543         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
13544         # set no grant so vvp_io_commit_write will do sync write
13545         $LCTL set_param fail_loc=0x411
13546         # write a full page at the end of file
13547         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
13548
13549         $LCTL set_param fail_loc=0
13550         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
13551         $LCTL set_param fail_loc=0x411
13552         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
13553
13554         # LU-4201
13555         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
13556         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
13557 }
13558 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
13559
13560 test_220() { #LU-325
13561         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
13562         remote_ost_nodsh && skip "remote OST with nodsh" && return
13563         remote_mds_nodsh && skip "remote MDS with nodsh" && return
13564         remote_mgs_nodsh && skip "remote MGS with nodsh" && return
13565         local OSTIDX=0
13566
13567         # create on MDT0000 so the last_id and next_id are correct
13568         mkdir $DIR/$tdir
13569         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
13570         OST=${OST%_UUID}
13571
13572         # on the mdt's osc
13573         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
13574         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
13575                         osc.$mdtosc_proc1.prealloc_last_id)
13576         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
13577                         osc.$mdtosc_proc1.prealloc_next_id)
13578
13579         $LFS df -i
13580
13581         if ! combined_mgs_mds ; then
13582                 mount_mgs_client
13583         fi
13584
13585         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
13586         #define OBD_FAIL_OST_ENOINO              0x229
13587         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
13588         create_pool $FSNAME.$TESTNAME || return 1
13589         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
13590
13591         $SETSTRIPE $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
13592
13593         MDSOBJS=$((last_id - next_id))
13594         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
13595
13596         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
13597         echo "OST still has $count kbytes free"
13598
13599         echo "create $MDSOBJS files @next_id..."
13600         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
13601
13602         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
13603                         osc.$mdtosc_proc1.prealloc_last_id)
13604         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
13605                         osc.$mdtosc_proc1.prealloc_next_id)
13606
13607         echo "after creation, last_id=$last_id2, next_id=$next_id2"
13608         $LFS df -i
13609
13610         echo "cleanup..."
13611
13612         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
13613         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
13614
13615         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
13616                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
13617         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
13618                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
13619         echo "unlink $MDSOBJS files @$next_id..."
13620         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
13621
13622         if ! combined_mgs_mds ; then
13623                 umount_mgs_client
13624         fi
13625 }
13626 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
13627
13628 test_221() {
13629         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
13630         dd if=`which date` of=$MOUNT/date oflag=sync
13631         chmod +x $MOUNT/date
13632
13633         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
13634         $LCTL set_param fail_loc=0x80001401
13635
13636         $MOUNT/date > /dev/null
13637         rm -f $MOUNT/date
13638 }
13639 run_test 221 "make sure fault and truncate race to not cause OOM"
13640
13641 test_222a () {
13642         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
13643         rm -rf $DIR/$tdir
13644         test_mkdir $DIR/$tdir
13645         $LFS setstripe -c 1 -i 0 $DIR/$tdir
13646         createmany -o $DIR/$tdir/$tfile 10
13647         cancel_lru_locks mdc
13648         cancel_lru_locks osc
13649         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
13650         $LCTL set_param fail_loc=0x31a
13651         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
13652         $LCTL set_param fail_loc=0
13653         rm -r $DIR/$tdir
13654 }
13655 run_test 222a "AGL for ls should not trigger CLIO lock failure"
13656
13657 test_222b () {
13658         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
13659         rm -rf $DIR/$tdir
13660         test_mkdir $DIR/$tdir
13661         $LFS setstripe -c 1 -i 0 $DIR/$tdir
13662         createmany -o $DIR/$tdir/$tfile 10
13663         cancel_lru_locks mdc
13664         cancel_lru_locks osc
13665         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
13666         $LCTL set_param fail_loc=0x31a
13667         rm -r $DIR/$tdir || error "AGL for rmdir failed"
13668         $LCTL set_param fail_loc=0
13669 }
13670 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
13671
13672 test_223 () {
13673         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
13674         rm -rf $DIR/$tdir
13675         test_mkdir $DIR/$tdir
13676         $LFS setstripe -c 1 -i 0 $DIR/$tdir
13677         createmany -o $DIR/$tdir/$tfile 10
13678         cancel_lru_locks mdc
13679         cancel_lru_locks osc
13680         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
13681         $LCTL set_param fail_loc=0x31b
13682         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
13683         $LCTL set_param fail_loc=0
13684         rm -r $DIR/$tdir
13685 }
13686 run_test 223 "osc reenqueue if without AGL lock granted ======================="
13687
13688 test_224a() { # LU-1039, MRP-303
13689         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
13690         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
13691         $LCTL set_param fail_loc=0x508
13692         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 conv=fsync
13693         $LCTL set_param fail_loc=0
13694         df $DIR
13695 }
13696 run_test 224a "Don't panic on bulk IO failure"
13697
13698 test_224b() { # LU-1039, MRP-303
13699         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
13700         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
13701         cancel_lru_locks osc
13702         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
13703         $LCTL set_param fail_loc=0x515
13704         dd of=/dev/null if=$DIR/$tfile bs=4096 count=1
13705         $LCTL set_param fail_loc=0
13706         df $DIR
13707 }
13708 run_test 224b "Don't panic on bulk IO failure"
13709
13710 test_224c() { # LU-6441
13711         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
13712         remote_mds_nodsh && skip "remote MDS with nodsh" && return
13713
13714         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13715         save_writethrough $p
13716         set_cache writethrough on
13717
13718         local pages_per_rpc=$($LCTL get_param \
13719                                 osc.*.max_pages_per_rpc)
13720         local at_max=$($LCTL get_param -n at_max)
13721         local timeout=$($LCTL get_param -n timeout)
13722         local test_at="$LCTL get_param -n at_max"
13723         local param_at="$FSNAME.sys.at_max"
13724         local test_timeout="$LCTL get_param -n timeout"
13725         local param_timeout="$FSNAME.sys.timeout"
13726
13727         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
13728
13729         set_conf_param_and_check client "$test_at" "$param_at" 0 ||
13730                 error "conf_param at_max=0 failed"
13731         set_conf_param_and_check client "$test_timeout" "$param_timeout" 5 ||
13732                 error "conf_param timeout=5 failed"
13733
13734         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3   0x520
13735         do_facet ost1 $LCTL set_param fail_loc=0x520
13736         $LFS setstripe -c 1 -i 0 $DIR/$tfile
13737         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
13738         sync
13739         do_facet ost1 $LCTL set_param fail_loc=0
13740
13741         set_conf_param_and_check client "$test_at" "$param_at" $at_max ||
13742                 error "conf_param at_max=$at_max failed"
13743         set_conf_param_and_check client "$test_timeout" "$param_timeout" \
13744                 $timeout || error "conf_param timeout=$timeout failed"
13745
13746         $LCTL set_param -n $pages_per_rpc
13747         restore_lustre_params < $p
13748         rm -f $p
13749 }
13750 run_test 224c "Don't hang if one of md lost during large bulk RPC"
13751
13752 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
13753 test_225a () {
13754         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
13755         remote_mds_nodsh && skip "remote MDS with nodsh" && return
13756         if [ -z ${MDSSURVEY} ]; then
13757               skip_env "mds-survey not found" && return
13758         fi
13759
13760         [ $MDSCOUNT -ge 2 ] &&
13761                 skip "skipping now for more than one MDT" && return
13762
13763        [ $(lustre_version_code $SINGLEMDS) -ge $(version_code 2.2.51) ] ||
13764             { skip "Need MDS version at least 2.2.51"; return; }
13765
13766        local mds=$(facet_host $SINGLEMDS)
13767        local target=$(do_nodes $mds 'lctl dl' | \
13768                       awk "{if (\$2 == \"UP\" && \$3 == \"mdt\") {print \$4}}")
13769
13770        local cmd1="file_count=1000 thrhi=4"
13771        local cmd2="dir_count=2 layer=mdd stripe_count=0"
13772        local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
13773        local cmd="$cmd1 $cmd2 $cmd3"
13774
13775        rm -f ${TMP}/mds_survey*
13776        echo + $cmd
13777        eval $cmd || error "mds-survey with zero-stripe failed"
13778        cat ${TMP}/mds_survey*
13779        rm -f ${TMP}/mds_survey*
13780 }
13781 run_test 225a "Metadata survey sanity with zero-stripe"
13782
13783 test_225b () {
13784         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
13785         remote_mds_nodsh && skip "remote MDS with nodsh" && return
13786         if [ -z ${MDSSURVEY} ]; then
13787               skip_env "mds-survey not found" && return
13788         fi
13789         [ $(lustre_version_code $SINGLEMDS) -ge $(version_code 2.2.51) ] ||
13790             { skip "Need MDS version at least 2.2.51"; return; }
13791
13792         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
13793               skip_env "Need to mount OST to test" && return
13794         fi
13795
13796        local mds=$(facet_host $SINGLEMDS)
13797        local target=$(do_nodes $mds 'lctl dl' | \
13798                       awk "{if (\$2 == \"UP\" && \$3 == \"mdt\") {print \$4}}")
13799
13800        local cmd1="file_count=1000 thrhi=4"
13801        local cmd2="dir_count=2 layer=mdd stripe_count=1"
13802        local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
13803        local cmd="$cmd1 $cmd2 $cmd3"
13804
13805        rm -f ${TMP}/mds_survey*
13806        echo + $cmd
13807        eval $cmd || error "mds-survey with stripe_count failed"
13808        cat ${TMP}/mds_survey*
13809        rm -f ${TMP}/mds_survey*
13810 }
13811 run_test 225b "Metadata survey sanity with stripe_count = 1"
13812
13813 mcreate_path2fid () {
13814         local mode=$1
13815         local major=$2
13816         local minor=$3
13817         local name=$4
13818         local desc=$5
13819         local path=$DIR/$tdir/$name
13820         local fid
13821         local rc
13822         local fid_path
13823
13824         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
13825                 error "cannot create $desc"
13826
13827         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
13828         rc=$?
13829         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
13830
13831         fid_path=$($LFS fid2path $MOUNT $fid)
13832         rc=$?
13833         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
13834
13835         [ "$path" == "$fid_path" ] ||
13836                 error "fid2path returned $fid_path, expected $path"
13837
13838         echo "pass with $path and $fid"
13839 }
13840
13841 test_226a () {
13842         rm -rf $DIR/$tdir
13843         mkdir -p $DIR/$tdir
13844
13845         mcreate_path2fid 0010666 0 0 fifo "FIFO"
13846         mcreate_path2fid 0020666 1 3 null "character special file (null)"
13847         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
13848         mcreate_path2fid 0040666 0 0 dir "directory"
13849         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
13850         mcreate_path2fid 0100666 0 0 file "regular file"
13851         mcreate_path2fid 0120666 0 0 link "symbolic link"
13852         mcreate_path2fid 0140666 0 0 sock "socket"
13853 }
13854 run_test 226a "call path2fid and fid2path on files of all type"
13855
13856 test_226b () {
13857         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
13858         rm -rf $DIR/$tdir
13859         local MDTIDX=1
13860
13861         mkdir -p $DIR/$tdir
13862         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
13863                 error "create remote directory failed"
13864         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
13865         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
13866                                 "character special file (null)"
13867         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
13868                                 "character special file (no device)"
13869         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
13870         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
13871                                 "block special file (loop)"
13872         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
13873         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
13874         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
13875 }
13876 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
13877
13878 # LU-1299 Executing or running ldd on a truncated executable does not
13879 # cause an out-of-memory condition.
13880 test_227() {
13881         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
13882         [ -z "$(which ldd)" ] && skip "should have ldd tool" && return
13883         dd if=$(which date) of=$MOUNT/date bs=1k count=1
13884         chmod +x $MOUNT/date
13885
13886         $MOUNT/date > /dev/null
13887         ldd $MOUNT/date > /dev/null
13888         rm -f $MOUNT/date
13889 }
13890 run_test 227 "running truncated executable does not cause OOM"
13891
13892 # LU-1512 try to reuse idle OI blocks
13893 test_228a() {
13894         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
13895         remote_mds_nodsh && skip "remote MDS with nodsh" && return
13896         [ "$(facet_fstype $SINGLEMDS)" != "ldiskfs" ] &&
13897                 skip "ldiskfs only test" && return
13898
13899         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
13900         local myDIR=$DIR/$tdir
13901
13902         mkdir -p $myDIR
13903         #define OBD_FAIL_SEQ_EXHAUST             0x1002
13904         $LCTL set_param fail_loc=0x80001002
13905         createmany -o $myDIR/t- 10000
13906         $LCTL set_param fail_loc=0
13907         # The guard is current the largest FID holder
13908         touch $myDIR/guard
13909         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
13910                     tr -d '[')
13911         local IDX=$(($SEQ % 64))
13912
13913         do_facet $SINGLEMDS sync
13914         # Make sure journal flushed.
13915         sleep 6
13916         local blk1=$(do_facet $SINGLEMDS \
13917                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
13918                      grep Blockcount | awk '{print $4}')
13919
13920         # Remove old files, some OI blocks will become idle.
13921         unlinkmany $myDIR/t- 10000
13922         # Create new files, idle OI blocks should be reused.
13923         createmany -o $myDIR/t- 2000
13924         do_facet $SINGLEMDS sync
13925         # Make sure journal flushed.
13926         sleep 6
13927         local blk2=$(do_facet $SINGLEMDS \
13928                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
13929                      grep Blockcount | awk '{print $4}')
13930
13931         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
13932 }
13933 run_test 228a "try to reuse idle OI blocks"
13934
13935 test_228b() {
13936         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
13937         remote_mds_nodsh && skip "remote MDS with nodsh" && return
13938         [ "$(facet_fstype $SINGLEMDS)" != "ldiskfs" ] &&
13939                 skip "ldiskfs only test" && return
13940
13941         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
13942         local myDIR=$DIR/$tdir
13943
13944         mkdir -p $myDIR
13945         #define OBD_FAIL_SEQ_EXHAUST             0x1002
13946         $LCTL set_param fail_loc=0x80001002
13947         createmany -o $myDIR/t- 10000
13948         $LCTL set_param fail_loc=0
13949         # The guard is current the largest FID holder
13950         touch $myDIR/guard
13951         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
13952                     tr -d '[')
13953         local IDX=$(($SEQ % 64))
13954
13955         do_facet $SINGLEMDS sync
13956         # Make sure journal flushed.
13957         sleep 6
13958         local blk1=$(do_facet $SINGLEMDS \
13959                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
13960                      grep Blockcount | awk '{print $4}')
13961
13962         # Remove old files, some OI blocks will become idle.
13963         unlinkmany $myDIR/t- 10000
13964
13965         # stop the MDT
13966         stop $SINGLEMDS || error "Fail to stop MDT."
13967         # remount the MDT
13968         start $SINGLEMDS $MDT_DEV $MDS_MOUNT_OPTS || error "Fail to start MDT."
13969
13970         df $MOUNT || error "Fail to df."
13971         # Create new files, idle OI blocks should be reused.
13972         createmany -o $myDIR/t- 2000
13973         do_facet $SINGLEMDS sync
13974         # Make sure journal flushed.
13975         sleep 6
13976         local blk2=$(do_facet $SINGLEMDS \
13977                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
13978                      grep Blockcount | awk '{print $4}')
13979
13980         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
13981 }
13982 run_test 228b "idle OI blocks can be reused after MDT restart"
13983
13984 #LU-1881
13985 test_228c() {
13986         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
13987         remote_mds_nodsh && skip "remote MDS with nodsh" && return
13988         [ "$(facet_fstype $SINGLEMDS)" != "ldiskfs" ] &&
13989                 skip "ldiskfs only test" && return
13990
13991         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
13992         local myDIR=$DIR/$tdir
13993
13994         mkdir -p $myDIR
13995         #define OBD_FAIL_SEQ_EXHAUST             0x1002
13996         $LCTL set_param fail_loc=0x80001002
13997         # 20000 files can guarantee there are index nodes in the OI file
13998         createmany -o $myDIR/t- 20000
13999         $LCTL set_param fail_loc=0
14000         # The guard is current the largest FID holder
14001         touch $myDIR/guard
14002         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
14003                     tr -d '[')
14004         local IDX=$(($SEQ % 64))
14005
14006         do_facet $SINGLEMDS sync
14007         # Make sure journal flushed.
14008         sleep 6
14009         local blk1=$(do_facet $SINGLEMDS \
14010                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
14011                      grep Blockcount | awk '{print $4}')
14012
14013         # Remove old files, some OI blocks will become idle.
14014         unlinkmany $myDIR/t- 20000
14015         rm -f $myDIR/guard
14016         # The OI file should become empty now
14017
14018         # Create new files, idle OI blocks should be reused.
14019         createmany -o $myDIR/t- 2000
14020         do_facet $SINGLEMDS sync
14021         # Make sure journal flushed.
14022         sleep 6
14023         local blk2=$(do_facet $SINGLEMDS \
14024                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
14025                      grep Blockcount | awk '{print $4}')
14026
14027         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
14028 }
14029 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
14030
14031 test_229() { # LU-2482, LU-3448
14032         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.4.53) ] &&
14033                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53" &&
14034                 return
14035         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
14036         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs" && return
14037
14038         rm -f $DIR/$tfile
14039
14040         # Create a file with a released layout and stripe count 2.
14041         $MULTIOP $DIR/$tfile H2c ||
14042                 error "failed to create file with released layout"
14043
14044         $GETSTRIPE -v $DIR/$tfile
14045
14046         local pattern=$($GETSTRIPE -L $DIR/$tfile)
14047         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
14048
14049         local stripe_count=$($GETSTRIPE -c $DIR/$tfile) || error "getstripe"
14050         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
14051         stat $DIR/$tfile || error "failed to stat released file"
14052
14053         chown $RUNAS_ID $DIR/$tfile ||
14054                 error "chown $RUNAS_ID $DIR/$tfile failed"
14055
14056         chgrp $RUNAS_ID $DIR/$tfile ||
14057                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
14058
14059         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
14060         rm $DIR/$tfile || error "failed to remove released file"
14061 }
14062 run_test 229 "getstripe/stat/rm/attr changes work on released files"
14063
14064 test_230a() {
14065         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
14066         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
14067         local MDTIDX=1
14068
14069         test_mkdir $DIR/$tdir
14070         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
14071         local mdt_idx=$($GETSTRIPE -M $DIR/$tdir/test_230_local)
14072         [ $mdt_idx -ne 0 ] &&
14073                 error "create local directory on wrong MDT $mdt_idx"
14074
14075         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
14076                         error "create remote directory failed"
14077         local mdt_idx=$($GETSTRIPE -M $DIR/$tdir/test_230)
14078         [ $mdt_idx -ne $MDTIDX ] &&
14079                 error "create remote directory on wrong MDT $mdt_idx"
14080
14081         createmany -o $DIR/$tdir/test_230/t- 10 ||
14082                 error "create files on remote directory failed"
14083         mdt_idx=$($GETSTRIPE -M $DIR/$tdir/test_230/t-0)
14084         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
14085         rm -r $DIR/$tdir || error "unlink remote directory failed"
14086 }
14087 run_test 230a "Create remote directory and files under the remote directory"
14088
14089 test_230b() {
14090         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
14091         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
14092         local MDTIDX=1
14093         local mdt_index
14094         local i
14095         local file
14096         local pid
14097         local stripe_count
14098         local migrate_dir=$DIR/$tdir/migrate_dir
14099         local other_dir=$DIR/$tdir/other_dir
14100
14101         test_mkdir $DIR/$tdir
14102         test_mkdir -i0 -c1 $migrate_dir
14103         test_mkdir -i0 -c1 $other_dir
14104         for ((i=0; i<10; i++)); do
14105                 mkdir -p $migrate_dir/dir_${i}
14106                 createmany -o $migrate_dir/dir_${i}/f 10 ||
14107                         error "create files under remote dir failed $i"
14108         done
14109
14110         cp /etc/passwd $migrate_dir/$tfile
14111         cp /etc/passwd $other_dir/$tfile
14112         chattr +SAD $migrate_dir
14113         chattr +SAD $migrate_dir/$tfile
14114
14115         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
14116         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
14117         local old_dir_mode=$(stat -c%f $migrate_dir)
14118         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
14119
14120         mkdir -p $migrate_dir/dir_default_stripe2
14121         $SETSTRIPE -c 2 $migrate_dir/dir_default_stripe2
14122         $SETSTRIPE -c 2 $migrate_dir/${tfile}_stripe2
14123
14124         mkdir -p $other_dir
14125         ln $migrate_dir/$tfile $other_dir/luna
14126         ln $migrate_dir/$tfile $migrate_dir/sofia
14127         ln $other_dir/$tfile $migrate_dir/david
14128         ln -s $migrate_dir/$tfile $other_dir/zachary
14129         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
14130         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
14131
14132         $LFS migrate -m $MDTIDX $migrate_dir ||
14133                 error "fails on migrating remote dir to MDT1"
14134
14135         echo "migratate to MDT1, then checking.."
14136         for ((i = 0; i < 10; i++)); do
14137                 for file in $(find $migrate_dir/dir_${i}); do
14138                         mdt_index=$($LFS getstripe -M $file)
14139                         [ $mdt_index == $MDTIDX ] ||
14140                                 error "$file is not on MDT${MDTIDX}"
14141                 done
14142         done
14143
14144         # the multiple link file should still in MDT0
14145         mdt_index=$($LFS getstripe -M $migrate_dir/$tfile)
14146         [ $mdt_index == 0 ] ||
14147                 error "$file is not on MDT${MDTIDX}"
14148
14149         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
14150         [ "$old_dir_flag" = "$new_dir_flag" ] ||
14151                 error " expect $old_dir_flag get $new_dir_flag"
14152
14153         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
14154         [ "$old_file_flag" = "$new_file_flag" ] ||
14155                 error " expect $old_file_flag get $new_file_flag"
14156
14157         local new_dir_mode=$(stat -c%f $migrate_dir)
14158         [ "$old_dir_mode" = "$new_dir_mode" ] ||
14159                 error "expect mode $old_dir_mode get $new_dir_mode"
14160
14161         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
14162         [ "$old_file_mode" = "$new_file_mode" ] ||
14163                 error "expect mode $old_file_mode get $new_file_mode"
14164
14165         diff /etc/passwd $migrate_dir/$tfile ||
14166                 error "$tfile different after migration"
14167
14168         diff /etc/passwd $other_dir/luna ||
14169                 error "luna different after migration"
14170
14171         diff /etc/passwd $migrate_dir/sofia ||
14172                 error "sofia different after migration"
14173
14174         diff /etc/passwd $migrate_dir/david ||
14175                 error "david different after migration"
14176
14177         diff /etc/passwd $other_dir/zachary ||
14178                 error "zachary different after migration"
14179
14180         diff /etc/passwd $migrate_dir/${tfile}_ln ||
14181                 error "${tfile}_ln different after migration"
14182
14183         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
14184                 error "${tfile}_ln_other different after migration"
14185
14186         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
14187         [ $stripe_count = 2 ] ||
14188                 error "dir strpe_count $d != 2 after migration."
14189
14190         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
14191         [ $stripe_count = 2 ] ||
14192                 error "file strpe_count $d != 2 after migration."
14193
14194         #migrate back to MDT0
14195         MDTIDX=0
14196
14197         $LFS migrate -m $MDTIDX $migrate_dir ||
14198                 error "fails on migrating remote dir to MDT0"
14199
14200         echo "migrate back to MDT0, checking.."
14201         for file in $(find $migrate_dir); do
14202                 mdt_index=$($LFS getstripe -M $file)
14203                 [ $mdt_index == $MDTIDX ] ||
14204                         error "$file is not on MDT${MDTIDX}"
14205         done
14206
14207         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
14208         [ "$old_dir_flag" = "$new_dir_flag" ] ||
14209                 error " expect $old_dir_flag get $new_dir_flag"
14210
14211         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
14212         [ "$old_file_flag" = "$new_file_flag" ] ||
14213                 error " expect $old_file_flag get $new_file_flag"
14214
14215         local new_dir_mode=$(stat -c%f $migrate_dir)
14216         [ "$old_dir_mode" = "$new_dir_mode" ] ||
14217                 error "expect mode $old_dir_mode get $new_dir_mode"
14218
14219         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
14220         [ "$old_file_mode" = "$new_file_mode" ] ||
14221                 error "expect mode $old_file_mode get $new_file_mode"
14222
14223         diff /etc/passwd ${migrate_dir}/$tfile ||
14224                 error "$tfile different after migration"
14225
14226         diff /etc/passwd ${other_dir}/luna ||
14227                 error "luna different after migration"
14228
14229         diff /etc/passwd ${migrate_dir}/sofia ||
14230                 error "sofia different after migration"
14231
14232         diff /etc/passwd ${other_dir}/zachary ||
14233                 error "zachary different after migration"
14234
14235         diff /etc/passwd $migrate_dir/${tfile}_ln ||
14236                 error "${tfile}_ln different after migration"
14237
14238         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
14239                 error "${tfile}_ln_other different after migration"
14240
14241         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
14242         [ $stripe_count = 2 ] ||
14243                 error "dir strpe_count $d != 2 after migration."
14244
14245         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
14246         [ $stripe_count = 2 ] ||
14247                 error "file strpe_count $d != 2 after migration."
14248
14249         rm -rf $DIR/$tdir || error "rm dir failed after migration"
14250 }
14251 run_test 230b "migrate directory"
14252
14253 test_230c() {
14254         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
14255         remote_mds_nodsh && skip "remote MDS with nodsh" && return
14256         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
14257         local MDTIDX=1
14258         local mdt_index
14259         local file
14260         local migrate_dir=$DIR/$tdir/migrate_dir
14261
14262         #If migrating directory fails in the middle, all entries of
14263         #the directory is still accessiable.
14264         test_mkdir $DIR/$tdir
14265         test_mkdir -i0 -c1 $migrate_dir
14266         stat $migrate_dir
14267         createmany -o $migrate_dir/f 10 ||
14268                 error "create files under ${migrate_dir} failed"
14269
14270         #failed after migrating 5 entries
14271         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
14272         do_facet mds1 lctl set_param fail_loc=0x20001801
14273         do_facet mds1 lctl  set_param fail_val=5
14274         local t=$(ls $migrate_dir | wc -l)
14275         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
14276                 error "migrate should fail after 5 entries"
14277
14278         mkdir $migrate_dir/dir &&
14279                 error "mkdir succeeds under migrating directory"
14280         touch $migrate_dir/file &&
14281                 error "touch file succeeds under migrating directory"
14282
14283         local u=$(ls $migrate_dir | wc -l)
14284         [ "$u" == "$t" ] || error "$u != $t during migration"
14285
14286         for file in $(find $migrate_dir); do
14287                 stat $file || error "stat $file failed"
14288         done
14289
14290         do_facet mds1 lctl set_param fail_loc=0
14291         do_facet mds1 lctl set_param fail_val=0
14292
14293         $LFS migrate -m $MDTIDX $migrate_dir ||
14294                 error "migrate open files should failed with open files"
14295
14296         echo "Finish migration, then checking.."
14297         for file in $(find $migrate_dir); do
14298                 mdt_index=$($LFS getstripe -M $file)
14299                 [ $mdt_index == $MDTIDX ] ||
14300                         error "$file is not on MDT${MDTIDX}"
14301         done
14302
14303         rm -rf $DIR/$tdir || error "rm dir failed after migration"
14304 }
14305 run_test 230c "check directory accessiblity if migration is failed"
14306
14307 test_230d() {
14308         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
14309         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
14310         local MDTIDX=1
14311         local mdt_index
14312         local migrate_dir=$DIR/$tdir/migrate_dir
14313         local i
14314         local j
14315
14316         test_mkdir $DIR/$tdir
14317         test_mkdir -i0 -c1 $migrate_dir
14318
14319         for ((i=0; i<100; i++)); do
14320                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
14321                 createmany -o $migrate_dir/dir_${i}/f 100 ||
14322                         error "create files under remote dir failed $i"
14323         done
14324
14325         $LFS migrate -m $MDTIDX $migrate_dir ||
14326                 error "migrate remote dir error"
14327
14328         echo "Finish migration, then checking.."
14329         for file in $(find $migrate_dir); do
14330                 mdt_index=$($LFS getstripe -M $file)
14331                 [ $mdt_index == $MDTIDX ] ||
14332                         error "$file is not on MDT${MDTIDX}"
14333         done
14334
14335         rm -rf $DIR/$tdir || error "rm dir failed after migration"
14336 }
14337 run_test 230d "check migrate big directory"
14338
14339 test_230e() {
14340         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
14341         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
14342         local i
14343         local j
14344         local a_fid
14345         local b_fid
14346
14347         mkdir -p $DIR/$tdir
14348         mkdir $DIR/$tdir/migrate_dir
14349         mkdir $DIR/$tdir/other_dir
14350         touch $DIR/$tdir/migrate_dir/a
14351         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
14352         ls $DIR/$tdir/other_dir
14353
14354         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
14355                 error "migrate dir fails"
14356
14357         mdt_index=$($LFS getstripe -M $DIR/$tdir/migrate_dir)
14358         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
14359
14360         mdt_index=$($LFS getstripe -M $DIR/$tdir/migrate_dir/a)
14361         [ $mdt_index == 0 ] || error "a is not on MDT0"
14362
14363         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
14364                 error "migrate dir fails"
14365
14366         mdt_index=$($LFS getstripe -M $DIR/$tdir/other_dir)
14367         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
14368
14369         mdt_index=$($LFS getstripe -M $DIR/$tdir/migrate_dir/a)
14370         [ $mdt_index == 1 ] || error "a is not on MDT1"
14371
14372         mdt_index=$($LFS getstripe -M $DIR/$tdir/other_dir/b)
14373         [ $mdt_index == 1 ] || error "b is not on MDT1"
14374
14375         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
14376         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
14377
14378         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
14379
14380         rm -rf $DIR/$tdir || error "rm dir failed after migration"
14381 }
14382 run_test 230e "migrate mulitple local link files"
14383
14384 test_230f() {
14385         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
14386         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
14387         local a_fid
14388         local ln_fid
14389
14390         mkdir -p $DIR/$tdir
14391         mkdir $DIR/$tdir/migrate_dir
14392         $LFS mkdir -i1 $DIR/$tdir/other_dir
14393         touch $DIR/$tdir/migrate_dir/a
14394         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
14395         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
14396         ls $DIR/$tdir/other_dir
14397
14398         # a should be migrated to MDT1, since no other links on MDT0
14399         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
14400                 error "#1 migrate dir fails"
14401         mdt_index=$($LFS getstripe -M $DIR/$tdir/migrate_dir)
14402         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
14403         mdt_index=$($LFS getstripe -M $DIR/$tdir/migrate_dir/a)
14404         [ $mdt_index == 1 ] || error "a is not on MDT1"
14405
14406         # a should stay on MDT1, because it is a mulitple link file
14407         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
14408                 error "#2 migrate dir fails"
14409         mdt_index=$($LFS getstripe -M $DIR/$tdir/migrate_dir/a)
14410         [ $mdt_index == 1 ] || error "a is not on MDT1"
14411
14412         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
14413                 error "#3 migrate dir fails"
14414
14415         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
14416         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
14417         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
14418
14419         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
14420         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
14421
14422         # a should be migrated to MDT0, since no other links on MDT1
14423         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
14424                 error "#4 migrate dir fails"
14425         mdt_index=$($LFS getstripe -M $DIR/$tdir/migrate_dir/a)
14426         [ $mdt_index == 0 ] || error "a is not on MDT0"
14427
14428         rm -rf $DIR/$tdir || error "rm dir failed after migration"
14429 }
14430 run_test 230f "migrate mulitple remote link files"
14431
14432 test_230g() {
14433         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
14434         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
14435
14436         mkdir -p $DIR/$tdir/migrate_dir
14437
14438         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
14439                 error "migrating dir to non-exist MDT succeeds"
14440         true
14441 }
14442 run_test 230g "migrate dir to non-exist MDT"
14443
14444 test_230h() {
14445         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
14446         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
14447         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.7.64) ] &&
14448                 skip "Need MDS version at least 2.7.64" && return
14449         local mdt_index
14450
14451         mkdir -p $DIR/$tdir/migrate_dir
14452
14453         $LFS migrate -m1 $DIR &&
14454                 error "migrating mountpoint1 should fail"
14455
14456         $LFS migrate -m1 $DIR/$tdir/.. &&
14457                 error "migrating mountpoint2 should fail"
14458
14459         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. ||
14460                 error "migrating $tdir fail"
14461
14462         mdt_index=$($LFS getstripe -M $DIR/$tdir)
14463         [ $mdt_index == 1 ] || error "$mdt_index != 1 after migration"
14464
14465         mdt_index=$($LFS getstripe -M $DIR/$tdir/migrate_dir)
14466         [ $mdt_index == 1 ] || error "$mdt_index != 1 after migration"
14467
14468 }
14469 run_test 230h "migrate .. and root"
14470
14471 test_230i() {
14472         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
14473         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
14474
14475         mkdir -p $DIR/$tdir/migrate_dir
14476
14477         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
14478                 error "migration fails with a tailing slash"
14479
14480         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
14481                 error "migration fails with two tailing slashes"
14482 }
14483 run_test 230i "lfs migrate -m tolerates trailing slashes"
14484
14485 test_231a()
14486 {
14487         # For simplicity this test assumes that max_pages_per_rpc
14488         # is the same across all OSCs
14489         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
14490         local bulk_size=$((max_pages * 4096))
14491         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
14492                                        head -n 1)
14493
14494         mkdir -p $DIR/$tdir
14495         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
14496                 error "failed to set stripe with -S ${brw_size}M option"
14497
14498         # clear the OSC stats
14499         $LCTL set_param osc.*.stats=0 &>/dev/null
14500         stop_writeback
14501
14502         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
14503         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
14504                 oflag=direct &>/dev/null || error "dd failed"
14505
14506         sync; sleep 1; sync # just to be safe
14507         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
14508         if [ x$nrpcs != "x1" ]; then
14509                 $LCTL get_param osc.*.stats
14510                 error "found $nrpcs ost_write RPCs, not 1 as expected"
14511         fi
14512
14513         start_writeback
14514         # Drop the OSC cache, otherwise we will read from it
14515         cancel_lru_locks osc
14516
14517         # clear the OSC stats
14518         $LCTL set_param osc.*.stats=0 &>/dev/null
14519
14520         # Client reads $bulk_size.
14521         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
14522                 iflag=direct &>/dev/null || error "dd failed"
14523
14524         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
14525         if [ x$nrpcs != "x1" ]; then
14526                 $LCTL get_param osc.*.stats
14527                 error "found $nrpcs ost_read RPCs, not 1 as expected"
14528         fi
14529 }
14530 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
14531
14532 test_231b() {
14533         mkdir -p $DIR/$tdir
14534         local i
14535         for i in {0..1023}; do
14536                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
14537                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
14538                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
14539         done
14540         sync
14541 }
14542 run_test 231b "must not assert on fully utilized OST request buffer"
14543
14544 test_232a() {
14545         mkdir -p $DIR/$tdir
14546         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
14547
14548         #define OBD_FAIL_LDLM_OST_LVB            0x31c
14549         do_facet ost1 $LCTL set_param fail_loc=0x31c
14550
14551         # ignore dd failure
14552         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
14553
14554         do_facet ost1 $LCTL set_param fail_loc=0
14555         umount_client $MOUNT || error "umount failed"
14556         mount_client $MOUNT || error "mount failed"
14557         stop ost1 || error "cannot stop ost1"
14558         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
14559 }
14560 run_test 232a "failed lock should not block umount"
14561
14562 test_232b() {
14563         mkdir -p $DIR/$tdir
14564         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
14565         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
14566         sync
14567         cancel_lru_locks osc
14568
14569         #define OBD_FAIL_LDLM_OST_LVB            0x31c
14570         do_facet ost1 $LCTL set_param fail_loc=0x31c
14571
14572         # ignore failure
14573         $LFS data_version $DIR/$tdir/$tfile || true
14574
14575         do_facet ost1 $LCTL set_param fail_loc=0
14576         umount_client $MOUNT || error "umount failed"
14577         mount_client $MOUNT || error "mount failed"
14578         stop ost1 || error "cannot stop ost1"
14579         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
14580 }
14581 run_test 232b "failed data version lock should not block umount"
14582
14583 test_233a() {
14584         [ $(lustre_version_code $SINGLEMDS) -ge $(version_code 2.3.64) ] ||
14585         { skip "Need MDS version at least 2.3.64"; return; }
14586         [ -n "$FILESET" ] && skip "SKIP due to FILESET set" && return
14587
14588         local fid=$($LFS path2fid $MOUNT)
14589         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
14590                 error "cannot access $MOUNT using its FID '$fid'"
14591 }
14592 run_test 233a "checking that OBF of the FS root succeeds"
14593
14594 test_233b() {
14595         [ $(lustre_version_code $SINGLEMDS) -ge $(version_code 2.5.90) ] ||
14596         { skip "Need MDS version at least 2.5.90"; return; }
14597         [ -n "$FILESET" ] && skip "SKIP due to FILESET set" && return
14598
14599         local fid=$($LFS path2fid $MOUNT/.lustre)
14600         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
14601                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
14602
14603         fid=$($LFS path2fid $MOUNT/.lustre/fid)
14604         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
14605                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
14606 }
14607 run_test 233b "checking that OBF of the FS .lustre succeeds"
14608
14609 test_234() {
14610         local p="$TMP/sanityN-$TESTNAME.parameters"
14611         save_lustre_params client "llite.*.xattr_cache" > $p
14612         lctl set_param llite.*.xattr_cache 1 ||
14613                 { skip "xattr cache is not supported"; return 0; }
14614
14615         mkdir -p $DIR/$tdir || error "mkdir failed"
14616         touch $DIR/$tdir/$tfile || error "touch failed"
14617         # OBD_FAIL_LLITE_XATTR_ENOMEM
14618         $LCTL set_param fail_loc=0x1405
14619         # output of the form: attr 2 4 44 3 fc13 x86_64
14620         V=($(IFS=".-" rpm -q attr))
14621         if [[ ${V[1]} > 2 || ${V[2]} > 4 || ${V[3]} > 44 ||
14622               ${V[1]} = 2 && ${V[2]} = 4 && ${V[3]} = 44 && ${V[4]} > 6 ]]; then
14623                 # attr pre-2.4.44-7 had a bug with rc
14624                 # LU-3703 - SLES 11 and FC13 clients have older attr
14625                 getfattr -n user.attr $DIR/$tdir/$tfile &&
14626                         error "getfattr should have failed with ENOMEM"
14627         else
14628                 skip "LU-3703: attr version $(getfattr --version) too old"
14629         fi
14630         $LCTL set_param fail_loc=0x0
14631         rm -rf $DIR/$tdir
14632
14633         restore_lustre_params < $p
14634         rm -f $p
14635 }
14636 run_test 234 "xattr cache should not crash on ENOMEM"
14637
14638 test_235() {
14639         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.4.52) ] &&
14640                 skip "Need MDS version at least 2.4.52" && return
14641         flock_deadlock $DIR/$tfile
14642         local RC=$?
14643         case $RC in
14644                 0)
14645                 ;;
14646                 124) error "process hangs on a deadlock"
14647                 ;;
14648                 *) error "error executing flock_deadlock $DIR/$tfile"
14649                 ;;
14650         esac
14651 }
14652 run_test 235 "LU-1715: flock deadlock detection does not work properly"
14653
14654 #LU-2935
14655 test_236() {
14656         check_swap_layouts_support && return 0
14657         test_mkdir -c1 $DIR/$tdir
14658
14659         local ref1=/etc/passwd
14660         local ref2=/etc/group
14661         local file1=$DIR/$tdir/f1
14662         local file2=$DIR/$tdir/f2
14663
14664         $SETSTRIPE -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
14665         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
14666         $SETSTRIPE -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
14667         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
14668         local fd=$(free_fd)
14669         local cmd="exec $fd<>$file2"
14670         eval $cmd
14671         rm $file2
14672         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
14673                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
14674         cmd="exec $fd>&-"
14675         eval $cmd
14676         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
14677
14678         #cleanup
14679         rm -rf $DIR/$tdir
14680 }
14681 run_test 236 "Layout swap on open unlinked file"
14682
14683 # test to verify file handle related system calls
14684 # (name_to_handle_at/open_by_handle_at)
14685 # The new system calls are supported in glibc >= 2.14.
14686
14687 test_237() {
14688         echo "Test file_handle syscalls" > $DIR/$tfile ||
14689                 error "write failed"
14690         check_fhandle_syscalls $DIR/$tfile ||
14691                 error "check_fhandle_syscalls failed"
14692 }
14693 run_test 237 "Verify name_to_handle_at/open_by_handle_at syscalls"
14694
14695 # LU-4659 linkea consistency
14696 test_238() {
14697         local server_version=$(lustre_version_code $SINGLEMDS)
14698
14699         [[ $server_version -gt $(version_code 2.5.57) ]] ||
14700                 [[ $server_version -gt $(version_code 2.5.1) &&
14701                    $server_version -lt $(version_code 2.5.50) ]] ||
14702                 { skip "Need MDS version at least 2.5.58 or 2.5.2+"; return; }
14703
14704         touch $DIR/$tfile
14705         ln $DIR/$tfile $DIR/$tfile.lnk
14706         touch $DIR/$tfile.new
14707         mv $DIR/$tfile.new $DIR/$tfile
14708         local fid1=$($LFS path2fid $DIR/$tfile)
14709         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
14710         local path1=$($LFS fid2path $FSNAME "$fid1")
14711         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
14712         local path2=$($LFS fid2path $FSNAME "$fid2")
14713         [ $tfile.lnk == $path2 ] ||
14714                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
14715         rm -f $DIR/$tfile*
14716 }
14717 run_test 238 "Verify linkea consistency"
14718
14719 test_239() {
14720         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.5.60) ] &&
14721                 skip "Need MDS version at least 2.5.60" && return
14722         local list=$(comma_list $(mdts_nodes))
14723
14724         mkdir -p $DIR/$tdir
14725         createmany -o $DIR/$tdir/f- 5000
14726         unlinkmany $DIR/$tdir/f- 5000
14727         [ $(lustre_version_code $SINGLEMDS) -gt $(version_code 2.10.53) ] &&
14728                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
14729         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
14730                         osp.*MDT*.sync_in_flight" | calc_sum)
14731         [ "$changes" -eq 0 ] || error "$changes not synced"
14732 }
14733 run_test 239 "osp_sync test"
14734
14735 test_239a() { #LU-5297
14736         remote_mds_nodsh && skip "remote MDS with nodsh" && return
14737         touch $DIR/$tfile
14738         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
14739         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
14740         chgrp $RUNAS_GID $DIR/$tfile
14741         wait_delete_completed
14742 }
14743 run_test 239a "process invalid osp sync record correctly"
14744
14745 test_239b() { #LU-5297
14746         remote_mds_nodsh && skip "remote MDS with nodsh" && return
14747         touch $DIR/$tfile1
14748         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
14749         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
14750         chgrp $RUNAS_GID $DIR/$tfile1
14751         wait_delete_completed
14752         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
14753         touch $DIR/$tfile2
14754         chgrp $RUNAS_GID $DIR/$tfile2
14755         wait_delete_completed
14756 }
14757 run_test 239b "process osp sync record with ENOMEM error correctly"
14758
14759 test_240() {
14760         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
14761         remote_mds_nodsh && skip "remote MDS with nodsh" && return
14762
14763         mkdir -p $DIR/$tdir
14764
14765         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
14766                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
14767         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
14768                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
14769
14770         umount_client $MOUNT || error "umount failed"
14771         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
14772         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
14773         mount_client $MOUNT || error "failed to mount client"
14774
14775         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
14776         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
14777 }
14778 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
14779
14780 test_241_bio() {
14781         for LOOP in $(seq $1); do
14782                 dd if=$DIR/$tfile of=/dev/null bs=40960 count=1 2>/dev/null
14783                 cancel_lru_locks $OSC || true
14784         done
14785 }
14786
14787 test_241_dio() {
14788         for LOOP in $(seq $1); do
14789                 dd if=$DIR/$tfile of=/dev/null bs=40960 count=1 \
14790                                                 iflag=direct 2>/dev/null
14791         done
14792 }
14793
14794 test_241a() { # was test_241
14795         dd if=/dev/zero of=$DIR/$tfile count=1 bs=40960
14796         ls -la $DIR/$tfile
14797         cancel_lru_locks $OSC
14798         test_241_bio 1000 &
14799         PID=$!
14800         test_241_dio 1000
14801         wait $PID
14802 }
14803 run_test 241a "bio vs dio"
14804
14805 test_241b() {
14806         dd if=/dev/zero of=$DIR/$tfile count=1 bs=40960
14807         ls -la $DIR/$tfile
14808         test_241_dio 1000 &
14809         PID=$!
14810         test_241_dio 1000
14811         wait $PID
14812 }
14813 run_test 241b "dio vs dio"
14814
14815 test_242() {
14816         remote_mds_nodsh && skip "remote MDS with nodsh" && return
14817         mkdir -p $DIR/$tdir
14818         touch $DIR/$tdir/$tfile
14819
14820         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
14821         do_facet mds1 lctl set_param fail_loc=0x105
14822         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
14823
14824         do_facet mds1 lctl set_param fail_loc=0
14825         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
14826 }
14827 run_test 242 "mdt_readpage failure should not cause directory unreadable"
14828
14829 test_243()
14830 {
14831         test_mkdir $DIR/$tdir
14832         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
14833 }
14834 run_test 243 "various group lock tests"
14835
14836 test_244()
14837 {
14838         test_mkdir $DIR/$tdir
14839         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
14840         sendfile_grouplock $DIR/$tdir/$tfile || \
14841                 error "sendfile+grouplock failed"
14842         rm -rf $DIR/$tdir
14843 }
14844 run_test 244 "sendfile with group lock tests"
14845
14846 test_245() {
14847         local flagname="multi_mod_rpcs"
14848         local connect_data_name="max_mod_rpcs"
14849         local out
14850
14851         # check if multiple modify RPCs flag is set
14852         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
14853                 grep "connect_flags:")
14854         echo "$out"
14855
14856         echo "$out" | grep -qw $flagname
14857         if [ $? -ne 0 ]; then
14858                 echo "connect flag $flagname is not set"
14859                 return
14860         fi
14861
14862         # check if multiple modify RPCs data is set
14863         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
14864         echo "$out"
14865
14866         echo "$out" | grep -qw $connect_data_name ||
14867                 error "import should have connect data $connect_data_name"
14868 }
14869 run_test 245 "check mdc connection flag/data: multiple modify RPCs"
14870
14871 test_246() { # LU-7371
14872         remote_ost_nodsh && skip "remote OST with nodsh" && return
14873         [ $(lustre_version_code ost1) -lt $(version_code 2.7.62) ] &&
14874                 skip "Need OST version >= 2.7.62" && return 0
14875         do_facet ost1 $LCTL set_param fail_val=4095
14876 #define OBD_FAIL_OST_READ_SIZE          0x234
14877         do_facet ost1 $LCTL set_param fail_loc=0x234
14878         $LFS setstripe $DIR/$tfile -i 0 -c 1
14879         dd if=/dev/zero of=$DIR/$tfile bs=4095 count=1 > /dev/null 2>&1
14880         cancel_lru_locks $FSNAME-OST0000
14881         dd if=$DIR/$tfile of=/dev/null bs=1048576 || error "Read failed"
14882 }
14883 run_test 246 "Read file of size 4095 should return right length"
14884
14885 cleanup_247() {
14886         local submount=$1
14887
14888         trap 0
14889         umount_client $submount
14890         rmdir $submount
14891 }
14892
14893 test_247a() {
14894         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
14895                 grep -q subtree ||
14896                 { skip "Fileset feature is not supported"; return; }
14897
14898         local submount=${MOUNT}_$tdir
14899
14900         mkdir $MOUNT/$tdir
14901         mkdir -p $submount || error "mkdir $submount failed"
14902         FILESET="$FILESET/$tdir" mount_client $submount ||
14903                 error "mount $submount failed"
14904         trap "cleanup_247 $submount" EXIT
14905         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
14906         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
14907                 error "read $MOUNT/$tdir/$tfile failed"
14908         cleanup_247 $submount
14909 }
14910 run_test 247a "mount subdir as fileset"
14911
14912 test_247b() {
14913         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
14914                 { skip "Fileset feature is not supported"; return; }
14915
14916         local submount=${MOUNT}_$tdir
14917
14918         rm -rf $MOUNT/$tdir
14919         mkdir -p $submount || error "mkdir $submount failed"
14920         SKIP_FILESET=1
14921         FILESET="$FILESET/$tdir" mount_client $submount &&
14922                 error "mount $submount should fail"
14923         rmdir $submount
14924 }
14925 run_test 247b "mount subdir that dose not exist"
14926
14927 test_247c() {
14928         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
14929                 { skip "Fileset feature is not supported"; return; }
14930
14931         local submount=${MOUNT}_$tdir
14932
14933         mkdir -p $MOUNT/$tdir/dir1
14934         mkdir -p $submount || error "mkdir $submount failed"
14935         trap "cleanup_247 $submount" EXIT
14936         FILESET="$FILESET/$tdir" mount_client $submount ||
14937                 error "mount $submount failed"
14938         local fid=$($LFS path2fid $MOUNT/)
14939         $LFS fid2path $submount $fid && error "fid2path should fail"
14940         cleanup_247 $submount
14941 }
14942 run_test 247c "running fid2path outside root"
14943
14944 test_247d() {
14945         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
14946                 { skip "Fileset feature is not supported"; return; }
14947
14948         local submount=${MOUNT}_$tdir
14949
14950         mkdir -p $MOUNT/$tdir/dir1
14951         mkdir -p $submount || error "mkdir $submount failed"
14952         FILESET="$FILESET/$tdir" mount_client $submount ||
14953                 error "mount $submount failed"
14954         trap "cleanup_247 $submount" EXIT
14955         local fid=$($LFS path2fid $submount/dir1)
14956         $LFS fid2path $submount $fid || error "fid2path should succeed"
14957         cleanup_247 $submount
14958 }
14959 run_test 247d "running fid2path inside root"
14960
14961 # LU-8037
14962 test_247e() {
14963         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
14964                 grep -q subtree ||
14965                 { skip "Fileset feature is not supported"; return; }
14966
14967         local submount=${MOUNT}_$tdir
14968
14969         mkdir $MOUNT/$tdir
14970         mkdir -p $submount || error "mkdir $submount failed"
14971         FILESET="$FILESET/.." mount_client $submount &&
14972                 error "mount $submount should fail"
14973         rmdir $submount
14974 }
14975 run_test 247e "mount .. as fileset"
14976
14977 test_248() {
14978         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
14979         [ -z "$fast_read_sav" ] && skip "no fast read support" && return
14980
14981         # create a large file for fast read verification
14982         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
14983
14984         # make sure the file is created correctly
14985         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
14986                 { rm -f $DIR/$tfile; skip "file creation error" && return; }
14987
14988         echo "Test 1: verify that fast read is 4 times faster on cache read"
14989
14990         # small read with fast read enabled
14991         $LCTL set_param -n llite.*.fast_read=1
14992         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
14993                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
14994                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
14995         # small read with fast read disabled
14996         $LCTL set_param -n llite.*.fast_read=0
14997         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
14998                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
14999                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
15000
15001         # verify that fast read is 4 times faster for cache read
15002         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
15003                 error_not_in_vm "fast read was not 4 times faster: " \
15004                            "$t_fast vs $t_slow"
15005
15006         echo "Test 2: verify the performance between big and small read"
15007         $LCTL set_param -n llite.*.fast_read=1
15008
15009         # 1k non-cache read
15010         cancel_lru_locks osc
15011         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
15012                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
15013                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
15014
15015         # 1M non-cache read
15016         cancel_lru_locks osc
15017         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
15018                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
15019                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
15020
15021         # verify that big IO is not 4 times faster than small IO
15022         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
15023                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
15024
15025         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
15026         rm -f $DIR/$tfile
15027 }
15028 run_test 248 "fast read verification"
15029
15030 test_249() { # LU-7890
15031         rm -f $DIR/$tfile
15032         $SETSTRIPE -c 1 $DIR/$tfile
15033
15034         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.8.53) ] &&
15035         skip "Need at least version 2.8.54"
15036
15037         # Offset 2T == 4k * 512M
15038         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
15039                 error "dd to 2T offset failed"
15040 }
15041 run_test 249 "Write above 2T file size"
15042
15043 test_250() {
15044         [ "$(facet_fstype ost$(($($GETSTRIPE -i $DIR/$tfile) + 1)))" = "zfs" ] \
15045          && skip "no 16TB file size limit on ZFS" && return
15046
15047         $SETSTRIPE -c 1 $DIR/$tfile
15048         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
15049         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
15050         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
15051         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
15052                 conv=notrunc,fsync && error "append succeeded"
15053         return 0
15054 }
15055 run_test 250 "Write above 16T limit"
15056
15057 test_251() {
15058         $SETSTRIPE -c -1 -S 1048576 $DIR/$tfile
15059
15060         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
15061         #Skip once - writing the first stripe will succeed
15062         $LCTL set_param fail_loc=0xa0001407 fail_val=1
15063         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
15064                 error "short write happened"
15065
15066         $LCTL set_param fail_loc=0xa0001407 fail_val=1
15067         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
15068                 error "short read happened"
15069
15070         rm -f $DIR/$tfile
15071 }
15072 run_test 251 "Handling short read and write correctly"
15073
15074 test_252() {
15075         local tgt
15076         local dev
15077         local out
15078         local uuid
15079         local num
15080         local gen
15081
15082         remote_mds_nodsh && skip "remote MDS with nodsh" && return
15083         remote_ost_nodsh && skip "remote OST with nodsh" && return
15084         if [ "$(facet_fstype ost1)" != "ldiskfs" -o \
15085              "$(facet_fstype mds1)" != "ldiskfs" ]; then
15086                 skip "ldiskfs only test"
15087                 return
15088         fi
15089
15090         # check lr_reader on OST0000
15091         tgt=ost1
15092         dev=$(facet_device $tgt)
15093         out=$(do_facet $tgt $LR_READER $dev)
15094         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
15095         echo "$out"
15096         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
15097         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
15098                 error "Invalid uuid returned by $LR_READER on target $tgt"
15099         echo -e "uuid returned by $LR_READER is '$uuid'\n"
15100
15101         # check lr_reader -c on MDT0000
15102         tgt=mds1
15103         dev=$(facet_device $tgt)
15104         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
15105                 echo "$LR_READER does not support additional options"
15106                 return 0
15107         fi
15108         out=$(do_facet $tgt $LR_READER -c $dev)
15109         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
15110         echo "$out"
15111         num=$(echo "$out" | grep -c "mdtlov")
15112         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
15113                 error "Invalid number of mdtlov clients returned by $LR_READER"
15114         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
15115
15116         # check lr_reader -cr on MDT0000
15117         out=$(do_facet $tgt $LR_READER -cr $dev)
15118         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
15119         echo "$out"
15120         echo "$out" | grep -q "^reply_data:$" ||
15121                 error "$LR_READER should have returned 'reply_data' section"
15122         num=$(echo "$out" | grep -c "client_generation")
15123         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
15124 }
15125 run_test 252 "check lr_reader tool"
15126
15127 test_253_fill_ost() {
15128         local size_mb #how many MB should we write to pass watermark
15129         local lwm=$3  #low watermark
15130         local free_10mb #10% of free space
15131
15132         free_kb=$($LFS df $MOUNT | grep $1 | awk '{ print $4 }')
15133         size_mb=$((free_kb / 1024 - lwm))
15134         free_10mb=$((free_kb / 10240))
15135         #If 10% of free space cross low watermark use it
15136         if (( free_10mb > size_mb )); then
15137                 size_mb=$free_10mb
15138         else
15139                 #At least we need to store 1.1 of difference between
15140                 #free space and low watermark
15141                 size_mb=$((size_mb + size_mb / 10))
15142         fi
15143         if (( lwm <= $((free_kb / 1024)) )) || [ ! -f $DIR/$tdir/1 ]; then
15144                 dd if=/dev/zero of=$DIR/$tdir/1 bs=1M count=$size_mb \
15145                          oflag=append conv=notrunc
15146         fi
15147
15148         sleep_maxage
15149
15150         free_kb=$($LFS df $MOUNT | grep $1 | awk '{ print $4 }')
15151         echo "OST still has $((free_kb / 1024)) mbytes free"
15152 }
15153
15154 test_253() {
15155         local ostidx=0
15156         local rc=0
15157
15158         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
15159         remote_mds_nodsh && skip "remote MDS with nodsh" && return
15160         remote_mgs_nodsh && skip "remote MGS with nodsh" && return
15161
15162         local ost_name=$($LFS osts |
15163                 sed -n 's/^'$ostidx': \(.*\)_UUID .*/\1/p')
15164         # on the mdt's osc
15165         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
15166         do_facet $SINGLEMDS $LCTL get_param -n \
15167                 osp.$mdtosc_proc1.reserved_mb_high ||
15168                 { skip  "remote MDS does not support reserved_mb_high" &&
15169                   return; }
15170
15171         rm -rf $DIR/$tdir
15172         wait_mds_ost_sync
15173         wait_delete_completed
15174         mkdir $DIR/$tdir
15175
15176         local last_wm_h=$(do_facet $SINGLEMDS $LCTL get_param -n \
15177                         osp.$mdtosc_proc1.reserved_mb_high)
15178         local last_wm_l=$(do_facet $SINGLEMDS $LCTL get_param -n \
15179                         osp.$mdtosc_proc1.reserved_mb_low)
15180         echo "prev high watermark $last_wm_h, prev low watermark $last_wm_l"
15181
15182         if ! combined_mgs_mds ; then
15183                 mount_mgs_client
15184         fi
15185         create_pool $FSNAME.$TESTNAME || error "Pool creation failed"
15186         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $ost_name ||
15187                 error "Adding $ost_name to pool failed"
15188
15189         # Wait for client to see a OST at pool
15190         wait_update $HOSTNAME "$LCTL get_param -n
15191                 lov.$FSNAME-*.pools.$TESTNAME | sort -u |
15192                 grep $ost_name" "$ost_name""_UUID" $((TIMEOUT/2)) ||
15193                 error "Client can not see the pool"
15194         $SETSTRIPE $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
15195                 error "Setstripe failed"
15196
15197         dd if=/dev/zero of=$DIR/$tdir/0 bs=1M count=10
15198         local blocks=$($LFS df $MOUNT | grep $ost_name | awk '{ print $4 }')
15199         echo "OST still has $((blocks/1024)) mbytes free"
15200
15201         local new_lwm=$((blocks/1024-10))
15202         do_facet $SINGLEMDS $LCTL set_param \
15203                         osp.$mdtosc_proc1.reserved_mb_high=$((new_lwm+5))
15204         do_facet $SINGLEMDS $LCTL set_param \
15205                         osp.$mdtosc_proc1.reserved_mb_low=$new_lwm
15206
15207         test_253_fill_ost $ost_name $mdtosc_proc1 $new_lwm
15208
15209         #First enospc could execute orphan deletion so repeat.
15210         test_253_fill_ost $ost_name $mdtosc_proc1 $new_lwm
15211
15212         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
15213                         osp.$mdtosc_proc1.prealloc_status)
15214         echo "prealloc_status $oa_status"
15215
15216         dd if=/dev/zero of=$DIR/$tdir/2 bs=1M count=1 &&
15217                 error "File creation should fail"
15218         #object allocation was stopped, but we still able to append files
15219         dd if=/dev/zero of=$DIR/$tdir/1 bs=1M seek=6 count=5 oflag=append ||
15220                 error "Append failed"
15221         rm -f $DIR/$tdir/1 $DIR/$tdir/0 $DIR/$tdir/r*
15222
15223         wait_delete_completed
15224
15225         sleep_maxage
15226
15227         for i in $(seq 10 12); do
15228                 dd if=/dev/zero of=$DIR/$tdir/$i bs=1M count=1 2>/dev/null ||
15229                         error "File creation failed after rm";
15230         done
15231
15232         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
15233                         osp.$mdtosc_proc1.prealloc_status)
15234         echo "prealloc_status $oa_status"
15235
15236         if (( oa_status != 0 )); then
15237                 error "Object allocation still disable after rm"
15238         fi
15239         do_facet $SINGLEMDS $LCTL set_param \
15240                         osp.$mdtosc_proc1.reserved_mb_high=$last_wm_h
15241         do_facet $SINGLEMDS $LCTL set_param \
15242                         osp.$mdtosc_proc1.reserved_mb_low=$last_wm_l
15243
15244
15245         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $ost_name ||
15246                 error "Remove $ost_name from pool failed"
15247         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
15248                 error "Pool destroy fialed"
15249
15250         if ! combined_mgs_mds ; then
15251                 umount_mgs_client
15252         fi
15253 }
15254 run_test 253 "Check object allocation limit"
15255
15256 test_254() {
15257         local cl_user
15258
15259         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
15260         remote_mds_nodsh && skip "remote MDS with nodsh" && return
15261         do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size ||
15262                 { skip "MDS does not support changelog_size" && return; }
15263
15264         cl_user=$(do_facet mds1 $LCTL --device $MDT0 changelog_register -n)
15265         echo "Registered as changelog user $cl_user"
15266
15267         $LFS changelog_clear $MDT0 $cl_user 0
15268
15269         local size1=$(do_facet mds1 \
15270                       $LCTL get_param -n mdd.$MDT0.changelog_size)
15271         echo "Changelog size $size1"
15272
15273         rm -rf $DIR/$tdir
15274         $LFS mkdir -i 0 $DIR/$tdir
15275         # change something
15276         mkdir -p $DIR/$tdir/pics/2008/zachy
15277         touch $DIR/$tdir/pics/2008/zachy/timestamp
15278         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
15279         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
15280         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
15281         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
15282         rm $DIR/$tdir/pics/desktop.jpg
15283
15284         local size2=$(do_facet mds1 \
15285                       $LCTL get_param -n mdd.$MDT0.changelog_size)
15286         echo "Changelog size after work $size2"
15287
15288         do_facet mds1 $LCTL --device $MDT0 changelog_deregister $cl_user
15289
15290         if (( size2 <= size1 )); then
15291                 error "Changelog size after work should be greater than original"
15292         fi
15293         return 0
15294 }
15295 run_test 254 "Check changelog size"
15296
15297 ladvise_no_type()
15298 {
15299         local type=$1
15300         local file=$2
15301
15302         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
15303                 awk -F: '{print $2}' | grep $type > /dev/null
15304         if [ $? -ne 0 ]; then
15305                 return 0
15306         fi
15307         return 1
15308 }
15309
15310 ladvise_no_ioctl()
15311 {
15312         local file=$1
15313
15314         lfs ladvise -a willread $file > /dev/null 2>&1
15315         if [ $? -eq 0 ]; then
15316                 return 1
15317         fi
15318
15319         lfs ladvise -a willread $file 2>&1 |
15320                 grep "Inappropriate ioctl for device" > /dev/null
15321         if [ $? -eq 0 ]; then
15322                 return 0
15323         fi
15324         return 1
15325 }
15326
15327 percent() {
15328         bc <<<"scale=2; ($1 - $2) * 100 / $2"
15329 }
15330
15331 # run a random read IO workload
15332 # usage: random_read_iops <filename> <filesize> <iosize>
15333 random_read_iops() {
15334         local file=$1
15335         local fsize=$2
15336         local iosize=${3:-4096}
15337
15338         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
15339                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
15340 }
15341
15342 drop_file_oss_cache() {
15343         local file="$1"
15344         local nodes="$2"
15345
15346         $LFS ladvise -a dontneed $file 2>/dev/null ||
15347                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
15348 }
15349
15350 ladvise_willread_performance()
15351 {
15352         local repeat=10
15353         local average_origin=0
15354         local average_cache=0
15355         local average_ladvise=0
15356
15357         for ((i = 1; i <= $repeat; i++)); do
15358                 echo "Iter $i/$repeat: reading without willread hint"
15359                 cancel_lru_locks osc
15360                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
15361                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
15362                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
15363                 average_origin=$(bc <<<"$average_origin + $speed_origin")
15364
15365                 cancel_lru_locks osc
15366                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
15367                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
15368                 average_cache=$(bc <<<"$average_cache + $speed_cache")
15369
15370                 cancel_lru_locks osc
15371                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
15372                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
15373                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
15374                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
15375                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
15376         done
15377         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
15378         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
15379         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
15380
15381         speedup_cache=$(percent $average_cache $average_origin)
15382         speedup_ladvise=$(percent $average_ladvise $average_origin)
15383
15384         echo "Average uncached read: $average_origin"
15385         echo "Average speedup with OSS cached read: " \
15386                 "$average_cache = +$speedup_cache%"
15387         echo "Average speedup with ladvise willread: " \
15388                 "$average_ladvise = +$speedup_ladvise%"
15389
15390         local lowest_speedup=20
15391         if [ ${average_cache%.*} -lt $lowest_speedup ]; then
15392                 echo "Speedup with OSS cached read less than $lowest_speedup%," \
15393                         "got $average_cache%. Skipping ladvise willread check."
15394                 return 0
15395         fi
15396
15397         # the test won't work on ZFS until it supports 'ladvise dontneed', but
15398         # it is still good to run until then to exercise 'ladvise willread'
15399         ! $LFS ladvise -a dontneed $DIR/$tfile &&
15400                 [ "$(facet_fstype ost1)" = "zfs" ] &&
15401                 echo "osd-zfs does not support dontneed or drop_caches" &&
15402                 return 0
15403
15404         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
15405         [ ${average_ladvise%.*} -gt $lowest_speedup ] ||
15406                 error_not_in_vm "Speedup with willread is less than " \
15407                         "$lowest_speedup%, got $average_ladvise%"
15408 }
15409
15410 test_255a() {
15411         [ $(lustre_version_code ost1) -lt $(version_code 2.8.54) ] &&
15412                 skip "lustre < 2.8.54 does not support ladvise " && return
15413         remote_ost_nodsh && skip "remote OST with nodsh" && return
15414
15415         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
15416
15417         ladvise_no_type willread $DIR/$tfile &&
15418                 skip "willread ladvise is not supported" && return
15419
15420         ladvise_no_ioctl $DIR/$tfile &&
15421                 skip "ladvise ioctl is not supported" && return
15422
15423         local size_mb=100
15424         local size=$((size_mb * 1048576))
15425         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
15426                 error "dd to $DIR/$tfile failed"
15427
15428         lfs ladvise -a willread $DIR/$tfile ||
15429                 error "Ladvise failed with no range argument"
15430
15431         lfs ladvise -a willread -s 0 $DIR/$tfile ||
15432                 error "Ladvise failed with no -l or -e argument"
15433
15434         lfs ladvise -a willread -e 1 $DIR/$tfile ||
15435                 error "Ladvise failed with only -e argument"
15436
15437         lfs ladvise -a willread -l 1 $DIR/$tfile ||
15438                 error "Ladvise failed with only -l argument"
15439
15440         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
15441                 error "End offset should not be smaller than start offset"
15442
15443         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
15444                 error "End offset should not be equal to start offset"
15445
15446         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
15447                 error "Ladvise failed with overflowing -s argument"
15448
15449         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
15450                 error "Ladvise failed with overflowing -e argument"
15451
15452         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
15453                 error "Ladvise failed with overflowing -l argument"
15454
15455         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
15456                 error "Ladvise succeeded with conflicting -l and -e arguments"
15457
15458         echo "Synchronous ladvise should wait"
15459         local delay=4
15460 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
15461         do_nodes $(comma_list $(osts_nodes)) \
15462                 $LCTL set_param fail_val=$delay fail_loc=0x237
15463
15464         local start_ts=$SECONDS
15465         lfs ladvise -a willread $DIR/$tfile ||
15466                 error "Ladvise failed with no range argument"
15467         local end_ts=$SECONDS
15468         local inteval_ts=$((end_ts - start_ts))
15469
15470         if [ $inteval_ts -lt $(($delay - 1)) ]; then
15471                 error "Synchronous advice didn't wait reply"
15472         fi
15473
15474         echo "Asynchronous ladvise shouldn't wait"
15475         local start_ts=$SECONDS
15476         lfs ladvise -a willread -b $DIR/$tfile ||
15477                 error "Ladvise failed with no range argument"
15478         local end_ts=$SECONDS
15479         local inteval_ts=$((end_ts - start_ts))
15480
15481         if [ $inteval_ts -gt $(($delay / 2)) ]; then
15482                 error "Asynchronous advice blocked"
15483         fi
15484
15485         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
15486         ladvise_willread_performance
15487 }
15488 run_test 255a "check 'lfs ladvise -a willread'"
15489
15490 facet_meminfo() {
15491         local facet=$1
15492         local info=$2
15493
15494         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
15495 }
15496
15497 test_255b() {
15498         remote_ost_nodsh && skip "remote OST with nodsh" && return
15499
15500         lfs setstripe -c 1 -i 0 $DIR/$tfile
15501
15502         ladvise_no_type dontneed $DIR/$tfile &&
15503                 skip "dontneed ladvise is not supported" && return
15504
15505         ladvise_no_ioctl $DIR/$tfile &&
15506                 skip "ladvise ioctl is not supported" && return
15507
15508         [ $(lustre_version_code ost1) -lt $(version_code 2.8.54) ] &&
15509                 skip "lustre < 2.8.54 does not support ladvise" && return
15510
15511         ! $LFS ladvise -a dontneed $DIR/$tfile &&
15512                 [ "$(facet_fstype ost1)" = "zfs" ] &&
15513                 skip "zfs-osd does not support 'ladvise dontneed'" && return
15514
15515         local size_mb=100
15516         local size=$((size_mb * 1048576))
15517         # In order to prevent disturbance of other processes, only check 3/4
15518         # of the memory usage
15519         local kibibytes=$((size_mb * 1024 * 3 / 4))
15520
15521         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
15522                 error "dd to $DIR/$tfile failed"
15523
15524         local total=$(facet_meminfo ost1 MemTotal)
15525         echo "Total memory: $total KiB"
15526
15527         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
15528         local before_read=$(facet_meminfo ost1 Cached)
15529         echo "Cache used before read: $before_read KiB"
15530
15531         lfs ladvise -a willread $DIR/$tfile ||
15532                 error "Ladvise willread failed"
15533         local after_read=$(facet_meminfo ost1 Cached)
15534         echo "Cache used after read: $after_read KiB"
15535
15536         lfs ladvise -a dontneed $DIR/$tfile ||
15537                 error "Ladvise dontneed again failed"
15538         local no_read=$(facet_meminfo ost1 Cached)
15539         echo "Cache used after dontneed ladvise: $no_read KiB"
15540
15541         if [ $total -lt $((before_read + kibibytes)) ]; then
15542                 echo "Memory is too small, abort checking"
15543                 return 0
15544         fi
15545
15546         if [ $((before_read + kibibytes)) -gt $after_read ]; then
15547                 error "Ladvise willread should use more memory" \
15548                         "than $kibibytes KiB"
15549         fi
15550
15551         if [ $((no_read + kibibytes)) -gt $after_read ]; then
15552                 error "Ladvise dontneed should release more memory" \
15553                         "than $kibibytes KiB"
15554         fi
15555 }
15556 run_test 255b "check 'lfs ladvise -a dontneed'"
15557
15558 test_255c() {
15559         local count
15560         local new_count
15561         local difference
15562         local i
15563         local rc
15564
15565         [ $(lustre_version_code ost1) -lt $(version_code 2.10.50) ] &&
15566                 skip "lustre < 2.10.53 does not support lockahead" && return
15567
15568         test_mkdir -p $DIR/$tdir
15569         $SETSTRIPE -i 0 $DIR/$tdir
15570
15571         #test 10 returns only success/failure
15572         i=10
15573         lockahead_test -d $DIR/$tdir -t $i
15574         rc=$?
15575         if [ $rc -eq 255 ]; then
15576                 error "Ladvise test${i} failed, ${rc}"
15577         fi
15578
15579         #test 11 counts lock enqueue requests, all others count new locks
15580         i=11
15581         count=$(do_facet ost1 \
15582                 $LCTL get_param -n ost.OSS.ost.stats)
15583         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
15584
15585         lockahead_test -d $DIR/$tdir -t $i
15586         rc=$?
15587         if [ $rc -eq 255 ]; then
15588                 error "Ladvise test${i} failed, ${rc}"
15589         fi
15590
15591         new_count=$(do_facet ost1 \
15592                 $LCTL get_param -n ost.OSS.ost.stats)
15593         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
15594                    awk '{ print $2 }')
15595
15596         difference="$((new_count - count))"
15597         if [ $difference -ne $rc ]; then
15598                 error "Ladvise test${i}, bad enqueue count, returned " \
15599                       "${rc}, actual ${difference}"
15600         fi
15601
15602         for i in $(seq 12 21); do
15603                 # If we do not do this, we run the risk of having too many
15604                 # locks and starting lock cancellation while we are checking
15605                 # lock counts.
15606                 cancel_lru_locks osc
15607
15608                 count=$($LCTL get_param -n \
15609                        ldlm.namespaces.$FSNAME-OST0000*osc-f*.lock_unused_count)
15610
15611                 lockahead_test -d $DIR/$tdir -t $i
15612                 rc=$?
15613                 if [ $rc -eq 255 ]; then
15614                         error "Ladvise test ${i} failed, ${rc}"
15615                 fi
15616
15617                 new_count=$($LCTL get_param -n \
15618                        ldlm.namespaces.$FSNAME-OST0000*osc-f*.lock_unused_count)
15619                 difference="$((new_count - count))"
15620
15621                 # Test 15 output is divided by 100 to map down to valid return
15622                 if [ $i -eq 15 ]; then
15623                         rc="$((rc * 100))"
15624                 fi
15625
15626                 if [ $difference -ne $rc ]; then
15627                         error "Ladvise test ${i}, bad lock count, returned " \
15628                               "${rc}, actual ${difference}"
15629                 fi
15630         done
15631
15632         #test 22 returns only success/failure
15633         i=22
15634         lockahead_test -d $DIR/$tdir -t $i
15635         rc=$?
15636         if [ $rc -eq 255 ]; then
15637                 error "Ladvise test${i} failed, ${rc}"
15638         fi
15639
15640 }
15641 run_test 255c "suite of ladvise lockahead tests"
15642
15643 test_256() {
15644         local cl_user
15645         local cat_sl
15646         local mdt_dev
15647
15648         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
15649         remote_mds_nodsh && skip "remote MDS with nodsh" && return
15650         [ "$(facet_fstype mds1)" != "ldiskfs" ] &&
15651                 skip "ldiskfs only test" && return
15652
15653         mdt_dev=$(mdsdevname 1)
15654         echo $mdt_dev
15655         cl_user=$(do_facet mds1 \
15656         "$LCTL get_param -n mdd.$MDT0.changelog_users | grep cl")
15657         if [[ -n $cl_user ]]; then
15658                 skip "active changelog user"
15659                 return
15660         fi
15661
15662         cl_user=$(do_facet mds1 $LCTL --device $MDT0 changelog_register -n)
15663         echo "Registered as changelog user $cl_user"
15664
15665         rm -rf $DIR/$tdir
15666         mkdir -p $DIR/$tdir
15667
15668         $LFS changelog_clear $MDT0 $cl_user 0
15669
15670         # change something
15671         touch $DIR/$tdir/{1..10}
15672
15673         # stop the MDT
15674         stop mds1 || error "Fail to stop MDT."
15675
15676         # remount the MDT
15677         start mds1 $mdt_dev $MDS_MOUNT_OPTS || error "Fail to start MDT."
15678
15679         #after mount new plainllog is used
15680         touch $DIR/$tdir/{11..19}
15681         do_facet mds1 sync
15682         local TEMP256FILE=$(mktemp -u TEMP256XXXXXX)
15683         cat_sl=$(do_facet mds1 \
15684         "$DEBUGFS -R \\\"dump changelog_catalog $TEMP256FILE\\\" $mdt_dev; \
15685          llog_reader $TEMP256FILE | grep \\\"type=1064553b\\\" | wc -l")
15686         do_facet mds1 rm $TEMP256FILE
15687
15688         if (( cat_sl != 2 )); then
15689                 do_facet mds1 $LCTL --device $MDT0 changelog_deregister $cl_user
15690                 error "Changelog catalog has wrong number of slots $cat_sl"
15691         fi
15692
15693         $LFS changelog_clear $MDT0 $cl_user 0
15694
15695         do_facet mds1 sync
15696         TEMP256FILE=$(mktemp -u TEMP256XXXXXX)
15697         cat_sl=$(do_facet mds1 \
15698         "$DEBUGFS -R \\\"dump changelog_catalog $TEMP256FILE\\\" $mdt_dev; \
15699          llog_reader $TEMP256FILE | grep \\\"type=1064553b\\\" | wc -l")
15700         do_facet mds1 rm $TEMP256FILE
15701
15702         do_facet mds1 $LCTL --device $MDT0 changelog_deregister $cl_user
15703
15704         if (( cat_sl == 2 )); then
15705                 error "Empty plain llog was not deleted from changelog catalog"
15706         fi
15707         if (( cat_sl != 1 )); then
15708                 error "Active plain llog shouldn\`t be deleted from catalog"
15709         fi
15710 }
15711 run_test 256 "Check llog delete for empty and not full state"
15712
15713 test_257() {
15714         remote_mds_nodsh && skip "remote MDS with nodsh" && return
15715         [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.8.55) ]] &&
15716                 skip "Need MDS version at least 2.8.55" && return
15717
15718         test_mkdir $DIR/$tdir
15719
15720         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
15721                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
15722         stat $DIR/$tdir
15723
15724 #define OBD_FAIL_MDS_XATTR_REP                  0x161
15725         local mdtidx=$($LFS getstripe -M $DIR/$tdir)
15726         local facet=mds$((mdtidx + 1))
15727         set_nodes_failloc $(facet_active_host $facet) 0x80000161
15728         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
15729
15730         stop $facet || error "stop MDS failed"
15731         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
15732                 error "start MDS fail"
15733 }
15734 run_test 257 "xattr locks are not lost"
15735
15736 # Verify we take the i_mutex when security requires it
15737 test_258a() {
15738 #define OBD_FAIL_IMUTEX_SEC 0x141c
15739         $LCTL set_param fail_loc=0x141c
15740         touch $DIR/$tfile
15741         chmod u+s $DIR/$tfile
15742         chmod a+rwx $DIR/$tfile
15743         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
15744         RC=$?
15745         if [ $RC -ne 0 ]; then
15746                 error "error, failed to take i_mutex, rc=$?"
15747         fi
15748         rm -f $DIR/$tfile
15749 }
15750 run_test 258a
15751
15752 # Verify we do NOT take the i_mutex in the normal case
15753 test_258b() {
15754 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
15755         $LCTL set_param fail_loc=0x141d
15756         touch $DIR/$tfile
15757         chmod a+rwx $DIR
15758         chmod a+rw $DIR/$tfile
15759         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
15760         RC=$?
15761         if [ $RC -ne 0 ]; then
15762                 error "error, took i_mutex unnecessarily, rc=$?"
15763         fi
15764         rm -f $DIR/$tfile
15765
15766 }
15767 run_test 258b "verify i_mutex security behavior"
15768
15769 test_260() {
15770 #define OBD_FAIL_MDC_CLOSE               0x806
15771         $LCTL set_param fail_loc=0x80000806
15772         touch $DIR/$tfile
15773
15774 }
15775 run_test 260 "Check mdc_close fail"
15776
15777 ### Data-on-MDT sanity tests ###
15778 test_270a() {
15779
15780         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.10.55) ] &&
15781                 skip "Need MDS version at least 2.10.55" && return
15782
15783         # create DoM file
15784         local dom=$DIR/$tdir/dom_file
15785         local tmp=$DIR/$tdir/tmp_file
15786
15787         mkdir -p $DIR/$tdir
15788
15789         # basic checks for DoM component creation
15790         $LFS setstripe -E 1024K -E 1024K -L mdt $dom 2>/dev/null &&
15791                 error "Can set MDT layout to non-first entry"
15792
15793         $LFS setstripe -E 1024K -L mdt -E 1024K -L mdt $dom 2>/dev/null &&
15794                 error "Can define multiple entries as MDT layout"
15795
15796         $LFS setstripe -E 1M -L mdt $dom ||
15797                 error "Can't create DoM layout"
15798
15799         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
15800         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
15801         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
15802
15803         local mdtidx=$($GETSTRIPE -M $dom)
15804         local mdtname=MDT$(printf %04x $mdtidx)
15805         local facet=mds$((mdtidx + 1))
15806         local space_check=1
15807
15808         # Skip free space checks with ZFS
15809         if [ "$(facet_fstype $facet)" == "zfs" ]; then
15810                 space_check=0
15811         fi
15812
15813         # write
15814         sync
15815         local mdtfree1=$(do_facet $facet \
15816                 lctl get_param -n osd*.*$mdtname.kbytesfree)
15817         dd if=/dev/urandom of=$tmp bs=1024 count=100
15818         # check also direct IO along write
15819         dd if=$tmp of=$dom bs=102400 count=1 oflag=direct
15820         sync
15821         cmp $tmp $dom || error "file data is different"
15822         [ $(stat -c%s $dom) == 102400 ] || error "bad size after write"
15823         if [ $space_check == 1 ]; then
15824                 local mdtfree2=$(do_facet $facet \
15825                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
15826                 [ $(($mdtfree1 - $mdtfree2)) -ge 102 ] ||
15827                         error "MDT free space is wrong after write"
15828         fi
15829
15830         # truncate
15831         $TRUNCATE $dom 10000
15832         [ $(stat -c%s $dom) == 10000 ] || error "bad size after truncate"
15833         if [ $space_check == 1 ]; then
15834                 mdtfree1=$(do_facet $facet \
15835                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
15836                 [ $(($mdtfree1 - $mdtfree2)) -ge 92 ] ||
15837                         error "MDT free space is wrong after truncate"
15838         fi
15839
15840         # append
15841         cat $tmp >> $dom
15842         sync
15843         [ $(stat -c%s $dom) == 112400 ] || error "bad size after append"
15844         if [ $space_check == 1 ]; then
15845                 mdtfree2=$(do_facet $facet \
15846                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
15847                 [ $(($mdtfree1 - $mdtfree2)) -ge 102 ] ||
15848                         error "MDT free space is wrong after append"
15849         fi
15850
15851         # delete
15852         rm $dom
15853         if [ $space_check == 1 ]; then
15854                 mdtfree1=$(do_facet $facet \
15855                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
15856                 [ $(($mdtfree1 - $mdtfree2)) -ge 112 ] ||
15857                         error "MDT free space is wrong after removal"
15858         fi
15859
15860         # combined striping
15861         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
15862                 error "Can't create DoM + OST striping"
15863
15864         dd if=/dev/urandom of=$tmp bs=1024 count=2000
15865         # check also direct IO along write
15866         dd if=$tmp of=$dom bs=102400 count=20 oflag=direct
15867         sync
15868         cmp $tmp $dom || error "file data is different"
15869         [ $(stat -c%s $dom) == 2048000 ] || error "bad size after write"
15870         rm $dom
15871         rm $tmp
15872
15873         return 0
15874 }
15875 run_test 270a "DoM: basic functionality tests"
15876
15877 test_270b() {
15878         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.10.55) ] &&
15879                 skip "Need MDS version at least 2.10.55" && return
15880
15881         local dom=$DIR/$tdir/dom_file
15882         local max_size=1048576
15883
15884         mkdir -p $DIR/$tdir
15885         $LFS setstripe -E $max_size -L mdt $dom
15886
15887         # truncate over the limit
15888         $TRUNCATE $dom $(($max_size + 1)) &&
15889                 error "successful truncate over the maximum size"
15890         # write over the limit
15891         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
15892                 error "successful write over the maximum size"
15893         # append over the limit
15894         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
15895         echo "12345" >> $dom && error "successful append over the maximum size"
15896         rm $dom
15897
15898         return 0
15899 }
15900 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
15901
15902 test_270c() {
15903         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.10.55) ] &&
15904                 skip "Need MDS version at least 2.10.55" && return
15905
15906         mkdir -p $DIR/$tdir
15907         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
15908
15909         # check files inherit DoM EA
15910         touch $DIR/$tdir/first
15911         [ $($GETSTRIPE -L $DIR/$tdir/first) == "mdt" ] ||
15912                 error "bad pattern"
15913         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
15914                 error "bad stripe count"
15915         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
15916                 error "bad stripe size"
15917
15918         # check directory inherits DoM EA and uses it as default
15919         mkdir $DIR/$tdir/subdir
15920         touch $DIR/$tdir/subdir/second
15921         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
15922                 error "bad pattern in sub-directory"
15923         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
15924                 error "bad stripe count in sub-directory"
15925         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
15926                 error "bad stripe size in sub-directory"
15927         return 0
15928 }
15929 run_test 270c "DoM: DoM EA inheritance tests"
15930
15931 test_270d() {
15932         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.10.55) ] &&
15933                 skip "Need MDS version at least 2.10.55" && return
15934
15935         mkdir -p $DIR/$tdir
15936         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
15937
15938         # inherit default DoM striping
15939         mkdir $DIR/$tdir/subdir
15940         touch $DIR/$tdir/subdir/f1
15941
15942         # change default directory striping
15943         $LFS setstripe -c 1 $DIR/$tdir/subdir
15944         touch $DIR/$tdir/subdir/f2
15945         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
15946                 error "wrong default striping in file 2"
15947         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
15948                 error "bad pattern in file 2"
15949         return 0
15950 }
15951 run_test 270d "DoM: change striping from DoM to RAID0"
15952
15953 test_270e() {
15954         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.10.55) ] &&
15955                 skip "Need MDS version at least 2.10.55" && return
15956
15957         mkdir -p $DIR/$tdir/dom
15958         mkdir -p $DIR/$tdir/norm
15959         DOMFILES=20
15960         NORMFILES=10
15961         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
15962         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
15963
15964         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
15965         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
15966
15967         # find DoM files by layout
15968         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
15969         [ $NUM -eq  $DOMFILES ] ||
15970                 error "lfs find -L: found $NUM, expected $DOMFILES"
15971         echo "Test 1: lfs find 20 DOM files by layout: OK"
15972
15973         # there should be 1 dir with default DOM striping
15974         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
15975         [ $NUM -eq  1 ] ||
15976                 error "lfs find -L: found $NUM, expected 1 dir"
15977         echo "Test 2: lfs find 1 DOM dir by layout: OK"
15978
15979         # find DoM files by stripe size
15980         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
15981         [ $NUM -eq  $DOMFILES ] ||
15982                 error "lfs find -S: found $NUM, expected $DOMFILES"
15983         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
15984
15985         # find files by stripe offset except DoM files
15986         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
15987         [ $NUM -eq  $NORMFILES ] ||
15988                 error "lfs find -i: found $NUM, expected $NORMFILES"
15989         echo "Test 5: lfs find no DOM files by stripe index: OK"
15990         return 0
15991 }
15992 run_test 270e "DoM: lfs find with DoM files test"
15993
15994 test_270f() {
15995         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.10.55) ] &&
15996                 skip "Need MDS version at least 2.10.55" && return
15997
15998         local mdtname=${FSNAME}-MDT0000-mdtlov
15999         local dom=$DIR/$tdir/dom_file
16000         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
16001                                                 lod.$mdtname.dom_stripesize)
16002         local dom_limit=131072
16003
16004         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
16005         local dom_current=$(do_facet mds1 $LCTL get_param -n \
16006                                                 lod.$mdtname.dom_stripesize)
16007         [ ${dom_limit} -eq ${dom_current} ] ||
16008                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
16009
16010         $LFS mkdir -i 0 -c 1 $DIR/$tdir
16011         $LFS setstripe -d $DIR/$tdir
16012         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
16013                 error "Can't set directory default striping"
16014
16015         # exceed maximum stripe size
16016         $LFS setstripe -E $(($dom_limit * 2)) -L mdt $dom &&
16017                 error "Able to create DoM component size more than LOD limit"
16018
16019         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
16020         dom_current=$(do_facet mds1 $LCTL get_param -n \
16021                                                 lod.$mdtname.dom_stripesize)
16022         [ 0 -eq ${dom_current} ] ||
16023                 error "Can't set zero DoM stripe limit"
16024
16025         # too low values to be aligned with smallest stripe size 64K
16026         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
16027         dom_current=$(do_facet mds1 $LCTL get_param -n \
16028                                                 lod.$mdtname.dom_stripesize)
16029         [ 30000 -eq ${dom_current} ] &&
16030                 error "Can set too small DoM stripe limit"
16031
16032         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
16033         dom_current=$(do_facet mds1 $LCTL get_param -n \
16034                                                 lod.$mdtname.dom_stripesize)
16035         echo $dom_current
16036         [ 2147483648 -eq ${dom_current} ] &&
16037                 error "Can set too large DoM stripe limit"
16038
16039         do_facet mds1 $LCTL set_param -n \
16040                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
16041         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
16042                 error "Can't create DoM component size after limit change"
16043         do_facet mds1 $LCTL set_param -n \
16044                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
16045         $LFS setstripe -E $dom_limit -L mdt ${dom}_big &&
16046                 error "Can create big DoM component after limit decrease"
16047         touch ${dom}_def ||
16048                 error "Can't create file with old default layout"
16049
16050         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
16051         return 0
16052 }
16053 run_test 270f "DoM: maximum DoM stripe size checks"
16054
16055 test_271a() {
16056         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.10.55) ] &&
16057                 skip "Need MDS version at least 2.10.55" && return
16058
16059         local dom=$DIR/$tdir/dom
16060
16061         mkdir -p $DIR/$tdir
16062
16063         $LFS setstripe -E 1024K -L mdt $dom
16064
16065         lctl set_param -n mdc.*.stats=clear
16066         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
16067         cat $dom > /dev/null
16068         local reads=$(lctl get_param -n mdc.*.stats |
16069                         awk '/ost_read/ {print $2}')
16070         [ -z $reads ] || error "Unexpected $reads READ RPCs"
16071         ls $dom
16072         rm -f $dom
16073 }
16074 run_test 271a "DoM: data is cached for read after write"
16075
16076 test_271b() {
16077         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.10.55) ] &&
16078                 skip "Need MDS version at least 2.10.55" && return
16079
16080         local dom=$DIR/$tdir/dom
16081
16082         mkdir -p $DIR/$tdir
16083
16084         $LFS setstripe -E 1024K -L mdt -E EOF $dom
16085
16086         lctl set_param -n mdc.*.stats=clear
16087         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
16088         cancel_lru_locks mdc
16089         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
16090         # second stat to check size is cached on client
16091         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
16092         local gls=$(lctl get_param -n mdc.*.stats |
16093                         awk '/ldlm_glimpse/ {print $2}')
16094         [ -z $gls ] || error "Unexpected $gls glimpse RPCs"
16095         rm -f $dom
16096 }
16097 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
16098
16099 test_271ba() {
16100         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.10.55) ] &&
16101                 skip "Need MDS version at least 2.10.55" && return
16102
16103         local dom=$DIR/$tdir/dom
16104
16105         mkdir -p $DIR/$tdir
16106
16107         $LFS setstripe -E 1024K -L mdt -E EOF $dom
16108
16109         lctl set_param -n mdc.*.stats=clear
16110         lctl set_param -n osc.*.stats=clear
16111         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
16112         cancel_lru_locks mdc
16113         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
16114         # second stat to check size is cached on client
16115         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
16116         local gls=$(lctl get_param -n mdc.*.stats |
16117                         awk '/ldlm_glimpse/ {print $2}')
16118         [ -z $gls ] || error "Unexpected $gls glimpse RPCs"
16119         local gls=$(lctl get_param -n osc.*.stats |
16120                         awk '/ldlm_glimpse/ {print $2}')
16121         [ -z $gls ] || error "Unexpected $gls OSC glimpse RPCs"
16122         rm -f $dom
16123 }
16124 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
16125
16126 test_271c() {
16127         # test to be enabled with lock_convert
16128         skip "skipped until lock convert will be implemented" && return
16129
16130         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.10.55) ] &&
16131                 skip "Need MDS version at least 2.10.55" && return
16132
16133         local dom=$DIR/$tdir/dom
16134
16135         mkdir -p $DIR/$tdir
16136
16137         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
16138
16139         local mdtidx=$($LFS getstripe -M $DIR/$tdir)
16140         local facet=mds$((mdtidx + 1))
16141
16142         cancel_lru_locks mdc
16143         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
16144         createmany -o $dom 1000
16145         lctl set_param -n mdc.*.stats=clear
16146         smalliomany -w $dom 1000 200
16147         lctl get_param -n mdc.*.stats
16148         local enq=$(lctl get_param -n mdc.*.stats |
16149                         awk '/ldlm_ibits_enqueue/ {print $2}')
16150         # Each file has 1 open, 1 IO enqueues, total 2000
16151         # but now we have also +1 getxattr for security.capability, total 3000
16152         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
16153         unlinkmany $dom 1000
16154
16155         cancel_lru_locks mdc
16156         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
16157         createmany -o $dom 1000
16158         lctl set_param -n mdc.*.stats=clear
16159         smalliomany -w $dom 1000 200
16160         lctl get_param -n mdc.*.stats
16161         local enq_2=$(lctl get_param -n mdc.*.stats |
16162                         awk '/ldlm_ibits_enqueue/ {print $2}')
16163         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
16164         # for OPEN and IO lock.
16165         [ $((enq - enq_2)) -ge 1000 ] ||
16166                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
16167         unlinkmany $dom 1000
16168         return 0
16169 }
16170 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
16171
16172 cleanup_test_300() {
16173         trap 0
16174         umask $SAVE_UMASK
16175 }
16176 test_striped_dir() {
16177         local mdt_index=$1
16178         local stripe_count
16179         local stripe_index
16180
16181         mkdir -p $DIR/$tdir
16182
16183         SAVE_UMASK=$(umask)
16184         trap cleanup_test_300 RETURN EXIT
16185
16186         $LFS setdirstripe -i $mdt_index -c 2 -t all_char -m 755 \
16187                                                 $DIR/$tdir/striped_dir ||
16188                 error "set striped dir error"
16189
16190         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
16191         [ "$mode" = "755" ] || error "expect 755 got $mode"
16192
16193         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
16194                 error "getdirstripe failed"
16195         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
16196         if [ "$stripe_count" != "2" ]; then
16197                 error "1:stripe_count is $stripe_count, expect 2"
16198         fi
16199         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
16200         if [ "$stripe_count" != "2" ]; then
16201                 error "2:stripe_count is $stripe_count, expect 2"
16202         fi
16203
16204         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
16205         if [ "$stripe_index" != "$mdt_index" ]; then
16206                 error "stripe_index is $stripe_index, expect $mdt_index"
16207         fi
16208
16209         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
16210                 error "nlink error after create striped dir"
16211
16212         mkdir $DIR/$tdir/striped_dir/a
16213         mkdir $DIR/$tdir/striped_dir/b
16214
16215         stat $DIR/$tdir/striped_dir/a ||
16216                 error "create dir under striped dir failed"
16217         stat $DIR/$tdir/striped_dir/b ||
16218                 error "create dir under striped dir failed"
16219
16220         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
16221                 error "nlink error after mkdir"
16222
16223         rmdir $DIR/$tdir/striped_dir/a
16224         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
16225                 error "nlink error after rmdir"
16226
16227         rmdir $DIR/$tdir/striped_dir/b
16228         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
16229                 error "nlink error after rmdir"
16230
16231         chattr +i $DIR/$tdir/striped_dir
16232         createmany -o $DIR/$tdir/striped_dir/f 10 &&
16233                 error "immutable flags not working under striped dir!"
16234         chattr -i $DIR/$tdir/striped_dir
16235
16236         rmdir $DIR/$tdir/striped_dir ||
16237                 error "rmdir striped dir error"
16238
16239         cleanup_test_300
16240
16241         true
16242 }
16243
16244 test_300a() {
16245         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.7.0) ] &&
16246                 skip "skipped for lustre < 2.7.0" && return
16247         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
16248         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
16249
16250         test_striped_dir 0 || error "failed on striped dir on MDT0"
16251         test_striped_dir 1 || error "failed on striped dir on MDT0"
16252 }
16253 run_test 300a "basic striped dir sanity test"
16254
16255 test_300b() {
16256         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.7.0) ] &&
16257                 skip "skipped for lustre < 2.7.0" && return
16258         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
16259         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
16260         local i
16261         local mtime1
16262         local mtime2
16263         local mtime3
16264
16265         test_mkdir $DIR/$tdir
16266         $LFS setdirstripe -i 0 -c 2 -t all_char $DIR/$tdir/striped_dir ||
16267                 error "set striped dir error"
16268         for ((i=0; i<10; i++)); do
16269                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
16270                 sleep 1
16271                 touch $DIR/$tdir/striped_dir/file_$i ||
16272                                         error "touch error $i"
16273                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
16274                 [ $mtime1 -eq $mtime2 ] &&
16275                         error "mtime not change after create"
16276                 sleep 1
16277                 rm -f $DIR/$tdir/striped_dir/file_$i ||
16278                                         error "unlink error $i"
16279                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
16280                 [ $mtime2 -eq $mtime3 ] &&
16281                         error "mtime did not change after unlink"
16282         done
16283         true
16284 }
16285 run_test 300b "check ctime/mtime for striped dir"
16286
16287 test_300c() {
16288         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.7.0) ] &&
16289                 skip "skipped for lustre < 2.7.0" && return
16290         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
16291         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
16292         local file_count
16293
16294         mkdir -p $DIR/$tdir
16295         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
16296                 error "set striped dir error"
16297
16298         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
16299                 error "chown striped dir failed"
16300
16301         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
16302                 error "create 5k files failed"
16303
16304         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
16305
16306         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
16307
16308         rm -rf $DIR/$tdir
16309 }
16310 run_test 300c "chown && check ls under striped directory"
16311
16312 test_300d() {
16313         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.7.0) ] &&
16314                 skip "skipped for lustre < 2.7.0" && return
16315         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
16316         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
16317         local stripe_count
16318         local file
16319
16320         mkdir -p $DIR/$tdir
16321         $SETSTRIPE -c 2 $DIR/$tdir
16322
16323         #local striped directory
16324         $LFS setdirstripe -i 0 -c 2 -t all_char $DIR/$tdir/striped_dir ||
16325                 error "set striped dir error"
16326         createmany -o $DIR/$tdir/striped_dir/f 10 ||
16327                 error "create 10 files failed"
16328
16329         #remote striped directory
16330         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
16331                 error "set striped dir error"
16332         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
16333                 error "create 10 files failed"
16334
16335         for file in $(find $DIR/$tdir); do
16336                 stripe_count=$($GETSTRIPE -c $file)
16337                 [ $stripe_count -eq 2 ] ||
16338                         error "wrong stripe $stripe_count for $file"
16339         done
16340
16341         rm -rf $DIR/$tdir
16342 }
16343 run_test 300d "check default stripe under striped directory"
16344
16345 test_300e() {
16346         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.7.55) ] &&
16347                 skip "Need MDS version at least 2.7.55" && return
16348         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
16349         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
16350         local stripe_count
16351         local file
16352
16353         mkdir -p $DIR/$tdir
16354
16355         $LFS setdirstripe -i 0 -c 2 -t all_char $DIR/$tdir/striped_dir ||
16356                 error "set striped dir error"
16357
16358         touch $DIR/$tdir/striped_dir/a
16359         touch $DIR/$tdir/striped_dir/b
16360         touch $DIR/$tdir/striped_dir/c
16361
16362         mkdir $DIR/$tdir/striped_dir/dir_a
16363         mkdir $DIR/$tdir/striped_dir/dir_b
16364         mkdir $DIR/$tdir/striped_dir/dir_c
16365
16366         $LFS setdirstripe -i 0 -c 2 -t all_char $DIR/$tdir/striped_dir/stp_a ||
16367                 error "set striped adir under striped dir error"
16368
16369         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
16370                 error "set striped bdir under striped dir error"
16371
16372         $LFS setdirstripe -i 0 -c 2 -t all_char $DIR/$tdir/striped_dir/stp_c ||
16373                 error "set striped cdir under striped dir error"
16374
16375         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
16376                 error "rename dir under striped dir fails"
16377
16378         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
16379                 error "rename dir under different stripes fails"
16380
16381         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
16382                 error "rename file under striped dir should succeed"
16383
16384         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
16385                 error "rename dir under striped dir should succeed"
16386
16387         rm -rf $DIR/$tdir
16388 }
16389 run_test 300e "check rename under striped directory"
16390
16391 test_300f() {
16392         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.7.55) ] &&
16393                 skip "Need MDS version at least 2.7.55" && return
16394         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
16395         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
16396         local stripe_count
16397         local file
16398
16399         rm -rf $DIR/$tdir
16400         mkdir -p $DIR/$tdir
16401
16402         $LFS setdirstripe -i 0 -c 2 -t all_char $DIR/$tdir/striped_dir ||
16403                 error "set striped dir error"
16404
16405         $LFS setdirstripe -i 0 -c 2 -t all_char $DIR/$tdir/striped_dir1 ||
16406                 error "set striped dir error"
16407
16408         touch $DIR/$tdir/striped_dir/a
16409         mkdir $DIR/$tdir/striped_dir/dir_a
16410         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
16411                 error "create striped dir under striped dir fails"
16412
16413         touch $DIR/$tdir/striped_dir1/b
16414         mkdir $DIR/$tdir/striped_dir1/dir_b
16415         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
16416                 error "create striped dir under striped dir fails"
16417
16418         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
16419                 error "rename dir under different striped dir should fail"
16420
16421         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
16422                 error "rename striped dir under diff striped dir should fail"
16423
16424         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
16425                 error "rename file under diff striped dirs fails"
16426
16427         rm -rf $DIR/$tdir
16428 }
16429 run_test 300f "check rename cross striped directory"
16430
16431 test_300_check_default_striped_dir()
16432 {
16433         local dirname=$1
16434         local default_count=$2
16435         local default_index=$3
16436         local stripe_count
16437         local stripe_index
16438         local dir_stripe_index
16439         local dir
16440
16441         echo "checking $dirname $default_count $default_index"
16442         $LFS setdirstripe -D -c $default_count -i $default_index \
16443                                 -t all_char $DIR/$tdir/$dirname ||
16444                 error "set default stripe on striped dir error"
16445         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
16446         [ $stripe_count -eq $default_count ] ||
16447                 error "expect $default_count get $stripe_count for $dirname"
16448
16449         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
16450         [ $stripe_index -eq $default_index ] ||
16451                 error "expect $default_index get $stripe_index for $dirname"
16452
16453         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
16454                                                 error "create dirs failed"
16455
16456         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
16457         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
16458         for dir in $(find $DIR/$tdir/$dirname/*); do
16459                 stripe_count=$($LFS getdirstripe -c $dir)
16460                 [ $stripe_count -eq $default_count ] ||
16461                 [ $stripe_count -eq 0 -o $default_count -eq 1 ] ||
16462                 error "stripe count $default_count != $stripe_count for $dir"
16463
16464                 stripe_index=$($LFS getdirstripe -i $dir)
16465                 [ $default_index -eq -1 -o $stripe_index -eq $default_index ] ||
16466                         error "$stripe_index != $default_index for $dir"
16467
16468                 #check default stripe
16469                 stripe_count=$($LFS getdirstripe -D -c $dir)
16470                 [ $stripe_count -eq $default_count ] ||
16471                 error "default count $default_count != $stripe_count for $dir"
16472
16473                 stripe_index=$($LFS getdirstripe -D -i $dir)
16474                 [ $stripe_index -eq $default_index ] ||
16475                 error "default index $default_index != $stripe_index for $dir"
16476         done
16477         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
16478 }
16479
16480 test_300g() {
16481         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.7.55) ] &&
16482                 skip "Need MDS version at least 2.7.55" && return
16483         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
16484         local dir
16485         local stripe_count
16486         local stripe_index
16487
16488         mkdir $DIR/$tdir
16489         mkdir $DIR/$tdir/normal_dir
16490
16491         #Checking when client cache stripe index
16492         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
16493         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
16494                 error "create striped_dir failed"
16495
16496         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
16497                 error "create dir0 fails"
16498         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
16499         [ $stripe_index -eq 0 ] ||
16500                 error "dir0 expect index 0 got $stripe_index"
16501
16502         mkdir $DIR/$tdir/striped_dir/dir1 ||
16503                 error "create dir1 fails"
16504         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
16505         [ $stripe_index -eq 1 ] ||
16506                 error "dir1 expect index 1 got $stripe_index"
16507
16508         #check default stripe count/stripe index
16509         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
16510         test_300_check_default_striped_dir normal_dir 1 0
16511         test_300_check_default_striped_dir normal_dir 2 1
16512         test_300_check_default_striped_dir normal_dir 2 -1
16513
16514         #delete default stripe information
16515         echo "delete default stripeEA"
16516         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
16517                 error "set default stripe on striped dir error"
16518
16519         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
16520         for dir in $(find $DIR/$tdir/normal_dir/*); do
16521                 stripe_count=$($LFS getdirstripe -c $dir)
16522                 [ $stripe_count -eq 0 ] ||
16523                         error "expect 1 get $stripe_count for $dir"
16524                 stripe_index=$($LFS getdirstripe -i $dir)
16525                 [ $stripe_index -eq 0 ] ||
16526                         error "expect 0 get $stripe_index for $dir"
16527         done
16528 }
16529 run_test 300g "check default striped directory for normal directory"
16530
16531 test_300h() {
16532         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.7.55) ] &&
16533                 skip "Need MDS version at least 2.7.55" && return
16534         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
16535         local dir
16536         local stripe_count
16537
16538         mkdir $DIR/$tdir
16539         $LFS setdirstripe -i 0 -c $MDSCOUNT -t all_char \
16540                                         $DIR/$tdir/striped_dir ||
16541                 error "set striped dir error"
16542
16543         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
16544         test_300_check_default_striped_dir striped_dir 1 0
16545         test_300_check_default_striped_dir striped_dir 2 1
16546         test_300_check_default_striped_dir striped_dir 2 -1
16547
16548         #delete default stripe information
16549         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
16550                 error "set default stripe on striped dir error"
16551
16552         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
16553         for dir in $(find $DIR/$tdir/striped_dir/*); do
16554                 stripe_count=$($LFS getdirstripe -c $dir)
16555                 [ $stripe_count -eq 0 ] ||
16556                         error "expect 1 get $stripe_count for $dir"
16557         done
16558 }
16559 run_test 300h "check default striped directory for striped directory"
16560
16561 test_300i() {
16562         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.7.55) ] &&
16563                 skip "Need MDS version at least 2.7.55" && return
16564         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
16565         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
16566         local stripe_count
16567         local file
16568
16569         mkdir $DIR/$tdir
16570
16571         $LFS setdirstripe -i 0 -c$MDSCOUNT -t all_char $DIR/$tdir/striped_dir ||
16572                 error "set striped dir error"
16573
16574         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
16575                 error "create files under striped dir failed"
16576
16577         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
16578                 error "set striped hashdir error"
16579
16580         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
16581                 error "create dir0 under hash dir failed"
16582         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
16583                 error "create dir1 under hash dir failed"
16584
16585         # unfortunately, we need to umount to clear dir layout cache for now
16586         # once we fully implement dir layout, we can drop this
16587         umount_client $MOUNT || error "umount failed"
16588         mount_client $MOUNT || error "mount failed"
16589
16590         $LFS find -H fnv_1a_64 $DIR/$tdir/hashdir
16591         local dircnt=$($LFS find -H fnv_1a_64 $DIR/$tdir/hashdir | wc -l)
16592         [ $dircnt -eq 1 ] || error "lfs find striped dir got:$dircnt,except:1"
16593
16594         #set the stripe to be unknown hash type
16595         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
16596         $LCTL set_param fail_loc=0x1901
16597         for ((i = 0; i < 10; i++)); do
16598                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
16599                         error "stat f-$i failed"
16600                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
16601         done
16602
16603         touch $DIR/$tdir/striped_dir/f0 &&
16604                 error "create under striped dir with unknown hash should fail"
16605
16606         $LCTL set_param fail_loc=0
16607
16608         umount_client $MOUNT || error "umount failed"
16609         mount_client $MOUNT || error "mount failed"
16610
16611         return 0
16612 }
16613 run_test 300i "client handle unknown hash type striped directory"
16614
16615 test_300j() {
16616         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
16617         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.7.55) ] &&
16618                 skip "Need MDS version at least 2.7.55" && return
16619         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
16620         local stripe_count
16621         local file
16622
16623         mkdir $DIR/$tdir
16624
16625         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
16626         $LCTL set_param fail_loc=0x1702
16627         $LFS setdirstripe -i 0 -c$MDSCOUNT -t all_char $DIR/$tdir/striped_dir ||
16628                 error "set striped dir error"
16629
16630         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
16631                 error "create files under striped dir failed"
16632
16633         $LCTL set_param fail_loc=0
16634
16635         rm -rf $DIR/$tdir || error "unlink striped dir fails"
16636
16637         return 0
16638 }
16639 run_test 300j "test large update record"
16640
16641 test_300k() {
16642         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.7.55) ] &&
16643                 skip "Need MDS version at least 2.7.55" && return
16644         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
16645         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
16646         local stripe_count
16647         local file
16648
16649         mkdir $DIR/$tdir
16650
16651         #define OBD_FAIL_LARGE_STRIPE   0x1703
16652         $LCTL set_param fail_loc=0x1703
16653         $LFS setdirstripe -i 0 -c512 $DIR/$tdir/striped_dir ||
16654                 error "set striped dir error"
16655         $LCTL set_param fail_loc=0
16656
16657         $LFS getdirstripe $DIR/$tdir/striped_dir ||
16658                 error "getstripeddir fails"
16659         rm -rf $DIR/$tdir/striped_dir ||
16660                 error "unlink striped dir fails"
16661
16662         return 0
16663 }
16664 run_test 300k "test large striped directory"
16665
16666 test_300l() {
16667         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.7.55) ] &&
16668                 skip "Need MDS version at least 2.7.55" && return
16669         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
16670         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
16671         local stripe_index
16672
16673         test_mkdir -p $DIR/$tdir/striped_dir
16674         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
16675                         error "chown $RUNAS_ID failed"
16676         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
16677                 error "set default striped dir failed"
16678
16679         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
16680         $LCTL set_param fail_loc=0x80000158
16681         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
16682
16683         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
16684         [ $stripe_index -eq 1 ] ||
16685                 error "expect 1 get $stripe_index for $dir"
16686 }
16687 run_test 300l "non-root user to create dir under striped dir with stale layout"
16688
16689 test_300m() {
16690         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.7.55) ] &&
16691                 skip "Need MDS version at least 2.7.55" && return
16692         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
16693         [ $MDSCOUNT -ge 2 ] && skip "Only for single MDT" && return
16694
16695         mkdir -p $DIR/$tdir/striped_dir
16696         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
16697                 error "set default stripes dir error"
16698
16699         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
16700
16701         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
16702         [ $stripe_count -eq 0 ] ||
16703                         error "expect 0 get $stripe_count for a"
16704
16705         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
16706                 error "set default stripes dir error"
16707
16708         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
16709
16710         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
16711         [ $stripe_count -eq 0 ] ||
16712                         error "expect 0 get $stripe_count for b"
16713
16714         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
16715                 error "set default stripes dir error"
16716
16717         mkdir $DIR/$tdir/striped_dir/c &&
16718                 error "default stripe_index is invalid, mkdir c should fails"
16719
16720         rm -rf $DIR/$tdir || error "rmdir fails"
16721 }
16722 run_test 300m "setstriped directory on single MDT FS"
16723
16724 cleanup_300n() {
16725         local list=$(comma_list $(mdts_nodes))
16726
16727         trap 0
16728         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
16729 }
16730
16731 test_300n() {
16732         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.7.55) ] &&
16733                 skip "Need MDS version at least 2.7.55" && return
16734         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
16735         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
16736         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16737
16738         local stripe_index
16739         local list=$(comma_list $(mdts_nodes))
16740
16741         trap cleanup_300n RETURN EXIT
16742         mkdir -p $DIR/$tdir
16743         chmod 777 $DIR/$tdir
16744         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
16745                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
16746                 error "create striped dir succeeds with gid=0"
16747
16748         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
16749         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
16750                 error "create striped dir fails with gid=-1"
16751
16752         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
16753         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
16754                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
16755                 error "set default striped dir succeeds with gid=0"
16756
16757
16758         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
16759         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
16760                 error "set default striped dir fails with gid=-1"
16761
16762
16763         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
16764         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
16765                                         error "create test_dir fails"
16766         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
16767                                         error "create test_dir1 fails"
16768         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
16769                                         error "create test_dir2 fails"
16770         cleanup_300n
16771 }
16772 run_test 300n "non-root user to create dir under striped dir with default EA"
16773
16774 test_300o() {
16775         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.7.55) ] &&
16776                 skip "Need MDS version at least 2.7.55" && return
16777         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
16778         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
16779         local numfree1
16780         local numfree2
16781
16782         mkdir -p $DIR/$tdir
16783
16784         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
16785         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
16786         if [ $numfree1 -lt 66000 -o $numfree2 -lt 66000 ]; then
16787                 skip "not enough free inodes $numfree1 $numfree2"
16788                 return
16789         fi
16790
16791         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
16792         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
16793         if [ $numfree1 -lt 300000 -o $numfree2 -lt 300000 ]; then
16794                 skip "not enough free space $numfree1 $numfree2"
16795                 return
16796         fi
16797
16798         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
16799                 error "setdirstripe fails"
16800
16801         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
16802                 error "create dirs fails"
16803
16804         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
16805         ls $DIR/$tdir/striped_dir > /dev/null ||
16806                 error "ls striped dir fails"
16807         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
16808                 error "unlink big striped dir fails"
16809 }
16810 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
16811
16812 test_300p() {
16813         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
16814         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
16815         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16816
16817         mkdir -p $DIR/$tdir
16818
16819         #define OBD_FAIL_OUT_ENOSPC     0x1704
16820         do_facet mds2 lctl set_param fail_loc=0x80001704
16821         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 &&
16822                         error "create striped directory should fail"
16823
16824         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
16825
16826         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
16827         true
16828 }
16829 run_test 300p "create striped directory without space"
16830
16831 test_300q() {
16832         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
16833         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
16834
16835         local fd=$(free_fd)
16836         local cmd="exec $fd<$tdir"
16837         cd $DIR
16838         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
16839         eval $cmd
16840         cmd="exec $fd<&-"
16841         trap "eval $cmd" EXIT
16842         cd $tdir || error "cd $tdir fails"
16843         rmdir  ../$tdir || error "rmdir $tdir fails"
16844         mkdir local_dir && error "create dir succeeds"
16845         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
16846         eval $cmd
16847         return 0
16848 }
16849 run_test 300q "create remote directory under orphan directory"
16850
16851 prepare_remote_file() {
16852         mkdir $DIR/$tdir/src_dir ||
16853                 error "create remote source failed"
16854
16855         cp /etc/hosts $DIR/$tdir/src_dir/a || error
16856         touch $DIR/$tdir/src_dir/a
16857
16858         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
16859                 error "create remote target dir failed"
16860
16861         touch $DIR/$tdir/tgt_dir/b
16862
16863         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
16864                 error "rename dir cross MDT failed!"
16865
16866         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
16867                 error "src_child still exists after rename"
16868
16869         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
16870                 error "missing file(a) after rename"
16871
16872         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
16873                 error "diff after rename"
16874 }
16875
16876 test_310a() {
16877         [[ $MDSCOUNT -lt 2 ]] && skip "needs >= 4 MDTs" && return
16878         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
16879         local remote_file=$DIR/$tdir/tgt_dir/b
16880
16881         mkdir -p $DIR/$tdir
16882
16883         prepare_remote_file || error "prepare remote file failed"
16884
16885         #open-unlink file
16886         $OPENUNLINK $remote_file $remote_file || error
16887         $CHECKSTAT -a $remote_file || error
16888 }
16889 run_test 310a "open unlink remote file"
16890
16891 test_310b() {
16892         [[ $MDSCOUNT -lt 2 ]] && skip "needs >= 4 MDTs" && return
16893         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
16894         local remote_file=$DIR/$tdir/tgt_dir/b
16895
16896         mkdir -p $DIR/$tdir
16897
16898         prepare_remote_file || error "prepare remote file failed"
16899
16900         ln $remote_file $DIR/$tfile || error "link failed for remote file"
16901         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
16902         $CHECKSTAT -t file $remote_file || error "check file failed"
16903 }
16904 run_test 310b "unlink remote file with multiple links while open"
16905
16906 test_310c() {
16907         [[ $MDSCOUNT -lt 4 ]] && skip "needs >= 4 MDTs" && return
16908         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
16909         local remote_file=$DIR/$tdir/tgt_dir/b
16910
16911         mkdir -p $DIR/$tdir
16912
16913         prepare_remote_file || error "prepare remote file failed"
16914
16915         ln $remote_file $DIR/$tfile || error "link failed for remote file"
16916         multiop_bg_pause $remote_file O_uc ||
16917                         error "mulitop failed for remote file"
16918         MULTIPID=$!
16919         $MULTIOP $DIR/$tfile Ouc
16920         kill -USR1 $MULTIPID
16921         wait $MULTIPID
16922 }
16923 run_test 310c "open-unlink remote file with multiple links"
16924
16925 #LU-4825
16926 test_311() {
16927         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.8.54) ] &&
16928                 skip "lustre < 2.8.54 does not contain LU-4825 fix" && return
16929         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
16930         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16931
16932         local old_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
16933
16934         mkdir -p $DIR/$tdir
16935         $SETSTRIPE -i 0 -c 1 $DIR/$tdir
16936         createmany -o $DIR/$tdir/$tfile. 1000
16937
16938         # statfs data is not real time, let's just calculate it
16939         old_iused=$((old_iused + 1000))
16940
16941         local count=$(do_facet $SINGLEMDS "lctl get_param -n \
16942                         osp.*OST0000*MDT0000.create_count")
16943         local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
16944                                 osp.*OST0000*MDT0000.max_create_count")
16945         for idx in $(seq $MDSCOUNT); do
16946                 do_facet mds$idx "lctl set_param -n \
16947                         osp.*OST0000*MDT000?.max_create_count=0"
16948         done
16949
16950         $SETSTRIPE -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
16951         local index=$($GETSTRIPE -i $DIR/$tdir/$tfile)
16952         [ $index -ne 0 ] || error "$tfile stripe index is 0"
16953
16954         unlinkmany $DIR/$tdir/$tfile. 1000
16955
16956         for idx in $(seq $MDSCOUNT); do
16957                 do_facet mds$idx "lctl set_param -n \
16958                         osp.*OST0000*MDT000?.max_create_count=$max_count"
16959                 do_facet mds$idx "lctl set_param -n \
16960                         osp.*OST0000*MDT000?.create_count=$count"
16961         done
16962
16963         local new_iused
16964         for i in $(seq 120); do
16965                 new_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
16966                 # system may be too busy to destroy all objs in time, use
16967                 # a somewhat small value to not fail autotest
16968                 [ $((old_iused - new_iused)) -gt 400 ] && break
16969                 sleep 1
16970         done
16971
16972         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
16973         [ $((old_iused - new_iused)) -gt 400 ] ||
16974                 error "objs not destroyed after unlink"
16975 }
16976 run_test 311 "disable OSP precreate, and unlink should destroy objs"
16977
16978 zfs_oid_to_objid()
16979 {
16980         local ost=$1
16981         local objid=$2
16982
16983         local vdevdir=$(dirname $(facet_vdevice $ost))
16984         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
16985         local zfs_zapid=$(do_facet $ost $cmd |
16986                           grep -w "/O/0/d$((objid%32))" -C 5 |
16987                           awk '/Object/{getline; print $1}')
16988         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
16989                           awk "/$objid = /"'{printf $3}')
16990
16991         echo $zfs_objid
16992 }
16993
16994 zfs_object_blksz() {
16995         local ost=$1
16996         local objid=$2
16997
16998         local vdevdir=$(dirname $(facet_vdevice $ost))
16999         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
17000         local blksz=$(do_facet $ost $cmd $objid |
17001                       awk '/dblk/{getline; printf $4}')
17002
17003         case "${blksz: -1}" in
17004                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
17005                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
17006                 *) ;;
17007         esac
17008
17009         echo $blksz
17010 }
17011
17012 test_312() { # LU-4856
17013         remote_ost_nodsh && skip "remote OST with nodsh" && return
17014
17015         [ $(facet_fstype ost1) = "zfs" ] ||
17016                 { skip "the test only applies to zfs" && return; }
17017
17018         local max_blksz=$(do_facet ost1 \
17019                           $ZFS get -p recordsize $(facet_device ost1) |
17020                           awk '!/VALUE/{print $3}')
17021         local min_blksz=$(getconf PAGE_SIZE)
17022
17023         # to make life a little bit easier
17024         $LFS mkdir -c 1 -i 0 $DIR/$tdir
17025         $LFS setstripe -c 1 -i 0 $DIR/$tdir
17026
17027         local tf=$DIR/$tdir/$tfile
17028         touch $tf
17029         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
17030
17031         # Get ZFS object id
17032         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
17033
17034         # block size change by sequential over write
17035         local blksz
17036         for ((bs=$min_blksz; bs <= max_blksz; bs <<= 2)); do
17037                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
17038
17039                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
17040                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
17041         done
17042         rm -f $tf
17043
17044         # block size change by sequential append write
17045         dd if=/dev/zero of=$tf bs=$min_blksz count=1 oflag=sync conv=notrunc
17046         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
17047         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
17048
17049         for ((count = 1; count < $((max_blksz / min_blksz)); count *= 2)); do
17050                 dd if=/dev/zero of=$tf bs=$min_blksz count=$count seek=$count \
17051                         oflag=sync conv=notrunc
17052
17053                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
17054                 [ $blksz -eq $((2 * count * min_blksz)) ] ||
17055                         error "blksz error, actual $blksz, "    \
17056                                 "expected: 2 * $count * $min_blksz"
17057         done
17058         rm -f $tf
17059
17060         # random write
17061         touch $tf
17062         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
17063         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
17064
17065         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
17066         blksz=$(zfs_object_blksz ost1 $zfs_objid)
17067         [ $blksz -eq $min_blksz ] ||
17068                 error "blksz error: $blksz, expected: $min_blksz"
17069
17070         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
17071         blksz=$(zfs_object_blksz ost1 $zfs_objid)
17072         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
17073
17074         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
17075         blksz=$(zfs_object_blksz ost1 $zfs_objid)
17076         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
17077 }
17078 run_test 312 "make sure ZFS adjusts its block size by write pattern"
17079
17080 test_313() {
17081         remote_ost_nodsh && skip "remote OST with nodsh" && return
17082
17083         local file=$DIR/$tfile
17084         rm -f $file
17085         $SETSTRIPE -c 1 -i 0 $file || error "setstripe failed"
17086
17087         # define OBD_FAIL_TGT_RCVD_EIO           0x720
17088         do_facet ost1 "$LCTL set_param fail_loc=0x720"
17089         dd if=/dev/zero of=$file bs=4096 oflag=direct count=1 &&
17090                 error "write should failed"
17091         do_facet ost1 "$LCTL set_param fail_loc=0"
17092         rm -f $file
17093 }
17094 run_test 313 "io should fail after last_rcvd update fail"
17095
17096 test_314() {
17097         $SETSTRIPE -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
17098         do_facet ost1 "$LCTL set_param fail_loc=0x720"
17099         rm -f $DIR/$tfile
17100         wait_delete_completed
17101         do_facet ost1 "$LCTL set_param fail_loc=0"
17102 }
17103 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
17104
17105 test_315() { # LU-618
17106         local file=$DIR/$tfile
17107         rm -f $file
17108
17109         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4096000c
17110         $MULTIOP $file oO_RDONLY:r4096000_c &
17111         PID=$!
17112
17113         sleep 2
17114
17115         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
17116         kill -USR1 $PID
17117
17118         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
17119         rm -f $file
17120 }
17121 run_test 315 "read should be accounted"
17122
17123 test_fake_rw() {
17124         local read_write=$1
17125         if [ "$read_write" = "write" ]; then
17126                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
17127         elif [ "$read_write" = "read" ]; then
17128                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
17129         else
17130                 error "argument error"
17131         fi
17132
17133         # turn off debug for performance testing
17134         local saved_debug=$($LCTL get_param -n debug)
17135         $LCTL set_param debug=0
17136
17137         $SETSTRIPE -c 1 -i 0 $DIR/$tfile
17138
17139         # get ost1 size - lustre-OST0000
17140         local ost1_avail_size=$($LFS df | awk /${ost1_svc}/'{ print $4 }')
17141         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
17142         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
17143
17144         if [ "$read_write" = "read" ]; then
17145                 truncate -s $(expr 1048576 \* $blocks) $DIR/$tfile
17146         fi
17147
17148         local start_time=$(date +%s.%N)
17149         $dd_cmd bs=1M count=$blocks oflag=sync ||
17150                 error "real dd $read_write error"
17151         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
17152
17153         if [ "$read_write" = "write" ]; then
17154                 rm -f $DIR/$tfile
17155         fi
17156
17157         # define OBD_FAIL_OST_FAKE_RW           0x238
17158         do_facet ost1 $LCTL set_param fail_loc=0x238
17159
17160         local start_time=$(date +%s.%N)
17161         $dd_cmd bs=1M count=$blocks oflag=sync ||
17162                 error "fake dd $read_write error"
17163         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
17164
17165         if [ "$read_write" = "write" ]; then
17166                 # verify file size
17167                 cancel_lru_locks osc
17168                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
17169                         error "$tfile size not $blocks MB"
17170         fi
17171         do_facet ost1 $LCTL set_param fail_loc=0
17172
17173         echo "fake $read_write $duration_fake vs. normal $read_write" \
17174                 "$duration in seconds"
17175         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
17176                 error_not_in_vm "fake write is slower"
17177
17178         $LCTL set_param -n debug="$saved_debug"
17179         rm -f $DIR/$tfile
17180 }
17181 test_399a() { # LU-7655 for OST fake write
17182         remote_ost_nodsh && skip "remote OST with nodsh" && return
17183
17184         test_fake_rw write
17185 }
17186 run_test 399a "fake write should not be slower than normal write"
17187
17188 test_399b() { # LU-8726 for OST fake read
17189         remote_ost_nodsh && skip "remote OST with nodsh" && return
17190
17191         if [ "$(facet_fstype ost1)" != "ldiskfs" ]; then
17192                 skip "ldiskfs only test" && return 0
17193         fi
17194         test_fake_rw read
17195 }
17196 run_test 399b "fake read should not be slower than normal read"
17197
17198 test_400a() { # LU-1606, was conf-sanity test_74
17199         local extra_flags=''
17200         local out=$TMP/$tfile
17201         local prefix=/usr/include/lustre
17202         local prog
17203
17204         if ! which $CC > /dev/null 2>&1; then
17205                 skip_env "$CC is not installed"
17206                 return 0
17207         fi
17208
17209         if ! [[ -d $prefix ]]; then
17210                 # Assume we're running in tree and fixup the include path.
17211                 extra_flags+=" -I$LUSTRE/include"
17212                 extra_flags+=" -L$LUSTRE/utils"
17213         fi
17214
17215         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
17216                 $CC -Wall -Werror $extra_flags -llustreapi -o $out $prog ||
17217                         error "client api broken"
17218         done
17219         rm -f $out
17220 }
17221 run_test 400a "Lustre client api program can compile and link"
17222
17223 test_400b() { # LU-1606, LU-5011
17224         local header
17225         local out=$TMP/$tfile
17226         local prefix=/usr/include/linux/lustre
17227
17228         # We use a hard coded prefix so that this test will not fail
17229         # when run in tree. There are headers in lustre/include/lustre/
17230         # that are not packaged (like lustre_idl.h) and have more
17231         # complicated include dependencies (like config.h and lnet/types.h).
17232         # Since this test about correct packaging we just skip them when
17233         # they don't exist (see below) rather than try to fixup cppflags.
17234
17235         if ! which $CC > /dev/null 2>&1; then
17236                 skip_env "$CC is not installed"
17237                 return 0
17238         fi
17239
17240         for header in $prefix/*.h; do
17241                 if ! [[ -f "$header" ]]; then
17242                         continue
17243                 fi
17244
17245                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
17246                         continue # lustre_ioctl.h is internal header
17247                 fi
17248
17249                 $CC -Wall -Werror -include $header -c -x c /dev/null -o $out ||
17250                         error "cannot compile '$header'"
17251         done
17252         rm -f $out
17253 }
17254 run_test 400b "packaged headers can be compiled"
17255
17256 test_401a() { #LU-7437
17257         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
17258         [ -n "$printf_arg" ] && skip_env "find does not support -printf" &&
17259                 return
17260         #count the number of parameters by "list_param -R"
17261         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
17262         #count the number of parameters by listing proc files
17263         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
17264         echo "proc_dirs='$proc_dirs'"
17265         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
17266         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
17267                       sort -u | wc -l)
17268
17269         [ $params -eq $procs ] ||
17270                 error "found $params parameters vs. $procs proc files"
17271
17272         # test the list_param -D option only returns directories
17273         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
17274         #count the number of parameters by listing proc directories
17275         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
17276                 sort -u | wc -l)
17277
17278         [ $params -eq $procs ] ||
17279                 error "found $params parameters vs. $procs proc files"
17280 }
17281 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
17282
17283 test_401b() {
17284         local save=$($LCTL get_param -n jobid_var)
17285         local tmp=testing
17286
17287         $LCTL set_param foo=bar jobid_var=$tmp bar=baz &&
17288                 error "no error returned when setting bad parameters"
17289
17290         local jobid_new=$($LCTL get_param -n foe jobid_var baz)
17291         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
17292
17293         $LCTL set_param -n fog=bam jobid_var=$save bat=fog
17294         local jobid_old=$($LCTL get_param -n foe jobid_var bag)
17295         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
17296 }
17297 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
17298
17299 test_401c() {
17300         local jobid_var_old=$($LCTL get_param -n jobid_var)
17301         local jobid_var_new
17302
17303         $LCTL set_param jobid_var= &&
17304                 error "no error returned for 'set_param a='"
17305
17306         jobid_var_new=$($LCTL get_param -n jobid_var)
17307         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
17308                 error "jobid_var was changed by setting without value"
17309
17310         $LCTL set_param jobid_var &&
17311                 error "no error returned for 'set_param a'"
17312
17313         jobid_var_new=$($LCTL get_param -n jobid_var)
17314         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
17315                 error "jobid_var was changed by setting without value"
17316 }
17317 run_test 401c "Verify 'lctl set_param' without value fails in either format."
17318
17319 test_401d() {
17320         local jobid_var_old=$($LCTL get_param -n jobid_var)
17321         local jobid_var_new
17322         local new_value="foo=bar"
17323
17324         $LCTL set_param jobid_var=$new_value ||
17325                 error "'set_param a=b' did not accept a value containing '='"
17326
17327         jobid_var_new=$($LCTL get_param -n jobid_var)
17328         [[ "$jobid_var_new" == "$new_value" ]] ||
17329                 error "'set_param a=b' failed on a value containing '='"
17330
17331         # Reset the jobid_var to test the other format
17332         $LCTL set_param jobid_var=$jobid_var_old
17333         jobid_var_new=$($LCTL get_param -n jobid_var)
17334         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
17335                 error "failed to reset jobid_var"
17336
17337         $LCTL set_param jobid_var $new_value ||
17338                 error "'set_param a b' did not accept a value containing '='"
17339
17340         jobid_var_new=$($LCTL get_param -n jobid_var)
17341         [[ "$jobid_var_new" == "$new_value" ]] ||
17342                 error "'set_param a b' failed on a value containing '='"
17343
17344         $LCTL set_param jobid_var $jobid_var_old
17345         jobid_var_new=$($LCTL get_param -n jobid_var)
17346         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
17347                 error "failed to reset jobid_var"
17348 }
17349 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
17350
17351 test_402() {
17352         local server_version=$(lustre_version_code $SINGLEMDS)
17353         [[ $server_version -ge $(version_code 2.7.66) ]] ||
17354         [[ $server_version -ge $(version_code 2.7.18.4) &&
17355                 $server_version -lt $(version_code 2.7.50) ]] ||
17356         [[ $server_version -ge $(version_code 2.7.2) &&
17357                 $server_version -lt $(version_code 2.7.11) ]] ||
17358                 { skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+";
17359                         return; }
17360         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17361         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
17362 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
17363         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
17364         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
17365                 echo "Touch failed - OK"
17366 }
17367 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
17368
17369 test_403() {
17370         local file1=$DIR/$tfile.1
17371         local file2=$DIR/$tfile.2
17372         local tfile=$TMP/$tfile
17373
17374         rm -f $file1 $file2 $tfile
17375
17376         touch $file1
17377         ln $file1 $file2
17378
17379         # 30 sec OBD_TIMEOUT in ll_getattr()
17380         # right before populating st_nlink
17381         $LCTL set_param fail_loc=0x80001409
17382         stat -c %h $file1 > $tfile &
17383
17384         # create an alias, drop all locks and reclaim the dentry
17385         < $file2
17386         cancel_lru_locks mdc
17387         cancel_lru_locks osc
17388         sysctl -w vm.drop_caches=2
17389
17390         wait
17391
17392         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
17393
17394         rm -f $tfile $file1 $file2
17395 }
17396 run_test 403 "i_nlink should not drop to zero due to aliasing"
17397
17398 test_404() { # LU-6601
17399         local server_version=$(lustre_version_code $SINGLEMDS)
17400         [[ $server_version -ge $(version_code 2.8.53) ]] ||
17401                 { skip "Need server version newer than 2.8.52"; return 0; }
17402
17403         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17404         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
17405                 awk '/osp .*-osc-MDT/ { print $4}')
17406
17407         local osp
17408         for osp in $mosps; do
17409                 echo "Deactivate: " $osp
17410                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
17411                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
17412                         awk -vp=$osp '$4 == p { print $2 }')
17413                 [ $stat = IN ] || {
17414                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
17415                         error "deactivate error"
17416                 }
17417                 echo "Activate: " $osp
17418                 do_facet $SINGLEMDS $LCTL --device %$osp activate
17419                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
17420                         awk -vp=$osp '$4 == p { print $2 }')
17421                 [ $stat = UP ] || {
17422                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
17423                         error "activate error"
17424                 }
17425         done
17426 }
17427 run_test 404 "validate manual {de}activated works properly for OSPs"
17428
17429 test_405() {
17430         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.6.92) -o \
17431         [ $(lustre_version_code client) -lt $(version_code 2.6.99) ] &&
17432                 skip "Layout swap lock is not supported" && return
17433
17434         check_swap_layouts_support && return 0
17435
17436         test_mkdir $DIR/$tdir
17437         swap_lock_test -d $DIR/$tdir ||
17438                 error "One layout swap locked test failed"
17439 }
17440 run_test 405 "Various layout swap lock tests"
17441
17442 test_406() {
17443         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
17444         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs" && return
17445         [ -n "$FILESET" ] && skip "SKIP due to FILESET set" && return
17446         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
17447         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.8.50) ] &&
17448                 skip "Need MDS version at least 2.8.50" && return
17449
17450         local def_stripe_count=$($GETSTRIPE -c $MOUNT)
17451         local def_stripe_size=$($GETSTRIPE -S $MOUNT)
17452         local def_stripe_offset=$($GETSTRIPE -i $MOUNT)
17453         local def_pool=$($GETSTRIPE -p $MOUNT)
17454         local test_pool=$TESTNAME
17455
17456         if ! combined_mgs_mds ; then
17457                 mount_mgs_client
17458         fi
17459         pool_add $test_pool || error "pool_add failed"
17460         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
17461                 error "pool_add_targets failed"
17462
17463         # parent set default stripe count only, child will stripe from both
17464         # parent and fs default
17465         $SETSTRIPE -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
17466                 error "setstripe $MOUNT failed"
17467         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
17468         $SETSTRIPE -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
17469         for i in $(seq 10); do
17470                 local f=$DIR/$tdir/$tfile.$i
17471                 touch $f || error "touch failed"
17472                 local count=$($GETSTRIPE -c $f)
17473                 [ $count -eq $OSTCOUNT ] ||
17474                         error "$f stripe count $count != $OSTCOUNT"
17475                 local offset=$($GETSTRIPE -i $f)
17476                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
17477                 local size=$($GETSTRIPE -S $f)
17478                 [ $size -eq $((def_stripe_size * 2)) ] ||
17479                         error "$f stripe size $size != $((def_stripe_size * 2))"
17480                 local pool=$($GETSTRIPE -p $f)
17481                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
17482         done
17483
17484         # change fs default striping, delete parent default striping, now child
17485         # will stripe from new fs default striping only
17486         $SETSTRIPE -c 1 -S $def_stripe_size -i 0 $MOUNT ||
17487                 error "change $MOUNT default stripe failed"
17488         $SETSTRIPE -c 0 $DIR/$tdir || error "delete $tdir default stripe failed"
17489         for i in $(seq 11 20); do
17490                 local f=$DIR/$tdir/$tfile.$i
17491                 touch $f || error "touch $f failed"
17492                 local count=$($GETSTRIPE -c $f)
17493                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
17494                 local offset=$($GETSTRIPE -i $f)
17495                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
17496                 local size=$($GETSTRIPE -S $f)
17497                 [ $size -eq $def_stripe_size ] ||
17498                         error "$f stripe size $size != $def_stripe_size"
17499                 local pool=$($GETSTRIPE -p $f)
17500                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
17501
17502         done
17503
17504         unlinkmany $DIR/$tdir/$tfile. 1 20
17505
17506         # restore FS default striping
17507         if [ -z $def_pool ]; then
17508                 $SETSTRIPE -c $def_stripe_count -S $def_stripe_size \
17509                         -i $def_stripe_offset $MOUNT ||
17510                         error "restore default striping failed"
17511         else
17512                 $SETSTRIPE -c $def_stripe_count -S $def_stripe_size \
17513                         -i $def_stripe_offset -p $def_pool $MOUNT ||
17514                         error "restore default striping with $def_pool failed"
17515         fi
17516
17517         local f=$DIR/$tdir/$tfile
17518         pool_remove_all_targets $test_pool $f
17519         pool_remove $test_pool $f
17520
17521         if ! combined_mgs_mds ; then
17522                 umount_mgs_client
17523         fi
17524 }
17525 run_test 406 "DNE support fs default striping"
17526
17527 test_407() {
17528         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
17529         [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.8.55) ]] &&
17530                 skip "Need MDS version at least 2.8.55" && return
17531         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17532
17533         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
17534                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
17535         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
17536                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
17537         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
17538
17539         #define OBD_FAIL_DT_TXN_STOP    0x2019
17540         for idx in $(seq $MDSCOUNT); do
17541                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
17542         done
17543         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
17544         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
17545                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
17546         true
17547 }
17548 run_test 407 "transaction fail should cause operation fail"
17549
17550 test_408() {
17551         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 oflag=direct
17552
17553         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
17554         lctl set_param fail_loc=0x8000040a
17555         # let ll_prepare_partial_page() fail
17556         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
17557
17558         rm -f $DIR/$tfile
17559
17560         # create at least 100 unused inodes so that
17561         # shrink_icache_memory(0) should not return 0
17562         touch $DIR/$tfile-{0..100}
17563         rm -f $DIR/$tfile-{0..100}
17564         sync
17565
17566         echo 2 > /proc/sys/vm/drop_caches
17567 }
17568 run_test 408 "drop_caches should not hang due to page leaks"
17569
17570 test_409()
17571 {
17572         [ $MDSCOUNT -lt 2 ] &&
17573                 skip "We need at least 2 MDTs for this test" && return
17574
17575         check_mount_and_prep
17576
17577         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
17578         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
17579         touch $DIR/$tdir/guard || error "(2) Fail to create"
17580
17581         local PREFIX=$(str_repeat 'A' 128)
17582         echo "Create 1K hard links start at $(date)"
17583         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
17584                 error "(3) Fail to hard link"
17585
17586         echo "Links count should be right although linkEA overflow"
17587         stat $DIR/$tdir/guard || error "(4) Fail to stat"
17588         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
17589         [ $linkcount -eq 1001 ] ||
17590                 error "(5) Unexpected hard links count: $linkcount"
17591
17592         echo "List all links start at $(date)"
17593         ls -l $DIR/$tdir/foo > /dev/null ||
17594                 error "(6) Fail to list $DIR/$tdir/foo"
17595
17596         echo "Unlink hard links start at $(date)"
17597         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
17598                 error "(7) Fail to unlink"
17599 }
17600 run_test 409 "Large amount of cross-MDTs hard links on the same file"
17601
17602 test_410()
17603 {
17604         [[ $(lustre_version_code client) -lt $(version_code 2.9.59) ]] &&
17605                 skip "Need client version at least 2.9.59" && return
17606
17607         # Create a file, and stat it from the kernel
17608         local testfile=$DIR/$tfile
17609         touch $testfile
17610
17611         local run_id=$RANDOM
17612         local my_ino=$(stat --format "%i" $testfile)
17613
17614         # Try to insert the module. This will always fail as the
17615         # module is designed to not be inserted.
17616         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
17617             &> /dev/null
17618
17619         # Anything but success is a test failure
17620         dmesg | grep -q \
17621             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
17622             error "no inode match"
17623 }
17624 run_test 410 "Test inode number returned from kernel thread"
17625
17626 cleanup_test411_cgroup() {
17627         trap 0
17628         rmdir "$1"
17629 }
17630
17631 test_411() {
17632         local cg_basedir=/sys/fs/cgroup/memory
17633         # LU-9966
17634         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
17635                 { skip "no setup for cgroup"; return; }
17636
17637         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
17638                 error "test file creation failed"
17639         cancel_lru_locks osc
17640
17641         # Create a very small memory cgroup to force a slab allocation error
17642         local cgdir=$cg_basedir/osc_slab_alloc
17643         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
17644         trap "cleanup_test411_cgroup $cgdir" EXIT
17645         echo 2M > $cgdir/memory.kmem.limit_in_bytes
17646         echo 1M > $cgdir/memory.limit_in_bytes
17647
17648         # Should not LBUG, just be killed by oom-killer
17649         sh -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null" &&
17650                 error "fail to trigger a memory allocation error"
17651
17652         cleanup_test411_cgroup $cgdir
17653
17654         return 0
17655 }
17656 run_test 411 "Slab allocation error with cgroup does not LBUG"
17657
17658 test_412() {
17659         [ $MDSCOUNT -lt 2 ] &&
17660                 skip "We need at least 2 MDTs for this test" && return
17661
17662         if [ $(lustre_version_code mds1) -lt $(version_code 2.10.55) ]; then
17663                 skip "Need server version at least 2.10.55" & exit 0
17664         fi
17665
17666         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
17667                 error "mkdir failed"
17668         $LFS getdirstripe $DIR/$tdir
17669         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
17670         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
17671                 error "expect $((MDSCOUT - 1)) get $stripe_index"
17672         stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
17673         [ $stripe_count -eq 2 ] ||
17674                 error "expect 2 get $stripe_count"
17675 }
17676 run_test 412 "mkdir on specific MDTs"
17677
17678 prep_801() {
17679         [[ $(lustre_version_code mds1) -lt $(version_code 2.9.55) ]] ||
17680         [[ $(lustre_version_code ost1) -lt $(version_code 2.9.55) ]] &&
17681                 skip "Need server version at least 2.9.55" & exit 0
17682         start_full_debug_logging
17683 }
17684
17685 post_801() {
17686         stop_full_debug_logging
17687 }
17688
17689 barrier_stat() {
17690         if [ $(lustre_version_code mgs) -le $(version_code 2.10.0) ]; then
17691                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
17692                            awk '/The barrier for/ { print $7 }')
17693                 echo $st
17694         else
17695                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
17696                 echo \'$st\'
17697         fi
17698 }
17699
17700 barrier_expired() {
17701         local expired
17702
17703         if [ $(lustre_version_code mgs) -le $(version_code 2.10.0) ]; then
17704                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
17705                           awk '/will be expired/ { print $7 }')
17706         else
17707                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
17708         fi
17709
17710         echo $expired
17711 }
17712
17713 test_801a() {
17714         prep_801
17715
17716         echo "Start barrier_freeze at: $(date)"
17717         #define OBD_FAIL_BARRIER_DELAY          0x2202
17718         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
17719         do_facet mgs $LCTL barrier_freeze $FSNAME 10 &
17720
17721         sleep 2
17722         local b_status=$(barrier_stat)
17723         echo "Got barrier status at: $(date)"
17724         [ "$b_status" = "'freezing_p1'" ] ||
17725                 error "(1) unexpected barrier status $b_status"
17726
17727         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
17728         wait
17729         b_status=$(barrier_stat)
17730         [ "$b_status" = "'frozen'" ] ||
17731                 error "(2) unexpected barrier status $b_status"
17732
17733         local expired=$(barrier_expired)
17734         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
17735         sleep $((expired + 3))
17736
17737         b_status=$(barrier_stat)
17738         [ "$b_status" = "'expired'" ] ||
17739                 error "(3) unexpected barrier status $b_status"
17740
17741         do_facet mgs $LCTL barrier_freeze $FSNAME 10 ||
17742                 error "(4) fail to freeze barrier"
17743
17744         b_status=$(barrier_stat)
17745         [ "$b_status" = "'frozen'" ] ||
17746                 error "(5) unexpected barrier status $b_status"
17747
17748         echo "Start barrier_thaw at: $(date)"
17749         #define OBD_FAIL_BARRIER_DELAY          0x2202
17750         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
17751         do_facet mgs $LCTL barrier_thaw $FSNAME &
17752
17753         sleep 2
17754         b_status=$(barrier_stat)
17755         echo "Got barrier status at: $(date)"
17756         [ "$b_status" = "'thawing'" ] ||
17757                 error "(6) unexpected barrier status $b_status"
17758
17759         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
17760         wait
17761         b_status=$(barrier_stat)
17762         [ "$b_status" = "'thawed'" ] ||
17763                 error "(7) unexpected barrier status $b_status"
17764
17765         #define OBD_FAIL_BARRIER_FAILURE        0x2203
17766         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
17767         do_facet mgs $LCTL barrier_freeze $FSNAME
17768
17769         b_status=$(barrier_stat)
17770         [ "$b_status" = "'failed'" ] ||
17771                 error "(8) unexpected barrier status $b_status"
17772
17773         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
17774         do_facet mgs $LCTL barrier_thaw $FSNAME
17775
17776         post_801
17777 }
17778 run_test 801a "write barrier user interfaces and stat machine"
17779
17780 test_801b() {
17781         prep_801
17782
17783         mkdir $DIR/$tdir || error "(1) fail to mkdir"
17784         createmany -d $DIR/$tdir/d 6 || "(2) fail to mkdir"
17785         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
17786         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
17787         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
17788
17789         cancel_lru_locks mdc
17790
17791         # 180 seconds should be long enough
17792         do_facet mgs $LCTL barrier_freeze $FSNAME 180
17793
17794         local b_status=$(barrier_stat)
17795         [ "$b_status" = "'frozen'" ] ||
17796                 error "(6) unexpected barrier status $b_status"
17797
17798         mkdir $DIR/$tdir/d0/d10 &
17799         mkdir_pid=$!
17800
17801         touch $DIR/$tdir/d1/f13 &
17802         touch_pid=$!
17803
17804         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
17805         ln_pid=$!
17806
17807         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
17808         mv_pid=$!
17809
17810         rm -f $DIR/$tdir/d4/f12 &
17811         rm_pid=$!
17812
17813         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
17814
17815         # To guarantee taht the 'stat' is not blocked
17816         b_status=$(barrier_stat)
17817         [ "$b_status" = "'frozen'" ] ||
17818                 error "(8) unexpected barrier status $b_status"
17819
17820         # let above commands to run at background
17821         sleep 5
17822
17823         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
17824         ps -p $touch_pid || error "(10) touch should be blocked"
17825         ps -p $ln_pid || error "(11) link should be blocked"
17826         ps -p $mv_pid || error "(12) rename should be blocked"
17827         ps -p $rm_pid || error "(13) unlink should be blocked"
17828
17829         b_status=$(barrier_stat)
17830         [ "$b_status" = "'frozen'" ] ||
17831                 error "(14) unexpected barrier status $b_status"
17832
17833         do_facet mgs $LCTL barrier_thaw $FSNAME
17834         b_status=$(barrier_stat)
17835         [ "$b_status" = "'thawed'" ] ||
17836                 error "(15) unexpected barrier status $b_status"
17837
17838         wait $mkdir_pid || error "(16) mkdir should succeed"
17839         wait $touch_pid || error "(17) touch should succeed"
17840         wait $ln_pid || error "(18) link should succeed"
17841         wait $mv_pid || error "(19) rename should succeed"
17842         wait $rm_pid || error "(20) unlink should succeed"
17843
17844         post_801
17845 }
17846 run_test 801b "modification will be blocked by write barrier"
17847
17848 test_801c() {
17849         [[ $MDSCOUNT -lt 2 ]] && skip "needs >= 2 MDTs" && return
17850
17851         prep_801
17852
17853         stop mds2 || error "(1) Fail to stop mds2"
17854
17855         do_facet mgs $LCTL barrier_freeze $FSNAME 30
17856
17857         local b_status=$(barrier_stat)
17858         [ "$b_status" = "'expired'" -o "$b_status" = "'failed'" ] || {
17859                 do_facet mgs $LCTL barrier_thaw $FSNAME
17860                 error "(2) unexpected barrier status $b_status"
17861         }
17862
17863         do_facet mgs $LCTL barrier_rescan $FSNAME ||
17864                 error "(3) Fail to rescan barrier bitmap"
17865
17866         do_facet mgs $LCTL barrier_freeze $FSNAME 10
17867
17868         b_status=$(barrier_stat)
17869         [ "$b_status" = "'frozen'" ] ||
17870                 error "(4) unexpected barrier status $b_status"
17871
17872         do_facet mgs $LCTL barrier_thaw $FSNAME
17873         b_status=$(barrier_stat)
17874         [ "$b_status" = "'thawed'" ] ||
17875                 error "(5) unexpected barrier status $b_status"
17876
17877         local devname=$(mdsdevname 2)
17878
17879         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
17880
17881         do_facet mgs $LCTL barrier_rescan $FSNAME ||
17882                 error "(7) Fail to rescan barrier bitmap"
17883
17884         post_801
17885 }
17886 run_test 801c "rescan barrier bitmap"
17887
17888 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
17889 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
17890 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
17891
17892 cleanup_802() {
17893         trap 0
17894
17895         stopall
17896         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
17897         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
17898         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
17899         setupall
17900 }
17901
17902 test_802() {
17903
17904         [[ $(lustre_version_code mds1) -lt $(version_code 2.9.55) ]] ||
17905         [[ $(lustre_version_code ost1) -lt $(version_code 2.9.55) ]] &&
17906                 skip "Need server version at least 2.9.55" & exit 0
17907
17908         mkdir $DIR/$tdir || error "(1) fail to mkdir"
17909
17910         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
17911                 error "(2) Fail to copy"
17912
17913         trap cleanup_802 EXIT
17914
17915         # sync by force before remount as readonly
17916         sync; sync_all_data; sleep 3; sync_all_data
17917
17918         stopall
17919
17920         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
17921         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
17922         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
17923
17924         echo "Mount the server as read only"
17925         setupall server_only || error "(3) Fail to start servers"
17926
17927         echo "Mount client without ro should fail"
17928         mount_client $MOUNT &&
17929                 error "(4) Mount client without 'ro' should fail"
17930
17931         echo "Mount client with ro should succeed"
17932         mount_client $MOUNT ro ||
17933                 error "(5) Mount client with 'ro' should succeed"
17934
17935         echo "Modify should be refused"
17936         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
17937
17938         echo "Read should be allowed"
17939         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
17940                 error "(7) Read should succeed under ro mode"
17941
17942         cleanup_802
17943 }
17944 run_test 802 "simulate readonly device"
17945
17946 test_803() {
17947         [[ $MDSCOUNT -lt 2 ]] && skip "needs >= 2 MDTs" && return
17948         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.10.54) ] &&
17949                 skip "MDS needs to be newer than 2.10.54" && return
17950
17951         mkdir -p $DIR/$tdir
17952         # Create some objects on all MDTs to trigger related logs objects
17953         for idx in $(seq $MDSCOUNT); do
17954                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
17955                         $DIR/$tdir/dir${idx} ||
17956                         error "Fail to create $DIR/$tdir/dir${idx}"
17957         done
17958
17959         sync; sleep 5
17960         echo "before create:"
17961         $LFS df -i $MOUNT
17962         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
17963
17964         for ((i=0; i<10; i++)); do
17965                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
17966                         error "Fail to create $DIR/$tdir/foo$i"
17967         done
17968
17969         sync; sleep 5
17970         echo "after create:"
17971         $LFS df -i $MOUNT
17972         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
17973
17974         [ $after_used -ge $((before_used + 10)) ] ||
17975                 error "before ($before_used) + 10 > after ($after_used)"
17976
17977         for ((i=0; i<10; i++)); do
17978                 rm -rf $DIR/$tdir/foo$i ||
17979                         error "Fail to remove $DIR/$tdir/foo$i"
17980         done
17981
17982         wait_delete_completed
17983         echo "after unlink:"
17984         $LFS df -i $MOUNT
17985         before_used=$after_used
17986         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
17987
17988         [ $after_used -le $((before_used - 8)) ] ||
17989                 error "before ($before_used) - 8 < after ($after_used)"
17990 }
17991 run_test 803 "verify agent object for remote object"
17992
17993 test_804() {
17994         [[ $MDSCOUNT -lt 2 ]] && skip "needs >= 2 MDTs" && return
17995         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.10.54) ] &&
17996                 skip "MDS needs to be newer than 2.10.54" && return
17997
17998         [ "$(facet_fstype $SINGLEMDS)" != "ldiskfs" ] &&
17999                 skip "ldiskfs only test" && return 0
18000
18001         mkdir -p $DIR/$tdir
18002         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
18003                 error "Fail to create $DIR/$tdir/dir0"
18004
18005         local fid=$($LFS path2fid $DIR/$tdir/dir0)
18006         local dev=$(mdsdevname 2)
18007
18008         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
18009                 grep ${fid} || error "NOT found agent entry for dir0"
18010
18011         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
18012                 error "Fail to create $DIR/$tdir/dir1"
18013
18014         touch $DIR/$tdir/dir1/foo0 ||
18015                 error "Fail to create $DIR/$tdir/dir1/foo0"
18016         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
18017         local rc=0
18018
18019         for idx in $(seq $MDSCOUNT); do
18020                 dev=$(mdsdevname $idx)
18021                 do_facet mds${idx} \
18022                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
18023                         grep ${fid} && rc=$idx
18024         done
18025
18026         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
18027                 error "Fail to rename foo0 to foo1"
18028         if [ $rc -eq 0 ]; then
18029                 for idx in $(seq $MDSCOUNT); do
18030                         dev=$(mdsdevname $idx)
18031                         do_facet mds${idx} \
18032                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
18033                         grep ${fid} && rc=$idx
18034                 done
18035         fi
18036
18037         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
18038                 error "Fail to rename foo1 to foo2"
18039         if [ $rc -eq 0 ]; then
18040                 for idx in $(seq $MDSCOUNT); do
18041                         dev=$(mdsdevname $idx)
18042                         do_facet mds${idx} \
18043                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
18044                         grep ${fid} && rc=$idx
18045                 done
18046         fi
18047
18048         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
18049
18050         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
18051                 error "Fail to link to $DIR/$tdir/dir1/foo2"
18052         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
18053                 error "Fail to rename foo2 to foo0"
18054         unlink $DIR/$tdir/dir1/foo0 ||
18055                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
18056         rm -rf $DIR/$tdir/dir0 ||
18057                 error "Fail to rm $DIR/$tdir/dir0"
18058
18059         for idx in $(seq $MDSCOUNT); do
18060                 dev=$(mdsdevname $idx)
18061                 rc=0
18062
18063                 stop mds${idx}
18064                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
18065                         rc=$?
18066                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
18067                         error "mount mds$idx failed"
18068                 df $MOUNT > /dev/null 2>&1
18069
18070                 # e2fsck should not return error
18071                 [ $rc -eq 0 ] ||
18072                         error "e2fsck detected error on MDT${idx}: rc=$rc"
18073         done
18074 }
18075 run_test 804 "verify agent entry for remote entry"
18076
18077 #
18078 # tests that do cleanup/setup should be run at the end
18079 #
18080
18081 test_900() {
18082         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
18083         local ls
18084         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
18085         $LCTL set_param fail_loc=0x903
18086
18087         cancel_lru_locks MGC
18088
18089         FAIL_ON_ERROR=true cleanup
18090         FAIL_ON_ERROR=true setup
18091 }
18092 run_test 900 "umount should not race with any mgc requeue thread"
18093
18094 complete $SECONDS
18095 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
18096 check_and_cleanup_lustre
18097 if [ "$I_MOUNTED" != "yes" ]; then
18098         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
18099 fi
18100 exit_status