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