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