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