"­R -1" for FreeBSD's xargs was invalid and produced errors.
[amitay/build-farm.git] / build_test.fns
1 #!/bin/sh -*- mode: shell-script; sh-indentation: 8; indent-tabs-mode: t; -*-
2
3 # build_farm -- distributed build/test architecture for samba, rsync, etc
4
5 # Copyright (C) 2001 by Andrew Tridgell <tridge@samba.org>
6 # Copyright (C) 2001 by Andrew Bartlett <abartlet@samba.org>
7 # Copyright (C) 2001, 2003 by Martin Pool <mbp@samba.org>
8
9 # default maximum runtime for any command
10 MAXTIME=7200
11 # default maximum memory size (100M) for any command
12 MAXMEM=100000
13 RUN_FROM_BUILD_FARM=yes
14 export RUN_FROM_BUILD_FARM
15
16 deptrees="";
17
18 build_test_fns_id='$Id$'
19
20 #############################
21 # build a signature of a tree, used to see if we
22 # need to rebuild 
23 sum_tree() {
24         sum_tree_test_root=$1
25         sum_tree_tree=$2
26         sum_tree_sum=$3
27         sum_tree_scm=$4
28         find $sum_tree_test_root/$sum_tree_tree -type f -print | grep -v version.h | sort | xargs sum > $sum_tree_sum
29         sum build_test build_test.fns >> $sum_tree_sum
30
31         if [ -f "$host.fns" ]; then
32             sum $host.fns >> $sum_tree_sum
33         else
34             sum generic.fns >> $sum_tree_sum
35         fi
36
37         if [ -f "$test_root/$tree.$scm" ]; then
38             sum "$test_root/$tree.$scm" >> $sum_tree_sum
39         fi
40
41         for d in $deptrees; do
42             dscm=`choose_scm "$d"`
43             if [ -f "$test_root/$d.$dscm" ]; then
44                 sum "$test_root/$d.$dscm" >> $sum_tree_sum
45             fi
46         done
47 }
48
49 #############################
50 # send the logs to the master site
51 send_logs() {
52         if [ "$nologreturn" = "yes" ]; then
53                 echo "skipping log transfer"
54         else
55                 log="$1"
56                 err="$2"
57                 shift
58                 shift
59                 chmod 0644 "$log" "$err"
60
61                 XARGS_I="xargs -I '{}'"
62                 find $log -size +40000 | $XARGS_I sh -c 'dd if={} bs=1024 count=20000 of={}.tmp && mv {}.tmp {} &&  echo "\n***LOG TRUNCATED***" >> {}'
63                 find $err -size +40000 | $XARGS_I sh -c 'dd if={} bs=1024 count=20000 of={}.tmp && mv {}.tmp {} &&  echo "\n***LOG TRUNCATED***" >> {}'
64
65                 rsync $* -ct -q --password-file=.password -z --timeout=200 \
66                     "$log" "$err" $host@build.samba.org::build_farm_data/
67         fi
68 }
69
70 #############################
71 # send the logs when they haven't changed
72 # the aim is to just update the servers timestamp.
73 # sending with a very large rsync block size does this
74 # with minimal network traffic
75 send_logs_skip() {
76     touch "$1" "$2"
77     send_logs "$1" "$2" -B 10000000
78 }
79
80 ############################
81 # fetch the latest copy of the tree
82 fetch_tree() {
83         if [ "$norsync" = "yes" ]; then
84                 echo "skipping tree transfer"
85         else
86                 fetchtree=$1
87                 if rsync --exclude=autom4te.cache/ --exclude=.svn/ --exclude=.git/ \
88                         --delete-excluded -q --partial --timeout=200 -crlpz --delete --ignore-errors \
89                         samba.org::ftp/unpacked/$fetchtree/ $test_root/$fetchtree; then
90                         echo "transferred $fetchtree OK"
91                 else
92                         echo "transfer of $fetchtree failed code $?"
93                         return 1
94                 fi
95         fi
96         return 0
97 }
98
99 ############################
100 # fetch the latest copy of the rev meta info
101 fetch_revinfo() {
102     tree=$1
103     scm=$2
104
105     test -z "$scm" && return 1
106     test x"$scm" = x"unknown" && return 1
107     test x"$scm" = x"cvs" && return 1
108
109     if [ "$norsync" = "yes" ]; then
110         echo "skipping .revinfo.$scm transfer"
111     else
112         if [ -r $test_root/$tree.$scm ]; then
113                 rm -f $test_root/$tree.$scm.old
114             mv $test_root/$tree.$scm $test_root/$tree.$scm.old
115         fi
116         rsync -q --timeout=200 -clz --ignore-errors \
117             samba.org::ftp/unpacked/$tree/.revinfo.$scm $test_root/$tree.$scm
118     fi
119     if [ -r $test_root/$tree.$scm ]; then
120         return 0;
121     fi
122     return 1
123 }
124
125 ############################
126 # choose the scm that is used for the given project
127 choose_scm() {
128         tree=$1
129
130         case "$tree" in
131                 ccache | distcc)
132                         echo "cvs"
133                         return 0
134                 ;;
135                 samba_3* | rsync)
136                         echo "git"
137                         return 0
138                 ;;
139         esac
140
141         echo "svn"
142         return 0
143 }
144
145 locknesting=0
146
147 ############################
148 # grab a lock file. Not atomic, but close :)
149 # tries to cope with NFS
150 lock_file() {
151         if [ -z "$lock_root" ]; then
152           lock_root=`pwd`;
153         fi
154         lckf="$lock_root/$1"
155         machine=`cat "$lckf" 2> /dev/null | cut -d: -f1`
156         pid=`cat "$lckf" 2> /dev/null | cut -d: -f2`
157
158         if [ "$pid" = "$$" ]; then
159             locknesting=`expr $locknesting + 1`
160             echo "lock nesting now $locknesting"
161             return 0
162         fi
163
164         if test -f "$lckf"; then
165             test $machine = $host || {
166                 echo "lock file $lckf is valid for other machine $machine"
167                 return 1                 
168             }
169             kill -0 $pid && {
170                 echo "lock file $lckf is valid for process $pid"
171                 return 1
172             }
173             echo "stale lock file $lckf for $machine:$pid"
174             cat "$lckf"
175             /bin/rm -f "$lckf"
176         fi
177         echo "$host:$$" > "$lckf"
178         return 0
179 }
180
181 ############################
182 # unlock a lock file
183 unlock_file() {
184         if [ -z "$lock_root" ]; then
185           lock_root=`pwd`;
186         fi
187         if [ "$locknesting" != "0" ]; then
188             locknesting=`expr $locknesting - 1`
189             echo "lock nesting now $locknesting"
190         else 
191             lckf="$lock_root/$1"
192             /bin/rm -f "$lckf"
193         fi
194 }
195
196 ############################
197 # run make, and print trace
198 do_make() {
199
200   if [ x"$MAKE" = x ] 
201   then
202     MAKE=make
203   fi 
204
205   MMTIME=$MAXTIME
206   # some trees don't need as much time
207   case "$tree" in
208         rsync | tdb | talloc | libreplace | ccache | distcc)
209           if [ "$compiler" != "checker" ]; then
210               MMTIME=`expr $MMTIME / 5`
211           fi
212           ;;
213   esac
214   
215     
216   for t in $*; do
217     if [ x"$BUILD_FARM_NUM_JOBS" = x ]; then
218       echo "$MAKE $t"
219       ./timelimit $MMTIME "$MAKE" "$t"
220       status=$?
221     else
222       # we can parallelize everything and all targets
223       if [ x"$t" = xeverything ] || [ x"$t" = xall]; then
224         echo "$MAKE" "-j$BUILD_FARM_NUM_JOBS"  "$t"
225         ./timelimit $MMTIME "$MAKE" "-j$BUILD_FARM_NUM_JOBS"  "$t"
226         status=$?
227       else
228         echo "$MAKE $t"
229         ./timelimit $MMTIME "$MAKE" "$t"
230         status=$?
231       fi
232     fi
233
234     if [ $status != 0 ]; then
235       return $status;
236     fi
237
238   done
239
240   return 0
241 }      
242
243 ############################
244 # configure the tree
245 action_configure() {
246         if [ ! -x $srcdir/configure ]; then
247             ls -l $srcdir/configure
248             echo "$srcdir/configure is missing"
249             cstatus=255
250             echo "CONFIGURE STATUS: $cstatus"
251             return $cstatus;
252         fi
253         echo "CFLAGS=$CFLAGS"
254         echo configure options: $config_and_prefix
255         echo CC="$CCACHE $compiler" $srcdir/configure $config_and_prefix
256         CC="$CCACHE $compiler"
257         export CC
258         ./timelimit $MAXTIME $srcdir/configure $config_and_prefix
259         cstatus=$?
260         echo "CONFIGURE STATUS: $cstatus"
261         if [ -f config.h ]; then
262             echo "contents of config.h:"
263             cat config.h
264         fi
265         if [ -f include/config.h ]; then
266             echo "contents of include/config.h:"
267             cat include/config.h
268         fi
269         return $cstatus;
270 }
271
272 ############################
273 # show the configure log
274 action_config_log() {
275         if [ ! -f config.log ]; then
276             return 0;
277         fi
278         echo "contents of config.log:"
279         cat config.log
280         return 0;
281 }
282
283 copy_dir() {
284         Tsrc=$1
285         Tdst=$2
286         rsync -a --delete $Tsrc/ $Tdst
287 }
288
289 s4selftest_create() {
290         lock_file "s4selftest.lck" || {
291                 return 1;
292         }
293
294         rm -rf $s4selftest/
295         mkdir -p $s4selftest/source
296
297         copy_dir $builddir/bin $s4selftest/source/bin || {
298                 rm -rf $s4selftest/;
299                 unlock_file "s4selftest.lck";
300                 return 1;
301         }
302
303         copy_dir $srcdir/setup $s4selftest/source/setup || {
304                 rm -rf $s4selftest/;
305                 unlock_file "s4selftest.lck";
306                 return 1;
307         }
308
309         copy_dir $srcdir/../testprogs $s4selftest/testprogs || {
310                 rm -rf $s4selftest/;
311                 unlock_file "s4selftest.lck";
312                 return 1;
313         }
314
315         copy_dir $srcdir/selftest $s4selftest/source/selftest || {
316                 rm -rf $s4selftest/;
317                 unlock_file "s4selftest.lck";
318                 return 1;
319         }
320
321         copy_dir $srcdir/script $s4selftest/source/script || {
322                 rm -rf $s4selftest/;
323                 unlock_file "s4selftest.lck";
324                 return 1;
325         }
326
327         mkdir -p $s4selftest/source/scripting || {
328                 rm -rf $s4selftest/;
329                 unlock_file "s4selftest.lck";
330                 return 1;
331         }
332
333         copy_dir $srcdir/scripting/libjs $s4selftest/source/scripting/libjs || {
334                 rm -rf $s4selftest/;
335                 unlock_file "s4selftest.lck";
336                 return 1;
337         }
338         
339         unlock_file "s4selftest.lck"
340 }
341
342 s4selftest_update() {
343         lock_file "s4selftest.lck" || {
344                 return 1;
345         }
346
347         copy_dir $s4selftest $s4selftest.$tree.$compiler.$$ || {
348                 rm -rf $s4selftest.$tree.$compiler.$$;
349                 unlock_file "s4selftest.lck";
350                 return 1;
351         }
352
353         rm -rf $s4selftest.$tree.$compiler
354         mv $s4selftest.$tree.$compiler.$$ $s4selftest.$tree.$compiler
355
356         unlock_file "s4selftest.lck"
357 }
358
359 ############################
360 # build the tree
361 action_build() {
362         case "$tree" in
363         samba4)
364                 do_make everything
365                 bstatus=$?
366                 if test x"$bstatus" != x"0"; then
367                         # the 2nd 'make everything' is to work around a bug
368                         # in netbsd make. 
369                         do_make everything
370                         bstatus=$?
371                 fi
372
373                 if test x"$bstatus" != x"0"; then
374                         do_make testsuite
375                         bstatus=$?
376                 fi
377
378                 if test x"$bstatus" = x"0"; then
379                         s4selftest_create
380                 fi
381
382                 ;;
383         samba_3*)
384                 do_make proto everything torture
385                 bstatus=$?
386                 ;;
387         *)
388                 do_make all
389                 bstatus=$?
390                 ;;
391         esac
392
393         echo "BUILD STATUS: $bstatus"
394
395         return $bstatus
396 }
397
398 ############################
399 # show static analysis results
400 action_cc_checker() {
401
402         # default to passing the cc_checker
403         cccstatus=0
404
405         if [ -f ibm_checker.out ]; then
406                 cat ibm_checker.out
407                 cccstatus=`cat ibm_checker.out | grep '^\-\- ' | wc -l`
408         fi
409
410         echo "CC_CHECKER STATUS: $cccstatus"
411         return $cccstatus;      
412 }
413
414 ############################
415 # install the tree
416 action_install() {
417         if [ -d $prefix ]; then
418                 if [ "$noclean" != "yes" ]; then
419                     rm -rf $prefix
420                 fi
421         fi
422
423         do_make install
424         istatus=$?
425         echo "INSTALL STATUS: $istatus"
426         return $istatus;
427 }
428
429 ############################
430 # test the tree
431 action_test_samba() {
432         do_make test
433         totalstatus=$?
434         return "$totalstatus"
435 }
436
437 action_test_generic() {
438         CC="$compiler"
439         export CC
440         do_make installcheck
441         totalstatus=$?
442         echo "TEST STATUS: $totalstatus"
443         return "$totalstatus"
444 }
445
446 action_test_lorikeet_heimdal() {
447         CC="$compiler"
448         export CC
449         SOCKET_WRAPPER_DIR=`pwd`/sw
450         mkdir $SOCKET_WRAPPER_DIR
451         export SOCKET_WRAPPER_DIR
452         do_make check
453         totalstatus=$?
454         SOCKET_WRAPPER_DIR=
455         export SOCKET_WRAPPER_DIR
456         echo "TEST STATUS: $totalstatus"
457         return "$totalstatus"
458 }
459
460
461 #############################
462 # attempt some basic tests of functionaility
463 # starting as basic as possible, and getting incresingly complex
464
465 action_test() {
466         # Samba needs crufty code of its own for backward
467         # compatiblity.  I think a better way to do this in the future
468         # is to just call 'make installcheck'.
469         case "$tree" in
470         samba*|smb-build|pidl)
471             action_test_samba
472             ;;
473         lorikeet-heimdal*)
474             action_test_lorikeet_heimdal
475             ;;
476         *)
477             action_test_generic
478             ;;
479         esac
480 }
481
482 ###########################
483 # do a test build of a particular tree
484 test_tree() {
485         tree=$1
486         source=$2
487         compiler="$3"
488         shift
489         shift
490         shift
491         if [ "$compiler" = "gcc" ] && [ "$tree" != "ccache" ] && ccache -V > /dev/null; then
492             CCACHE="ccache"
493             export CCACHE
494         else
495             CCACHE=""
496         fi
497
498         # limit our resource usage
499         ulimit -t $MAXTIME 2> /dev/null
500
501         # max mem size 100M
502         ulimit -m $MAXMEM 2> /dev/null
503
504         # max file size 100M
505         # darn, this affects sparse files too! disable it
506         # ulimit -f 100000 2> /dev/null
507
508         # try and limit the number of open files to 150. That means we'll discover
509         # fd leaks faster
510         ulimit -n 150 2> /dev/null
511
512         # Keep stuff private
513         umask 077
514
515         if [ -z "$test_root" ]; then
516                 test_root=`pwd`
517         fi
518
519         log="build.$tree.$host.$compiler.log"
520         err="build.$tree.$host.$compiler.err"
521         sum="build.$tree.$host.$compiler.sum"
522         lck="build.$tree.lck"
523         srcdir="$test_root/$tree/$source"
524
525         lock_file "$lck" || {
526                 return
527         }
528
529         # work out what other trees this package depends on
530         deptrees=""
531         case "$tree" in
532             talloc | tdb)
533                 deptrees="libreplace";
534             ;;
535             ldb)
536                 deptrees="libreplace talloc tdb";
537             ;;
538                 samba-gtk)
539                 deptrees="samba4"
540                 ;;
541         esac
542
543         scm=`choose_scm "$tree"`
544
545         # pull the entries, if any
546         if fetch_revinfo "$tree" "$scm"; then
547             for d in $deptrees; do
548                 dscm=`choose_scm "$d"`
549                 if [ -f "$test_root/$d.$dscm" ]; then
550                     if [ "$d" != "$tree" ]; then
551                         cat "$test_root/$d.$dscm" >> $test_root/$tree.$scm
552                     fi
553                 fi
554             done
555             rm -f $test_root/$tree.$compiler.$scm.old
556             mv $test_root/$tree.$compiler.$scm $test_root/$tree.$compiler.$scm.old
557             cp $test_root/$tree.$scm $test_root/$tree.$compiler.$scm
558             if cmp $test_root/$tree.$compiler.$scm $test_root/$tree.$compiler.$scm.old > /dev/null; then
559                 echo "skip: $tree.$compiler nothing changed in $scm"
560                 cd $test_root
561                 send_logs_skip "$log" "$err"
562                 unlock_file "$lck"
563                 return
564             fi
565         fi
566
567         # pull the tree
568         fetch_tree "$tree" || {
569             cd $test_root
570             unlock_file "$lck"
571             return
572         }
573
574         if [ ! -x $srcdir/configure ] && [ "$tree" != "pidl" ]; then
575                 echo "skip: $tree.$compiler configure not present, try again next time!"
576                 cd $test_root
577                 unlock_file "$lck"
578                 return
579         fi
580
581         echo "Starting build of $tree.$compiler in process $$ at `date`"
582
583         case "$tree" in
584             tdb | talloc | ldb | libreplace)
585                 builddir="$test_root/tmp.$tree.$compiler"
586                 usingtmpbuild=1
587                 if [ -d $builddir ]; then
588                     rm -rf $builddir
589                 fi
590                 mkdir -p $builddir
591                 export builddir
592             ;;
593             *)
594                 builddir=$srcdir
595                 usingtmpbuild=0
596                 export builddir
597             ;;
598         esac
599         
600         if [ ! x$USER = x"" ]; then
601             whoami=$USER
602         else 
603             if [ ! x$LOGNAME = x"" ]; then
604                 whoami=$LOGNAME
605             else
606                 whoami=build
607             fi
608         fi
609
610         prefix="$test_root/prefix/$tree.$compiler"
611         mkdir -p "$prefix"
612
613         s4selftest=$test_root/s4selftest
614         export s4selftest
615
616         sw_config=$config
617
618         case "$tree" in
619         lorikeet-heimdal)
620                 sw_config="$config --enable-socket-wrapper"
621                 ;;
622         samba4)
623                 sw_config="$config --enable-socket-wrapper"
624                 sw_config="$sw_config --enable-nss-wrapper"
625                 ;;
626         samba_3*)
627                 sw_config="$config --enable-socket-wrapper"
628                 sw_config="$sw_config --enable-nss-wrapper"
629                 s4selftest_update "$tree" "$compiler" && {
630                         t="$s4selftest.$tree.$compiler/source"
631                         #sw_config="$sw_config --with-samba4srcdir=$t"
632                         t="$t/bin/smbtorture"
633                         sw_config="$sw_config --with-smbtorture4-path=$t"
634                 }
635                 ;;
636         samba-gtk)
637                 PKG_CONFIG_PATH="$test_root/prefix/samba4.$compiler/lib/pkgconfig"
638                 export PKG_CONFIG_PATH
639                 ;;
640         ldb)
641                 fetch_tree popt
642                 ;;
643         talloc)
644                 fetch_tree libreplace
645                 ;;
646         *)
647                 testsuite=testsuite
648                 ;;
649         esac
650
651         if [ "$LCOV_REPORT" = "yes" ]; then
652             GCOV_FLAGS="-ftest-coverage -fprofile-arcs"
653             GCOV_LIBS="-lgcov"
654             HOSTCC_CFLAGS="$HOSTCC_CFLAGS $GCOV_FLAGS" 
655             CFLAGS="$CFLAGS $GCOV_FLAGS" 
656             LDFLAGS="$LDFLAGS $GCOV_FLAGS $GCOV_LIBS" 
657             SHLD_FLAGS="$SHLD_FLAGS $GCOV_FLAGS $GCOV_LIBS"
658             export HOSTCC_CFLAGS CFLAGS LDFLAGS SHLD_FLAGS
659         fi
660
661         config_and_prefix="$sw_config --prefix=$prefix"
662
663         # see if we need to rebuild
664         sum_tree $test_root $tree $sum $scm
665         echo "CFLAGS=$CFLAGS $config_and_prefix" >> $sum
666
667         if cmp "$sum" "$sum.old" > /dev/null; then
668                 echo "skip: $tree.$compiler nothing changed"
669                 cd $test_root
670                 send_logs_skip "$log" "$err"
671                 unlock_file "$lck"
672                 echo "Ending build of $tree.$compiler in process $$ at `date`"
673                 return
674         fi
675
676         # we do need to rebuild - save the old sum
677         /bin/rm -f $sum.old
678         mv $sum $sum.old
679
680         actions="$*"
681         
682         if [ "$actions" = "" ]; then
683             actions="configure config_log build install test"
684         fi
685
686         # start the build
687         (
688                 # we all want to be able to read the output...
689                 LANG=C
690                 export LANG
691
692                 uname -a
693
694                 echo ""
695                 echo "build_test          : $build_test_id"
696                 echo "build_test.fns      : $build_test_fns_id"
697                 echo "local settings file : $build_test_settings_local_file"
698                 echo "local functions file: $build_test_fns_local_file"
699                 echo "used .fns file      : $build_test_used_fns_file"
700                 echo ""
701
702                 # we need to be able to see if a build farm machine is accumulating
703                 # stuck processes. We do this in two ways, as we don't know what style
704                 # of ps it will have
705                 ps xfuw 2> /dev/null
706                 ps -fu $USER 2> /dev/null
707
708                 echo "building $tree with CC=$compiler on $host at "`date`
709                 echo "builddir=$builddir"
710                 echo "prefix=$prefix"
711
712                 echo "Showing limits"
713                 ulimit -a 2> /dev/null
714
715                 # build the timelimit utility
716                 echo "Building timelimit"
717                 mkdir -p $builddir
718                 $compiler $TIMELIMIT_FLAGS -o $builddir/timelimit $test_root/timelimit.c || exit 1
719
720                 # the following is for non-samba builds only
721                 if [ -r $test_root/$tree.svn ]; then
722                   h_rev=`grep 'Revision: ' $test_root/$tree.svn | cut -d ':' -f2 | cut -d ' ' -f2 | sed 1q`
723                   if [ -n "$h_rev" ]; then
724                         echo "HIGHEST SVN REVISION: $h_rev"
725                   fi
726                   rev=`grep 'Last Changed Rev: ' $test_root/$tree.svn | cut -d ':' -f2 | cut -d ' ' -f2 | sed 1q`
727                   if [ -n "$rev" ]; then
728                         echo "BUILD REVISION: $rev"
729                   fi
730                 elif [ -r $test_root/$tree.git ]; then
731                   csha1=`cat $test_root/$tree.git |head -3 | tail -1`
732                   if [ -n "$csha1" ]; then
733                     echo "BUILD COMMIT REVISION: $csha1"
734                   fi
735                   cdate=`cat $test_root/$tree.git |head -4 | tail -1`
736                   if [ -n "$cdate" ]; then
737                     echo "BUILD COMMIT DATE: $cdate"
738                   fi
739                   ctime=`cat $test_root/$tree.git |head -2 | tail -1`
740                   if [ -n "$ctime" ]; then
741                     echo "BUILD COMMIT TIME: $ctime"
742                   fi
743                 fi
744
745                 if [ "$tree" = "pidl" ] 
746                 then
747                         cd $builddir
748                         perl ./Makefile.PL "$prefix"
749                 fi
750
751                 for action in $actions; do
752
753                     echo Running action $action
754
755                     date
756
757                     cd $builddir || exit 1
758                     export srcdir
759                     df .
760                     mount
761                     vmstat
762
763                     ( action_$action )
764                     action_status=$?
765                     
766                     if [ $action_status != 0 ]; then
767                         echo "ACTION FAILED: $action";
768                     else
769                         echo "ACTION PASSED: $action";
770                     fi
771                     
772                     if [ $action_status != 0 ]; then 
773                         break;
774                     fi
775
776                 done
777
778                 if [ "$LCOV_REPORT" = "yes" ]; then
779                     case "$tree" in
780                         lorikeet-heimdal*)
781                             lcov --directory $builddir --capture --output-file $builddir/$tree.lcov.info
782                             ;;
783                         *)
784                             # ugly hack for s4, as lcov is otherwise not able to find 
785                             # these files
786                             rm -f heimdal/lib/*/{lex,parse}.{gcda,gcno}
787                             lcov --base-directory $builddir --directory $builddir --capture --output-file $builddir/$tree.lcov.info
788                             ;;
789                     esac
790                     genhtml -o $builddir/coverage $builddir/$tree.lcov.info
791                 fi
792
793                 if [ "$noclean" = "yes" ]; then
794                     echo cleanup skipped!
795                 else
796                     echo cleaning up
797                     do_make clean
798                 fi
799                 date
800         ) > "$log" 2> "$err"
801
802         if [ "$LCOV_REPORT" = "yes" ]; then
803             chmod u=rwX,g=rX,o=rX -R $builddir/coverage
804             rsync -rct -q --password-file=.password -z --timeout=200 \
805                 $builddir/coverage/ $host@build.samba.org::lcov_data/$host/$tree/
806         fi
807
808         cd $test_root
809
810         /bin/rm -rf $prefix
811         if [ "$usingtmpbuild" = "1" ]; then
812             if [ "$noclean" = "yes" ]; then
813                 echo builddir cleanup skipped!
814             else
815                 /bin/rm -rf $builddir
816             fi
817         fi
818         # send the logs to the master site
819         send_logs "$log" "$err"
820
821         # cleanup
822         echo "Ending build of $tree.$compiler in process $$ at `date`"
823         unlock_file "$lck"
824 }
825
826 #########################################################
827 # if you want to build only one project at a time
828 # add 'global_lock' after 'per_run_hook' and
829 # 'global_unlock' to the end of the file
830 global_lock() {
831     lock_file "global.lck" || {
832         exit 0
833     }
834 }
835 global_unlock() {
836     unlock_file "global.lck"
837 }
838
839 #########################################################
840 # enable this on a per host basis only when needed please
841 # (at least for the moment)
842 kill_old_processes() {
843     # this should work on systems with linux like ps
844     (ps uxfw | grep /build | grep -v grep | egrep 'Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec' | awk '{print $2}' | xargs kill -9) 2> /dev/null
845     # and this should work on sysv style ps
846     (ps -fu $USER | grep /build | grep -v grep | egrep 'Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec' | awk '{print $2}' | xargs kill -9) 2> /dev/null
847 }
848
849 delete_old_svn_tree() {
850         otree=$1
851
852         test -z "$otree" && return 0;
853
854         rm -rf $otree
855         rm -rf $otree.svn
856         rm -rf $otree.*.svn
857         rm -rf s4selftest.$otree.*
858         rm -rf build.$otree.*
859 }
860
861 # this is a special fn that allows us to add a "special" hook to the build
862 # farm that we want to do to the build farm. never leave it empty. instead,
863 # use ":" as the fn body.
864 per_run_hook() {
865     # kill old processes on systems with a known problem
866     case $host in
867         nohost)
868             echo "just a placeholder";
869             ;;
870         tridge)
871             kill_old_processes
872             ;;
873         deckchair)
874             rm -f deckchair.fns
875             ;;
876     esac
877     # trim the log if too large
878     if [ "`wc -c < build.log`" -gt 2000000 ]; then
879         rm -f build.log
880     fi
881
882     delete_old_svn_tree "samba_3_2"
883 }
884
885
886 ######################################################
887 # main code that is run on each call to the build code
888 rsync --timeout=200 -q -az build.samba.org::build_farm/*.c .
889
890
891 # build.log can grow to an excessive size, trim it beyond 50M
892 if [ -f build.log ]; then
893   find build.log -size +100000 -exec /bin/rm '{}' \;
894 fi
895