Whamcloud - gitweb
LU-831 header: struct bit field should be unsigned type
[fs/lustre-release.git] / build / lbuild
index 4286fd4..3abf846 100755 (executable)
@@ -2,9 +2,34 @@
 
 # vim:expandtab:shiftwidth=4:softtabstop=4:tabstop=4:
 
+# this is an alternative FD for stdout, to be used especially when we are
+# taking stdout from a function as it's return value.  i.e. foo=$(bar)
+# this is a workaround until a version of bash where we can put xtrace
+# on a specific FD
+exec 3>&1; STDOUT=3
+
 #set -x
+xtrace="+x"
+if [[ $SHELLOPTS = *xtrace* ]]; then
+    xtrace="-x"
+fi
 shopt -s extdebug
 
+# include the exit_traps library
+. ${0%/lbuild}/exit_traps.sh
+. ${0%/lbuild}/funcs.sh
+
+# our children should die when we do
+push_exit_trap "kill -INT -$$ || true" kill_children
+
+# increment this if you have made a change that should force a new kernel
+# to build built
+#BUILD_GEN=1
+#BUILD_GEN=2   # bz19952: remove -lustre tag from kernel RPM names
+#BUILD_GEN=3   # bz19975: enable the building of src.rpms by default
+#BUILD_GEN=4   # bz22281: use the git hash in the kernel extra version
+BUILD_GEN=5    # TT-107: don't cache the BUILD dir
+
 TOPDIR=$PWD
 
 # CVSROOT is inherited from the environment
@@ -21,21 +46,24 @@ DOWNLOAD=true
 TAG=
 CANONICAL_TARGET=
 TARGET=
-TARGET_ARCH=$(uname -m)
-TARGET_ARCHS=
-TARGET_ARCHS_ALL=$TARGET_ARCH
+TARGET_ARCH="$(uname -m)"
+# change default behavior to only build for the current arch
+TARGET_ARCHS="$TARGET_ARCH"
+TARGET_ARCHS_ALL="$TARGET_ARCH"
 [ "$TARGET_ARCH" = "i686" ] && TARGET_ARCHS_ALL="i686 i586 i386"
 CONFIGURE_FLAGS=
 EXTERNAL_PATCHES=
 EXTRA_VERSION=
-LUSTRE_EXTRA_VERSION=
 STAGEDIR=
 TMPDIR=${TMPDIR:-"/var/tmp"}
 TIMESTAMP=
-# XXX - i think these two parameters/arguments/variables need to be
-#       cleaned up and merged.  they effectively do the same thing
+# this is a dir to try reuse old kernel RPMs in (although, it seems to be
+# unused in any real manner
 REUSERPM=
+# this is the dir that should be used to store reuse products
 REUSEBUILD=
+# should cached products be used or force rebuilding?
+USE_BUILD_CACHE=true
 # what does this do exactly?  does it imply no kernel build?
 NORPM=false
 LDISKFSRPM=true
@@ -48,6 +76,8 @@ DISTRO=
 KERNELTREE=
 # default to not adding -lustre- into the kernel RPM package names
 KERNEL_LUSTRE_NAMING=false
+# default not use kabi check.
+USE_KABI=false
 
 # patchless build
 KERNELRPMSBASE=
@@ -67,6 +97,9 @@ UP_ARCHS=
 # not in the target file any more
 CONFIG=
 
+# build the lustre-tests rpm?
+LUSTRE_TESTS=true
+
 DATE=$(date)
 
 USE_DATESTAMP=1
@@ -88,26 +121,6 @@ readlink() {
     fi
 }
 
-cleanup() {
-
-    true
-}
-
-error() {
-    local msg="$1"
-
-    [ -n "$msg" ] && echo -e "\n${0##*/}: $msg" >&2
-
-}
-
-fatal() {
-
-    cleanup
-    error "$2"
-    exit $1
-
-}
-
 usage() {
     cat <<EOF
 Usage: ${0##*/} [OPTION]... [-- <lustre configure options>]
@@ -215,6 +228,9 @@ Usage: ${0##*/} [OPTION]... [-- <lustre configure options>]
   --xen
     Builds a Xen domX kernel.
 
+  --set-value
+    Set's a variable to a given value.
+
 EOF
 
 #   list_targets
@@ -222,7 +238,22 @@ EOF
     fatal "$1" "$2"
 }
 
-# canonicalize a relative path
+# canonicalize a relative path to a file
+canon_filepath() {
+    local PATH="$1"
+
+    if [ ! -f "$PATH" ]; then
+        return 1
+    fi
+
+    local FILE=${PATH##*/}
+    local DIR=${PATH%/*}
+
+    echo $(canon_path "$DIR")/$FILE
+    return 0
+}
+
+# canonicalize a relative path to a dir
 canon_path() {
     local PATH="$1"
 
@@ -250,6 +281,8 @@ check_options() {
             usage 1 "A branch/tag name must be specified with --tag when not building from a tarball."
     fi
 
+    [ -z "$DISTRO" ] && DISTRO=$(autodetect_distro)
+
     if [ -z "$LINUX" ]; then
         [ "$KERNELDIR" -o "$KERNELTREE" ] || \
             usage 1 "A kernel directory must be specified with --kerneldir or --kerneltree."
@@ -262,13 +295,16 @@ check_options() {
                 usage 1 "When building a snapshot, a tag name must be used."
         fi
 
-        [ "$TARGET" ] || usage 1 "A target must be specified with --target."
+        [ "$TARGET" ] || TARGET=$(autodetect_target "$DISTRO")
 #       TARGET_FILE="$TOPDIR/lustre/kernel_patches/targets/$TARGET.target"
 #       [ -r "$TARGET_FILE" ] || \
 #               usage 1 "Target '$TARGET' was not found."
     fi
 
     case $TARGET in
+        2.6-rhel6)
+            CANONICAL_TARGET="rhel6"
+            ;;
         2.6-rhel5)
             CANONICAL_TARGET="rhel5"
             ;;
@@ -318,50 +354,33 @@ check_options() {
     fi
 
     if [ -n "$CCACHE" ]; then
-        which "$DISTCC" 2>/dev/null && export DISTCC RPM_BUILD_NCPUS
+        which "$DISTCC" &>/dev/null && export DISTCC RPM_BUILD_NCPUS
 
-        if which "$CCACHE" 2>/dev/null; then
+        if which "$CCACHE" &>/dev/null; then
             local ccache=$(which "$CCACHE")
             local bindir="$TOPDIR/bin"
 
-            [ -d $bindir ] || mkdir -p $bindir
-            if [ -d $bindir ]; then
-                rm ${bindir}/* > /dev/null 2>&1
-                ln -s "$ccache" ${bindir}/ccache
-                ln -s "$ccache" ${bindir}/cc
-                ln -s "$ccache" ${bindir}/$CC
-                export PATH=$bindir:$PATH
+            if [ ! -d $bindir ]; then
+                mkdir -p $bindir || fatal 1 "error trying to create $bindir"
+            else
+                rm ${bindir}/* > /dev/null 2>&1 || true
             fi
+            ln -s "$ccache" ${bindir}/ccache
+            ln -s "$ccache" ${bindir}/cc
+            ln -s "$ccache" ${bindir}/$CC
+            export PATH=$bindir:$PATH
             export CCACHE && export CC="ccache $CC"
             # zero the cache so we can see how effective we are being with it
+            echo -n "ccache "
             ccache -z
-        fi
-    fi
 
-    [ -z "$DISTRO" ] && DISTRO=$(autodetect_distro)
-}
-
-# autodetect used Distro
-autodetect_distro() {
-
-    local name
-    local version
-
-    if [ -f /etc/SuSE-release ]; then
-        name=sles
-        version=$(grep ^VERSION /etc/SuSE-release)
-        version=${version#*= }
-    elif [ -f /etc/redhat-release ]; then
-        name=$(head -1 /etc/redhat-release)
-        version=$(echo "$distroname" |
-                  sed -e 's/^[^0-9.]*//g' | sed -e 's/[ \.].*//')
-    fi
-    if [ -z "$name" -o -z "$version" ]; then
-        fatal 1 "I don't know how to determine distro type/version.\n" \
-                "Either update autodetect_distro() or use the --distro argument"
+            # get some ccache stats when we are done
+            push_exit_trap '[ -n "$CCACHE" ] && ccache -s' "ccache_summary"
+            # should remove the ccache trap if lbuild is interrupted
+            trap 'echo "Received an INT TERM or HUP signal, terminating."; delete_exit_trap "ccache_summary"; exit 1' INT TERM HUP
+        fi
     fi
 
-    echo ${name}${version}
     return 0
 
 }
@@ -372,6 +391,27 @@ uniqify() {
 
 }
 
+fetch_url() {
+    local url="$1"
+    local target="$2"
+
+    local rc=0
+    if which wget >/dev/null 2>&1; then
+        if ! wget -nv "$url" -O "$target"; then
+            rc=${PIPESTATUS[0]}
+        fi
+    elif which curl >/dev/null 2>&1; then
+        if ! curl -L -s -o "$target" "$url"; then
+            rc=${PIPESTATUS[0]}
+        fi
+    else
+        fatal 1 "Could not find either wget or curl to fetch URLs."
+    fi
+
+    return $rc
+
+}
+
 download_srpm() {
     local target=$1
     local srpm=$2
@@ -381,12 +421,22 @@ download_srpm() {
        [ ! -s "$KERNELDIR/$srpm" ]; then
         if $DOWNLOAD; then
             local location="http://downloads.lustre.org/public/kernels/$target/old"
+            # get the location from a distro specific method if it exists
+            if type -p kernel_srpm_location; then
+                location=$(kernel_srpm_location)
+            fi
             echo "Downloading $location/$srpm..."
-            if ! wget -nv "$location/$srpm" -O "$KERNELDIR/$srpm" ||
+            if ! fetch_url "$location/$srpm" "$KERNELDIR/$srpm" 2>&1 ||
                [ ! -s "$KERNELDIR/$srpm" ]; then
                 rm -f $KERNELDIR/$srpm
-                fatal 1 "Could not download target $target's kernel SRPM" \
-                        "$srpm from $location."
+                # punt to a distro specific method if it exists
+                if ! type -p download_srpm-$DISTRO; then
+                    fatal 1 "Could not download target $target's kernel SRPM $srpm from $location."
+                else
+                    if ! download_srpm-$DISTRO "$target" "$srpm" "$force"; then
+                        fatal 1 "Could not download target $target's kernel SRPM $srpm using download_srpm-$DISTRO."
+                    fi
+                fi
             fi
         else
             fatal 1 "$srpm not found in directory $KERNELDIR."
@@ -395,41 +445,114 @@ download_srpm() {
 
 }
 
+download_file() {
+    local from="$1"
+    local to="$2"
+    local force="$3"
+
+    local file=${from##*/}
+
+    if [ -d $to ]; then
+        to="$to/$file"
+    fi
+
+    local semaphore="$to-downloading"
+
+    is_downloading() {
+        if [ ! -f $semaphore ]; then
+            return 1
+        fi
+
+        # make sure the download has not been aborted
+        local now=$(date +%s)
+        local file_mtime=$(stat -c %Y "$to")
+        local staleness=$((now - file_mtime))
+        # let's assume an active download will write at least once a minute
+        if [ $staleness -gt 60 ]; then
+            return 1
+        fi
+
+        return 0
+    }
+
+    is_downloaded() {
+        # if the semaphore file exists, the file is either still downloading
+        # or a download was aborted and we cannot trust the target file
+        if [ -f $semaphore ]; then
+            return 1
+        fi
+
+        if ! is_downloading && [ -r "$to" ] && [ -s "$to" ]; then
+            return 0
+        fi
+
+        return 1
+    }
+
+    if $force || ! is_downloaded; then
+        if is_downloading; then
+            echo "Somebody else is downloading $from..."
+            while is_downloading; do
+                echo "Waiting for $to to finish downloading"
+                sleep 60
+            done
+            if is_downloaded; then
+                return 0
+            else
+                echo "The download we were waiting for seems to have been aborted"
+            fi
+
+        fi
+
+        if $DOWNLOAD; then
+            echo "Downloading $from..."
+            # flag others so they don't try to download also
+            push_exit_trap "rm -f $to $semaphore" "download"
+            touch $semaphore
+            if ! fetch_url "$from" "$to" || [ ! -s "$to" ]; then
+                # the trap will remove the files via the fatal below
+                fatal 1 "Could not download ${to##*/} from ${from%/*}/."
+            fi
+            rm -f $semaphore
+            delete_exit_trap "download"
+        else
+            fatal 1 "${to##*/} not found in directory ${to%/*}."
+        fi
+    fi
+
+    return 0
+
+}
+
 download_ofed() {
     local force="${1:-false}"
 
-    local location="http://downloads.lustre.org/public/OFED/"
+    if [ -z "$OFED_VERSION" -o "$OFED_VERSION" = "inkernel" ]; then
+        return 0
+    fi
+
+    local OFED_BASE_VERSION=$OFED_VERSION
+    if [[ $OFED_VERSION = *.*.*.* ]]; then
+        OFED_BASE_VERSION=${OFED_VERSION%.*}
+    fi
+
+    local location="http://www.openfabrics.org/downloads/OFED/ofed-${OFED_BASE_VERSION}/"
 
-    local Mmv daily
     if [[ $OFED_VERSION = daily-* ]]; then
+        local Mmv daily
         OFED_VERSION=${OFED_VERSION/daily-/}
         Mmv=${OFED_VERSION%%-*}
         daily=${OFED_VERSION##$Mmv-}
         location="http://www.openfabrics.org/downloads/OFED/ofed-${Mmv}-daily/"
         # find the filename for the version for the date specified
-        OFED_VERSION=$(curl -s "$location" | sed -nre "/${daily}-/s/.*href=\"OFED-([0-9]+\.[0-9]+-${daily}-[0-9]{4,4}).tgz.*$/\1/p")
+        OFED_VERSION=$(curl -s "$location" | sed -nre "/${daily}-/s/.*href=\"OFED-(${Mmv//./\\.}-${daily}-[0-9]{4,4}).tgz.*$/\1/p" | tail -1)
         if [ -z "$OFED_VERSION" ]; then
             fatal 1 "Could not determine the filename of the OFED snapshot for ${daily}"
         fi
     fi
 
-    if [ -n "$OFED_VERSION" -a "$OFED_VERSION" != "inkernel" ] &&
-       ( $force || [ ! -r "$KERNELTREE/OFED-${OFED_VERSION}.tgz" ] ||
-           [ ! -s "$KERNELTREE/OFED-${OFED_VERSION}.tgz" ] ); then
-        if $DOWNLOAD; then
-            echo "Downloading $location/OFED-${OFED_VERSION}.tgz..."
-            if ! wget -nv "$location/OFED-${OFED_VERSION}.tgz" \
-                -O "$KERNELTREE/OFED-${OFED_VERSION}.tgz" ||
-               [ ! -s "$KERNELTREE/OFED-${OFED_VERSION}.tgz" ]; then
-                rm -f $KERNELTREE/OFED-${OFED_VERSION}.tgz
-                fatal 1 "Could not download OFED-${OFED_VERSION}.tgz" \
-                        "from downloads.lustre.org."
-            fi
-        else
-            fatal 1 "OFED-${OFED_VERSION}.tgz not found in kernel" \
-                    "directory $KERNELTREE."
-        fi
-    fi
+    local file="OFED-${OFED_VERSION}.tgz"
+    download_file "$location/$file" "$KERNELTREE" "$force"
 
 }
 
@@ -465,7 +588,7 @@ load_target() {
     [ -z "$RPMSMPTYPE" ] && set_rpm_smp_type
 
     # CC might have been overwriten in TARGET_FILE
-    if [[ $CC != ccache\ * ]] && which "$CCACHE" 2>/dev/null; then
+    if [[ $CC != ccache\ * ]] && which "$CCACHE" &>/dev/null; then
         export CCACHE && export CC="ccache $CC"
     fi
 
@@ -480,9 +603,7 @@ load_target() {
             for patchesdir in "$EXTERNAL_PATCHES" "$TOPDIR/lustre/lustre/kernel_patches"; do
                 [ -r "$patchesdir/series/$series" ] && continue 2
             done
-            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."
+            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."
         done
     fi
 
@@ -505,8 +626,7 @@ load_target() {
     PRISTINE_EXTRA_VERSION=$EXTRA_VERSION
 
     if ! $PATCHLESS && [ ! -f "$CONFIG_FILE" ]; then
-        fatal 1 "Config file for target $TARGET missing from" \
-                "$TOPDIR/lustre/lustre/kernel_patches/kernel_configs/."
+        fatal 1 "Config file for target $TARGET missing from $TOPDIR/lustre/lustre/kernel_patches/kernel_configs/."
     fi
 
     if [ "$EXTRA_VERSION_save" ]; then
@@ -514,11 +634,12 @@ load_target() {
     elif ! $RELEASE; then
         # if there is no patch series, then this is not a lustre specific
         # kernel.  don't make it look like one
-        if [ -n "$SERIES" ]; then
-            #remove the @VERSION@ (lustre version)
-#            EXTRA_VERSION=$(echo $EXTRA_VERSION | sed -e "s/\(.*_lustre\)\..*/\1/")
+        if $PATCHLESS || [ -n "$SERIES" ]; then
+            EXTRA_VERSION=$(echo $EXTRA_VERSION | sed -e "s/\(.*_lustre\)\..*/\1/")
 #            EXTRA_VERSION="${EXTRA_VERSION}-${TAG}.${TIMESTAMP}"
-            ! ( $PATCHLESS ) && EXTRA_VERSION="${EXTRA_VERSION}.${TIMESTAMP}"
+            if ! $PATCHLESS && [ -n "$BUILDID" ]; then
+                EXTRA_VERSION="${EXTRA_VERSION}.${BUILDID}"
+            fi
         fi
     fi
     # EXTRA_VERSION=${EXTRA_VERSION//-/_}
@@ -560,10 +681,12 @@ tarflags() {
 }
 
 untar() {
-    local file="$1"
+    local tarfile="$1"
+    shift
+    local extractfile="$@"
 
-    echo "Untarring ${file##*/}..."
-    tar $(tarflags "$file") "$file"
+    echo "Untarring ${tarfile##*/}..."
+    tar $(tarflags "$tarfile") "$tarfile" $extractfile
 
 }
 
@@ -594,7 +717,7 @@ unpack_lustre() {
             fatal 1 "There was an error checking out Lustre/Portals/Build from CVS."
         echo "Creating lustre tarball..."
         sh autogen.sh || fatal 1 "There was an error running autogen.sh."
-        ./configure --disable-{modules,utils,liblustre,tests,doc} || \
+        ./configure --enable-dist || \
             fatal 1 "There was an error running ./configure to create makefiles."
         make dist || fatal 1 "There was an error running 'make dist'."
         LUSTRE=$PWD/lustre-*.tar.gz
@@ -610,7 +733,7 @@ do_patch_linux() {
 
     local do_patch=${1:-true}
 
-    FULL_PATCH="$PWD/lustre-kernel-${TARGET}${EXTRA_VERSION_DELIMITER}${EXTRA_VERSION}.patch"
+    FULL_PATCH="$PWD/lustre-kernel-${TARGET}-${EXTRA_VERSION}.patch"
     [ -f "$FULL_PATCH" ] && rm -f "$FULL_PATCH"
     $do_patch && pushd linux >/dev/null
     for series in $SERIES; do
@@ -628,7 +751,7 @@ do_patch_linux() {
                     fatal 1 "Error adding patch $patch to full patch."
                 }
                 if $do_patch; then
-                    patch -s -p1 < "$PATCH_FILE" || {
+                    patch -s -p1 < "$PATCH_FILE" 2>&1 || {
                         rm -f $FULL_PATCH
                         fatal 1 "Error applying patch $patch."
                     }
@@ -644,108 +767,124 @@ do_patch_linux() {
 }
 
 build_lustre() {
+    local linux="$1"
+    local linuxobj="$2"
 
     cp "$LUSTRE" SOURCES
 
     pushd lustre >/dev/null
 
     echo "Building Lustre RPMs for: $BUILD_ARCHS..."
-    targets=
+    local targets arch
     for arch in $BUILD_ARCHS; do
         targets="--target $arch $targets"
     done
 
-    local confoptions="--with-linux=${LINUX}"
+    local confoptions=""
+
     if $PATCHLESS; then
-        confoptions="--with-linux=${LINUX} --disable-server"
-    fi
-    if [ ! "$LINUXOBJ" = "" ]; then
-        confoptions="$confoptions --with-linux-obj=${LINUXOBJ}"
+        confoptions="$confoptions --disable-server"
     fi
 
-    ./configure $confoptions ${CONFIGURE_FLAGS}
-    if [ "$?" != "0" ]; then
-        local saved_config="../config.log.$(date +%s)"
-        cp config.log $saved_config
-        chmod a+r $saved_config
-        echo "Saved config.log is at $saved_config"
-        cat /proc/mounts
-        ls -l /proc/$$
-        pwd
-        echo "config.log contents:"
-        cat config.log
-        popd
-        return 255
+    local rpmbuildopt='-tb'
+    if $NORPM; then
+        rpmbuildopt='-tc'
+        echo NORPM mode. Only compiling.
     fi
 
-    gen_lustre_version
+    ( $(skeep_ldiskfs_rpm $TAG) ) || {
+
+        pushd ldiskfs > /dev/null || return 255
+
+        if !  ./configure --enable-dist; then
+            echo "failed to configure in ldiskfs"
+            popd >/dev/null # pushd ldiskfs
+            popd >/dev/null # pushd lustre
+            return 255
+        fi
 
-    # hack. Somebody move build/lustre.spec to lustre.spec for b1_6
-    local lustre_spec
-    [ -f lustre.spec ] && lustre_spec=lustre.spec
-    [ -f build/lustre.spec ] && lustre_spec=build/lustre.spec
+        if ! make dist 2>&1; then
+            popd >/dev/null # pushd ldiskfs
+            popd >/dev/null # pushd lustre
+            return 255
+        fi
 
-    [ -f "$lustre_spec" ] && sed \
-        -e "s^Release: .*$^Release: $LUSTRE_EXTRA_VERSION^" \
-        < $lustre_spec \
-        > ../lustre.spec
+        #cp lustre-ldiskfs*.tar.gz $TOPDIR/SOURCES || \
+        #    fatal 1 "Could not copy lustre-ldiskfs*.tar.gz to $TOPDIR/SOURCES"
 
-    local rpmbuildopt='-bb'
-    if $NORPM; then
-        rpmbuildopt='-bc'
-        echo NORPM mode. Only compiling.
-    fi
+        if ! $RPMBUILD $targets $rpmbuildopt lustre-ldiskfs*.tar.gz \
+            --define "configure_args $confoptions ${CONFIGURE_FLAGS}" \
+            --define "kdir $linux" \
+            ${linuxobj:+--define "kobjdir $linuxobj"} \
+            --define "_tmppath /var/tmp" \
+            --define "_topdir $TOPDIR" 2>&1; then
+            popd >/dev/null # pushd ldiskfs
+            popd >/dev/null # pushd lustre
+            return 255
+        fi
 
-    # convert the $PATCHLESS boolean to an empty/no-empty boolean
+        if $DO_SRC; then
+            if ! $RPMBUILD -ts lustre-ldiskfs*.tar.gz \
+                --define "configure_args $confoptions ${CONFIGURE_FLAGS}" \
+                --define "kdir $linux" \
+                ${linuxobj:+--define "kobjdir $linuxobj"} \
+                --define "_tmppath /var/tmp" \
+                --define "_topdir $TOPDIR" 2>&1; then
+                popd >/dev/null # pushd ldiskfs
+                popd >/dev/null # pushd lustre
+                return 255
+            fi
+        fi
+        popd >/dev/null # pushd ldiskfs
+
+        # tell lustre where ldiskfs is
+        # XXX - pointing to the RPM BUILD dir is a hack.  we need to flesh
+        #       out the ldiskfs RPM build so that it builds a
+        #       lustre-ldiskfs-devel RPM and install that and point lustre
+        #       to that instead
+        confoptions="$confoptions --with-ldiskfs=$(ls -d $TOPDIR/BUILD/lustre-ldiskfs-*)"
+    }
+
+    # convert the $PATCHLESS boolean to an empty/not-empty boolean
     # as silly as this seems, it makes the syntax of the rpmbuild command
-    # simpler and not need an eval to deal with the quotes in the quotes 
+    # simpler and not need an eval to deal with the quotes in the quotes
     local is_patchless=""
     if $PATCHLESS; then
         is_patchless="yes"
     fi
-    $RPMBUILD $targets $rpmbuildopt ../lustre.spec \
-        ${is_patchless:+--define "lustre_name lustre-client"} \
-        --define "_tmppath $TMPDIR" \
-        --define "_topdir $TOPDIR" || \
-        fatal 1 "Error building rpms for $BUILD_ARCHS."
-
-    popd >/dev/null
-    ( $(skeep_ldiskfs_rpm $TAG) ) && return
 
-    pushd lustre/ldiskfs || return 255
-    make dist
-    if [ "$?" != "0" ]; then
-        popd
-        return 255
+    # ditto for the lustre-tests boolean
+    local lustre_tests=""
+    if ! $LUSTRE_TESTS; then
+        lustre_tests="no"
     fi
-    cp lustre-ldiskfs*.tar.gz $TOPDIR/SOURCES
-
-    gen_lustre_version
 
-    local ldiskfs_spec=lustre-ldiskfs.spec
-    [ -f "$ldiskfs_spec" ] && sed \
-    -e "s^Release: .*$^Release: $LUSTRE_EXTRA_VERSION^" \
-    < $ldiskfs_spec \
-    > ../lustre-ldiskfs.spec
-
-    $RPMBUILD $targets $rpmbuildopt ../lustre-ldiskfs.spec \
-        --define "_tmppath /var/tmp" \
-        --define "_topdir $TOPDIR"
-    if [ "$?" != "0" ]; then
-        popd
-        return 255
-    fi
+    $RPMBUILD $targets $rpmbuildopt "$LUSTRE" \
+        ${is_patchless:+--define "lustre_name lustre-client"} \
+        ${lustre_tests:+--define "build_lustre_tests 0"} \
+        ${FIND_REQUIRES:+--define "__find_requires $FIND_REQUIRES"} \
+        --define "configure_args $confoptions ${CONFIGURE_FLAGS}" \
+        --define "kdir $linux" \
+        ${linuxobj:+--define "kobjdir $linuxobj"} \
+        --define "_tmppath $TMPDIR" \
+        --define "_topdir $TOPDIR" 2>&1 || \
+        fatal 1 "Error building rpms for $BUILD_ARCHS."
 
     if $DO_SRC; then
-            $RPMBUILD -bs ../lustre-ldiskfs.spec \
-            --define "_tmppath /var/tmp" \
-            --define "_topdir $TOPDIR"
-        if [ "$?" != "0" ]; then
+        if ! $RPMBUILD -ts "$LUSTRE" \
+                 ${is_patchless:+--define "lustre_name lustre-client"} \
+                 ${lustre_tests:+--define "build_lustre_tests 0"} \
+                 ${FIND_REQUIRES:+--define "__find_requires $FIND_REQUIRES"} \
+                 --define "configure_args $confoptions ${CONFIGURE_FLAGS}" \
+                 --define "kdir $linux" \
+                 ${linuxobj:+--define "kobjdir $linuxobj"} \
+                 --define "_tmppath $TMPDIR" \
+                 --define "_topdir $TOPDIR" 2>&1; then
             popd
             return 255
         fi
     fi
-    popd
+    popd >/dev/null
 
 }
 
@@ -769,33 +908,21 @@ stage() {
 
 #check if we need to build separate ldiskfs RPM
 skeep_ldiskfs_rpm() {
-        local tag="$1"
+    local tag="$1"
 
-        local skip=false
+    local skip=false
 
-        if ! $LDISKFSRPM; then
-            skip=true
-        elif $PATCHLESS; then
-            skip=true
-        else
-            for skiptag in $SKIPLDISKFSRPM; do
-                [[ $tag == $skiptag ]] && skip=true && break
-            done
-        fi
-
-        pushd $TOPDIR/BUILD/lustre-[1-9]* >/dev/null
-        grep -q '^SERVER_TRUE[ \t]=[ \t]#$' autoMakefile && skip=true
-        popd >/dev/null
-
-        echo $skip
-
-}
-
-#generate LUSTRE_EXTRA_VERSION from EXTRA_VERSION
-gen_lustre_version() {
+    if ! $LDISKFSRPM; then
+        skip=true
+    elif $PATCHLESS; then
+        skip=true
+    else
+        for skiptag in $SKIPLDISKFSRPM; do
+            [[ $tag == $skiptag ]] && skip=true && break
+        done
+    fi
 
-    LUSTRE_EXTRA_VERSION="${lnxmaj}${EXTRA_VERSION_DELIMITER}${EXTRA_VERSION}${TARGET_DELIMITER}${RPMSMPTYPE}"
-    LUSTRE_EXTRA_VERSION=${LUSTRE_EXTRA_VERSION//-/_}
+    echo $skip
 
 }
 
@@ -815,6 +942,10 @@ set_rpm_smp_type() {
         [ $infact_arch == $smp_type ] && RPMSMPTYPE=bigsmp && break
     done
 
+    for smp_type in $PPC64_ARCHS; do
+        [ $infact_arch == $smp_type ] && RPMSMPTYPE=ppc64 && break
+    done
+
     for smp_type in $DEFAULT_ARCHS; do
         [ $infact_arch == $smp_type ] && RPMSMPTYPE=default && break
     done
@@ -835,36 +966,6 @@ find_linux_release() {
 
 }
 
-# XXX this needs to be re-written as a wrapper around find_rpm
-#     or just gotten rid of.  :-)
-find_linux_rpm() {
-    local prefix="$1"
-    local delimiter=${2:-"-"}
-
-    local pathtorpms="${KERNELRPMSBASE}/${lnxmaj}/${DISTRO}"
-    [ -d $pathtorpms ] || return 255
-
-    local kernelbinaryrpm rpmfile
-    local wanted_kernel="${lnxmaj}${delimiter}${lnxrel}"
-
-    local arch ret=1
-    for arch in $TARGET_ARCHS_ALL; do
-        local found_rpm="" rpm
-        for rpm in ${pathtorpms}/${arch}/*.rpm; do
-            if rpm -q --provides -p "$rpm" | grep -q "kernel${prefix} = $wanted_kernel"; then
-                found_rpm="$rpm"
-                ret=0
-                break
-            fi
-        done
-        [ -f "$found_rpm" ] && break
-    done
-
-    echo "$found_rpm"
-    return $ret
-
-}
-
 # unpack kernel(/source/devel) RPM
 #
 # This function and it's setting of $LINUX and $LINUXOBJ is a total hack that
@@ -873,15 +974,11 @@ find_linux_rpm() {
 # lustre itself)
 unpack_linux_devel_rpm() {
     local kernelrpm="${1}"
-    # it's worth noting that neither sles10 nor rhel5 appear to use their
-    # extra_version delimiter for the dirname under /usr/src, so we could
-    # probably just get rid of this parameter
-    local delimiter=${2:-"-"}
 
     [ -f "$kernelrpm" ] || return 255
     [ -d $TOPDIR/reused ] || mkdir $TOPDIR/reused || return 255
 
-    pushd $TOPDIR/reused || return 255
+    pushd $TOPDIR/reused &>/dev/null || return 255
 
     if ! rpm2cpio < "$kernelrpm" | cpio -id > /dev/null 2>&1; then
         return 255
@@ -889,10 +986,12 @@ unpack_linux_devel_rpm() {
 
     # call a distro specific hook, if available
     if type -p unpack_linux_devel_rpm-$DISTRO; then
-        unpack_linux_devel_rpm-$DISTRO "$kernelrpm"
+        if ! unpack_linux_devel_rpm-$DISTRO "$kernelrpm"; then
+            return 255
+        fi
     fi
 
-    popd
+    popd &>/dev/null
 
     find_linux_devel_paths $TOPDIR/reused
 
@@ -900,55 +999,6 @@ unpack_linux_devel_rpm() {
 
 }
 
-# XXX - this rhel/sles goop needs abstracting out into the
-#       lbuild-{rhel5,sles10} method files
-find_linux_devel_paths() {
-    local path="$1"
-
-    local RC=0
-
-    pushd $path
-        # RHEL-style and SLES-style rpms
-        # XXX - until bug 19336 cleans this up, we need to extricate the
-        #       ${lnxmin}- from the $lnxrel
-        local paths="kernels/${lnxmaj}${lnxmin}${delimiter}${lnxrel}-${TARGET_ARCH} linux-${lnxmaj}${lnxmin}${delimiter}${lnxrel##${lnxmin#.}-}"
-
-        local path
-        for path in $paths; do
-            local src='usr/src'
-
-            if [ -d "$src/$path/" ]; then
-                LINUX="$(pwd)/$src/$path"
-            fi
-            # SLES has a separate -obj tree
-            if [ -d "$src/${path}-obj" ]; then
-                local src="$src/${path}-obj"
-                local objects="$TARGET_ARCH/$RPMSMPTYPE"
-
-                # Novell, are you *TRYING* to make life hard for me?
-                if [ -d "$src/powerpc" ]; then
-                    objects="powerpc/$TARGET_ARCH"
-                elif [ $TARGET_ARCH == 'i686' ]; then
-                    objects="i386/$RPMSMPTYPE"
-                fi
-
-                LINUXOBJ="$(pwd)/$src/$objects"
-            fi
-        done
-        if [ -z "$LINUX" ]; then
-            RC=255
-        else
-            # dig out the release version
-            LINUXRELEASE=$(find_linux_release ${LINUXOBJ:-$LINUX})
-            if [ -z "$LINUXRELEASE" ]; then
-                echo "Failed to find linux release in ${LINUXOBJ:-$LINUX}"
-                RC=255
-            fi
-        fi
-    popd
-    return $RC
-}
-
 build_kernel_ib() {
     local linux="$1"
 
@@ -964,74 +1014,126 @@ build_kernel_ib() {
     # some I/B drivers are architecture dependent and kernel-ib's configure
     # does not figure it out for us ~sigh~
     case "$TARGET_ARCH" in
-       ppc64)
+        ppc64)
             OFED_HARDWARE="$OFED_HARDWARE --with-ehca-mod"
-           ;;
+            ;;
     esac
     # we're no longer shipping the OFED iSCSI
     #OFED_ISCSI="--with-srp-mod --with-srp-target-mod"
     ## ISER module has no backport support as of OFED 1.5 (i.e. only builds on
     ##kernels >= 2.6.30)
     #if [[ $OFED_VERSION = 1.[0-4]* ]]; then
-    #  OFED_ISCSI="$OFED_ISCSI --with-iser-mod"
+    #   OFED_ISCSI="$OFED_ISCSI --with-iser-mod"
     #fi
 
+    # assume we are just rebuilding the SRPM
+    local BUILD_TYPE=${BUILD_TYPE:-"--rebuild"}
+    local SOURCE="${TOPDIR}/OFED/SRPMS/ofa_kernel-*.src.rpm"
+
+    # but switch to building from the SPEC if we need to apply patches
+    if ls ${TOPDIR}/lustre/build/patches/ofed/* >/dev/null; then
+        BUILD_TYPE="-bb"
+        rpm --define "_topdir ${TOPDIR}" -ivh $SOURCE
+        SOURCE="${TOPDIR}/SPECS/ofa_kernel.spec"
+        local file ed_fragment1 ed_fragment2 n=1
+        for file in $(ls ${TOPDIR}/lustre/build/patches/ofed/*.patch); do
+            ed_fragment1="$ed_fragment1
+Patch$n: ${file%%*/}"
+            ed_fragment2="$ed_fragment2
+%patch$n -p0"
+            cp $file ${TOPDIR}/SOURCES
+            let n=$n+1
+        done
+        for file in $(ls ${TOPDIR}/lustre/build/patches/ofed/*.ed); do
+            ed_fragment3="$ed_fragment3
+$(cat $file)"
+            let n=$n+1
+        done
+
+        if [ $n -gt 1 ]; then
+            ed $SOURCE <<EOF
+/^Source: /a
+$ed_fragment1
+.
+/^%setup /a
+$ed_fragment2
+.
+$ed_fragment3
+wq
+EOF
+        fi
+    fi
+
     local linuxrelease=$(find_linux_release "$linux")
-    $RPMBUILD --rebuild --define 'build_kernel_ib 1' --define 'build_kernel_ib_devel 1' \
-             --define "_topdir ${TOPDIR}" --target ${TARGET_ARCH} \
-              --define "KVERSION ${linuxrelease}" \
-              --define "$K_SRC ${linux}" \
-              --define "LIB_MOD_DIR /lib/modules/${linuxrelease}/updates" \
-              ${OFA_KERNEL_RELEASE:+--define "_release $OFA_KERNEL_RELEASE"} \
-              --define "configure_options --without-quilt $OFED_CORE $OFED_HARDWARE $OFED_ISCSI" \
-              ${TOPDIR}/OFED/SRPMS/ofa_kernel-*.src.rpm
-
-    if [ ${PIPESTATUS[0]} != 0 ]; then
+    if ! $RPMBUILD $BUILD_TYPE --define 'build_kernel_ib 1' --define 'build_kernel_ib_devel 1' \
+                  ${FIND_REQUIRES:+--define "__find_requires $FIND_REQUIRES"} \
+                  --define "_topdir ${TOPDIR}" --target ${TARGET_ARCH} \
+                  --define "KVERSION ${linuxrelease}" \
+                  --define "$K_SRC ${linux}" \
+                  --define "LIB_MOD_DIR /lib/modules/${linuxrelease}/updates" \
+                  ${OFA_KERNEL_RELEASE:+--define "_release $OFA_KERNEL_RELEASE"} \
+                  --define "configure_options --without-quilt $OFED_CORE $OFED_HARDWARE $OFED_ISCSI" \
+                  ${SOURCE} 2>&1; then
         fatal 1 "Error building kernel-ib"
     fi
 
 }
 
 store_for_reuse() {
-        local articles="$1"
-        local module="$2"
-        local location="$3"
-        local signature="$4"
-        local use_links="$5"
+    local articles="$1"
+    local module="$2"
+    local location="$3"
+    local signature="$4"
+    local use_links="$5"
 
-        local linkflag=""
-        if $use_links; then
-            linkflag="l"
-        fi
+    local linkflag=""
+    if $use_links; then
+        linkflag="l"
+    fi
 
-        location="$location"/"$signature"/"$module"
-        mkdir -p "$location"
-        # the cleanup script removes any directory that doesn't have a
-        # .lastused, so let's try to prevent that as soon as we can
-        # this solution still slightly racy with the cleanup script
-        # but the race is a lot tighter now
-        touch -t 197001010000 "$location/.lastused"
-        ## use eval/echo here to make sure shell expansions are performed
-        #if ! cp -a${linkflag} $(eval echo $articles) "$location"; then
-        local article
-        for article in $(eval echo $articles); do
-            if ! cp -a${linkflag} "$article" "$location"; then
-                error "Failed to copy \"$article\" to \"$location\" in store_for_reuse()"
-                # rename the cache location so that it's not cached
-                # product, but is around for analysis
-                mv "$location"{,-bad-$(date +%s)} || 
-                    error "failed to clean up a failed cache attempt" \
-                          "in \"$location\" -- manual cleanup will be" \
-                          "necessary"
-                return 1
-            fi
-        done
+    local default_iface=$(/sbin/ip route get 192.1.1.1 | sed -ne 's/.* dev \(.*\)  * src .*/\1/p')
+    if [ -z "$default_iface" ]; then
+        fatal 1 "Failed to determine the default route interface"
+    fi
+    local unique_id=$(/sbin/ip addr show dev $default_iface | sed -ne '/ inet /s/ *inet \(.*\)\/.*/\1/p' | head -1)
+    if [ -z "$unique_id" ]; then
+        fatal 1 "Failed to determine a unique id from interface $default_interface"
+    fi
+
+    local finallocation="$location"/"$signature"/"$module"
+    location="$location"/"$signature-${unique_id}"/"$module"
+    mkdir -p "$location"
+    # the cleanup script removes any directory that doesn't have a
+    # .lastused, so let's try to prevent that as soon as we can
+    # this solution still slightly racy with the cleanup script
+    # but the race is a lot tighter now
+    touch -t 197001010000 "$location/.lastused"
+    ## use eval/echo here to make sure shell expansions are performed
+    #if ! cp -a${linkflag} $(eval echo $articles) "$location"; then
+    local article
+    for article in $(eval echo $articles); do
+        if ! cp -a${linkflag} "$article" "$location"; then
+            error "Failed to copy \"$article\" to \"$location\" in store_for_reuse()"
+            # rename the cache location so that it's not cached
+            # product, but is around for analysis
+            mv "$location"{,-bad-$(date +%s)} ||
+                error "failed to clean up a failed cache attempt" \
+                      "in \"$location\" -- manual cleanup will be" \
+                      "necessary"
+            return 1
+        fi
+    done
 
-        # flag the cache as complete (i.e. in case lbuild was previously
-        # interrupted while caching)
-        touch "$location/.lastused"
+    # flag the cache as complete (i.e. in case lbuild was previously
+    # interrupted while caching)
+    touch "$location/.lastused"
 
-        return 0
+    # put the temporary location into the final location
+    # (last one wins)
+    mkdir -p "${finallocation%/*}"
+    mv "$location" "$finallocation"
+    rmdir "${location%/*}"
+    return 0
 
 }
 
@@ -1044,12 +1146,10 @@ reuse() {
     if [ -n "$REUSEBUILD" ] && [ -d "$REUSEBUILD/$signature/$module" ]; then
         if [ ! -f "$REUSEBUILD/$signature/$module/.lastused" ]; then
             # the .lastused flag is populated at the end of the caching to
-            # signal that the caching was completeld.  if that flag is not
-            # there, then the cache is invalid (and should be removed in fact) 
-            mv "$REUSEBUILD/$signature/$module"{,-bad-$(date +%s)} || 
-                fatal 1 "failed to clean up a bad cache in location" \
-                      "\"$REUSEBUILD/$signature/$module\" -- manual cleanup" \
-                      "will be necessary"
+            # signal that the caching was completed.  if that flag is not
+            # there, then the cache is invalid (and should be removed in fact)
+            mv "$REUSEBUILD/$signature/$module"{,-bad-$(date +%s)} ||
+                fatal 1 "failed to clean up a bad cache in location $REUSEBUILD/$signature/$module\" -- manual cleanup will be necessary"
             return 1
         fi
 
@@ -1086,7 +1186,6 @@ reuse() {
                 find $dir -type f |
                   xargs ln -t $dest/RPMS/${dir##*/} -s
             done
-                     
         fi
         return 0
     else
@@ -1105,46 +1204,15 @@ basearch() {
 
 }
 
-#
-# in a given directory, find the first rpm matching given requirements
-#
-find_rpm() {
-    local dir="$1"
-    local match_type="$2"
-    local match="$3"
-
-    pushd "$dir" > /dev/null || \
-        fatal 1 "Unable to chdir to directory \"$dir\" in find_rpm()"
-
-    local file
-    for file in $(ls *.rpm); do
-        if [ ! -f "$file" ]; then
-            continue
-        fi
-        case "$match_type" in
-            provides)
-                # match is any valid ERE (i.e. given to egrep) match
-                if rpm -q --provides -p "$file" | egrep -q "$match"; then
-                    echo "$file"
-                    popd >/dev/null
-                    return 0
-                fi
-                ;;
-            *)
-                popd >/dev/null
-                fatal 1 "Unknown match type \"$match_type\" given to find_rpm()"
-                ;;
-        esac
-    done
-
-    popd >/dev/null
-    return 1
-}
-
 build_kernel_with_srpm() {
+    local outfd=$1
+
+    if [ -z "$outfd" ] || [ $outfd = 1 ]; then
+        fatal 1 "You must supply a file descriptor to ${FUNCNAME[0]} and it cannot be 1"
+    fi
 
     # need to generate the patch for this target
-    do_patch_linux false >&2   # sets global $FULL_PATCH (yeah, yuck)
+    do_patch_linux false >&${outfd}    # sets global $FULL_PATCH (yeah, yuck)
 
     # get an md5sum of the kernel patch + config for reuse check
     # XXX really, there needs to be a signature and a CONFIG_FILE per arch
@@ -1153,29 +1221,36 @@ build_kernel_with_srpm() {
     if $RELEASE; then
         local release_str="RELEASE=$RELEASE\n"
     fi
-    local REUSE_SIGNATURE=$({ echo -en $release_str; echo $BUILD_GEN; cat $CONFIG_FILE $TARGET_FILE $FULL_PATCH; } | md5sum | cut -d" " -f1)
-
-    # see if we can link to the reuse pool
-    # XXX - hrm.  i'm not convinced this doesn't belong in the reuse "library"
-    local CAN_LINK_FOR_REUSE=false
-    touch $REUSEBUILD/$$
-    if cp -al $REUSEBUILD/$$ $TOPDIR/; then
-        CAN_LINK_FOR_REUSE=true
+
+    if $USE_BUILD_CACHE && [ -n "$REUSEBUILD" ]; then
+        local REUSE_SIGNATURE=$({ echo -en $release_str;
+                                  echo $BUILD_GEN;
+                                  cat $CONFIG_FILE $TARGET_FILE $FULL_PATCH; } |
+                                md5sum | cut -d" " -f1)
+        # see if we can link to the reuse pool
+        # XXX - hrm.  i'm not convinced this doesn't belong in the reuse
+        #       "library"
+        local CAN_LINK_FOR_REUSE=false
+        touch $REUSEBUILD/$$
+        if cp -al $REUSEBUILD/$$ $TOPDIR/ 2>/dev/null; then
+            CAN_LINK_FOR_REUSE=true
+        fi
+        rm $REUSEBUILD/$$
     fi
-    rm $REUSEBUILD/$$
 
     # the extra version string to use for the kernel (which might be a reused
     # kernel, remember)
     local kernel_extra_version=""
-    if $REUSERPM && ! reuse kernel "$TOPDIR" "$CAN_LINK_FOR_REUSE" \
+    if ! $USE_BUILD_CACHE || ! reuse kernel "$TOPDIR" "$CAN_LINK_FOR_REUSE" \
                                    "$REUSE_SIGNATURE"; then
         # nothing cached, build from scratch
         if [ ! -r "$KERNELDIR/$KERNEL_SRPM" ]; then
-            download_srpm "$CANONICAL_TARGET" "$KERNEL_SRPM" >&2
+            echo "Downloading kernel SRPM" >&${outfd}
+            download_srpm "$CANONICAL_TARGET" "$KERNEL_SRPM" >&${outfd}
         fi
 
         if ! rpm -ivh $KERNELDIR/$KERNEL_SRPM \
-                  --define "_topdir $TOPDIR" >&2; then
+                  --define "_topdir $TOPDIR" >&${outfd} 2>&1; then
             # should we clean this up or leave it for analysis?
             #rm -rf $RPMTOPDIR
             fatal 1 "Error installing kernel SRPM."
@@ -1183,17 +1258,23 @@ build_kernel_with_srpm() {
 
         # put the Lustre kernel patch into the RPM build tree
         cp $FULL_PATCH $TOPDIR/SOURCES/linux-${lnxmaj}-lustre.patch
-        prepare_and_build_srpm >&2
-
-        # store the resulting kernel RPM build tree for future use
-        if ! store_for_reuse "$TOPDIR/{SPECS,SOURCES,BUILD,SRPMS,RPMS}" \
-                             "kernel" "$REUSEBUILD" "$REUSE_SIGNATURE" \
-                             "$CAN_LINK_FOR_REUSE"; then
-            error "Failed to store kernel RPMS for reuse"
-            echo "unknown"
-            return 1
+        prepare_and_build_srpm >&${outfd} ||
+            fatal 1 "failed to prepare_and_build_srpm"
+
+        if [ -z "$REUSE_SIGNATURE" ]; then
+            echo "No reuse signature was caculated so not storing the built kernel" >&${outfd}
+        else
+            # store the resulting kernel RPM build tree for future use
+            echo "Storing the built kernel for future reuse" >&${outfd}
+            if ! store_for_reuse "$TOPDIR/{SPECS,SOURCES,SRPMS,RPMS}" \
+                                 "kernel" "$REUSEBUILD" "$REUSE_SIGNATURE" \
+                                 "$CAN_LINK_FOR_REUSE"; then
+                error "Failed to store kernel RPMS for reuse"
+                echo "unknown" >&${outfd}
+                return 1
+            fi
         fi
-    fi # build reuse
+    fi  # build reuse
 
     # figure out the EXTRA_VERSION of the kernel we built or are re-using
     local KERNEL_RPM
@@ -1214,55 +1295,59 @@ build_kernel_with_srpm() {
 
 }
 
-build_with_srpm() {
+# build OFED
+# globals used:
+#    TOPDIR
+#    REUSEBUILD, USE_BUILD_CACHE
+#    CONFIGURE_FLAGS
 
-    if ! $PATCHLESS; then
-        local kernel_extra_version
-        if ! kernel_extra_version=$(build_kernel_with_srpm); then
-            fatal 1 "Failed to build the kernel from it's SRPM"
-        fi
-
-        for arch in $BUILD_ARCHS; do
+build_ofed() {
+    local linux="$1"
+    local ofed_version="$2"
 
-            local kernel_devel_rpm
-            if ! kernel_devel_rpm=$(find_rpm "$TOPDIR/RPMS/$arch/" provides "^$(devel_kernel_name $KERNEL_LUSTRE_NAMING) ="); then
-                fatal 1 "Failed to find a kernel development RPM in $TOPDIR/RPMS/$arch/"
-            fi
+    # if an ofed version is given, then it means use OFED proper,
+    # not any vendor specific "inkernel" version
+    if [ -z "$ofed_version" ]; then
+        return 0
+    fi
 
-            # install the -devel RPM in preparation for the lustre build
-            # note that the EXTRA_VERSION_DELIMITER is *NOT* used in the
-            # version of the directory name under /usr/src
-            if ! lnxrel="$kernel_extra_version" unpack_linux_devel_rpm \
-                           "$TOPDIR/RPMS/$arch/$kernel_devel_rpm" "-"; then
-                fatal 1 "Could not find the Linux tree in $TOPDIR/RPMS/$arch/$kernel_devel_rpm"
-            fi
-        done
-    else
-        # need to find and unpack the vendor's own kernel-devel for patchless
-        # client build
-        local kernelrpm
-        if ! kernelrpm=$(find_linux_rpm "-$DEVEL_KERNEL_TYPE" ${EXTRA_VERSION_DELIMITER:-"-"}); then
-            fatal 1 "Could not find the kernel-$DEVEL_KERNEL_TYPE RPM in ${KERNELRPMSBASE}/${lnxmaj}/${DISTRO}"
-        fi
-        if ! lnxrel="$lnxrel" unpack_linux_devel_rpm "$kernelrpm" "-"; then
-            fatal 1 "Could not find the Linux tree in $kernelrpm"
+    if [ "$ofed_version" = "inkernel" ]; then
+        # see if there is a distro specific override for this and use
+        # that if it exists
+        # XXX we need to better integrate a distro specific override with
+        #     the rest of this function so that all of the reuse cache
+        #     stuff is leveraged given that 80% of this function is reuse
+        if type -p build_ofed-${DISTRO}; then
+            local ofed_location
+            ofed_location=$(build_ofed-${DISTRO} ${STDOUT})
+            local rc=${PIPESTATUS[0]}
+            CONFIGURE_FLAGS="--with-o2ib=${ofed_location} ${CONFIGURE_FLAGS}"
+            return $rc
+        else
+            return 0
         fi
     fi
 
-    # before lustre, build kernel-ib
-    if [ -n "$OFED_VERSION" -a "$OFED_VERSION" != "inkernel" ]; then
+    # build kernel-ib
+    if $USE_BUILD_CACHE && [ -n "$REUSEBUILD" ]; then
+        local REUSE_SIGNATURE=$({ echo "$ofed_version";
+                                  echo "$(find_linux_release ${linux})";
+                                  cat "${linux}/include/linux/autoconf.h"; } |
+                                md5sum | cut -d" " -f1)
         # see if we can link to the reuse pool
-        # XXX - hrm.  i'm not convinced this doesn't belong in the reuse "library"
+        # XXX - hrm.  i'm not convinced this doesn't belong in the reuse
+        #       "library"
         local CAN_LINK_FOR_REUSE=false
         touch $REUSEBUILD/$$
         if cp -al $REUSEBUILD/$$ $TOPDIR/; then
             CAN_LINK_FOR_REUSE=true
         fi
         rm $REUSEBUILD/$$
+    fi
 
-        local REUSE_SIGNATURE=$({ echo "$OFED_VERSION"; echo "$(find_linux_release ${LINUXOBJ:-$LINUX})"; cat "${LINUXOBJ:-${LINUX}}/include/linux/autoconf.h"; } | md5sum | cut -d" " -f1)
-        if ! reuse ofed "$TOPDIR" "$CAN_LINK_FOR_REUSE" \
-                        "$REUSE_SIGNATURE"; then
+    if ! $USE_BUILD_CACHE || ! reuse ofed "$TOPDIR" "$CAN_LINK_FOR_REUSE" \
+                                   "$REUSE_SIGNATURE"; then
+        if [ -n "$REUSE_SIGNATURE" ]; then
             # stash away the existing built articles for a moment
             mkdir bak
             mv {BUILD,{S,}RPMS,S{OURCE,PEC}S} bak
@@ -1273,8 +1358,15 @@ build_with_srpm() {
                 rm -rf bak
             }
             create_rpmbuild_dirs
-            # build it
-            build_kernel_ib "${LINUXOBJ:-${LINUX}}"
+        fi
+        # build it
+        build_kernel_ib "${linux}"
+
+        if [ -z "$REUSE_SIGNATURE" ]; then
+            echo "No reuse signature was caculated so not storing the built ofed"
+        else
+            # store the resulting RPM build tree for future use
+            echo "Storing the built ofed for future reuse"
             if ! store_for_reuse "$TOPDIR/{SPECS,SOURCES,BUILD,SRPMS,RPMS}" \
                                  "ofed" "$REUSEBUILD" "$REUSE_SIGNATURE" \
                                  "$CAN_LINK_FOR_REUSE"; then
@@ -1285,40 +1377,128 @@ build_with_srpm() {
             # put the stuff we stashed away back
             mv_back
         fi
+    fi
+
+    pushd "$TOPDIR" >/dev/null
+    rm -rf kernel-ib-devel
+    mkdir kernel-ib-devel
+    cd kernel-ib-devel
+    # the actual ofed RPMs don't have the -rc$n or -$date string appened that
+    # might be present on the file
+    local linuxrelease=$(find_linux_release "$linux")
+    ofed_version=$(echo $ofed_version |
+                   sed -re 's/-(20[0-9]{6,6}-[0-9]{4,4}|rc[0-9]*)$//')
+    local rpm=$(ls $TOPDIR/RPMS/*/kernel-ib-devel-${ofed_version}-${linuxrelease//-/_}.*.rpm)
+    if ! rpm2cpio < $rpm | cpio -id; then
+        fatal 1 "could not unpack the kernel-ib-devel rpm."
+    fi
+    CONFIGURE_FLAGS="--with-o2ib=$(pwd)/usr/src/ofa_kernel ${CONFIGURE_FLAGS}"
+    popd >/dev/null
+
+}
+
+build_with_srpm() {
+
+    if ! $PATCHLESS; then
+        local kernel_extra_version
+        if ! kernel_extra_version=$(build_kernel_with_srpm ${STDOUT}); then
+            fatal 1 "Failed to build the kernel from it's SRPM"
+        fi
+
+        for arch in $BUILD_ARCHS; do
+            local kernel_devel_rpm
+            if ! kernel_devel_rpm=$(find_rpm "$TOPDIR/RPMS/$arch/" provides "^$(devel_kernel_name $KERNEL_LUSTRE_NAMING) ="); then
+                fatal 1 "Failed to find a kernel development RPM in $TOPDIR/RPMS/$arch/"
+            fi
 
-        pushd "$TOPDIR" >/dev/null
-        rm -rf kernel-ib-devel
-        mkdir kernel-ib-devel
-        cd kernel-ib-devel
-        # the actual ofed RPMs don't have the -rc$n or -$date string appened that
-        # might be present on the file
-        local ofed_version=$(echo $OFED_VERSION |
-                         sed -re 's/-(20[0-9]{6,6}-[0-9]{4,4}|rc[0-9]*)$//')
-        local rpm=$(ls $TOPDIR/RPMS/*/kernel-ib-devel-${ofed_version}-${LINUXRELEASE//-/_}.*.rpm)
-        rpm2cpio -itv < $rpm | cpio -id
-        CONFIGURE_FLAGS="--with-o2ib=$(pwd)/usr/src/ofa_kernel ${CONFIGURE_FLAGS}"
-        popd >/dev/null
+            # install the -devel RPM in preparation for modules builds
+            if ! lnxrel="$kernel_extra_version" unpack_linux_devel_rpm \
+                           "$TOPDIR/RPMS/$arch/$kernel_devel_rpm"; then
+                fatal 1 "Could not find the Linux tree in $TOPDIR/RPMS/$arch/$kernel_devel_rpm"
+            fi
+        done
+    else
+        # need to find and unpack the vendor's own kernel-devel for patchless
+        # client build
+        local kernelrpm
+        if ! kernelrpm=$(find_linux_rpm "-$DEVEL_KERNEL_TYPE"); then
+            fatal 1 "Could not find the kernel-$DEVEL_KERNEL_TYPE RPM in ${KERNELRPMSBASE}/${lnxmaj}/${DISTRO}"
+        fi
+        if ! lnxrel="$lnxrel" unpack_linux_devel_rpm "$kernelrpm" "-"; then
+            fatal 1 "Could not find the Linux tree in $kernelrpm"
+        fi
     fi
 
+    # ~sigh~  have to make copies of and modify some of the rpm
+    # infrastructure files so that find-requires can find our unpacked
+    # kernel-devel artifacts
+    cp $RPM_HELPERS_DIR/{symset-table,find-requires{,.ksyms}} .
+    FIND_REQUIRES="$(pwd)/find-requires"
+    chmod 755 {symset-table,find-requires{,.ksyms}}
+    local tmp="$(pwd)"
+    tmp="${tmp//\//\\/}"
+    ed find-requires <<EOF
+1a
+set -x
+.
+/|.*find-requires.ksyms/s/|/| bash -x/
+g/ [^ ]*\/\(find-requires\.ksyms\)/s// $tmp\/\1/g
+wq
+EOF
+    ed find-requires.ksyms <<EOF
+1a
+set -x
+.
+g/\/.*\/\(symset-table\)/s//$tmp\/\1/g
+wq
+EOF
+    ed symset-table <<EOF
+1a
+set -x
+.
+g/\(\/boot\/\)/s//$tmp\/reused\1/g
+g/\(\/usr\/src\/kernels\/\)/s//$tmp\/reused\1/g
+wq
+EOF
+
+    build_ofed "${LINUXOBJ:-$LINUX}" "$OFED_VERSION" ||
+        fatal 1 "error building OFED"
+
     # now build Lustre
-    if build_lustre; then
+    if build_lustre "$LINUX" "$LINUXOBJ"; then
         # the build worked.  resolve any symlinked files (i.e. from reuse)
         # in RPMS/$arch to real files so that that that huge mess of
-        # complication knows as LTS can copy them yet somewhere else.
+        # complication known as LTS can copy them yet somewhere else.
         # is it any wonder this whole process is so damn so?  anyone ever
-        # heard of hardlinks?  it this cool new thing that allows you save
+        # heard of hardlinks?  it's this cool new thing that allows you save
         # tons of time and space by creating... well you can go read about
         # them if you have not heard about them yet.
         # can i say how much the implemenation of all of this really impedes
         # RPM reuse?
-        pushd RPMS/$TARGET_ARCH
-            for file in *; do
+        local dir
+        for dir in RPMS/*; do
+            pushd $dir
+            for file in $(ls); do
                 if [ -h $file ]; then
                     cp $file foo
                     mv foo $file
                 fi
             done
-        popd
+            popd
+        done
+        # also, for i?86, make sure all of the RPMs are in RPMS/$TARGET_ARCH
+        # as that's where LTS expects to find them
+        for dir in RPMS/*; do
+            if [ $dir = RPMS/$TARGET_ARCH ]; then
+                continue
+            fi
+            pushd $dir
+            local files=$(ls)
+            if [ -n "$files" ]; then
+                cp -al $files ../$TARGET_ARCH
+            fi
+            popd
+        done
     else
         return 1
     fi
@@ -1381,6 +1561,9 @@ backtrace() {
         funcname=${FUNCNAME[$n - 1]}
         sourcefile=$(basename ${BASH_SOURCE[$n]})
         lineno=${BASH_LINENO[$n - 1]}
+        if [ $n = 1 ]; then
+            let lineno-=11
+        fi
         # Display function arguments
         if [[ ! -z "${BASH_ARGV[@]}" ]]; then
             local args newarg j p=0
@@ -1389,7 +1572,7 @@ backtrace() {
                 args="${args:+${args} }'${newarg}'"
             done
             let p+=${BASH_ARGC[$n - 1]}
-       fi
+        fi
         echo "  ${funcname} ${args:+${args} }at ${sourcefile}:${lineno}"
     done
 
@@ -1401,7 +1584,11 @@ backtrace() {
     #echo ${FUNCNAME[*]}
     local i=$((${#FUNCNAME[@]} - 1))
     while [ $i -ge 0 ]; do
-        local SOURCELINE="${BASH_SOURCE[$i + 1]}:${BASH_LINENO[$i]}"
+        local lineno=${BASH_LINENO[$i]}
+        if [ $i = 0 ]; then
+            let lineno-=11
+        fi
+        local SOURCELINE="${BASH_SOURCE[$i + 1]}:${lineno}"
         # Can't figure out how to get function args from other frames...
         local FUNCTION="${FUNCNAME[$i]}()"
         echo "$SOURCELINE:$FUNCTION"
@@ -1414,9 +1601,30 @@ backtrace() {
 
 }
 
+seen_list=$(new_list)
+trap 'set +x;
+echo "An unexpected error has occurred at ${BASH_SOURCE[0]##*/}:$((LINENO-1)).
+Unfortunately the above line number in the message may or may not be correct,
+but details have been send to the lbuild maintainer.  Attempting to continue."; (echo "Untrapped error"
+echo
+# have we seen this one
+echo "checking seen list for ${BASH_SOURCE[0]}:${BASH_LINENO[0]}"
+
+if is_list_member "$seen_list" "${BASH_SOURCE[0]}:${BASH_LINENO[0]}"; then
+  echo "seen this one already"
+else
+  seen_list=$(add_list "$seen_list" "${BASH_SOURCE[0]}:${BASH_LINENO[0]}")
+fi
+backtrace
+echo
+echo "Environment:"
+set
+) | mail -s "Untrapped error at ${BASH_SOURCE[0]##*/}:$((LINENO-15)) on $HOSTNAME" brian@sun.com >&2; set $xtrace' ERR
+set -E
+
 [ -r ~/.lbuildrc ] && . ~/.lbuildrc
 
-options=$(getopt -o d:D:h -l kerneltree:,distro:,kernelrpm:,reusebuild:,patchless,ldiskfs,ccache,reuse:,norpm,disable-datestamp,external-patches:,timestamp:,extraversion:,kerneldir:,linux:,lustre:,nodownload,nosrc,ofed-version:,publish,release,src,stage:,tag:,target:,target-archs:,with-linux:,xen -- "$@")
+options=$(getopt -o d:D:h -l kerneltree:,distro:,kernelrpm:,reusebuild:,patchless,ldiskfs,ccache,reuse:,norpm,disable-datestamp,external-patches:,timestamp:,extraversion:,kerneldir:,linux:,lustre:,nodownload,nosrc,ofed-version:,publish,release,set-value:,src,stage:,tag:,target:,target-archs:,with-linux:,xen -- "$@")
 
 if [ $? != 0 ]; then
     usage 1
@@ -1505,7 +1713,9 @@ while [ "$1" ]; do
             shift 2
             ;;
         --lustre)
-            LUSTRE=$2
+            if ! LUSTRE=$(canon_filepath "$2"); then
+                fatal 1 "Could not determine the canonical location of $2"
+            fi
             shift 2
             ;;
         --nodownload)
@@ -1555,8 +1765,17 @@ while [ "$1" ]; do
             XEN=true
             shift
             ;;
+        --set-value)
+            eval $2
+            shift 2
+            ;;
         --)
             shift
+            # there are actually some lustre configure flags that we need to
+            # handle ourselves (but we still give them to configure)
+            if [[ \ $@\  == *\ --disable-tests\ * ]]; then
+                LUSTRE_TESTS=false
+            fi
             CONFIGURE_FLAGS=$@
             CONFIGURE_FLAGS="$CONFIGURE_FLAGS --enable-liblustre --enable-liblustre-tests"
             break
@@ -1571,8 +1790,11 @@ check_options
 
 unpack_lustre
 
+# XXX - should we _always_ get the buildid from the META file?  what are the
+# other (i.e. non-lustre-tarball use cases of lbuild)?
+BUILDID=$(sed -ne '/^BUILDID =/s/.*= *//p' lustre/META)
+
 load_target
-EXTRA_VERSION_DELIMITER=${EXTRA_VERSION_DELIMITER:-"-"}
 
 if [ -n "$OFED_VERSION" -a "$OFED_VERSION" != "inkernel" ]; then
     download_ofed
@@ -1582,36 +1804,19 @@ fi
 # make sure the RPM build environment is set up
 create_rpmbuild_dirs
 
-trap '[ -n "$CCACHE" ] && ccache -s' EXIT
-
 # if an unpacked kernel source tree was given on the command line
 # just build lustre with it (nothing distro kernel specific here)
 if [ -n "$LINUX" ]; then
-    build_lustre
+    build_ofed "${LINUXOBJ:-$LINUX}" "$OFED_VERSION" ||
+        fatal 1 "error building OFED"
+    build_lustre "$LINUX" "$LINUXOBJ"
 else
     if [ -f "${0%/*}/lbuild-$DISTRO" ]; then
-        seen_list=$(new_list)
-        trap '(echo "Untrapped error"
-echo
-# have we seen this one
-echo "checking seen list for ${BASH_SOURCE[0]}:${BASH_LINENO[0]}"
-
-if is_list_member "$seen_list" "${BASH_SOURCE[0]}:${BASH_LINENO[0]}"; then
-  echo "seen this one already"
-else
-  seen_list=$(add_list "$seen_list" "${BASH_SOURCE[0]}:${BASH_LINENO[0]}")
-fi
-backtrace
-echo
-echo "Environment:"
-set
-) | tee >(mail -s "Untrapped error at ${BASH_SOURCE[0]##*/}:${BASH_LINENO[0]} on $HOSTNAME" brian@sun.com) >&2' ERR
-        set -E
-
         source ${0%/*}/lbuild-$DISTRO
 
         build_with_srpm || fatal 1 "Failed to build_with_srpm"
     else
+        EXTRA_VERSION_DELIMITER=${EXTRA_VERSION_DELIMITER:-"-"}
         source ${0%/*}/lbuild.old_school
 
         old_school_download_kernel