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