Whamcloud - gitweb
LU-17038 tests: remove mlink utility
[fs/lustre-release.git] / lustre / tests / lustre-rsync-test.sh
1 #!/bin/bash
2 #
3 # Run select tests by setting ONLY, or as arguments to the script.
4 # Skip specific tests by setting EXCEPT.
5 #
6 set -e
7
8 ONLY=${ONLY:-"$*"}
9
10 KILL=/bin/kill
11 LREPL_LOG=$TMP/lustre_rsync.log
12 ORIG_PWD=${PWD}
13
14 LUSTRE=${LUSTRE:-$(dirname $0)/..}
15 . $LUSTRE/tests/test-framework.sh
16 init_test_env "$@"
17 init_logging
18
19 ALWAYS_EXCEPT="$LRSYNC_EXCEPT "
20 # bug number for skipped test: LU-4256
21 ALWAYS_EXCEPT+="               2b"
22 # UPDATE THE COMMENT ABOVE WITH BUG NUMBERS WHEN CHANGING ALWAYS_EXCEPT!
23
24 build_test_filter
25
26 [ -n "$FILESET" ] && skip "Not functional for FILESET set"
27
28 check_and_setup_lustre
29
30 DIR=${DIR:-$MOUNT}
31 assert_DIR
32
33 if getent group nobody; then
34         GROUP=nobody
35 elif getent group nogroup; then
36         GROUP=nogroup
37 else
38         error "No generic nobody group"
39 fi
40
41 export LRSYNC=${LRSYNC:-"$LUSTRE/utils/lustre_rsync"}
42 [ ! -f "$LRSYNC" ] && export LRSYNC=$(which lustre_rsync)
43 export LRSYNC="$LRSYNC -v -c no -d 2"
44
45 # Number of seconds to run dbench
46 DBENCH_TIME=${DBENCH_TIME:-60}
47 TGT=$TMP/target
48 TGT2=$TMP/target2
49 MDT0=$($LCTL get_param -n mdc.*.mds_server_uuid |
50         awk '{ gsub(/_UUID/,""); print $1 }' | head -n1)
51
52 init_changelog() {
53         changelog_register || error "changelog_register failed"
54         CL_USER=(${CL_USERS[$SINGLEMDS]})
55         echo $MDT0: Registered changelog user $CL_USER
56         [ -z $CL_USER ] &&
57                 echo "No changelog users present on $SINGLEMDS"
58 }
59
60 fini_changelog() {
61         changelog_clear
62         changelog_deregister
63 }
64
65 init_src() {
66         rm -rf $TGT/$tdir $TGT/d*.lustre_rsync-test 2> /dev/null
67         rm -rf $TGT2/$tdir $TGT2/d*.lustre_rsync-test 2> /dev/null
68         rm -rf ${DIR}/$tdir $DIR/d*.lustre_rsync-test ${DIR}/tgt 2> /dev/null
69         rm -f $LREPL_LOG
70
71         mkdir_on_mdt0 $DIR/$tdir || error "Failed to create target: " $DIR/$tdir
72         mkdir -p ${TGT}/$tdir || error "Failed to create target: " $TGT/$tdir
73         mkdir -p ${TGT2}/$tdir || error "Failed to create target: " $TGT2/$tdir
74 }
75
76 cleanup_src_tgt() {
77         rm -rf $TGT/$tdir
78         rm -rf $DIR/$tdir
79         rm -rf $DIR/tgt
80 }
81
82 # Check whether the filesystem supports xattr or not.
83 # Return value:
84 # "large" - large xattr is supported
85 # "small" - large xattr is unsupported but small xattr is supported
86 # "no"    - xattr is unsupported
87 check_xattr() {
88         local tgt=$1
89         local xattr="no"
90
91         touch $tgt
92
93         local val="$(generate_string $(max_xattr_size))"
94
95         if large_xattr_enabled &&
96                 setfattr -n user.foo -v $val $tgt 2>/dev/null; then
97                 xattr="large"
98         else
99                 setfattr -n user.foo -v bar $tgt 2>/dev/null && xattr="small"
100         fi
101
102         rm -f $tgt
103         echo $xattr
104 }
105
106 check_diff() {
107         local changelog_file=$(generate_logname "changelog")
108
109         if [ -e $1 -o -e $2 ]; then
110                 diff -rq -x "dev1" $1 $2
111                 local RC=$?
112                 if [ $RC -ne 0 ]; then
113                         $LFS changelog $MDT0 > $changelog_file
114                         error "Failure in replication; differences found."
115                 fi
116         fi
117 }
118
119 procs_are_stopped() {
120         local pids="$*"
121         local state
122
123         for state in $(ps -p "$pids" -o state=); do
124                 if [[ "$state" != T ]]; then
125                         return 1
126                 fi
127         done
128
129         return 0
130 }
131
132 # Send SIGSTOP to PIDs and wait up to 60 seconds for them to show a
133 # stopped process state.
134 stop_procs() {
135         local pids="$*"
136         local end
137
138         $KILL -SIGSTOP $pids
139         end=$((SECONDS + 60))
140         while ((SECONDS < end)); do
141                 if procs_are_stopped $pids; then
142                         return 0
143                 fi
144
145                 sleep 1
146         done
147
148         return 1
149 }
150
151 # Test 1A - test basic operations
152 test_1A() { # was test_1
153         init_src
154         init_changelog
155         local xattr=$(check_xattr $TGT/foo)
156
157         # Directory create
158         mkdir $DIR/$tdir/d1
159         mkdir $DIR/$tdir/d2
160
161         # File create
162         touch $DIR/$tdir/file1
163         cp /etc/hosts  $DIR/$tdir/d1/
164         touch $DIR/$tdir/d1/"space in filename"
165         touch $DIR/$tdir/d1/file2
166
167         # File rename
168         mv $DIR/$tdir/d1/file2 $DIR/$tdir/d2/file3
169
170         # File and directory delete
171         touch $DIR/$tdir/d1/file4
172         mkdir $DIR/$tdir/d1/del
173         touch $DIR/$tdir/d1/del/del1
174         touch $DIR/$tdir/d1/del/del2
175         rm -rf $DIR/$tdir/d1/del
176         rm $DIR/$tdir/d1/file4
177
178         # Hard and soft links
179         cat /etc/hosts > $DIR/$tdir/d1/link1
180         ln $DIR/$tdir/d1/link1  $DIR/$tdir/d1/link2
181         ln -s $DIR/$tdir/d1/link1  $DIR/$tdir/d1/link3
182
183         # Device files
184         #mknod $DIR/$tdir/dev1 b 8 1
185
186         # Replicate
187         local LRSYNC_LOG=$(generate_logname "lrsync_log")
188         echo "Replication #1"
189         $LRSYNC -s $DIR -t $TGT -t $TGT2 -m $MDT0 -u $CL_USER -l $LREPL_LOG \
190                 -D $LRSYNC_LOG
191
192         # Set attributes
193         chmod 000 $DIR/$tdir/d2/file3
194         chown nobody:$GROUP $DIR/$tdir/d2/file3
195
196         # Set xattrs
197         if [[ "$xattr" != "no" ]]; then
198                 local value
199                 touch $DIR/$tdir/file5
200                 [[ "$xattr" = "large" ]] &&
201                         value="$(generate_string $(max_xattr_size))" || value="bar"
202                 setfattr -n user.foo -v $value $DIR/$tdir/file5 ||
203                         error "setfattr failed"
204         fi
205
206         echo "Replication #2"
207         $LRSYNC -l $LREPL_LOG -D $LRSYNC_LOG
208
209         if [[ "$xattr" != "no" ]]; then
210                 local xval1=$(get_xattr_value user.foo $TGT/$tdir/file5)
211                 local xval2=$(get_xattr_value user.foo $TGT2/$tdir/file5)
212
213                 if [[ "$xval1" != "$value" || "$xval2" != "$value" ]]; then
214                         error "Error in replicating xattrs."
215                 fi
216         fi
217
218         # Use diff to compare the source and the destination
219         check_diff $DIR/$tdir $TGT/$tdir
220         check_diff $DIR/$tdir $TGT2/$tdir
221
222         fini_changelog
223         cleanup_src_tgt
224 }
225 run_test 1A "Simple Replication"
226
227 # Test 1a - test create/delete operations in ROOT directory
228 test_1a() { # LU-5005
229         rm -rf $TGT/root-* 2> /dev/null
230         rm -rf $DIR/root-* 2> /dev/null
231         init_src
232         init_changelog
233
234         # Directory create
235         mkdir_on_mdt0 $DIR/root-dir
236
237         # File create
238         touch $DIR/root-file
239         touch $DIR/root-file2
240
241         # File rename
242         mv $DIR/root-file2 $DIR/root-file3
243
244         # File and directory delete
245         touch $DIR/root-file4
246         mkdir_on_mdt0 $DIR/root-dir1
247         rm $DIR/root-file4
248         rm -rf $DIR/root-dir1
249
250         # Replicate
251         local LRSYNC_LOG=$(generate_logname "lrsync_log")
252         echo "Replication"
253         $LRSYNC -s $DIR -t $TGT -m $MDT0 -u $CL_USER -l $LREPL_LOG \
254                 -D $LRSYNC_LOG
255
256         # Verify
257         stat $TGT/root-dir || error "Dir create not replicated"
258         stat $TGT/root-file || error "File create not replicated"
259         stat $TGT/root-file2 && error "Rename not replicated (src)"
260         stat $TGT/root-file3 || error "Rename not replicated (tgt)"
261         stat $TGT/root-dir1 && error "Dir delete not replicated"
262         stat $TGT/root-file4 && error "File delete not replicated"
263
264         cleanup_src_tgt
265         fini_changelog
266         rm -fr $TGT/root-*
267         rm -fr $DIR/root-*
268         return 0
269 }
270 run_test 1a "Replicate create/delete operations in ROOT directory"
271
272 # Test 2a - Replicate files created by dbench
273 test_2a() {
274         init_src
275         init_changelog
276
277         # Run dbench
278         bash rundbench -C -D $DIR/$tdir 2 -t $DBENCH_TIME ||
279                 error "dbench failed"
280
281         local LRSYNC_LOG=$(generate_logname "lrsync_log")
282         # Replicate the changes to $TGT
283         $LRSYNC -s $DIR -t $TGT -t $TGT2 -m $MDT0 -u $CL_USER -l $LREPL_LOG \
284                 -D $LRSYNC_LOG
285
286         # Use diff to compare the source and the destination
287         check_diff $DIR/$tdir $TGT/$tdir
288         check_diff $DIR/$tdir $TGT2/$tdir
289
290         fini_changelog
291         cleanup_src_tgt
292         return 0
293 }
294 run_test 2a "Replicate files created by dbench."
295
296 # Test 2b - Replicate files changed by dbench.
297 test_2b() {
298         local child_pid
299         init_src
300         init_changelog
301
302         # Run dbench
303         bash rundbench -C -D $DIR/$tdir 2 -t $DBENCH_TIME &
304         # wait for dbench to start
305         wait_for_function 'child_pid=$(pgrep dbench)' 360
306         # let dbench run for a bit
307         sleep 10
308
309         echo PIDs: $child_pid
310         echo Stopping dbench
311         stop_procs $child_pid
312
313         local LRSYNC_LOG=$(generate_logname "lrsync_log")
314         echo Starting replication
315         $LRSYNC -s $DIR -t $TGT -t $TGT2 -m $MDT0 -u $CL_USER -l $LREPL_LOG \
316                 -D $LRSYNC_LOG
317         check_diff $DIR/$tdir $TGT/$tdir
318
319     echo Resuming dbench
320     $KILL -SIGCONT $child_pid
321     sleep 10
322
323     echo Stopping dbench
324         stop_procs $child_pid
325
326         echo Starting replication
327         $LRSYNC -l $LREPL_LOG -D $LRSYNC_LOG
328         check_diff $DIR/$tdir $TGT/$tdir
329
330     echo "Wait for dbench to finish"
331     $KILL -SIGCONT $child_pid
332     wait
333
334         # Replicate the changes to $TGT
335         echo Starting replication
336         $LRSYNC -l $LREPL_LOG -D $LRSYNC_LOG
337
338         check_diff $DIR/$tdir $TGT/$tdir
339         check_diff $DIR/$tdir $TGT2/$tdir
340
341     fini_changelog
342     cleanup_src_tgt
343     return 0
344 }
345 run_test 2b "Replicate files changed by dbench."
346
347 # Test 2c - Replicate files while dbench is running
348 test_2c() {
349         init_src
350         init_changelog
351
352         # Run dbench
353         bash rundbench -C -D $DIR/$tdir 2 -t $DBENCH_TIME &
354
355         local LRSYNC_LOG=$(generate_logname "lrsync_log")
356         # Replicate the changes to $TGT
357         sleep 10 # give dbench a headstart
358         local quit=0
359         while [ $quit -le 1 ];
360         do
361                 echo "Running lustre_rsync"
362                 $LRSYNC -s $DIR -t $TGT -t $TGT2 -m ${mds1_svc} -u $CL_USER \
363                         -l $LREPL_LOG -D $LRSYNC_LOG
364                 sleep 5
365                 pgrep dbench
366                 if [ $? -ne 0 ]; then
367                         quit=$(expr $quit + 1)
368                 fi
369         done
370
371         # Use diff to compare the source and the destination
372         check_diff $DIR/$tdir $TGT/$tdir
373         check_diff $DIR/$tdir $TGT2/$tdir
374
375         fini_changelog
376         cleanup_src_tgt
377         return 0
378 }
379 run_test 2c "Replicate files while dbench is running."
380
381 # Test 3a - Replicate files created by createmany
382 test_3a() {
383         init_src
384         init_changelog
385
386         local numfiles=1000
387         createmany -o $DIR/$tdir/$tfile $numfiles || error "createmany failed"
388
389         local LRSYNC_LOG=$(generate_logname "lrsync_log")
390         # Replicate the changes to $TGT
391         $LRSYNC -s $DIR -t $TGT -t $TGT2 -m $MDT0 -u $CL_USER -l $LREPL_LOG \
392                 -D $LRSYNC_LOG
393         check_diff $DIR/$tdir $TGT/$tdir
394         check_diff $DIR/$tdir $TGT2/$tdir
395
396         fini_changelog
397         cleanup_src_tgt
398         return 0
399 }
400 run_test 3a "Replicate files created by createmany"
401
402 # Test 3b - Replicate files created by writemany
403 test_3b() {
404         init_src
405         init_changelog
406
407         local time=60
408         local threads=5
409         writemany -q -a $DIR/$tdir/$tfile $time $threads ||
410                 error "writemany failed"
411
412         local LRSYNC_LOG=$(generate_logname "lrsync_log")
413         # Replicate the changes to $TGT
414         $LRSYNC -s $DIR -t $TGT -t $TGT2 -m $MDT0 -u $CL_USER -l $LREPL_LOG \
415                 -D $LRSYNC_LOG
416
417         check_diff $DIR/$tdir $TGT/$tdir
418         check_diff $DIR/$tdir $TGT2/$tdir
419
420         fini_changelog
421         cleanup_src_tgt
422         return 0
423 }
424 run_test 3b "Replicate files created by writemany"
425
426 # Test 3c - Replicate files created by createmany/unlinkmany
427 test_3c() {
428         init_src
429         init_changelog
430
431         local numfiles=1000
432         createmany -o $DIR/$tdir/$tfile $numfiles || error "createmany failed"
433         unlinkmany $DIR/$tdir/$tfile $numfiles || error "unlinkmany failed"
434
435         local LRSYNC_LOG=$(generate_logname "lrsync_log")
436         # Replicate the changes to $TGT
437         $LRSYNC -s $DIR -t $TGT -t $TGT2 -m $MDT0  -u $CL_USER -l $LREPL_LOG \
438                 -D $LRSYNC_LOG
439         check_diff $DIR/$tdir $TGT/$tdir
440         check_diff $DIR/$tdir $TGT2/$tdir
441
442         fini_changelog
443         cleanup_src_tgt
444         return 0
445 }
446 run_test 3c "Replicate files created by createmany/unlinkmany"
447
448 # Test 4 - Replicate files created by iozone
449 test_4() {
450         which iozone > /dev/null 2>&1
451         [ $? -ne 0 ] && skip "iozone not found"
452
453         init_src
454         init_changelog
455
456         END_RUN_FILE=${DIR}/$tdir/run LOAD_PID_FILE=${DIR}/$tdir/pid \
457                 MOUNT=${DIR}/$tdir run_iozone.sh &
458         sleep 30
459         child_pid=$(pgrep iozone)
460         stop_procs $child_pid
461
462         local LRSYNC_LOG=$(generate_logname "lrsync_log")
463         # Replicate the changes to $TGT
464         $LRSYNC -s $DIR -t $TGT -t $TGT2 -m $MDT0  -u $CL_USER -l $LREPL_LOG \
465                 -D $LRSYNC_LOG
466         check_diff $DIR/$tdir $TGT/$tdir
467         check_diff $DIR/$tdir $TGT2/$tdir
468
469     $KILL -SIGCONT $child_pid
470     sleep 60
471     $KILL -SIGKILL $(pgrep run_iozone.sh)
472     $KILL -SIGKILL $(pgrep iozone)
473
474     # After killing 'run_iozone.sh', process 'iozone' becomes the
475     # child of PID 1. Hence 'wait' does not wait for it. Killing
476     # iozone first, means more iozone processes are spawned off which
477     # is not desirable. So, after sending a sigkill, the test goes
478     # into a wait loop for iozone to cleanup and exit.
479     wait
480     while [ "$(pgrep "iozone")" != "" ];
481     do
482       ps -ef | grep iozone | grep -v grep
483       sleep 1;
484     done
485
486         $LRSYNC -l $LREPL_LOG -D $LRSYNC_LOG
487         check_diff $DIR/$tdir $TGT/$tdir
488         check_diff $DIR/$tdir $TGT2/$tdir
489
490     fini_changelog
491     cleanup_src_tgt
492     return 0
493 }
494 run_test 4 "Replicate files created by iozone"
495
496 # Test 5a - Stop / start lustre_rsync
497 test_5a() {
498         init_src
499         init_changelog
500
501         NUMTEST=2000
502         createmany -o $DIR/$tdir/$tfile $NUMTEST
503
504         # Replicate the changes to $TGT
505         local LRSYNC_LOG=$(generate_logname "lrsync_log")
506         $LRSYNC -s $DIR -t $TGT -t $TGT2 -m $MDT0 -u $CL_USER -l $LREPL_LOG \
507                 -D $LRSYNC_LOG &
508         local child_pid=$!
509         sleep 30
510         $KILL -SIGHUP $child_pid
511         wait
512         $LRSYNC -l $LREPL_LOG -D $LRSYNC_LOG
513
514         check_diff $DIR/$tdir $TGT/$tdir
515         check_diff $DIR/$tdir $TGT2/$tdir
516
517         fini_changelog
518         cleanup_src_tgt
519         return 0
520 }
521 run_test 5a "Stop / start lustre_rsync"
522
523 # Test 5b - Kill / restart lustre_rsync
524 test_5b() {
525         init_src
526         init_changelog
527
528         NUMTEST=2000
529         createmany -o $DIR/$tdir/$tfile $NUMTEST
530
531         # Replicate the changes to $TGT
532         local LRSYNC_LOG=$(generate_logname "lrsync_log")
533         $LRSYNC -s $DIR -t $TGT -t $TGT2 -m $MDT0 -u $CL_USER -l $LREPL_LOG \
534                 -D $LRSYNC_LOG &
535         local child_pid=$!
536         sleep 30
537         $KILL -SIGKILL $child_pid
538         wait
539         $LRSYNC -l $LREPL_LOG -D $LRSYNC_LOG
540
541         check_diff $DIR/$tdir $TGT/$tdir
542         check_diff $DIR/$tdir $TGT2/$tdir
543
544         fini_changelog
545         cleanup_src_tgt
546         return 0
547 }
548 run_test 5b "Kill / restart lustre_rsync"
549
550 # Test 6 - lustre_rsync large no of hard links
551 test_6() {
552         init_src
553         init_changelog
554
555         local num_links=128
556         local i
557
558         touch $DIR/$tdir/link0
559         for ((i = 1; i < num_links - 1; i++)); do
560                 ln $DIR/$tdir/link0 $DIR/$tdir/link$i
561         done
562         # create an extra hard link of src name ending with dest name
563         ln $DIR/$tdir/link0 $DIR/$tdir/ink0
564
565         local LRSYNC_LOG=$(generate_logname "lrsync_log")
566         # Replicate the changes to $TGT
567         $LRSYNC -s $DIR -t $TGT -t $TGT2 -m $MDT0 -u $CL_USER -l $LREPL_LOG \
568                 -D $LRSYNC_LOG
569         check_diff $DIR/$tdir $TGT/$tdir
570         check_diff $DIR/$tdir $TGT2/$tdir
571
572         local count1=$(stat --format=%h $TGT/$tdir/link0)
573         local count2=$(stat --format=%h $TGT2/$tdir/link0)
574         if ((count1 != num_links || count2 != num_links)); then
575                 ls -l $TGT/$tdir/link0 $TGT2/$tdir/link0
576                 error "Incorrect no of hard links found $count1, $count2"
577         fi
578
579         fini_changelog
580         cleanup_src_tgt
581         return 0
582 }
583 run_test 6 "lustre_rsync large no of hard links"
584
585 # Test 7 - lustre_rsync stripesize
586 test_7() {
587         local numfiles=100
588
589         init_src
590         mkdir -p ${DIR}/tgt/$tdir
591         init_changelog
592
593         $LFS setstripe -c $OSTCOUNT $DIR/$tdir ||
594                 error "$LFS setstripe failed"
595         createmany -o $DIR/$tdir/$tfile $numfiles
596
597         # To simulate replication to another lustre filesystem, replicate
598         # the changes to $DIR/tgt. We can't turn off the changelogs
599         # while we are registered, so lustre_rsync better not try to
600         # replicate the replication steps.  It seems ok :)
601
602         local LRSYNC_LOG=$(generate_logname "lrsync_log")
603         $LRSYNC -s $DIR -t $DIR/tgt -m $MDT0 -u $CL_USER -l $LREPL_LOG \
604                 -D $LRSYNC_LOG
605         check_diff ${DIR}/$tdir $DIR/tgt/$tdir
606
607         local i=0
608         while [ $i -lt $numfiles ];
609         do
610                 local count=$($LFS getstripe $DIR/tgt/$tdir/${tfile}$i |
611                               awk '/stripe_count/ {print $2}')
612                 if [ $count -ne $OSTCOUNT ]; then
613                         error "Stripe size not replicated"
614                 fi
615                 i=$(expr $i + 1)
616         done
617         fini_changelog
618         cleanup_src_tgt
619         return 0
620 }
621 run_test 7 "lustre_rsync stripesize"
622
623 # Test 8 - Replicate multiple file/directory moves
624 test_8() {
625     init_src
626     init_changelog
627
628     for i in 1 2 3 4 5 6 7 8 9; do
629         mkdir $DIR/$tdir/d$i
630             for j in 1 2 3 4 5 6 7 8 9; do
631                 mkdir $DIR/$tdir/d$i/d$i$j
632                 createmany -o $DIR/$tdir/d$i/d$i$j/a 10 \
633                     > /dev/null
634                 mv $DIR/$tdir/d$i/d$i$j $DIR/$tdir/d$i/d0$i$j
635                 createmany -o $DIR/$tdir/d$i/d0$i$j/b 10 \
636                     > /dev/null
637                 mv $DIR/$tdir/d$i/d0$i$j/a0 $DIR/$tdir/d$i/d0$i$j/c0
638             done
639             mv $DIR/$tdir/d$i $DIR/$tdir/d0$i
640     done
641
642         local LRSYNC_LOG=$(generate_logname "lrsync_log")
643         $LRSYNC -s $DIR -t $TGT -m $MDT0 -u $CL_USER -l $LREPL_LOG \
644                 -D $LRSYNC_LOG
645
646         check_diff ${DIR}/$tdir $TGT/$tdir
647
648     fini_changelog
649     cleanup_src_tgt
650     return 0
651 }
652 run_test 8 "Replicate multiple file/directory moves"
653
654 test_9() {
655     init_src
656     init_changelog
657
658     mkdir $DIR/$tdir/foo
659     touch $DIR/$tdir/foo/a1
660
661         local LRSYNC_LOG=$(generate_logname "lrsync_log")
662         $LRSYNC -s $DIR -t $TGT -m $MDT0 -u $CL_USER -l $LREPL_LOG \
663                 -D $LRSYNC_LOG
664
665         check_diff ${DIR}/$tdir $TGT/$tdir
666
667         rm -rf $DIR/$tdir/foo
668
669         $LRSYNC -s $DIR -t $TGT -m $MDT0 -u $CL_USER -l $LREPL_LOG \
670                 -D $LRSYNC_LOG
671
672         check_diff ${DIR}/$tdir $TGT/$tdir
673
674     fini_changelog
675     cleanup_src_tgt
676     return 0
677 }
678 run_test 9 "Replicate recursive directory removal"
679
680 cd $ORIG_PWD
681 complete_test $SECONDS
682 check_and_cleanup_lustre
683 exit_status