Whamcloud - gitweb
b=16855
[fs/lustre-release.git] / lustre / tests / lreplicate-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 # Run test by setting NOSETUP=true when ltest has setup env for us
7 set -e
8
9 SRCDIR=`dirname $0`
10 export PATH=$PWD/$SRCDIR:$SRCDIR:$PWD/$SRCDIR/../utils:$PATH:/sbin
11
12 ONLY=${ONLY:-"$*"}
13 ALWAYS_EXCEPT="$LREPLICATE_EXCEPT"
14 # bug number for skipped test: -
15 # UPDATE THE COMMENT ABOVE WITH BUG NUMBERS WHEN CHANGING ALWAYS_EXCEPT!
16
17 [ "$ALWAYS_EXCEPT$EXCEPT" ] && \
18         echo "Skipping tests: `echo $ALWAYS_EXCEPT $EXCEPT`"
19
20 KILL=/bin/kill
21
22 TMP=${TMP:-/tmp}
23 LREPL_LOG=$TMP/lreplicate.log
24 ORIG_PWD=${PWD}
25
26 LUSTRE=${LUSTRE:-$(cd $(dirname $0)/..; echo $PWD)}
27 . $LUSTRE/tests/test-framework.sh
28 init_test_env $@
29 . ${CONFIG:=$LUSTRE/tests/cfg/$NAME.sh}
30
31
32 REPLLOG=${TESTSUITELOG:-$TMP/$(basename $0 .sh).log}
33
34 [ "$REPLLOG" ] && rm -f $REPLLOG || true
35
36 check_and_setup_lustre
37
38 DIR=${DIR:-$MOUNT}
39 assert_DIR
40
41
42 build_test_filter
43
44 export LREPLICATE=${LREPLICATE:-"$LUSTRE/utils/lreplicate"}
45 [ ! -f "$LREPLICATE" ] && export LREPLICATE=$(which lreplicate)
46
47 # control the time of tests
48 DBENCH_TIME=${DBENCH_TIME:-60}  # No of seconds to run dbench
49 TGT=/tmp/target
50 TGT2=/tmp/target2
51 MDT0=$($LCTL get_param -n mdc.*.mds_server_uuid | \
52     awk '{gsub(/_UUID/,""); print $1}' | head -1)
53
54 init_changelog() {
55     CL_USER=$(do_facet $SINGLEMDS lctl --device $MDT0 changelog_register -n)
56     echo $MDT0: Registered changelog user $CL_USER
57     CL_USERS=$(( $(do_facet $SINGLEMDS lctl get_param -n \
58         mdd.$MDT0.changelog_users | wc -l) - 2 ))
59     [ $CL_USERS -ne 1 ] && \
60         echo "Other changelog users present ($CL_USERS)"
61 }
62
63 init_src() {
64     rm -rf $TGT/$tdir $TGT/d*.lreplicate-test 2> /dev/null
65     rm -rf $TGT2/$tdir $TGT2/d*.lreplicate-test 2> /dev/null
66     rm -rf ${DIR}/$tdir $DIR/d*.lreplicate-test ${DIR}/tgt 2> /dev/null
67     rm -f $LREPL_LOG
68     mkdir -p $TGT
69     mkdir -p $TGT2
70     if [ $? -ne 0 ]; then
71         error "Failed to create target: " $TGT
72     fi
73 }
74
75 cleanup_src_tgt() {
76     rm -rf $TGT/$tdir
77     rm -rf $DIR/$tdir
78     rm -rf $DIR/tgt
79 }
80
81 fini_changelog() {
82     $LFS changelog_clear $MDT0 $CL_USER 0
83     do_facet $SINGLEMDS lctl --device $MDT0 changelog_deregister $CL_USER
84 }
85
86 check_xattr() {
87     local tgt=$1
88     local xattr="yes"
89     touch $tgt
90     setfattr -n user.foo -v 'bar' $tgt 2> /dev/null
91     if [ $? -ne 0 ]; then
92         xattr="no"
93     fi
94     rm -f $tgt
95     echo $xattr
96 }
97
98 check_diff() {
99     if [ -e $1 -o -e $2 ]; then 
100         diff -rq -x "dev1" $1 $2
101         local RC=$?
102         if [ $RC -ne 0 ]; then
103             error "Failure in replication; differences found."
104         fi
105     fi
106 }
107
108 # Test 1 - test basic operations
109 test_1() {
110     init_src
111     init_changelog
112     local xattr=`check_xattr $TGT/foo`
113
114     # Directory create
115     mkdir -p ${DIR}/$tdir
116     mkdir $DIR/$tdir/d1
117     mkdir $DIR/$tdir/d2
118
119     # File create
120     touch $DIR/$tdir/file1
121     cp /etc/hosts  $DIR/$tdir/d1/
122     touch  $DIR/$tdir/d1/"space in filename"
123     touch  $DIR/$tdir/d1/file2
124
125     # File rename
126     mv $DIR/$tdir/d1/file2 $DIR/$tdir/d2/file3
127
128     # File and directory delete
129     touch $DIR/$tdir/d1/file4
130     mkdir $DIR/$tdir/d1/del
131     touch  $DIR/$tdir/d1/del/del1
132     touch  $DIR/$tdir/d1/del/del2
133     rm -rf $DIR/$tdir/d1/del
134     rm $DIR/$tdir/d1/file4
135
136     #hard and soft links
137     cat /etc/hosts > $DIR/$tdir/d1/link1
138     ln  $DIR/$tdir/d1/link1  $DIR/$tdir/d1/link2
139     ln -s $DIR/$tdir/d1/link1  $DIR/$tdir/d1/link3
140
141     # Device files
142     mknod $DIR/$tdir/dev1 b 8 1
143
144     # Replicate
145     echo "Replication #1"
146     $LREPLICATE -s $DIR -t $TGT -t $TGT2 -m $MDT0 -u $CL_USER -l $LREPL_LOG -v
147
148     # Set attributes
149     chmod 000 $DIR/$tdir/d2/file3
150     chown nobody:nobody $DIR/$tdir/d2/file3
151
152     # Set xattrs
153     if [ "$xattr" == "yes" ]; then
154         touch $DIR/$tdir/file5
155         setfattr -n user.foo -v 'bar' $DIR/$tdir/file5
156     fi
157
158     echo "Replication #2"
159     $LREPLICATE -l $LREPL_LOG -v
160
161     if [ "$xattr" == "yes" ]; then
162         local xval1=$(getfattr -n user.foo --absolute-names --only-values \
163             $TGT/$tdir/file5)
164         local xval2=$(getfattr -n user.foo --absolute-names --only-values \
165             $TGT2/$tdir/file5)
166     fi
167
168     RC=0
169     if [[ ! -b $TGT/$tdir/dev1 ]] || [[ ! -b $TGT2/$tdir/dev1 ]]; then
170         ls -l $DIR/$tdir/dev1 $TGT/$tdir/dev1 $TGT2/$tdir/dev1
171         error "Error replicating block devices"
172         RC=1
173     elif [[ "$xattr" == "yes" ]] &&
174        [[ "$xval1" != "bar" || "$xval2" != "bar" ]]; then
175         error "Error in replicating xattrs. $xval1, $xval2"
176         RC=1
177     fi
178
179     # Use diff to compare the source and the destination
180     check_diff $DIR/$tdir $TGT/$tdir
181     check_diff $DIR/$tdir $TGT2/$tdir
182
183     fini_changelog
184     cleanup_src_tgt
185     return $RC
186
187 }
188 run_test 1 "Simple Replication"
189
190 # Test 2a - Replicate files created by dbench 
191 test_2a() {
192     [ "$SLOW" = "no" ] && skip "Skipping slow test" && return
193     init_src
194     init_changelog
195
196     # Run dbench
197     sh rundbench -C -D $DIR/$tdir 2 -t $DBENCH_TIME || error "dbench failed!"
198
199     # Replicate the changes to $TGT
200     $LREPLICATE -s $DIR -t $TGT -t $TGT2 -m $MDT0 -u $CL_USER -l $LREPL_LOG -v
201
202     # Use diff to compare the source and the destination
203     check_diff $DIR/$tdir $TGT/$tdir
204     check_diff $DIR/$tdir $TGT2/$tdir
205
206     fini_changelog
207     cleanup_src_tgt
208     return 0
209 }
210 run_test 2a "Replicate files created by dbench."
211
212
213 # Test 2b - Replicate files changed by dbench.
214 test_2b() {
215     [ "$SLOW" = "no" ] && skip "Skipping slow test" && return
216
217     init_src
218     init_changelog
219
220     # Run dbench
221     sh rundbench -C -D $DIR/$tdir 2 -t $DBENCH_TIME &
222     sleep 20
223
224     local child_pid=$(pgrep dbench)
225     echo PIDs: $child_pid
226     echo Stopping dbench
227     $KILL -SIGSTOP $child_pid
228
229     echo Starting replication
230     $LREPLICATE -s $DIR -t $TGT -t $TGT2 -m $MDT0 -u $CL_USER -l $LREPL_LOG -v
231     check_diff $DIR/$tdir $TGT/$tdir
232
233     echo Resuming dbench
234     $KILL -SIGCONT $child_pid
235     sleep 10
236
237     echo Stopping dbench
238     $KILL -SIGSTOP $child_pid
239
240     echo Starting replication
241     $LREPLICATE -l $LREPL_LOG -v
242     check_diff $DIR/$tdir $TGT/$tdir
243
244     echo "Wait for dbench to finish"
245     $KILL -SIGCONT $child_pid
246     wait
247
248     # Replicate the changes to $TGT
249     echo Starting replication
250     $LREPLICATE -l $LREPL_LOG -v
251
252     check_diff $DIR/$tdir $TGT/$tdir
253     check_diff $DIR/$tdir $TGT2/$tdir
254
255     fini_changelog
256     cleanup_src_tgt
257     return 0
258 }
259 run_test 2b "Replicate files changed by dbench."
260
261 # Test 2c - Replicate files while dbench is running 
262 test_2c() {
263     [ "$SLOW" = "no" ] && skip "Skipping slow test" && return
264     init_src
265     init_changelog
266
267     # Run dbench
268     sh rundbench -C -D $DIR/$tdir 2 -t $DBENCH_TIME &
269
270     # Replicate the changes to $TGT
271     sleep 10 # give dbench a headstart
272     local quit=0
273     while [ $quit -le 1 ];
274     do
275         echo "Running lreplicate"
276         $LREPLICATE -s $DIR -t $TGT -t $TGT2 -m ${mds1_svc} -u $CL_USER -l $LREPL_LOG -v
277         sleep 5
278         pgrep dbench
279         if [ $? -ne 0 ]; then
280             quit=$(expr $quit + 1)
281         fi
282     done
283
284     # Use diff to compare the source and the destination
285     check_diff $DIR/$tdir $TGT/$tdir
286     check_diff $DIR/$tdir $TGT2/$tdir
287
288     fini_changelog
289     cleanup_src_tgt
290     return 0
291 }
292 run_test 2c "Replicate files while dbench is running."
293
294 # Test 3a - Replicate files created by createmany
295 test_3a() {
296     [ "$SLOW" = "no" ] && skip "Skipping slow test" && return
297
298     init_src
299     init_changelog
300
301     local numfiles=1000
302     mkdir -p ${DIR}/$tdir
303     createmany -o $DIR/$tdir/$tfile $numfiles || error "createmany failed!"
304
305     # Replicate the changes to $TGT
306     $LREPLICATE -s $DIR -t $TGT -t $TGT2 -m $MDT0 -u $CL_USER -l $LREPL_LOG -v
307     check_diff $DIR/$tdir $TGT/$tdir   
308     check_diff $DIR/$tdir $TGT2/$tdir
309
310     fini_changelog
311     cleanup_src_tgt
312     return 0
313 }
314 run_test 3a "Replicate files created by createmany"
315
316
317 # Test 3b - Replicate files created by writemany
318 test_3b() {
319     [ "$SLOW" = "no" ] && skip "Skipping slow test" && return
320
321     init_src
322     init_changelog
323
324     local time=60
325     local threads=5
326     mkdir -p ${DIR}/$tdir
327     writemany -q -a $DIR/$tdir/$tfile $time $threads || error "writemany failed!"
328
329     # Replicate the changes to $TGT
330     $LREPLICATE -s $DIR -t $TGT -t $TGT2 -m $MDT0 -u $CL_USER -l $LREPL_LOG -v
331
332     check_diff $DIR/$tdir $TGT/$tdir   
333     check_diff $DIR/$tdir $TGT2/$tdir
334
335     fini_changelog
336     cleanup_src_tgt
337     return 0
338 }
339 run_test 3b "Replicate files created by writemany"
340
341 # Test 3c - Replicate files created by createmany/unlinkmany
342 test_3c() {
343     [ "$SLOW" = "no" ] && skip "Skipping slow test" && return
344
345     init_src
346     init_changelog
347
348     local numfiles=1000
349     mkdir -p ${DIR}/$tdir
350     createmany -o $DIR/$tdir/$tfile $numfiles || error "createmany failed!"
351     unlinkmany $DIR/$tdir/$tfile $numfiles || error "unlinkmany failed!"
352
353     # Replicate the changes to $TGT
354     $LREPLICATE -s $DIR -t $TGT -t $TGT2 -m $MDT0  -u $CL_USER -l $LREPL_LOG -v
355     check_diff $DIR/$tdir $TGT/$tdir   
356     check_diff $DIR/$tdir $TGT2/$tdir
357
358     fini_changelog
359     cleanup_src_tgt
360     return 0
361 }
362 run_test 3c "Replicate files created by createmany/unlinkmany"
363
364 # Test 4 - Replicate files created by iozone
365 test_4() {
366     [ "$SLOW" = "no" ] && skip "Skipping slow test" && return
367
368     which iozone > /dev/null 2>&1
369     if [ $? -ne 0 ]; then
370         skip "iozone not found. Skipping test"
371         return
372     fi
373
374     init_src
375     init_changelog
376
377     mkdir -p ${DIR}/$tdir
378     END_RUN_FILE=${DIR}/$tdir/run LOAD_PID_FILE=${DIR}/$tdir/pid \
379         MOUNT=${DIR}/$tdir run_iozone.sh &
380     sleep 30
381     child_pid=$(pgrep iozone)
382     $KILL -SIGSTOP $child_pid
383
384     # Replicate the changes to $TGT
385     $LREPLICATE -s $DIR -t $TGT -t $TGT2 -m $MDT0  -u $CL_USER -l $LREPL_LOG -v
386     check_diff $DIR/$tdir $TGT/$tdir
387     check_diff $DIR/$tdir $TGT2/$tdir
388
389     $KILL -SIGCONT $child_pid
390     sleep 60
391     $KILL -SIGKILL $child_pid
392
393     $LREPLICATE -l $LREPL_LOG -v
394     check_diff $DIR/$tdir $TGT/$tdir
395     check_diff $DIR/$tdir $TGT2/$tdir
396
397     fini_changelog
398     cleanup_src_tgt
399     return 0
400 }
401 run_test 4 "Replicate files created by iozone"
402
403 # Test 5a - Stop / start lreplicate
404 test_5a() {
405     [ "$SLOW" = "no" ] && skip "Skipping slow test" && return
406
407     init_src
408     init_changelog
409
410     NUMTEST=2000
411     mkdir -p ${DIR}/$tdir
412     createmany -o $DIR/$tdir/$tfile $NUMTEST
413
414     # Replicate the changes to $TGT
415     
416     $LREPLICATE -s $DIR -t $TGT -t $TGT2 -m $MDT0 -u $CL_USER -l $LREPL_LOG -v &
417     local child_pid=$!
418     sleep 30
419     $KILL -SIGHUP $child_pid
420     wait
421     $LREPLICATE -l $LREPL_LOG -v
422
423     check_diff $DIR/$tdir $TGT/$tdir   
424     check_diff $DIR/$tdir $TGT2/$tdir
425
426     fini_changelog
427     cleanup_src_tgt
428     return 0
429 }
430 run_test 5a "Stop / start lreplicate"
431
432 # Test 5b - Kill / restart lreplicate
433 test_5b() {
434     [ "$SLOW" = "no" ] && skip "Skipping slow test" && return
435
436     init_src
437     init_changelog
438
439     NUMTEST=2000
440     mkdir -p ${DIR}/$tdir
441     createmany -o $DIR/$tdir/$tfile $NUMTEST
442
443     # Replicate the changes to $TGT
444     
445     $LREPLICATE -s $DIR -t $TGT -t $TGT2 -m $MDT0 -u $CL_USER -l $LREPL_LOG -v &
446     local child_pid=$!
447     sleep 30
448     $KILL -SIGKILL $child_pid
449     wait
450     $LREPLICATE -l $LREPL_LOG -v
451
452     check_diff $DIR/$tdir $TGT/$tdir   
453     check_diff $DIR/$tdir $TGT2/$tdir
454
455     fini_changelog
456     cleanup_src_tgt
457     return 0
458 }
459 run_test 5b "Kill / restart lreplicate"
460
461 # Test 6 - lreplicate large no of hard links
462 test_6() {
463     init_src
464     init_changelog
465
466     local NUMLINKS=128
467     mkdir -p ${DIR}/$tdir
468     touch $DIR/$tdir/link0
469     local i=1
470     while [ $i -lt $NUMLINKS ];
471     do
472       ln $DIR/$tdir/link0  $DIR/$tdir/link${i}
473       i=$(expr $i + 1)
474     done
475
476     # Replicate the changes to $TGT
477     $LREPLICATE -s $DIR -t $TGT -t $TGT2 -m $MDT0 -u $CL_USER -l $LREPL_LOG -v
478     check_diff $DIR/$tdir $TGT/$tdir
479     check_diff $DIR/$tdir $TGT2/$tdir
480
481     local count1=$(ls -l $TGT/$tdir/link0 | sed -r 's/ +/ /g' | cut -f 2 -d ' ')
482     local count2=$(ls -l $TGT/$tdir/link0 | sed -r 's/ +/ /g' | cut -f 2 -d ' ')
483     if [[ $count1 -ne $NUMLINKS ]] ||  [[ $count2 -ne $NUMLINKS ]]; then
484         ls -l $TGT/$tdir/link0 $TGT2/$tdir/link0
485         error "Incorrect no of hard links found $count1, $count2"
486     fi
487     fini_changelog
488     cleanup_src_tgt
489     return 0
490 }
491 run_test 6 "lreplicate large no of hard links"
492
493 # Test 7 - lreplicate stripesize
494 test_7() {
495     init_src
496     init_changelog
497
498     local NUMFILES=100
499     mkdir -p ${DIR}/$tdir
500     lfs setstripe -c 2 ${DIR}/$tdir
501     createmany -o $DIR/$tdir/$tfile $NUMFILES
502
503     # To simulate replication to another lustre filesystem, replicate
504     # the changes to $DIR/tgt. Disable changelogs before replication
505     # so that the files created as part of replication are not logged.
506     do_facet $SINGLEMDS lctl set_param -n mdd.$MDT0.changelog off
507     mkdir $DIR/tgt
508
509     $LREPLICATE -s $DIR -t $DIR/tgt -m $MDT0 -u $CL_USER -l $LREPL_LOG -v
510     check_diff ${DIR}/$tdir $DIR/tgt/$tdir
511
512     local i=0
513     while [ $i -lt $NUMFILES ];
514     do
515       local count=$(( $(lfs getstripe -q $DIR/tgt/$tdir/${tfile}$i | wc -l) - 1))
516       if [ $count -ne 2 ]; then
517           error "Stripe size not replicated" 
518       fi
519       i=$(expr $i + 1)
520     done
521     fini_changelog
522     cleanup_src_tgt
523     return 0
524 }
525 run_test 7 "lreplicate stripesize"
526
527 # Test 8 - Replicate multiple file/directory moves
528 test_8() {
529     init_src
530     init_changelog
531
532     mkdir -p ${DIR}/$tdir
533
534     for i in 1 2 3 4 5 6 7 8 9; do
535         mkdir $DIR/$tdir/d$i
536             for j in 1 2 3 4 5 6 7 8 9; do
537                 mkdir $DIR/$tdir/d$i/d$i$j
538                 createmany -o $DIR/$tdir/d$i/d$i$j/a 10 \
539                     > /dev/null
540                 mv $DIR/$tdir/d$i/d$i$j $DIR/$tdir/d$i/d0$i$j
541                 createmany -o $DIR/$tdir/d$i/d0$i$j/b 10 \
542                     > /dev/null
543                 mv $DIR/$tdir/d$i/d0$i$j/a0 $DIR/$tdir/d$i/d0$i$j/c0
544             done
545             mv $DIR/$tdir/d$i $DIR/$tdir/d0$i
546     done
547
548     $LREPLICATE -s $DIR -t $TGT -m $MDT0 -u $CL_USER -l $LREPL_LOG -v
549
550     check_diff ${DIR}/$tdir $TGT/$tdir
551
552     fini_changelog
553     cleanup_src_tgt
554     return 0
555 }
556 run_test 8 "Replicate multiple file/directory moves"
557
558 log "cleanup: ======================================================"
559 cd $ORIG_PWD
560 check_and_cleanup_lustre
561 echo '=========================== finished ==============================='
562 [ -f "$REPLOG" ] && cat $REPLLOG && grep -q FAIL $REPLLOG && exit 1 || true
563 echo "$0: completed"