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