+
+}
+
+#check if we need to build separate ldiskfs RPM
+skeep_ldiskfs_rpm() {
+ local tag="$1"
+
+ 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
+
+ echo $skip
+
+}
+
+set_rpm_smp_type() {
+
+ local infact_arch="${TARGET_ARCH}"
+
+ RPMSMPTYPE=""
+ [ "$infact_arch" == "i586" ] && infact_arch="i686"
+
+ local smp_type
+ for smp_type in $SMP_ARCHS; do
+ [ $infact_arch == $smp_type ] && RPMSMPTYPE=smp && break
+ done
+
+ for smp_type in $BIGSMP_ARCHS; do
+ [ $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
+
+}
+
+# This function takes a linux source pool and digs out the linux release
+# from it
+find_linux_release() {
+ local SRCDIR="$1"
+
+ local LINUXRELEASEHEADER=$SRCDIR/include/linux/version.h
+ if [ -s $SRCDIR/include/linux/utsrelease.h ]; then
+ LINUXRELEASEHEADER=$SRCDIR/include/linux/utsrelease.h
+ fi
+
+ sed -ne 's/#define UTS_RELEASE "\(.*\)"$/\1/p' $LINUXRELEASEHEADER
+
+}
+
+# unpack kernel(/source/devel) RPM
+#
+# This function and it's setting of $LINUX and $LINUXOBJ is a total hack that
+# needs to completely refactored. It completely ingores that $BUILD_ARCHS may
+# contain a list of arches for which rpmbuild commands (including the one for
+# lustre itself)
+unpack_linux_devel_rpm() {
+ local kernelrpm="${1}"
+
+ [ -f "$kernelrpm" ] || return 255
+ [ -d $TOPDIR/reused ] || mkdir $TOPDIR/reused || return 255
+
+ pushd $TOPDIR/reused &>/dev/null || return 255
+
+ if ! rpm2cpio < "$kernelrpm" | cpio -id > /dev/null 2>&1; then
+ return 255
+ fi
+
+ # call a distro specific hook, if available
+ if type -p unpack_linux_devel_rpm-$DISTRO; then
+ if ! unpack_linux_devel_rpm-$DISTRO "$kernelrpm"; then
+ return 255
+ fi
+ fi
+
+ popd &>/dev/null
+
+ find_linux_devel_paths $TOPDIR/reused
+
+ return 0
+
+}
+
+build_kernel_ib() {
+ local linux="$1"
+
+ # build kernel-ib{,-devel}
+ local K_SRC="K_SRC"
+ # ofed 1.3 had a bug in the rpm spec
+ if [ "$OFED_VERSION" = "1.3" ]; then
+ K_SRC="KSRC"
+ fi
+
+ local OFED_CORE="--with-core-mod --with-ipoib-mod --with-sdp-mod --with-user_mad-mod --with-user_access-mod --with-addr_trans-mod --with-rds-mod --with-qlgc_vnic-mod --with-madeye-mod"
+ local OFED_HARDWARE="--with-mthca-mod --with-mlx4-mod --with-mlx4_en-mod --with-cxgb3-mod --with-nes-mod"
+ # 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)
+ 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"
+ #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/*); do
+ ed_fragment1="$ed_fragment1
+Patch$n: ${file%%*/}"
+ ed_fragment2="$ed_fragment2
+%patch$n -p0"
+ cp $file ${TOPDIR}/SOURCES
+ let n=$n+1
+ done
+
+ if [ $n -gt 1 ]; then
+ ed $SOURCE <<EOF
+/^Source: /a
+$ed_fragment1
+.
+/^%setup /a
+$ed_fragment2
+.
+wq
+EOF
+ fi
+ fi
+
+ local linuxrelease=$(find_linux_release "$linux")
+ 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 linkflag=""
+ if $use_links; then
+ linkflag="l"
+ fi
+
+ 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"
+
+ # put the temporary location into the final location
+ # (last one wins)
+ mkdir -p "${finallocation%/*}"
+ mv "$location" "$finallocation"
+ rmdir "${location%/*}"
+ return 0
+
+}
+
+reuse() {
+ local module="$1"
+ local dest="$2"
+ local use_links="${3:-false}"
+ local signature="$4"
+
+ 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 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
+
+ # so that we know how stale this entry is
+ touch $REUSEBUILD/$signature/$module/.lastused
+
+ if $use_links; then
+ if ls $REUSEBUILD/$signature/$module/* >/dev/null 2>&1; then
+ cp -al $REUSEBUILD/$signature/$module/* $dest/
+ fi
+ else
+ # copying is pretty heavy
+ # cp -a $REUSEBUILD/$signature/$module/* $dest/
+ # do some creative symlinking instead
+ local dir
+ for dir in BUILD SRPMS SPECS; do
+ if ls $REUSEBUILD/$signature/$module/$dir/* >/dev/null 2>&1; then
+ ln -s $REUSEBUILD/$signature/$module/$dir/* $dest/$dir
+ fi
+ done
+ # sources have to be copied by file because we need SOURCES to
+ # be a dir we can write into
+# could overrun ls's arg list here
+ #ls $REUSEBUILD/$signature/$module/SOURCES/* |
+ find $REUSEBUILD/$signature/$module/SOURCES/ -type f |
+ xargs ln -t $dest/SOURCES -s
+
+ # same for RPMS/* dirs
+# could overrun ls's arg list here
+ #ls $REUSEBUILD/$signature/$module/RPMS/$TARGET_ARCH/* |
+ local dir
+ for dir in $REUSEBUILD/$signature/$module/RPMS/*; do
+ mkdir -p $dest/RPMS/${dir##*/}
+ find $dir -type f |
+ xargs ln -t $dest/RPMS/${dir##*/} -s
+ done
+ fi
+ return 0
+ else
+ return 1
+ fi
+}
+
+basearch() {
+ local arch="$1"
+
+ if [[ $arch = i[3456]86 ]]; then
+ echo "i386"
+ else
+ echo "$arch"
+ fi
+
+}
+
+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 >&${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
+ # in BUILD_ARCHS
+ local release_str
+ if $RELEASE; then
+ local release_str="RELEASE=$RELEASE\n"
+ fi
+
+ 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
+
+ # the extra version string to use for the kernel (which might be a reused
+ # kernel, remember)
+ local kernel_extra_version=""
+ 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
+ echo "Downloading kernel SRPM" >&${outfd}
+ download_srpm "$CANONICAL_TARGET" "$KERNEL_SRPM" >&${outfd}
+ fi
+
+ if ! rpm -ivh $KERNELDIR/$KERNEL_SRPM \
+ --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."
+ fi
+
+ # put the Lustre kernel patch into the RPM build tree
+ cp $FULL_PATCH $TOPDIR/SOURCES/linux-${lnxmaj}-lustre.patch
+ 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
+
+ # figure out the EXTRA_VERSION of the kernel we built or are re-using
+ local KERNEL_RPM
+ if ! KERNEL_RPM=$(find_rpm "$TOPDIR/RPMS/$TARGET_ARCH/" provides "^kernel ="); then
+ fatal 1 "Failed to find a kernel RPM in $TOPDIR/RPMS/$TARGET_ARCH/"
+ fi
+ kernel_extra_version=$(rpm -q --queryformat "%{RELEASE}" -p $TOPDIR/RPMS/$TARGET_ARCH/$KERNEL_RPM)
+
+ # should now have the following RPMs
+ # $TOPDIR/RPMS/$arch/kernel-lustre-2.6.18-53.1.21.el5_lustre.1.6.5.1.$arch.rpm
+ # $TOPDIR/RPMS/$arch/kernel-lustre-devel-2.6.18-53.1.21.el5_lustre.1.6.5.1.$arch.rpm
+ # $TOPDIR/RPMS/$arch/kernel-lustre-headers-2.6.18-53.1.21.el5_lustre.1.6.5.1.$arch.rpm
+ # $TOPDIR/RPMS/$arch/kernel-lustre-debuginfo-common-2.6.18-53.1.21.el5_lustre.1.6.5.1.$arch.rpm
+ # $TOPDIR/RPMS/$arch/kernel-lustre-debuginfo-2.6.18-53.1.21.el5_lustre.1.6.5.1.$arch.rpm
+
+ echo $kernel_extra_version
+ return 0
+
+}
+
+# build OFED
+# globals used:
+# TOPDIR
+# REUSEBUILD, USE_BUILD_CACHE
+# CONFIGURE_FLAGS
+
+build_ofed() {
+ local linux="$1"
+ local ofed_version="$2"
+
+ # 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
+
+ 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
+
+ # 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"
+ local CAN_LINK_FOR_REUSE=false
+ touch $REUSEBUILD/$$
+ if cp -al $REUSEBUILD/$$ $TOPDIR/; then
+ CAN_LINK_FOR_REUSE=true
+ fi
+ rm $REUSEBUILD/$$
+ fi
+
+ 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
+ function mv_back {
+ pushd bak
+ find . | cpio -pudlm ..
+ popd
+ rm -rf bak
+ }
+ create_rpmbuild_dirs
+ 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
+ error "Failed to store OFED RPMS for reuse"
+ mv_back
+ return 1
+ fi
+ # 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
+