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