Whamcloud - gitweb
20697bfc0128a14b8899913726328efaff2df90a
[fs/lustre-release.git] / build / lbuild
1 #!/bin/bash
2
3 # vim:expandtab:shiftwidth=4:softtabstop=4:tabstop=4:
4
5 # this is an alternative FD for stdout, to be used especially when we are
6 # taking stdout from a function as it's return value.  i.e. foo=$(bar)
7 # this is a workaround until a version of bash where we can put xtrace
8 # on a specific FD
9 exec 3>&1; STDOUT=3
10
11 #set -x
12 xtrace="+x"
13 if [[ $SHELLOPTS = *xtrace* ]]; then
14     xtrace="-x"
15 fi
16 shopt -s extdebug
17
18 # include the exit_traps library
19 . ${0%/lbuild}/exit_traps.sh
20
21 # our children should die when we do
22 push_exit_trap "kill -INT -$$ || true" kill_children
23
24 TOPDIR=$PWD
25
26 # CVSROOT is inherited from the environment
27 KERNELDIR=
28 LINUX=
29 LUSTRE=
30 RELEASE=false
31 # XXX - some recent hacking has pretty much neutered this option.
32 #       search through this file (and lbuild.old_school -- but that will
33 #       be going away soon) for "-bb" and see how many places
34 #       simply don't account for this option
35 DO_SRC=true
36 DOWNLOAD=true
37 TAG=
38 CANONICAL_TARGET=
39 TARGET=
40 TARGET_ARCH=$(uname -m)
41 TARGET_ARCHS=
42 TARGET_ARCHS_ALL=$TARGET_ARCH
43 [ "$TARGET_ARCH" = "i686" ] && TARGET_ARCHS_ALL="i686 i586 i386"
44 CONFIGURE_FLAGS=
45 EXTERNAL_PATCHES=
46 EXTRA_VERSION=
47 LUSTRE_EXTRA_VERSION=
48 STAGEDIR=
49 TMPDIR=${TMPDIR:-"/var/tmp"}
50 TIMESTAMP=
51 # XXX - i think these two parameters/arguments/variables need to be
52 #       cleaned up and merged.  they effectively do the same thing
53 REUSERPM=
54 REUSEBUILD=
55 # what does this do exactly?  does it imply no kernel build?
56 NORPM=false
57 LDISKFSRPM=true
58 SKIPLDISKFSRPM="v1_4_* b1_4"
59 SMPTYPES="smp bigsmp default ''"
60 PATCHLESS=false
61 XEN=false
62 LINUXOBJ=
63 DISTRO=
64 KERNELTREE=
65 # default to not adding -lustre- into the kernel RPM package names
66 KERNEL_LUSTRE_NAMING=false
67
68 # patchless build
69 KERNELRPMSBASE=
70 RPMSMPTYPE=
71
72 # from target file
73 SERIES=
74 BASE_ARCHS=
75 BIGMEM_ARCHS=
76 BOOT_ARCHS=
77 JENSEN_ARCHS=
78 SMP_ARCHS=
79 BIGSMP_ARCHS=
80 PSERIES64_ARCHS=
81 UP_ARCHS=
82
83 # not in the target file any more
84 CONFIG=
85
86 # build the lustre-tests rpm?
87 LUSTRE_TESTS=true
88
89 DATE=$(date)
90
91 USE_DATESTAMP=1
92 RPMBUILD=
93
94 OLD_SCHOOL=false
95
96 export CC=${CC:-gcc}
97
98 # Readlink is not present on some older distributions: emulate it.
99 readlink() {
100     local path=$1 ll
101
102     if [ -L "$path" ]; then
103         ll="$(LC_ALL=C ls -l "$path" 2> /dev/null)" &&
104         echo "${ll/* -> }"
105     else
106         return 1
107     fi
108 }
109
110 cleanup() {
111
112     true
113 }
114
115 error() {
116     local msg="$1"
117
118     [ -n "$msg" ] && echo -e "\n${0##*/}: $msg" >&3
119
120 }
121
122 fatal() {
123
124     cleanup
125     error "$2"
126     exit $1
127
128 }
129
130 usage() {
131     cat <<EOF
132 Usage: ${0##*/} [OPTION]... [-- <lustre configure options>]
133
134   -d CVSROOT
135     Specifies the CVS Root to use when pulling files from CVS.  The
136     environment variable \$CVSROOT is used if this option is not
137     present.
138
139   --external-patches=EXTERNAL_PATCHES
140     Directory similar to lustre/lustre/kernel_patches/ that lbuild should
141     look for seres and config files in before looking in the lustre
142     tree.
143
144   --extraversion=EXTRAVERSION
145     Text to use for the rpm release and kernel extraversion.
146
147   --timestamp=TIMESTAMP
148     Date of building lustre in format YYYYMMDDhhmmss
149
150   --reuserpm=DIR
151     Try to reuse old kernel RPMs from DIR
152
153   --reusebuild=DIR
154     Try to reuse old kernel builds from DIR
155
156   --kernelrpm=DIR
157     Path to distro kernel RPM collection
158
159   --ccache
160     Use ccache
161
162   --norpm
163     Do not build RPMs (compile only mode)
164
165   --patchless
166     Build lustre client only
167
168   --distro=DISTRO
169     Which distro using. Autodetect by default
170
171   --kerneldir=KERNELDIR
172     Directory containing Linux source tarballs referenced by target
173     files.
174
175   --kerneltree=KERNELTREE
176     Directory containing dirs with Linux source tarballs referenced by target
177     files. Dir names in format kernel version ('2.6.9', etc.)
178
179   --linux=LINUX --with-linux=LINUX
180     Directory of Linux kernel sources.  When this option is used, only
181     Lustre modules and userspace are built.
182
183   --lustre=LUSTRE
184     Path to an existing lustre source tarball to use instead of
185     pulling from CVS.
186
187   --nodownload
188     Do not try to download a kernel from downloads.lustre.org
189
190   --nosrc
191     Do not build a .src.rpm, a full kernel patch, or a patched kernel
192     tarball.
193
194   --ldiskfs
195     Do ldiskfs RPM. Now true by default
196
197   --publish
198     Unused.
199
200   --release
201     Specifies that the files generated do not include timestamps, and
202     that this is an official release.
203
204   --src
205     Build a .src.rpm, a full kernel patch, and a patched kernel tarball.
206
207   --stage=DIR
208     Directory used to stage packages for release.  RPMs will be placed
209     more or less in DIR/<target>-<arch>, and the tarball will be
210     placed in DIR.
211
212   --tag=TAG
213     A CVS branch/tag name to build from when pulling from CVS.
214
215   --target=TARGET
216     The name of the target to build.  The available targets are listed
217     below.
218
219   --target-archs=TARGET_ARCHS
220     A (space delimited) list of architectures to build.  By default,
221     all of the archs supported by the TARGET will be built, in
222     addition to a .src.rpm.  This option can limit those, for machines
223     that can only build certain archs or if you only want a certain
224     arch built (for testing, or a one-off kernel).
225
226     Also note that by using a non-"base" arch (eg, i386) only kernels
227     will be built - there will be no lustre-lite-utils package.
228
229   --disable-datestamp
230     Prevents the datestamp flag (-D) from being passed to cvs for
231     checkouts. This is a workaround for a problem encountered when
232     using lbuild with tinderbox.
233
234   --xen
235     Builds a Xen domX kernel.
236
237 EOF
238
239 #   list_targets
240
241     fatal "$1" "$2"
242 }
243
244 # canonicalize a relative path
245 canon_path() {
246     local PATH="$1"
247
248     if [ ! -d "$PATH" ]; then
249         return 1
250     fi
251
252     pushd "$PATH" >/dev/null || return 1
253     local CANONPATH=$PWD
254     popd >/dev/null
255
256     echo "$CANONPATH"
257     return 0
258 }
259
260 check_options() {
261
262     if [ "$LUSTRE" ]; then
263         [ -r "$LUSTRE" ] || \
264             usage 1 "Could not find Lustre source tarball '$LUSTRE'."
265     else
266         [ "$CVSROOT" ] || \
267             usage 1 "Either specify a CVS Root with -d, or a Lustre source tarball with --lustre."
268         [ "$TAG" ] || \
269             usage 1 "A branch/tag name must be specified with --tag when not building from a tarball."
270     fi
271
272     if [ -z "$LINUX" ]; then
273         [ "$KERNELDIR" -o "$KERNELTREE" ] || \
274             usage 1 "A kernel directory must be specified with --kerneldir or --kerneltree."
275
276         [ -d "$KERNELDIR" -o -d "$KERNELTREE" ] || \
277             usage 1 "$KERNELDIR and $KERNELTREE are not a directory."
278
279         if ! $RELEASE; then
280             [ "$TAG" ] || \
281                 usage 1 "When building a snapshot, a tag name must be used."
282         fi
283
284         [ "$TARGET" ] || usage 1 "A target must be specified with --target."
285 #       TARGET_FILE="$TOPDIR/lustre/kernel_patches/targets/$TARGET.target"
286 #       [ -r "$TARGET_FILE" ] || \
287 #               usage 1 "Target '$TARGET' was not found."
288     fi
289
290     case $TARGET in
291         2.6-rhel5)
292             CANONICAL_TARGET="rhel5"
293             ;;
294         2.6-rhel4)
295             CANONICAL_TARGET="rhel-2.6"
296             ;;
297         2.6-suse)
298             CANONICAL_TARGET="sles-2.6"
299             ;;
300         2.6-sles10)
301             CANONICAL_TARGET="sles10-2.6"
302             ;;
303         2.6-sles11)
304             CANONICAL_TARGET="sles11"
305             ;;
306         2.6-oel5)
307             CANONICAL_TARGET="oel5"
308             ;;
309         hp_pnnl-2.4)
310             CANONICAL_TARGET="hp-pnnl-2.4"
311             ;;
312         2.6-vanilla \
313             | suse-2.4.21-2 \
314             | rh-2.4 \
315             | rhel-2.4 \
316             | sles-2.4 \
317             | 2.6-patchless)
318                 CANONICAL_TARGET="$TARGET"
319                 ;;
320     esac
321
322     local timestampnodig=$(echo $TIMESTAMP | sed -e s/[0-9]*//g)
323     [ "$timestampnodig" = "" ] || TIMESTAMP=$(date -d "$DATE" "+%Y%m%d%H%M%S")
324     local timestamplength="${#TIMESTAMP}"
325     if [ $timestamplength -eq 12 ]; then
326         TIMESTAMP="${TIMESTAMP}00"
327     elif [ $timestamplength -ne 14 ]; then
328         TIMESTAMP=$(date -d "$DATE" "+%Y%m%d%H%M%S")
329     fi
330
331     RPMBUILD=$(which rpmbuild 2>/dev/null | head -1)
332     if [ ! "$RPMBUILD" -o "$RPMBUILD" == "" ]; then
333         RPMBUILD=$(which rpm 2>/dev/null | head -1)
334         if [ ! "$RPMBUILD" -o "$RPMBUILD" == "" ]; then
335             usage 1 "Could not find binary for making rpms (tried rpmbuild and rpm)."
336         fi
337     fi
338
339     if [ -n "$CCACHE" ]; then
340         which "$DISTCC" &>/dev/null && export DISTCC RPM_BUILD_NCPUS
341
342         if which "$CCACHE" &>/dev/null; then
343             local ccache=$(which "$CCACHE")
344             local bindir="$TOPDIR/bin"
345
346             if [ ! -d $bindir ]; then
347                 mkdir -p $bindir || fatal 1 "error trying to create $bindir"
348             else
349                 rm ${bindir}/* > /dev/null 2>&1 || true
350             fi
351             ln -s "$ccache" ${bindir}/ccache
352             ln -s "$ccache" ${bindir}/cc
353             ln -s "$ccache" ${bindir}/$CC
354             export PATH=$bindir:$PATH
355             export CCACHE && export CC="ccache $CC"
356             # zero the cache so we can see how effective we are being with it
357             echo -n "ccache "
358             ccache -z
359
360             # get some ccache stats when we are done
361             push_exit_trap '[ -n "$CCACHE" ] && ccache -s' "ccache_summary"
362             # should remove the ccache trap if lbuild is interrupted
363             trap 'echo "Received an INT TERM or HUP signal, terminating."; delete_exit_trap "ccache_summary"; exit 1' INT TERM HUP
364         fi
365     fi
366
367     [ -z "$DISTRO" ] && DISTRO=$(autodetect_distro)
368
369     return 0
370
371 }
372
373 # autodetect used Distro
374 autodetect_distro() {
375
376     local name
377     local version
378
379     if [ -f /etc/SuSE-release ]; then
380         name=sles
381         version=$(grep ^VERSION /etc/SuSE-release)
382         version=${version#*= }
383     elif [ -f /etc/redhat-release ]; then
384         name=$(head -1 /etc/redhat-release)
385         version=$(echo "$distroname" |
386                   sed -e 's/^[^0-9.]*//g' | sed -e 's/[ \.].*//')
387     fi
388     if [ -z "$name" -o -z "$version" ]; then
389         fatal 1 "I don't know how to determine distro type/version.\nEither update autodetect_distro() or use the --distro argument"
390     fi
391
392     echo ${name}${version}
393     return 0
394
395 }
396
397 uniqify() {
398
399     echo $(echo "$*" | xargs -n 1 | sort -u)
400
401 }
402
403 download_srpm() {
404     local target=$1
405     local srpm=$2
406     local force="${3:-false}"
407
408     if $force || [ ! -r "$KERNELDIR/$srpm" ] ||
409        [ ! -s "$KERNELDIR/$srpm" ]; then
410         if $DOWNLOAD; then
411             local location="http://downloads.lustre.org/public/kernels/$target/old"
412             echo "Downloading $location/$srpm..."
413             if ! wget -nv "$location/$srpm" -O "$KERNELDIR/$srpm" 2>&1 ||
414                [ ! -s "$KERNELDIR/$srpm" ]; then
415                 rm -f $KERNELDIR/$srpm
416                 fatal 1 "Could not download target $target's kernel SRPM $srpm from $location."
417             fi
418         else
419             fatal 1 "$srpm not found in directory $KERNELDIR."
420         fi
421     fi
422
423 }
424
425 download_file() {
426     local from="$1"
427     local to="$2"
428     local force="$3"
429
430     local file=${from##*/}
431
432     if [ -d $to ]; then
433         to="$to/$file"
434     fi
435
436     local semaphore="$to-downloading"
437
438     is_downloading() {
439         if [ ! -f $semaphore ]; then
440             return 1
441         fi
442
443         # make sure the download has not been aborted
444         local now=$(date +%s)
445         local file_mtime=$(stat -c %Y "$to")
446         local staleness=$((now - file_mtime))
447         # let's assume an active download will write at least once a minute
448         if [ $staleness -gt 60 ]; then
449             return 1
450         fi
451
452         return 0
453     }
454
455     is_downloaded() {
456         # if the semaphore file exists, the file is either still downloading
457         # or a download was aborted and we cannot trust the target file
458         if [ -f $semaphore ]; then
459             return 1
460         fi
461
462         if ! is_downloading && [ -r "$to" ] && [ -s "$to" ]; then
463             return 0
464         fi
465
466         return 1
467     }
468
469     if $force || ! is_downloaded; then
470         if is_downloading; then
471             echo "Somebody else is downloading $from..."
472             while is_downloading; do
473                 echo "Waiting for $to to finish downloading"
474                 sleep 60
475             done
476             if is_downloaded; then
477                 return 0
478             else
479                 echo "The download we were waiting for seems to have been aborted"
480             fi
481
482         fi
483
484         if $DOWNLOAD; then
485             echo "Downloading $from..."
486             # flag others so they don't try to download also
487             push_exit_trap "rm -f $to $semaphore" "download"
488             touch $semaphore
489             if ! wget -nv "$from" -O "$to" || [ ! -s "$to" ]; then
490                 # the trap will remove the files via the fatal below
491                 fatal 1 "Could not download ${to##*/} from ${from%%/*}/."
492             fi
493             rm -f $semaphore
494             delete_exit_trap "download"
495         else
496             fatal 1 "${to##*/} not found in directory ${to%/*}."
497         fi
498     fi
499
500     return 0
501
502 }
503
504 download_ofed() {
505     local force="${1:-false}"
506
507     local location="http://downloads.lustre.org/public/OFED/"
508
509     local Mmv daily
510     if [[ $OFED_VERSION = daily-* ]]; then
511         OFED_VERSION=${OFED_VERSION/daily-/}
512         Mmv=${OFED_VERSION%%-*}
513         daily=${OFED_VERSION##$Mmv-}
514         location="http://www.openfabrics.org/downloads/OFED/ofed-${Mmv}-daily/"
515         # find the filename for the version for the date specified
516         OFED_VERSION=$(curl -s "$location" | sed -nre "/${daily}-/s/.*href=\"OFED-(${Mmv//./\\.}-${daily}-[0-9]{4,4}).tgz.*$/\1/p" | tail -1)
517         if [ -z "$OFED_VERSION" ]; then
518             fatal 1 "Could not determine the filename of the OFED snapshot for ${daily}"
519         fi
520     fi
521
522     if [ -z "$OFED_VERSION" -o "$OFED_VERSION" = "inkernel" ]; then
523         return 0
524     fi
525
526     local file="OFED-${OFED_VERSION}.tgz"
527     download_file "$location/$file" "$KERNELTREE" "$force"
528
529 }
530
531 download_rdac() {
532     local force="${1:-false}"
533
534     local location="http://downloads.lustre.org/public/RDAC/"
535
536     if [ -z "$RDAC_VERSION" -o "$RDAC_VERSION" = "inkernel" ]; then
537         return 0
538     fi
539
540     local file="rdac-LINUX-${RDAC_VERSION}-source.tar.gz"
541     download_file "$location/$file" "$KERNELTREE" "$force"
542
543 }
544
545 download_mptlinux() {
546     local force="${1:-false}"
547
548     local location="http://downloads.lustre.org/public/MPTLINUX/"
549
550     if [ -z "$MPTLINUX_VERSION" -o "$MPTLINUX_VERSION" = "inkernel" ]; then
551         return 0
552     fi
553
554     file="MPTLINUX_RHEL5_SLES10_PH15-${MPTLINUX_VERSION}.zip"
555     download_file "$location/$file" "$KERNELTREE" "$force"
556
557 }
558
559 load_target() {
560
561     EXTRA_VERSION_save="$EXTRA_VERSION"
562     for patchesdir in "$EXTERNAL_PATCHES" \
563                       "$TOPDIR/lustre/lustre/kernel_patches"; do
564         TARGET_FILE="$patchesdir/targets/$TARGET.target"
565         [ -r "$TARGET_FILE" ] && break
566     done
567     [ -r "$TARGET_FILE" ] || fatal 1 "Target $TARGET was not found."
568
569     echo "Loading target config file $TARGET.target..."
570
571     # if the caller specified an OFED_VERSION it should override whatever
572     # the target file specifies
573     local env_OFED_VERSION="$OFED_VERSION"
574
575     . "$TARGET_FILE"
576
577     if [ -n "$env_OFED_VERSION" ]; then
578         OFED_VERSION="$env_OFED_VERSION"
579     fi
580
581     # doesn't make any sense to build OFED for xen domX's
582     if $XEN; then
583         OFED_VERSION=""
584     fi
585
586     # XXX - set_rpm_smp_type is an ugly undeterministic hack.  it needs to
587     #       go away and the target just specify the $RPMSMPTYPE
588     [ -z "$RPMSMPTYPE" ] && set_rpm_smp_type
589
590     # CC might have been overwriten in TARGET_FILE
591     if [[ $CC != ccache\ * ]] && which "$CCACHE" &>/dev/null; then
592         export CCACHE && export CC="ccache $CC"
593     fi
594
595     if [ ! "$KERNELTREE" = "" ] && [ -d "$KERNELTREE" ]; then
596         KERNELDIR="$KERNELTREE/${lnxmaj}"
597         [ -d "$KERNELDIR" ] || mkdir "$KERNELDIR"
598     fi
599
600     # verify the series is available
601     if [ "$SERIES" ]; then
602         for series in $SERIES; do
603             for patchesdir in "$EXTERNAL_PATCHES" "$TOPDIR/lustre/lustre/kernel_patches"; do
604                 [ -r "$patchesdir/series/$series" ] && continue 2
605             done
606             fatal 1 "Target $TARGET's series $SERIES could not be found.\nSearched:\n\t$EXTERNAL_PATCHES/series\n\t$TOPDIR/lustre/lustre/kernel_patches/series."
607         done
608     fi
609
610     # set the location of the .config file
611     local XENPOSTFIX=""
612     if $XEN; then
613         XENPOSTFIX="-xen"
614     fi
615
616     if [ -f $TOPDIR/lustre/lustre/kernel_patches/kernel_configs/kernel-$lnxmaj-$TARGET-$TARGET_ARCH.config ]; then
617         CONFIG_FILE="$TOPDIR/lustre/lustre/kernel_patches/kernel_configs/kernel-$lnxmaj-$TARGET$XENPOSTFIX-$TARGET_ARCH${RPMSMPTYPE:+-}${RPMSMPTYPE}.config"
618     fi
619
620     local lnxrelnew=${lnxrel//-/_}
621
622     # remember the EXTRA_VERSION before we diddle it here
623     # XXX - we really should not diddle with any values read in from the
624     #       target file.  if we want to modify a value, we should create
625     #       a new variable.
626     PRISTINE_EXTRA_VERSION=$EXTRA_VERSION
627
628     if ! $PATCHLESS && [ ! -f "$CONFIG_FILE" ]; then
629         fatal 1 "Config file for target $TARGET missing from $TOPDIR/lustre/lustre/kernel_patches/kernel_configs/."
630     fi
631
632     if [ "$EXTRA_VERSION_save" ]; then
633         EXTRA_VERSION="$EXTRA_VERSION_save"
634     elif ! $RELEASE; then
635         # if there is no patch series, then this is not a lustre specific
636         # kernel.  don't make it look like one
637         if [ -n "$SERIES" ]; then
638             #remove the @VERSION@ (lustre version)
639 #            EXTRA_VERSION=$(echo $EXTRA_VERSION | sed -e "s/\(.*_lustre\)\..*/\1/")
640 #            EXTRA_VERSION="${EXTRA_VERSION}-${TAG}.${TIMESTAMP}"
641             ! ( $PATCHLESS ) && EXTRA_VERSION="${EXTRA_VERSION}.${TIMESTAMP}"
642         fi
643     fi
644     # EXTRA_VERSION=${EXTRA_VERSION//-/_}
645
646     ALL_ARCHS="$BASE_ARCHS $BIGMEM_ARCHS $BOOT_ARCHS $JENSEN_ARCHS $SMP_ARCHS $BIGSMP_ARCHS $PSERIES64_ARCHS $UP_ARCHS"
647
648     BUILD_ARCHS=
649     for arch in $(uniqify "$ALL_ARCHS"); do
650         if [ -z "$TARGET_ARCHS" ] ||
651            [[ \ $TARGET_ARCHS\  = *\ $arch\ * ]]; then
652             BUILD_ARCHS="$BUILD_ARCHS $arch"
653         fi
654     done
655     [ "$BUILD_ARCHS" ] || usage 1 "No available target archs to build."
656     echo "Building for: $BUILD_ARCHS"
657 }
658
659 tarflags() {
660     local file="$1"
661
662     case "$file" in
663         '')
664             fatal 1 "tarflags(): File name argument missing."
665             ;;
666         *.tar.gz | *.tgz)
667             echo 'zxf'
668             ;;
669         *.tar.bz2)
670             echo 'jxf'
671             ;;
672         *.tar)
673             echo 'xf'
674             ;;
675         *)
676             fatal 1 "tarflags(): Unrecognized tar extension in file: $1"
677             ;;
678     esac
679
680 }
681
682 untar() {
683     local file="$1"
684
685     echo "Untarring ${file##*/}..."
686     tar $(tarflags "$file") "$file"
687
688 }
689
690 unpack_ofed() {
691
692     if ! untar "$KERNELTREE/OFED-${OFED_VERSION}.tgz"; then
693         return 1
694     fi
695     [ -d OFED ] || ln -sf OFED-[0-9].[0-9]* OFED
696
697 }
698
699 unpack_rdac() {
700
701     if ! untar "$KERNELTREE/rdac-LINUX-${RDAC_VERSION}-source.tar.gz"; then
702         return 1
703     fi
704     [ -d rdac-LINUX ] || ln -sf rdac-LINUX-[0-9][0-9].* rdac-LINUX
705
706 }
707
708 unpack_mptlinux() {
709
710     if ! unzip -p $KERNELTREE/MPTLINUX_RHEL5_SLES10_PH15-4.16.00.00-2.zip | tar xzvf - srpms-2/mptlinux-4.16.00.00-2.src.rpm; then
711         return 1
712     fi
713     mv srpms-2/mptlinux-4.16.00.00-2.src.rpm .
714
715 }
716
717 unpack_lustre() {
718
719     if [ -z "$LUSTRE" ]; then
720         local DATESTAMP=""
721
722         if [ -n "$USE_DATESTAMP" ]; then
723             DATESTAMP="-D '$DATE'"
724         fi
725
726         local DIRNAME="lustre-$TAG-$TIMESTAMP"
727
728         cvs -d "$CVSROOT" -qz3 co $DATESTAMP -d "$DIRNAME" lustre || \
729             fatal 1 "There was an error checking out toplevel Lustre from CVS."
730         pushd "$DIRNAME" > /dev/null
731         ./lustrecvs "$TAG" || \
732             fatal 1 "There was an error checking out Lustre/Portals/Build from CVS."
733         echo "Creating lustre tarball..."
734         sh autogen.sh || fatal 1 "There was an error running autogen.sh."
735         ./configure --disable-{modules,utils,liblustre,tests,doc} || \
736             fatal 1 "There was an error running ./configure to create makefiles."
737         make dist || fatal 1 "There was an error running 'make dist'."
738         LUSTRE=$PWD/lustre-*.tar.gz
739         popd > /dev/null
740     fi
741
742     untar "$LUSTRE" || fatal 1 "Error unpacking Lustre tarball"
743     [ -d lustre ] || ln -sf lustre-[0-9].[0-9]* lustre
744
745 }
746
747 do_patch_linux() {
748
749     local do_patch=${1:-true}
750
751     FULL_PATCH="$PWD/lustre-kernel-${TARGET}${EXTRA_VERSION_DELIMITER}${EXTRA_VERSION}.patch"
752     [ -f "$FULL_PATCH" ] && rm -f "$FULL_PATCH"
753     $do_patch && pushd linux >/dev/null
754     for series in $SERIES; do
755         echo -n "Applying series $series:"
756         for patchesdir in "$EXTERNAL_PATCHES" "$TOPDIR/lustre/lustre/kernel_patches"; do
757             [ -r "$patchesdir/series/$series" ] || continue
758             SERIES_FILE="$patchesdir/series/$series"
759             for patch in $(<"$SERIES_FILE"); do
760                 echo -n " $patch"
761                 PATCH_FILE="$patchesdir/patches/$patch"
762                 [ -r "$PATCH_FILE" ] || \
763                     fatal 1 "Patch $patch does not exist in Lustre tree."
764                 cat "$PATCH_FILE" >> "$FULL_PATCH" || {
765                     rm -f $FULL_PATCH
766                     fatal 1 "Error adding patch $patch to full patch."
767                 }
768                 if $do_patch; then
769                     patch -s -p1 < "$PATCH_FILE" 2>&1 || {
770                         rm -f $FULL_PATCH
771                         fatal 1 "Error applying patch $patch."
772                     }
773                 fi
774             done
775             break
776         done
777         echo
778     done
779     $do_patch && popd >/dev/null
780     echo "Full patch has been saved in ${FULL_PATCH##*/}."
781
782 }
783
784 build_lustre() {
785     local linux="$1"
786     local linuxobj="$2"
787
788     cp "$LUSTRE" SOURCES
789
790     pushd lustre >/dev/null
791
792     echo "Building Lustre RPMs for: $BUILD_ARCHS..."
793     local targets arch
794     for arch in $BUILD_ARCHS; do
795         targets="--target $arch $targets"
796     done
797
798     local confoptions="--with-linux=${linux}"
799     if $PATCHLESS; then
800         confoptions="--with-linux=${linux} --disable-server"
801     fi
802     if [ "$linuxobj" != "" ]; then
803         confoptions="$confoptions --with-linux-obj=${linuxobj}"
804     fi
805
806     ./configure $confoptions ${CONFIGURE_FLAGS} 2>&1
807     if [ "$?" != "0" ]; then
808         local saved_config="../config.log.$(date +%s)"
809         cp config.log $saved_config
810         chmod a+r $saved_config
811         echo "Saved config.log is at $saved_config"
812         cat /proc/mounts
813         ls -l /proc/$$
814         pwd
815         echo "config.log contents:"
816         cat config.log
817         popd
818         return 255
819     fi
820
821     gen_lustre_version
822
823     # hack. Somebody move build/lustre.spec to lustre.spec for b1_6
824     local lustre_spec
825     [ -f lustre.spec ] && lustre_spec=lustre.spec
826     [ -f build/lustre.spec ] && lustre_spec=build/lustre.spec
827
828     [ -f "$lustre_spec" ] && sed \
829         -e "s^Release: .*$^Release: $LUSTRE_EXTRA_VERSION^" \
830         < $lustre_spec \
831         > ../lustre.spec
832
833     local rpmbuildopt='-bb'
834     if $NORPM; then
835         rpmbuildopt='-bc'
836         echo NORPM mode. Only compiling.
837     fi
838
839     # convert the $PATCHLESS boolean to an empty/not-empty boolean
840     # as silly as this seems, it makes the syntax of the rpmbuild command
841     # simpler and not need an eval to deal with the quotes in the quotes
842     local is_patchless=""
843     if $PATCHLESS; then
844         is_patchless="yes"
845     fi
846
847     # ditto for the lustre-tests boolean
848     local lustre_tests=""
849     if ! $LUSTRE_TESTS; then
850         lustre_tests="no"
851     fi
852
853     $RPMBUILD $targets $rpmbuildopt ../lustre.spec \
854         ${is_patchless:+--define "lustre_name lustre-client"} \
855         ${lustre_tests:+--define "build_lustre_tests 0"} \
856         --define "configure_args $confoptions ${CONFIGURE_FLAGS}" \
857         --define "_tmppath $TMPDIR" \
858         --define "_topdir $TOPDIR" 2>&1 || \
859         fatal 1 "Error building rpms for $BUILD_ARCHS."
860
861     popd >/dev/null
862     ( $(skeep_ldiskfs_rpm $TAG) ) && return
863
864     pushd lustre/ldiskfs || return 255
865     make dist 2>&1
866     if [ "$?" != "0" ]; then
867         popd
868         return 255
869     fi
870     cp lustre-ldiskfs*.tar.gz $TOPDIR/SOURCES
871
872     gen_lustre_version
873
874     local ldiskfs_spec=lustre-ldiskfs.spec
875     [ -f "$ldiskfs_spec" ] && sed \
876     -e "s^Release: .*$^Release: $LUSTRE_EXTRA_VERSION^" \
877     < $ldiskfs_spec \
878     > ../lustre-ldiskfs.spec
879
880     if ! $RPMBUILD $targets $rpmbuildopt ../lustre-ldiskfs.spec \
881         --define "_tmppath /var/tmp" \
882         --define "_topdir $TOPDIR" 2>&1; then
883         popd
884         return 255
885     fi
886
887     if $DO_SRC; then
888         if ! $RPMBUILD -bs ../lustre-ldiskfs.spec \
889             --define "_tmppath /var/tmp" \
890             --define "_topdir $TOPDIR" 2>&1; then
891             popd
892             return 255
893         fi
894     fi
895     popd
896
897 }
898
899 stage() {
900
901     [ "$STAGEDIR" ] || return 0
902
903     for arch in $BUILD_ARCHS; do
904         rpmdir="${STAGEDIR}/${CANONICAL_TARGET}-${arch}"
905         echo "${0##*/}: Copying RPMs into ${rpmdir}"
906         mkdir -p "${rpmdir}"
907         cp -v RPMS/${arch}/*.rpm "${rpmdir}"
908         if [ -d RPMS/noarch ]; then
909             cp -v RPMS/noarch/*.rpm "${rpmdir}"
910         fi
911     done
912
913     cp -v "$LUSTRE" "$STAGEDIR"
914
915 }
916
917 #check if we need to build separate ldiskfs RPM
918 skeep_ldiskfs_rpm() {
919         local tag="$1"
920
921         local skip=false
922
923         if ! $LDISKFSRPM; then
924             skip=true
925         elif $PATCHLESS; then
926             skip=true
927         else
928             for skiptag in $SKIPLDISKFSRPM; do
929                 [[ $tag == $skiptag ]] && skip=true && break
930             done
931         fi
932
933         pushd $TOPDIR/BUILD/lustre-[1-9]* >/dev/null
934         grep -q '^SERVER_TRUE[ \t]=[ \t]#$' autoMakefile && skip=true
935         popd >/dev/null
936
937         echo $skip
938
939 }
940
941 #generate LUSTRE_EXTRA_VERSION from EXTRA_VERSION
942 gen_lustre_version() {
943
944     LUSTRE_EXTRA_VERSION="${lnxmaj}${EXTRA_VERSION_DELIMITER}${EXTRA_VERSION}${TARGET_DELIMITER}${RPMSMPTYPE}"
945     LUSTRE_EXTRA_VERSION=${LUSTRE_EXTRA_VERSION//-/_}
946
947 }
948
949 set_rpm_smp_type() {
950
951     local infact_arch="${TARGET_ARCH}"
952
953     RPMSMPTYPE=""
954     [ "$infact_arch" == "i586" ] && infact_arch="i686"
955
956     local smp_type
957     for smp_type in $SMP_ARCHS; do
958         [ $infact_arch == $smp_type ] && RPMSMPTYPE=smp && break
959     done
960
961     for smp_type in $BIGSMP_ARCHS; do
962         [ $infact_arch == $smp_type ] && RPMSMPTYPE=bigsmp && break
963     done
964
965     for smp_type in $DEFAULT_ARCHS; do
966         [ $infact_arch == $smp_type ] && RPMSMPTYPE=default && break
967     done
968
969 }
970
971 # This function takes a linux source pool and digs out the linux release
972 # from it
973 find_linux_release() {
974     local SRCDIR="$1"
975
976     local LINUXRELEASEHEADER=$SRCDIR/include/linux/version.h
977     if [ -s $SRCDIR/include/linux/utsrelease.h ]; then
978         LINUXRELEASEHEADER=$SRCDIR/include/linux/utsrelease.h
979     fi
980
981     sed -ne 's/#define UTS_RELEASE "\(.*\)"$/\1/p' $LINUXRELEASEHEADER
982
983 }
984
985 # XXX this needs to be re-written as a wrapper around find_rpm
986 #     or just gotten rid of.  :-)
987 find_linux_rpm() {
988     local prefix="$1"
989     local delimiter=${2:-"-"}
990
991     local pathtorpms="${KERNELRPMSBASE}/${lnxmaj}/${DISTRO}"
992     [ -d $pathtorpms ] || return 255
993
994     local kernelbinaryrpm rpmfile
995     local wanted_kernel="${lnxmaj}${delimiter}${lnxrel}"
996
997     local arch ret=1
998     for arch in $TARGET_ARCHS_ALL; do
999         local found_rpm="" rpm
1000         for rpm in ${pathtorpms}/${arch}/*.rpm; do
1001             if rpm -q --provides -p "$rpm" 2>&3 | grep -q "kernel${prefix} = $wanted_kernel" 2>&3; then
1002
1003                 found_rpm="$rpm"
1004                 ret=0
1005                 break
1006             fi
1007         done
1008         [ -f "$found_rpm" ] && break
1009     done
1010
1011     echo "$found_rpm"
1012     return $ret
1013
1014 }
1015
1016 # unpack kernel(/source/devel) RPM
1017 #
1018 # This function and it's setting of $LINUX and $LINUXOBJ is a total hack that
1019 # needs to completely refactored.  It completely ingores that $BUILD_ARCHS may
1020 # contain a list of arches for which rpmbuild commands (including the one for
1021 # lustre itself)
1022 unpack_linux_devel_rpm() {
1023     local kernelrpm="${1}"
1024     # it's worth noting that neither sles10 nor rhel5 appear to use their
1025     # extra_version delimiter for the dirname under /usr/src, so we could
1026     # probably just get rid of this parameter
1027     local delimiter=${2:-"-"}
1028
1029     [ -f "$kernelrpm" ] || return 255
1030     [ -d $TOPDIR/reused ] || mkdir $TOPDIR/reused || return 255
1031
1032     pushd $TOPDIR/reused &>/dev/null || return 255
1033
1034     if ! rpm2cpio < "$kernelrpm" | cpio -id > /dev/null 2>&1; then
1035         return 255
1036     fi
1037
1038     # call a distro specific hook, if available
1039     if type -p unpack_linux_devel_rpm-$DISTRO; then
1040         unpack_linux_devel_rpm-$DISTRO "$kernelrpm"
1041     fi
1042
1043     popd &>/dev/null
1044
1045     find_linux_devel_paths $TOPDIR/reused
1046
1047     return 0
1048
1049 }
1050
1051 # XXX - this rhel/sles goop needs abstracting out into the
1052 #       lbuild-{rhel5,sles10} method files
1053 find_linux_devel_paths() {
1054     local path="$1"
1055
1056     local RC=0
1057
1058     pushd $path
1059         # RHEL-style and SLES-style rpms
1060         # XXX - until bug 19336 cleans this up, we need to extricate the
1061         #       ${lnxmin}- from the $lnxrel
1062         local paths="kernels/${lnxmaj}${lnxmin}${delimiter}${lnxrel}-${TARGET_ARCH} linux-${lnxmaj}${lnxmin}${delimiter}${lnxrel##${lnxmin#.}-}"
1063
1064         local path
1065         for path in $paths; do
1066             local src='usr/src'
1067
1068             if [ -d "$src/$path/" ]; then
1069                 LINUX="$(pwd)/$src/$path"
1070             fi
1071             # SLES has a separate -obj tree
1072             if [ -d "$src/${path}-obj" ]; then
1073                 local src="$src/${path}-obj"
1074                 local objects="$TARGET_ARCH/$RPMSMPTYPE"
1075
1076                 # Novell, are you *TRYING* to make life hard for me?
1077                 if [ -d "$src/powerpc" ]; then
1078                     objects="powerpc/$TARGET_ARCH"
1079                 elif [ $TARGET_ARCH == 'i686' ]; then
1080                     objects="i386/$RPMSMPTYPE"
1081                 fi
1082
1083                 LINUXOBJ="$(pwd)/$src/$objects"
1084             fi
1085         done
1086         if [ -z "$LINUX" ]; then
1087             RC=255
1088         else
1089             # dig out the release version
1090             LINUXRELEASE=$(find_linux_release ${LINUXOBJ:-$LINUX})
1091             if [ -z "$LINUXRELEASE" ]; then
1092                 echo "Failed to find linux release in ${LINUXOBJ:-$LINUX}"
1093                 RC=255
1094             fi
1095         fi
1096     popd
1097     return $RC
1098 }
1099
1100 build_kernel_ib() {
1101     local linux="$1"
1102
1103     # build kernel-ib{,-devel}
1104     local K_SRC="K_SRC"
1105     # ofed 1.3 had a bug in the rpm spec
1106     if [ "$OFED_VERSION" = "1.3" ]; then
1107         K_SRC="KSRC"
1108     fi
1109
1110     local OFED_CORE="--with-core-mod --with-ipoib-mod --with-sdp-mod --with-user_mad-mod --with-user_access-mod --with-addr_trans-mod --with-rds-mod --with-qlgc_vnic-mod --with-madeye-mod"
1111     local OFED_HARDWARE="--with-mthca-mod --with-mlx4-mod --with-mlx4_en-mod --with-cxgb3-mod --with-nes-mod"
1112     # some I/B drivers are architecture dependent and kernel-ib's configure
1113     # does not figure it out for us ~sigh~
1114     case "$TARGET_ARCH" in
1115         ppc64)
1116             OFED_HARDWARE="$OFED_HARDWARE --with-ehca-mod"
1117             ;;
1118     esac
1119     # we're no longer shipping the OFED iSCSI
1120     #OFED_ISCSI="--with-srp-mod --with-srp-target-mod"
1121     ## ISER module has no backport support as of OFED 1.5 (i.e. only builds on
1122     ##kernels >= 2.6.30)
1123     #if [[ $OFED_VERSION = 1.[0-4]* ]]; then
1124     #   OFED_ISCSI="$OFED_ISCSI --with-iser-mod"
1125     #fi
1126
1127     # assume we are just rebuilding the SRPM
1128     local BUILD_TYPE=${BUILD_TYPE:-"--rebuild"}
1129     local SOURCE="${TOPDIR}/OFED/SRPMS/ofa_kernel-*.src.rpm"
1130
1131     # but switch to building from the SPEC if we need to apply patches
1132     if ls ${TOPDIR}/lustre/build/patches/ofed/* >/dev/null; then
1133         BUILD_TYPE="-bb"
1134         rpm --define "_topdir ${TOPDIR}" -ivh $SOURCE
1135         SOURCE="${TOPDIR}/SPECS/ofa_kernel.spec"
1136         local file ed_fragment1 ed_fragment2 n=1
1137         for file in ${TOPDIR}/lustre/build/patches/ofed/*; do
1138             ed_fragment1="$ed_fragment1
1139 Patch$n: ${file%%*/}"
1140             ed_fragment2="$ed_fragment2
1141 %patch$n -p0"
1142             cp $file ${TOPDIR}/SOURCES
1143             let n=$n+1
1144         done
1145
1146         ed $SOURCE <<EOF
1147 /^Source: /a
1148 $ed_fragment1
1149 .
1150 /^%setup /a
1151 $ed_fragment2
1152 .
1153 wq
1154 EOF
1155     fi
1156
1157     local linuxrelease=$(find_linux_release "$linux")
1158     if ! $RPMBUILD $BUILD_TYPE --define 'build_kernel_ib 1' --define 'build_kernel_ib_devel 1' \
1159                   --define "_topdir ${TOPDIR}" --target ${TARGET_ARCH} \
1160                   --define "KVERSION ${linuxrelease}" \
1161                   --define "$K_SRC ${linux}" \
1162                   --define "LIB_MOD_DIR /lib/modules/${linuxrelease}/updates" \
1163                   ${OFA_KERNEL_RELEASE:+--define "_release $OFA_KERNEL_RELEASE"} \
1164                   --define "configure_options --without-quilt $OFED_CORE $OFED_HARDWARE $OFED_ISCSI" \
1165                   ${SOURCE} 2>&1; then
1166         fatal 1 "Error building kernel-ib"
1167     fi
1168
1169 }
1170
1171 store_for_reuse() {
1172         local articles="$1"
1173         local module="$2"
1174         local location="$3"
1175         local signature="$4"
1176         local use_links="$5"
1177
1178         local linkflag=""
1179         if $use_links; then
1180             linkflag="l"
1181         fi
1182
1183         location="$location"/"$signature"/"$module"
1184         mkdir -p "$location"
1185         # the cleanup script removes any directory that doesn't have a
1186         # .lastused, so let's try to prevent that as soon as we can
1187         # this solution still slightly racy with the cleanup script
1188         # but the race is a lot tighter now
1189         touch -t 197001010000 "$location/.lastused"
1190         ## use eval/echo here to make sure shell expansions are performed
1191         #if ! cp -a${linkflag} $(eval echo $articles) "$location"; then
1192         local article
1193         for article in $(eval echo $articles); do
1194             if ! cp -a${linkflag} "$article" "$location"; then
1195                 error "Failed to copy \"$article\" to \"$location\" in store_for_reuse()"
1196                 # rename the cache location so that it's not cached
1197                 # product, but is around for analysis
1198                 mv "$location"{,-bad-$(date +%s)} ||
1199                     error "failed to clean up a failed cache attempt" \
1200                           "in \"$location\" -- manual cleanup will be" \
1201                           "necessary"
1202                 return 1
1203             fi
1204         done
1205
1206         # flag the cache as complete (i.e. in case lbuild was previously
1207         # interrupted while caching)
1208         touch "$location/.lastused"
1209
1210         return 0
1211
1212 }
1213
1214 reuse() {
1215     local module="$1"
1216     local dest="$2"
1217     local use_links="${3:-false}"
1218     local signature="$4"
1219
1220     if [ -n "$REUSEBUILD" ] && [ -d "$REUSEBUILD/$signature/$module" ]; then
1221         if [ ! -f "$REUSEBUILD/$signature/$module/.lastused" ]; then
1222             # the .lastused flag is populated at the end of the caching to
1223             # signal that the caching was completed.  if that flag is not
1224             # there, then the cache is invalid (and should be removed in fact)
1225             mv "$REUSEBUILD/$signature/$module"{,-bad-$(date +%s)} ||
1226                 fatal 1 "failed to clean up a bad cache in location $REUSEBUILD/$signature/$module\" -- manual cleanup will be necessary"
1227             return 1
1228         fi
1229
1230         # so that we know how stale this entry is
1231         touch $REUSEBUILD/$signature/$module/.lastused
1232
1233         if $use_links; then
1234             if ls $REUSEBUILD/$signature/$module/* >/dev/null 2>&1; then
1235                 cp -al $REUSEBUILD/$signature/$module/* $dest/
1236             fi
1237         else
1238             # copying is pretty heavy
1239             # cp -a $REUSEBUILD/$signature/$module/* $dest/
1240             # do some creative symlinking instead
1241             local dir
1242             for dir in BUILD SRPMS SPECS; do
1243                 if ls $REUSEBUILD/$signature/$module/$dir/* >/dev/null 2>&1; then
1244                     ln -s $REUSEBUILD/$signature/$module/$dir/* $dest/$dir
1245                 fi
1246             done
1247             # sources have to be copied by file because we need SOURCES to
1248             # be a dir we can write into
1249 # could overrun ls's arg list here
1250             #ls $REUSEBUILD/$signature/$module/SOURCES/* |
1251             find $REUSEBUILD/$signature/$module/SOURCES/ -type f |
1252                 xargs ln -t $dest/SOURCES -s
1253
1254             # same for RPMS/* dirs
1255 # could overrun ls's arg list here
1256             #ls $REUSEBUILD/$signature/$module/RPMS/$TARGET_ARCH/* |
1257             local dir
1258             for dir in $REUSEBUILD/$signature/$module/RPMS/*; do
1259                 mkdir -p $dest/RPMS/${dir##*/}
1260                 find $dir -type f |
1261                   xargs ln -t $dest/RPMS/${dir##*/} -s
1262             done
1263
1264         fi
1265         return 0
1266     else
1267         return 1
1268     fi
1269 }
1270
1271 basearch() {
1272     local arch="$1"
1273
1274     if [[ $arch = i[3456]86 ]]; then
1275         echo "i386"
1276     else
1277         echo "$arch"
1278     fi
1279
1280 }
1281
1282 #
1283 # in a given directory, find the first rpm matching given requirements
1284 #
1285 find_rpm() {
1286     local dir="$1"
1287     local match_type="$2"
1288     local match="$3"
1289
1290     pushd "$dir" > /dev/null || \
1291         fatal 1 "Unable to chdir to directory \"$dir\" in find_rpm()"
1292
1293     local file
1294     for file in $(ls *.rpm); do
1295         if [ ! -f "$file" ]; then
1296             continue
1297         fi
1298         case "$match_type" in
1299             provides)
1300                 # match is any valid ERE (i.e. given to egrep) match
1301                 if rpm -q --provides -p "$file" 2>&3 | egrep -q "$match"; then
1302                     echo "$file"
1303                     popd >/dev/null
1304                     return 0
1305                 fi
1306                 ;;
1307             *)
1308                 popd >/dev/null
1309                 fatal 1 "Unknown match type \"$match_type\" given to find_rpm()"
1310                 ;;
1311         esac
1312     done
1313
1314     popd >/dev/null
1315     return 1
1316 }
1317
1318 build_kernel_with_srpm() {
1319     local outfd=$1
1320
1321     if [ -z "$outfd" ] || [ $outfd = 1 ]; then
1322         fatal 1 "You must supply a file descriptor to ${FUNCNAME[0]} and it cannot be 1"
1323     fi
1324
1325     # need to generate the patch for this target
1326     do_patch_linux false >&${outfd}    # sets global $FULL_PATCH (yeah, yuck)
1327
1328     # get an md5sum of the kernel patch + config for reuse check
1329     # XXX really, there needs to be a signature and a CONFIG_FILE per arch
1330     #     in BUILD_ARCHS
1331     local release_str
1332     if $RELEASE; then
1333         local release_str="RELEASE=$RELEASE\n"
1334     fi
1335     local REUSE_SIGNATURE=$({ echo -en $release_str; echo $BUILD_GEN; cat $CONFIG_FILE $TARGET_FILE $FULL_PATCH; } | md5sum | cut -d" " -f1)
1336
1337     # see if we can link to the reuse pool
1338     # XXX - hrm.  i'm not convinced this doesn't belong in the reuse "library"
1339     local CAN_LINK_FOR_REUSE=false
1340     touch $REUSEBUILD/$$
1341     if cp -al $REUSEBUILD/$$ $TOPDIR/ 2>/dev/null; then
1342         CAN_LINK_FOR_REUSE=true
1343     fi
1344     rm $REUSEBUILD/$$
1345
1346     # the extra version string to use for the kernel (which might be a reused
1347     # kernel, remember)
1348     local kernel_extra_version=""
1349     if $REUSERPM && ! reuse kernel "$TOPDIR" "$CAN_LINK_FOR_REUSE" \
1350                                    "$REUSE_SIGNATURE"; then
1351         # nothing cached, build from scratch
1352         if [ ! -r "$KERNELDIR/$KERNEL_SRPM" ]; then
1353             echo "Downloading kernel SRPM"
1354             download_srpm "$CANONICAL_TARGET" "$KERNEL_SRPM" >&${outfd}
1355         fi
1356
1357         if ! rpm -ivh $KERNELDIR/$KERNEL_SRPM \
1358                   --define "_topdir $TOPDIR" >&${outfd} 2>&1; then
1359             # should we clean this up or leave it for analysis?
1360             #rm -rf $RPMTOPDIR
1361             fatal 1 "Error installing kernel SRPM."
1362         fi
1363
1364         # put the Lustre kernel patch into the RPM build tree
1365         cp $FULL_PATCH $TOPDIR/SOURCES/linux-${lnxmaj}-lustre.patch
1366         prepare_and_build_srpm >&${outfd} ||
1367             fatal 1 "failed to prepare_and_build_srpm"
1368
1369         # store the resulting kernel RPM build tree for future use
1370         echo "caching the built kenel for future builds..." >&${outfd}
1371         if ! store_for_reuse "$TOPDIR/{SPECS,SOURCES,BUILD,SRPMS,RPMS}" \
1372                              "kernel" "$REUSEBUILD" "$REUSE_SIGNATURE" \
1373                              "$CAN_LINK_FOR_REUSE"; then
1374             error "Failed to store kernel RPMS for reuse"
1375             echo "unknown"
1376             return 1
1377         fi
1378     fi  # build reuse
1379
1380     # figure out the EXTRA_VERSION of the kernel we built or are re-using
1381     local KERNEL_RPM
1382     if ! KERNEL_RPM=$(find_rpm "$TOPDIR/RPMS/$TARGET_ARCH/" provides "^kernel ="); then
1383         fatal 1 "Failed to find a kernel RPM in $TOPDIR/RPMS/$TARGET_ARCH/"
1384     fi
1385     kernel_extra_version=$(rpm -q --queryformat "%{RELEASE}" -p $TOPDIR/RPMS/$TARGET_ARCH/$KERNEL_RPM)
1386
1387     # should now have the following RPMs
1388     # $TOPDIR/RPMS/$arch/kernel-lustre-2.6.18-53.1.21.el5_lustre.1.6.5.1.$arch.rpm
1389     # $TOPDIR/RPMS/$arch/kernel-lustre-devel-2.6.18-53.1.21.el5_lustre.1.6.5.1.$arch.rpm
1390     # $TOPDIR/RPMS/$arch/kernel-lustre-headers-2.6.18-53.1.21.el5_lustre.1.6.5.1.$arch.rpm
1391     # $TOPDIR/RPMS/$arch/kernel-lustre-debuginfo-common-2.6.18-53.1.21.el5_lustre.1.6.5.1.$arch.rpm
1392     # $TOPDIR/RPMS/$arch/kernel-lustre-debuginfo-2.6.18-53.1.21.el5_lustre.1.6.5.1.$arch.rpm
1393
1394     echo $kernel_extra_version
1395     return 0
1396
1397 }
1398
1399 build_mptlinux() {
1400     local linux="$1"
1401     local version="$2"
1402
1403     if [ -z "$version" -o "$version" = "inkernel" ]; then
1404         return 0
1405     fi
1406
1407     local targets arch
1408     for arch in $BUILD_ARCHS; do
1409         targets="--target $arch $targets"
1410     done
1411
1412     local rpmbuildopt='-bb'
1413     if $NORPM; then
1414         rpmbuildopt='-bc'
1415         echo NORPM mode. Only compiling.
1416     fi
1417
1418     # if only we could just rebuild the src.rpm.  but the included spec
1419     # is a real pig's breakfast.  just check out the patch we need to
1420     # apply to it to make it useful.
1421     #$RPMBUILD --rebuild \
1422     #          --define "_topdir ${TOPDIR}" --target ${TARGET_ARCH} \
1423     #          ${TOPDIR}/mptlinux-*.src.rpm
1424     rpm -ivh --define "_topdir ${TOPDIR}" ${TOPDIR}/mptlinux-*.src.rpm
1425
1426     # now the big honkin' patch to the spec file
1427     pushd ${TOPDIR}/SPECS
1428     # to regen this patch use:
1429     # !!cd ~/rpm/SPECS/ && diff -u mptlinux.spec{.dist,}
1430     patch -p0 < ${TOPDIR}/lustre/build/mptlinux.spec.patch || fatal 1 "failed to patch mptlinux.spec"
1431     popd
1432
1433     local targets arch
1434         for arch in $BUILD_ARCHS; do
1435         targets="--target $arch $targets"
1436     done
1437
1438     local rpmbuildopt='-bb'
1439     if $NORPM; then
1440         rpmbuildopt='-bc'
1441         echo NORPM mode. Only compiling.
1442     fi
1443
1444     if ! $RPMBUILD $targets $rpmbuildopt \
1445                   --define "_tmppath /var/tmp" \
1446                   --define "_topdir ${TOPDIR}" \
1447                   --define "kernel_obj $linux" \
1448                   ${TOPDIR}/SPECS/mptlinux.spec 2>&1; then
1449         return 1
1450     fi
1451     if $DO_SRC; then
1452         if ! $RPMBUILD -bs \
1453                       --define "_tmppath /var/tmp" \
1454                       --define "_topdir ${TOPDIR}" \
1455                       --define "kernel_obj $linux" \
1456                       ${TOPDIR}/SPECS/mptlinux.spec 2>&1; then
1457             return 1
1458         fi
1459     fi
1460
1461     return 0
1462
1463 }
1464
1465 # build RDAC
1466 build_rdac() {
1467     local linux="$1"
1468     local version="$2"
1469
1470     if [ -z "$version" -o "$version" = "inkernel" ]; then
1471         return 0
1472     fi
1473
1474     # note that we use an _, not a . before the spec on purpose.  we are not
1475     # allowed to have more than one file with a .spec trailer in a tarball
1476     # that is supposed to be usable with rpmbuild
1477     cp lustre/build/rdac_spec ${TOPDIR}/SPECS/rdac.spec || fatal 1 "Could not find rdac.spec in lustre/build" 
1478
1479     local targets arch
1480     for arch in $BUILD_ARCHS; do
1481         targets="--target $arch $targets"
1482     done
1483
1484     local rpmbuildopt='-bb'
1485     if $NORPM; then
1486         rpmbuildopt='-bc'
1487         echo NORPM mode. Only compiling.
1488     fi
1489
1490     local distro
1491     case $DISTRO in
1492      rhel5)     distro="REDHAT"
1493                 ;;
1494     sles1*)     distro="SUSE"
1495                 ;;
1496          *)     echo "$DISTRO not supported by RDAC, skipping"
1497                 return 0
1498                 ;;
1499     esac
1500     if ! $RPMBUILD $targets $rpmbuildopt --define "dist $distro" \
1501                   --define "_tmppath /var/tmp" \
1502                   --define "_topdir ${TOPDIR}" \
1503                   --define "kernel_obj $linux" \
1504                   ${TOPDIR}/SPECS/rdac.spec 2>&1; then
1505         return 1
1506     fi
1507     if $DO_SRC; then
1508         if ! $RPMBUILD -bs --define "dist $distro" \
1509                       --define "_tmppath /var/tmp" \
1510                       --define "_topdir ${TOPDIR}" \
1511                       --define "kernel_obj $linux" \
1512                       ${TOPDIR}/SPECS/rdac.spec 2>&1; then
1513             return 1
1514         fi
1515     fi
1516
1517     return 0
1518 }
1519
1520 # build OFED
1521 # globals used:
1522 #    TOPDIR
1523 #    REUSEBUILD, REUSERPM
1524 #    CONFIGURE_FLAGS
1525
1526 build_ofed() {
1527     local linux="$1"
1528     local ofed_version="$2"
1529
1530     # before lustre, build kernel-ib
1531     if [ -z "$ofed_version" -o "$ofed_version" = "inkernel" ]; then
1532         return 0
1533     fi
1534
1535     if [ -n "$REUSEBUILD" ]; then
1536         # see if we can link to the reuse pool
1537             # XXX - hrm.  i'm not convinced this doesn't belong in the reuse
1538             #       "library"
1539         local CAN_LINK_FOR_REUSE=false
1540         touch $REUSEBUILD/$$
1541         if cp -al $REUSEBUILD/$$ $TOPDIR/; then
1542             CAN_LINK_FOR_REUSE=true
1543         fi
1544         rm $REUSEBUILD/$$
1545     fi
1546
1547     local REUSE_SIGNATURE=$({ echo "$ofed_version";
1548                               echo "$(find_linux_release ${linux})";
1549                               cat "${linux}/include/linux/autoconf.h"; } |
1550                             md5sum | cut -d" " -f1)
1551     if ! $REUSERPM || ! reuse ofed "$TOPDIR" "$CAN_LINK_FOR_REUSE" \
1552                                    "$REUSE_SIGNATURE"; then
1553         # stash away the existing built articles for a moment
1554         mkdir bak
1555         mv {BUILD,{S,}RPMS,S{OURCE,PEC}S} bak
1556         function mv_back {
1557             pushd bak
1558             find . | cpio -pudlm ..
1559             popd
1560             rm -rf bak
1561         }
1562         create_rpmbuild_dirs
1563         # build it
1564         build_kernel_ib "${linux}"
1565         if ! store_for_reuse "$TOPDIR/{SPECS,SOURCES,BUILD,SRPMS,RPMS}" \
1566                              "ofed" "$REUSEBUILD" "$REUSE_SIGNATURE" \
1567                              "$CAN_LINK_FOR_REUSE"; then
1568             error "Failed to store OFED RPMS for reuse"
1569             mv_back
1570             return 1
1571         fi
1572         # put the stuff we stashed away back
1573         mv_back
1574     fi
1575
1576     pushd "$TOPDIR" >/dev/null
1577     rm -rf kernel-ib-devel
1578     mkdir kernel-ib-devel
1579     cd kernel-ib-devel
1580     # the actual ofed RPMs don't have the -rc$n or -$date string appened that
1581     # might be present on the file
1582     local linuxrelease=$(find_linux_release "$linux")
1583     ofed_version=$(echo $ofed_version |
1584                    sed -re 's/-(20[0-9]{6,6}-[0-9]{4,4}|rc[0-9]*)$//')
1585     local rpm=$(ls $TOPDIR/RPMS/*/kernel-ib-devel-${ofed_version}-${linuxrelease//-/_}.*.rpm)
1586     rpm2cpio -itv < $rpm | cpio -id
1587     CONFIGURE_FLAGS="--with-o2ib=$(pwd)/usr/src/ofa_kernel ${CONFIGURE_FLAGS}"
1588     popd >/dev/null
1589
1590 }
1591
1592 build_with_srpm() {
1593
1594     if ! $PATCHLESS; then
1595         local kernel_extra_version
1596         if ! kernel_extra_version=$(build_kernel_with_srpm ${STDOUT}); then
1597             fatal 1 "Failed to build the kernel from it's SRPM"
1598         fi
1599
1600         for arch in $BUILD_ARCHS; do
1601             local kernel_devel_rpm
1602             if ! kernel_devel_rpm=$(find_rpm "$TOPDIR/RPMS/$arch/" provides "^$(devel_kernel_name $KERNEL_LUSTRE_NAMING) ="); then
1603                 fatal 1 "Failed to find a kernel development RPM in $TOPDIR/RPMS/$arch/"
1604             fi
1605
1606             # install the -devel RPM in preparation for the lustre build
1607             # note that the EXTRA_VERSION_DELIMITER is *NOT* used in the
1608             # version of the directory name under /usr/src
1609             if ! lnxrel="$kernel_extra_version" unpack_linux_devel_rpm \
1610                            "$TOPDIR/RPMS/$arch/$kernel_devel_rpm" "-"; then
1611                 fatal 1 "Could not find the Linux tree in $TOPDIR/RPMS/$arch/$kernel_devel_rpm"
1612             fi
1613         done
1614     else
1615         # need to find and unpack the vendor's own kernel-devel for patchless
1616         # client build
1617         local kernelrpm
1618         if ! kernelrpm=$(find_linux_rpm "-$DEVEL_KERNEL_TYPE" ${EXTRA_VERSION_DELIMITER:-"-"}); then
1619             fatal 1 "Could not find the kernel-$DEVEL_KERNEL_TYPE RPM in ${KERNELRPMSBASE}/${lnxmaj}/${DISTRO}"
1620         fi
1621         if ! lnxrel="$lnxrel" unpack_linux_devel_rpm "$kernelrpm" "-"; then
1622             fatal 1 "Could not find the Linux tree in $kernelrpm"
1623         fi
1624     fi
1625
1626     build_ofed "${LINUXOBJ:-$LINUX}" "$OFED_VERSION" ||
1627         fatal 1 "error building OFED"
1628
1629     if ! $PATCHLESS; then
1630         # only need RDAC for the server
1631         build_rdac "${LINUXOBJ:-$LINUX}" "$RDAC_VERSION" ||
1632             fatal 1 "error building RDAC"
1633     fi
1634
1635     build_mptlinux "${LINUXOBJ:-$LINUX}" "$MPTLINUX_VERSION" ||
1636         fatal 1 "error building mptlinux"
1637
1638     # now build Lustre
1639     if build_lustre "$LINUX" "$LINUXOBJ"; then
1640         # the build worked.  resolve any symlinked files (i.e. from reuse)
1641         # in RPMS/$arch to real files so that that that huge mess of
1642         # complication known as LTS can copy them yet somewhere else.
1643         # is it any wonder this whole process is so damn so?  anyone ever
1644         # heard of hardlinks?  it this cool new thing that allows you save
1645         # tons of time and space by creating... well you can go read about
1646         # them if you have not heard about them yet.
1647         # can i say how much the implemenation of all of this really impedes
1648         # RPM reuse?
1649         pushd RPMS/$TARGET_ARCH
1650             for file in *; do
1651                 if [ -h $file ]; then
1652                     cp $file foo
1653                     mv foo $file
1654                 fi
1655             done
1656         popd
1657     else
1658         return 1
1659     fi
1660
1661 }
1662
1663 create_rpmbuild_dirs() {
1664
1665     [ -d RPMS ] || mkdir RPMS
1666     for arch in $BUILD_ARCHS; do
1667         if [[ $arch = i?86 ]]; then
1668             # some stupidity in the sles11 kernel spec requires an RPMS/i386
1669             # even if the target arch is i686
1670             [ -d RPMS/i386 ] || mkdir RPMS/i386
1671         fi
1672         [ -d RPMS/$arch ] || mkdir RPMS/$arch
1673     done
1674     [ -d BUILD ] || mkdir BUILD
1675     [ -d SOURCES ] || mkdir SOURCES
1676     [ -d SPECS ] || mkdir SPECS
1677     [ -d SRPMS ] || mkdir SRPMS
1678
1679 }
1680
1681 new_list() {
1682
1683     echo ""
1684
1685 }
1686
1687 add_list() {
1688     local list="$1"
1689     local item="$2"
1690
1691     echo "$list $item"
1692
1693 }
1694
1695 is_list_member() {
1696     local list="$1"
1697     local item="$2"
1698
1699     [[ $list\  == *\ $item\ * ]]
1700
1701 }
1702
1703 #########################################################################
1704 # Generate a backtrace through the call stack.
1705 #
1706 # Input: None
1707 # Output: None
1708 #########################################################################
1709 backtrace() {
1710     local strip=${1:-1}
1711
1712     local funcname="" sourcefile="" lineno="" n
1713
1714     echo "Call stack: (most recent first)"
1715     for (( n = $strip ; n < ${#FUNCNAME[@]} ; ++n )) ; do
1716         funcname=${FUNCNAME[$n - 1]}
1717         sourcefile=$(basename ${BASH_SOURCE[$n]})
1718         lineno=${BASH_LINENO[$n - 1]}
1719         if [ $n = 1 ]; then
1720             let lineno-=11
1721         fi
1722         # Display function arguments
1723         if [[ ! -z "${BASH_ARGV[@]}" ]]; then
1724             local args newarg j p=0
1725             for (( j = ${BASH_ARGC[$n - 1]}; j > 0; j-- )); do
1726                 newarg=${BASH_ARGV[$j + $p - 1]}
1727                 args="${args:+${args} }'${newarg}'"
1728             done
1729             let p+=${BASH_ARGC[$n - 1]}
1730         fi
1731         echo "  ${funcname} ${args:+${args} }at ${sourcefile}:${lineno}"
1732     done
1733
1734     echo
1735     echo "BEGIN BACKTRACE"
1736
1737     #echo ${BASH_LINENO[*]}
1738     #echo ${BASH_SOURCE[*]}
1739     #echo ${FUNCNAME[*]}
1740     local i=$((${#FUNCNAME[@]} - 1))
1741     while [ $i -ge 0 ]; do
1742         local lineno=${BASH_LINENO[$i]}
1743         if [ $i = 0 ]; then
1744             let lineno-=11
1745         fi
1746         local SOURCELINE="${BASH_SOURCE[$i + 1]}:${lineno}"
1747         # Can't figure out how to get function args from other frames...
1748         local FUNCTION="${FUNCNAME[$i]}()"
1749         echo "$SOURCELINE:$FUNCTION"
1750         i=$((i - 1))
1751     done
1752
1753     echo "END BACKTRACE"
1754
1755     echo $BACKTRACE
1756
1757 }
1758
1759 seen_list=$(new_list)
1760 trap 'set +x;
1761 echo "An unexpected error has occurred at ${BASH_SOURCE[0]##*/}:$((LINENO-1)).
1762 Unfortunately the above line number in the message may or may not be correct,
1763 but details have been send to the lbuild maintainer.  Attempting to continue."; (echo "Untrapped error"
1764 echo
1765 # have we seen this one
1766 echo "checking seen list for ${BASH_SOURCE[0]}:${BASH_LINENO[0]}"
1767
1768 if is_list_member "$seen_list" "${BASH_SOURCE[0]}:${BASH_LINENO[0]}"; then
1769   echo "seen this one already"
1770 else
1771   seen_list=$(add_list "$seen_list" "${BASH_SOURCE[0]}:${BASH_LINENO[0]}")
1772 fi
1773 backtrace
1774 echo
1775 echo "Environment:"
1776 set
1777 ) | mail -s "Untrapped error at ${BASH_SOURCE[0]##*/}:$((LINENO-15)) on $HOSTNAME" brian@sun.com >&2; set $xtrace' ERR
1778 set -E
1779
1780 [ -r ~/.lbuildrc ] && . ~/.lbuildrc
1781
1782 options=$(getopt -o d:D:h -l kerneltree:,distro:,kernelrpm:,reusebuild:,patchless,ldiskfs,ccache,reuse:,norpm,disable-datestamp,external-patches:,timestamp:,extraversion:,kerneldir:,linux:,lustre:,nodownload,nosrc,ofed-version:,publish,release,set-value:,src,stage:,tag:,target:,target-archs:,with-linux:,xen -- "$@")
1783
1784 if [ $? != 0 ]; then
1785     usage 1
1786 fi
1787
1788 eval set -- "$options"
1789
1790 while [ "$1" ]; do
1791     case "$1" in
1792         '')
1793             usage 1
1794             ;;
1795         --ccache)
1796             CCACHE='ccache'
1797             shift
1798             ;;
1799         -d)
1800             CVSROOT=$2
1801             shift 2
1802             ;;
1803         -D)
1804             DATE=$2
1805             shift 2
1806             ;;
1807         --external-patches)
1808             EXTERNAL_PATCHES=$2
1809             shift 2
1810             ;;
1811         --extraversion)
1812             EXTRA_VERSION=$2
1813             shift 2
1814             ;;
1815         --help | -h)
1816             usage 0
1817             ;;
1818         --kerneldir)
1819             KERNELDIR=$2
1820             shift 2
1821             ;;
1822         --kerneltree)
1823             if ! KERNELTREE=$(canon_path "$2"); then
1824                 fatal 1 "Could not determine the canonical location of $2"
1825             fi
1826             shift 2
1827             ;;
1828         --linux | --with-linux)
1829             if ! LINUX=$(canon_path "$2"); then
1830                 fatal 1 "Could not determine the canonical location of $2"
1831             fi
1832             shift 2
1833             ;;
1834         --distro)
1835             DISTRO=$2
1836             shift 2
1837             ;;
1838         --reuserpm)
1839             REUSERPM=$2
1840             shift 2
1841             ;;
1842         --reusebuild)
1843             if ! REUSEBUILD=$(canon_path "$2"); then
1844                 fatal 1 "Could not determine the canonical location of $2"
1845             fi
1846             shift 2
1847             ;;
1848         --norpm)
1849             NORPM=true
1850             shift
1851             ;;
1852         --ldiskfs)
1853             LDISKFSRPM=true
1854             shift
1855             ;;
1856         --patchless)
1857             PATCHLESS=true
1858             shift
1859             ;;
1860         --kernelrpm)
1861             if ! KERNELRPMSBASE=$(canon_path "$2"); then
1862                 fatal 1 "Could not determine the canonical location of $2"
1863             fi
1864             shift 2
1865             ;;
1866         --timestamp)
1867             TIMESTAMP=$2
1868             shift 2
1869             ;;
1870         --lustre)
1871             LUSTRE=$2
1872             shift 2
1873             ;;
1874         --nodownload)
1875             DOWNLOAD=false
1876             shift 1
1877             ;;
1878         --nosrc)
1879             DO_SRC=false
1880             shift 1
1881             ;;
1882         --ofed-version)
1883             OFED_VERSION="$2"
1884             shift 2
1885             ;;
1886         --publish)
1887             shift
1888             ;;
1889         --release)
1890             RELEASE=true
1891             shift
1892             ;;
1893         --src)
1894             DO_SRC=true
1895             shift 1
1896             ;;
1897         --stage)
1898             STAGEDIR=$2
1899             shift 2
1900             ;;
1901         --tag)
1902             TAG=$2
1903             shift 2
1904             ;;
1905         --target)
1906             TARGET=$2
1907             shift 2
1908             ;;
1909         --target-archs)
1910             TARGET_ARCHS=$2
1911             shift 2
1912             ;;
1913         --disable-datestamp)
1914             USE_DATESTAMP=
1915             shift
1916             ;;
1917         --xen)
1918             XEN=true
1919             shift
1920             ;;
1921         --set-value)
1922             eval $2
1923             shift 2
1924             ;;
1925         --)
1926             shift
1927             # there are actually some lustre configure flags that we need to
1928             # handle ourselves (but we still give them to configure)
1929             if [[ \ $@\  == *\ --disable-tests\ * ]]; then
1930                 LUSTRE_TESTS=false
1931             fi
1932             CONFIGURE_FLAGS=$@
1933             CONFIGURE_FLAGS="$CONFIGURE_FLAGS --enable-liblustre --enable-liblustre-tests"
1934             break
1935             ;;
1936         *)
1937             usage 1 "Unrecognized option: $1"
1938             ;;
1939     esac
1940 done
1941
1942 check_options
1943
1944 unpack_lustre
1945
1946 load_target
1947 EXTRA_VERSION_DELIMITER=${EXTRA_VERSION_DELIMITER:-"-"}
1948
1949 if [ -n "$OFED_VERSION" -a "$OFED_VERSION" != "inkernel" ]; then
1950     download_ofed
1951     unpack_ofed || fatal 1 "Error unpacking OFED tarball"
1952 fi
1953
1954 if [ -n "$MPTLINUX_VERSION" -a "$MPTLINUX_VERSION" != "inkernel" ]; then
1955     download_mptlinux
1956     unpack_mptlinux || fatal 1 "Error unpacking MPTLINUX distribution"
1957 fi
1958
1959 # make sure the RPM build environment is set up
1960 create_rpmbuild_dirs
1961
1962 if [ -n "$RDAC_VERSION" -a "$RDAC_VERSION" != "inkernel" ]; then
1963     download_rdac
1964     # we don't actually need to unpack this.  just put it in the SOURCES dir
1965     #unpack_rdac || fatal 1 "Error unpacking RDAC tarball"
1966     cp "$KERNELTREE/rdac-LINUX-${RDAC_VERSION}-source.tar.gz" ${TOPDIR}/SOURCES/ ||
1967         fatal 1 "Error copying RDAC source tarball to RPM SOURCES dir"
1968 fi
1969
1970 # if an unpacked kernel source tree was given on the command line
1971 # just build lustre with it (nothing distro kernel specific here)
1972 if [ -n "$LINUX" ]; then
1973     build_mptlinux "${LINUXOBJ:-$LINUX}" "$MPTLINUX_VERSION" ||
1974         fatal 1 "error building mptlinux"
1975     build_ofed "${LINUXOBJ:-$LINUX}" "$OFED_VERSION" ||
1976         fatal 1 "error building OFED"
1977     if ! $PATCHLESS; then
1978         build_rdac "${LINUXOBJ:-$LINUX}" "$RDAC_VERSION" ||
1979             fatal 1 "error building RDAC"
1980     fi
1981     build_lustre "$LINUX" "$LINUXOBJ"
1982 else
1983     if [ -f "${0%/*}/lbuild-$DISTRO" ]; then
1984         source ${0%/*}/lbuild-$DISTRO
1985
1986         build_with_srpm || fatal 1 "Failed to build_with_srpm"
1987     else
1988         source ${0%/*}/lbuild.old_school
1989
1990         old_school_download_kernel
1991
1992         build_success=false
1993         if $PATCHLESS; then
1994             patchless_build_sequence && build_success=true
1995         else
1996             [ "$DISTRO" = "sles9" ] && build_sequence_rpm_reuse && build_success=true
1997             if ! $build_success; then
1998                 build_sequence_reuse && build_success=true
1999                 if ! $build_success; then
2000                     build_sequence && build_success=true
2001                     if $build_success; then
2002                         store_for_reuse || echo "Cannot store for future reuse"
2003                     fi
2004                 fi
2005             fi
2006         fi
2007         ( $build_success ) || fatal 1 "Cannot build lustre"
2008     fi
2009 fi
2010
2011 stage