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